aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/stex.c
diff options
context:
space:
mode:
authorEd Lin <ed.lin@promise.com>2009-03-31 21:30:19 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-04-03 10:23:08 -0400
commitf14981616205eedb6fe8b24a09ec103ed976e122 (patch)
tree50cc151e9350d8ccdab00fefa7f6adeadc8d9391 /drivers/scsi/stex.c
parent97c8389d54b9665c38105ea72a428a44b97ff2f6 (diff)
[SCSI] stex: small code fixes and changes
These are some small code fixes and changes, including: - use 64 bit when possible - remove some unnecessary code (in interrupt, queuecommand routine etc.) - code change for reset handler Signed-off-by: Ed Lin <ed.lin@promise.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/stex.c')
-rw-r--r--drivers/scsi/stex.c125
1 files changed, 60 insertions, 65 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 47b614e8580c..de6c30e37463 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -160,26 +160,22 @@ struct st_sgitem {
160 u8 ctrl; /* SG_CF_xxx */ 160 u8 ctrl; /* SG_CF_xxx */
161 u8 reserved[3]; 161 u8 reserved[3];
162 __le32 count; 162 __le32 count;
163 __le32 addr; 163 __le64 addr;
164 __le32 addr_hi;
165}; 164};
166 165
167struct st_sgtable { 166struct st_sgtable {
168 __le16 sg_count; 167 __le16 sg_count;
169 __le16 max_sg_count; 168 __le16 max_sg_count;
170 __le32 sz_in_byte; 169 __le32 sz_in_byte;
171 struct st_sgitem table[ST_MAX_SG];
172}; 170};
173 171
174struct handshake_frame { 172struct handshake_frame {
175 __le32 rb_phy; /* request payload queue physical address */ 173 __le64 rb_phy; /* request payload queue physical address */
176 __le32 rb_phy_hi;
177 __le16 req_sz; /* size of each request payload */ 174 __le16 req_sz; /* size of each request payload */
178 __le16 req_cnt; /* count of reqs the buffer can hold */ 175 __le16 req_cnt; /* count of reqs the buffer can hold */
179 __le16 status_sz; /* size of each status payload */ 176 __le16 status_sz; /* size of each status payload */
180 __le16 status_cnt; /* count of status the buffer can hold */ 177 __le16 status_cnt; /* count of status the buffer can hold */
181 __le32 hosttime; /* seconds from Jan 1, 1970 (GMT) */ 178 __le64 hosttime; /* seconds from Jan 1, 1970 (GMT) */
182 __le32 hosttime_hi;
183 u8 partner_type; /* who sends this frame */ 179 u8 partner_type; /* who sends this frame */
184 u8 reserved0[7]; 180 u8 reserved0[7];
185 __le32 partner_ver_major; 181 __le32 partner_ver_major;
@@ -273,6 +269,7 @@ struct st_ccb {
273 u32 req_type; 269 u32 req_type;
274 u8 srb_status; 270 u8 srb_status;
275 u8 scsi_status; 271 u8 scsi_status;
272 u8 reserved[2];
276}; 273};
277 274
278struct st_hba { 275struct st_hba {
@@ -293,7 +290,6 @@ struct st_hba {
293 void *copy_buffer; /* temp buffer for driver-handled commands */ 290 void *copy_buffer; /* temp buffer for driver-handled commands */
294 struct st_ccb ccb[MU_MAX_REQUEST]; 291 struct st_ccb ccb[MU_MAX_REQUEST];
295 struct st_ccb *wait_ccb; 292 struct st_ccb *wait_ccb;
296 wait_queue_head_t waitq;
297 293
298 unsigned int mu_status; 294 unsigned int mu_status;
299 int out_req_cnt; 295 int out_req_cnt;
@@ -318,19 +314,17 @@ MODULE_DESCRIPTION("Promise Technology SuperTrak EX Controllers");
318MODULE_LICENSE("GPL"); 314MODULE_LICENSE("GPL");
319MODULE_VERSION(ST_DRIVER_VERSION); 315MODULE_VERSION(ST_DRIVER_VERSION);
320 316
321static void stex_gettime(__le32 *time) 317static void stex_gettime(__le64 *time)
322{ 318{
323 struct timeval tv; 319 struct timeval tv;
324 320
325 do_gettimeofday(&tv); 321 do_gettimeofday(&tv);
326 *time = cpu_to_le32(tv.tv_sec & 0xffffffff); 322 *time = cpu_to_le64(tv.tv_sec);
327 *(time + 1) = cpu_to_le32((tv.tv_sec >> 16) >> 16);
328} 323}
329 324
330static struct status_msg *stex_get_status(struct st_hba *hba) 325static struct status_msg *stex_get_status(struct st_hba *hba)
331{ 326{
332 struct status_msg *status = 327 struct status_msg *status = hba->status_buffer + hba->status_tail;
333 hba->status_buffer + hba->status_tail;
334 328
335 ++hba->status_tail; 329 ++hba->status_tail;
336 hba->status_tail %= MU_STATUS_COUNT; 330 hba->status_tail %= MU_STATUS_COUNT;
@@ -366,32 +360,30 @@ static int stex_map_sg(struct st_hba *hba,
366 struct scsi_cmnd *cmd; 360 struct scsi_cmnd *cmd;
367 struct scatterlist *sg; 361 struct scatterlist *sg;
368 struct st_sgtable *dst; 362 struct st_sgtable *dst;
363 struct st_sgitem *table;
369 int i, nseg; 364 int i, nseg;
370 365
371 cmd = ccb->cmd; 366 cmd = ccb->cmd;
372 dst = (struct st_sgtable *)req->variable;
373 dst->max_sg_count = cpu_to_le16(ST_MAX_SG);
374 dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd));
375
376 nseg = scsi_dma_map(cmd); 367 nseg = scsi_dma_map(cmd);
377 if (nseg < 0) 368 BUG_ON(nseg < 0);
378 return -EIO;
379 if (nseg) { 369 if (nseg) {
370 dst = (struct st_sgtable *)req->variable;
371
380 ccb->sg_count = nseg; 372 ccb->sg_count = nseg;
381 dst->sg_count = cpu_to_le16((u16)nseg); 373 dst->sg_count = cpu_to_le16((u16)nseg);
374 dst->max_sg_count = cpu_to_le16(hba->host->sg_tablesize);
375 dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd));
382 376
377 table = (struct st_sgitem *)(dst + 1);
383 scsi_for_each_sg(cmd, sg, nseg, i) { 378 scsi_for_each_sg(cmd, sg, nseg, i) {
384 dst->table[i].count = cpu_to_le32((u32)sg_dma_len(sg)); 379 table[i].count = cpu_to_le32((u32)sg_dma_len(sg));
385 dst->table[i].addr = 380 table[i].addr = cpu_to_le64(sg_dma_address(sg));
386 cpu_to_le32(sg_dma_address(sg) & 0xffffffff); 381 table[i].ctrl = SG_CF_64B | SG_CF_HOST;
387 dst->table[i].addr_hi =
388 cpu_to_le32((sg_dma_address(sg) >> 16) >> 16);
389 dst->table[i].ctrl = SG_CF_64B | SG_CF_HOST;
390 } 382 }
391 dst->table[--i].ctrl |= SG_CF_EOT; 383 table[--i].ctrl |= SG_CF_EOT;
392 } 384 }
393 385
394 return 0; 386 return nseg;
395} 387}
396 388
397static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) 389static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
@@ -400,7 +392,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
400 size_t count = sizeof(struct st_frame); 392 size_t count = sizeof(struct st_frame);
401 393
402 p = hba->copy_buffer; 394 p = hba->copy_buffer;
403 count = scsi_sg_copy_to_buffer(ccb->cmd, p, count); 395 scsi_sg_copy_to_buffer(ccb->cmd, p, count);
404 memset(p->base, 0, sizeof(u32)*6); 396 memset(p->base, 0, sizeof(u32)*6);
405 *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); 397 *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0);
406 p->rom_addr = 0; 398 p->rom_addr = 0;
@@ -418,15 +410,13 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
418 p->subid = 410 p->subid =
419 hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; 411 hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device;
420 412
421 count = scsi_sg_copy_from_buffer(ccb->cmd, p, count); 413 scsi_sg_copy_from_buffer(ccb->cmd, p, count);
422} 414}
423 415
424static void 416static void
425stex_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag) 417stex_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag)
426{ 418{
427 req->tag = cpu_to_le16(tag); 419 req->tag = cpu_to_le16(tag);
428 req->task_attr = TASK_ATTRIBUTE_SIMPLE;
429 req->task_manage = 0; /* not supported yet */
430 420
431 hba->ccb[tag].req = req; 421 hba->ccb[tag].req = req;
432 hba->out_req_cnt++; 422 hba->out_req_cnt++;
@@ -442,7 +432,7 @@ stex_slave_alloc(struct scsi_device *sdev)
442 /* Cheat: usually extracted from Inquiry data */ 432 /* Cheat: usually extracted from Inquiry data */
443 sdev->tagged_supported = 1; 433 sdev->tagged_supported = 1;
444 434
445 scsi_activate_tcq(sdev, ST_CMD_PER_LUN); 435 scsi_activate_tcq(sdev, sdev->host->can_queue);
446 436
447 return 0; 437 return 0;
448} 438}
@@ -469,7 +459,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
469{ 459{
470 struct st_hba *hba; 460 struct st_hba *hba;
471 struct Scsi_Host *host; 461 struct Scsi_Host *host;
472 unsigned int id,lun; 462 unsigned int id, lun;
473 struct req_msg *req; 463 struct req_msg *req;
474 u16 tag; 464 u16 tag;
475 465
@@ -572,7 +562,6 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
572 hba->ccb[tag].cmd = cmd; 562 hba->ccb[tag].cmd = cmd;
573 hba->ccb[tag].sense_bufflen = SCSI_SENSE_BUFFERSIZE; 563 hba->ccb[tag].sense_bufflen = SCSI_SENSE_BUFFERSIZE;
574 hba->ccb[tag].sense_buffer = cmd->sense_buffer; 564 hba->ccb[tag].sense_buffer = cmd->sense_buffer;
575 hba->ccb[tag].req_type = 0;
576 565
577 if (cmd->sc_data_direction != DMA_NONE) 566 if (cmd->sc_data_direction != DMA_NONE)
578 stex_map_sg(hba, req, &hba->ccb[tag]); 567 stex_map_sg(hba, req, &hba->ccb[tag]);
@@ -586,7 +575,7 @@ static void stex_scsi_done(struct st_ccb *ccb)
586 struct scsi_cmnd *cmd = ccb->cmd; 575 struct scsi_cmnd *cmd = ccb->cmd;
587 int result; 576 int result;
588 577
589 if (ccb->srb_status == SRB_STATUS_SUCCESS || ccb->srb_status == 0) { 578 if (ccb->srb_status == SRB_STATUS_SUCCESS || ccb->srb_status == 0) {
590 result = ccb->scsi_status; 579 result = ccb->scsi_status;
591 switch (ccb->scsi_status) { 580 switch (ccb->scsi_status) {
592 case SAM_STAT_GOOD: 581 case SAM_STAT_GOOD:
@@ -626,8 +615,6 @@ static void stex_scsi_done(struct st_ccb *ccb)
626static void stex_copy_data(struct st_ccb *ccb, 615static void stex_copy_data(struct st_ccb *ccb,
627 struct status_msg *resp, unsigned int variable) 616 struct status_msg *resp, unsigned int variable)
628{ 617{
629 size_t count = variable;
630
631 if (resp->scsi_status != SAM_STAT_GOOD) { 618 if (resp->scsi_status != SAM_STAT_GOOD) {
632 if (ccb->sense_buffer != NULL) 619 if (ccb->sense_buffer != NULL)
633 memcpy(ccb->sense_buffer, resp->variable, 620 memcpy(ccb->sense_buffer, resp->variable,
@@ -637,17 +624,16 @@ static void stex_copy_data(struct st_ccb *ccb,
637 624
638 if (ccb->cmd == NULL) 625 if (ccb->cmd == NULL)
639 return; 626 return;
640 count = scsi_sg_copy_from_buffer(ccb->cmd, resp->variable, count); 627 scsi_sg_copy_from_buffer(ccb->cmd, resp->variable, variable);
641} 628}
642 629
643static void stex_ys_commands(struct st_hba *hba, 630static void stex_check_cmd(struct st_hba *hba,
644 struct st_ccb *ccb, struct status_msg *resp) 631 struct st_ccb *ccb, struct status_msg *resp)
645{ 632{
646 if (ccb->cmd->cmnd[0] == MGT_CMD && 633 if (ccb->cmd->cmnd[0] == MGT_CMD &&
647 resp->scsi_status != SAM_STAT_CHECK_CONDITION) { 634 resp->scsi_status != SAM_STAT_CHECK_CONDITION)
648 scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) - 635 scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) -
649 le32_to_cpu(*(__le32 *)&resp->variable[0])); 636 le32_to_cpu(*(__le32 *)&resp->variable[0]));
650 }
651} 637}
652 638
653static void stex_mu_intr(struct st_hba *hba, u32 doorbell) 639static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
@@ -658,7 +644,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
658 unsigned int size; 644 unsigned int size;
659 u16 tag; 645 u16 tag;
660 646
661 if (!(doorbell & MU_OUTBOUND_DOORBELL_STATUSHEADCHANGED)) 647 if (unlikely(!(doorbell & MU_OUTBOUND_DOORBELL_STATUSHEADCHANGED)))
662 return; 648 return;
663 649
664 /* status payloads */ 650 /* status payloads */
@@ -693,13 +679,13 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
693 continue; 679 continue;
694 } 680 }
695 681
682 hba->out_req_cnt--;
696 ccb = &hba->ccb[tag]; 683 ccb = &hba->ccb[tag];
697 if (hba->wait_ccb == ccb) 684 if (unlikely(hba->wait_ccb == ccb))
698 hba->wait_ccb = NULL; 685 hba->wait_ccb = NULL;
699 if (unlikely(ccb->req == NULL)) { 686 if (unlikely(ccb->req == NULL)) {
700 printk(KERN_WARNING DRV_NAME 687 printk(KERN_WARNING DRV_NAME
701 "(%s): lagging req\n", pci_name(hba->pdev)); 688 "(%s): lagging req\n", pci_name(hba->pdev));
702 hba->out_req_cnt--;
703 continue; 689 continue;
704 } 690 }
705 691
@@ -720,7 +706,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
720 706
721 if (likely(ccb->cmd != NULL)) { 707 if (likely(ccb->cmd != NULL)) {
722 if (hba->cardtype == st_yosemite) 708 if (hba->cardtype == st_yosemite)
723 stex_ys_commands(hba, ccb, resp); 709 stex_check_cmd(hba, ccb, resp);
724 710
725 if (unlikely(ccb->cmd->cmnd[0] == PASSTHRU_CMD && 711 if (unlikely(ccb->cmd->cmnd[0] == PASSTHRU_CMD &&
726 ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER)) 712 ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER))
@@ -728,17 +714,8 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
728 714
729 scsi_dma_unmap(ccb->cmd); 715 scsi_dma_unmap(ccb->cmd);
730 stex_scsi_done(ccb); 716 stex_scsi_done(ccb);
731 hba->out_req_cnt--; 717 } else
732 } else if (ccb->req_type & PASSTHRU_REQ_TYPE) {
733 hba->out_req_cnt--;
734 if (ccb->req_type & PASSTHRU_REQ_NO_WAKEUP) {
735 ccb->req_type = 0;
736 continue;
737 }
738 ccb->req_type = 0; 718 ccb->req_type = 0;
739 if (waitqueue_active(&hba->waitq))
740 wake_up(&hba->waitq);
741 }
742 } 719 }
743 720
744update_status: 721update_status:
@@ -800,13 +777,14 @@ static int stex_handshake(struct st_hba *hba)
800 data = readl(base + OMR1); 777 data = readl(base + OMR1);
801 if ((data & 0xffff0000) == MU_HANDSHAKE_SIGNATURE_HALF) { 778 if ((data & 0xffff0000) == MU_HANDSHAKE_SIGNATURE_HALF) {
802 data &= 0x0000ffff; 779 data &= 0x0000ffff;
803 if (hba->host->can_queue > data) 780 if (hba->host->can_queue > data) {
804 hba->host->can_queue = data; 781 hba->host->can_queue = data;
782 hba->host->cmd_per_lun = data;
783 }
805 } 784 }
806 785
807 h = (struct handshake_frame *)(hba->dma_mem + MU_REQ_BUFFER_SIZE); 786 h = (struct handshake_frame *)hba->status_buffer;
808 h->rb_phy = cpu_to_le32(hba->dma_handle); 787 h->rb_phy = cpu_to_le64(hba->dma_handle);
809 h->rb_phy_hi = cpu_to_le32((hba->dma_handle >> 16) >> 16);
810 h->req_sz = cpu_to_le16(sizeof(struct req_msg)); 788 h->req_sz = cpu_to_le16(sizeof(struct req_msg));
811 h->req_cnt = cpu_to_le16(MU_REQ_COUNT); 789 h->req_cnt = cpu_to_le16(MU_REQ_COUNT);
812 h->status_sz = cpu_to_le16(sizeof(struct status_msg)); 790 h->status_sz = cpu_to_le16(sizeof(struct status_msg));
@@ -950,8 +928,8 @@ static void stex_hard_reset(struct st_hba *hba)
950static int stex_reset(struct scsi_cmnd *cmd) 928static int stex_reset(struct scsi_cmnd *cmd)
951{ 929{
952 struct st_hba *hba; 930 struct st_hba *hba;
953 unsigned long flags; 931 void __iomem *base;
954 unsigned long before; 932 unsigned long flags, before;
955 933
956 hba = (struct st_hba *) &cmd->device->host->hostdata[0]; 934 hba = (struct st_hba *) &cmd->device->host->hostdata[0];
957 935
@@ -994,7 +972,23 @@ static int stex_reset(struct scsi_cmnd *cmd)
994 msleep(1); 972 msleep(1);
995 } 973 }
996 974
975 base = hba->mmio_base;
976 writel(0, base + IMR0);
977 readl(base + IMR0);
978 writel(0, base + OMR0);
979 readl(base + OMR0);
980 writel(0, base + IMR1);
981 readl(base + IMR1);
982 writel(0, base + OMR1);
983 readl(base + OMR1); /* flush */
984 spin_lock_irqsave(hba->host->host_lock, flags);
985 hba->req_head = 0;
986 hba->req_tail = 0;
987 hba->status_head = 0;
988 hba->status_tail = 0;
989 hba->out_req_cnt = 0;
997 hba->mu_status = MU_STATE_STARTED; 990 hba->mu_status = MU_STATE_STARTED;
991 spin_unlock_irqrestore(hba->host->host_lock, flags);
998 return SUCCESS; 992 return SUCCESS;
999} 993}
1000 994
@@ -1130,7 +1124,6 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1130 1124
1131 hba->host = host; 1125 hba->host = host;
1132 hba->pdev = pdev; 1126 hba->pdev = pdev;
1133 init_waitqueue_head(&hba->waitq);
1134 1127
1135 err = request_irq(pdev->irq, stex_intr, IRQF_SHARED, DRV_NAME, hba); 1128 err = request_irq(pdev->irq, stex_intr, IRQF_SHARED, DRV_NAME, hba);
1136 if (err) { 1129 if (err) {
@@ -1206,16 +1199,18 @@ static void stex_hba_stop(struct st_hba *hba)
1206 hba->ccb[tag].sg_count = 0; 1199 hba->ccb[tag].sg_count = 0;
1207 hba->ccb[tag].sense_bufflen = 0; 1200 hba->ccb[tag].sense_bufflen = 0;
1208 hba->ccb[tag].sense_buffer = NULL; 1201 hba->ccb[tag].sense_buffer = NULL;
1209 hba->ccb[tag].req_type |= PASSTHRU_REQ_TYPE; 1202 hba->ccb[tag].req_type = PASSTHRU_REQ_TYPE;
1210 1203
1211 stex_send_cmd(hba, req, tag); 1204 stex_send_cmd(hba, req, tag);
1212 spin_unlock_irqrestore(hba->host->host_lock, flags); 1205 spin_unlock_irqrestore(hba->host->host_lock, flags);
1213 1206
1214 before = jiffies; 1207 before = jiffies;
1215 while (hba->ccb[tag].req_type & PASSTHRU_REQ_TYPE) { 1208 while (hba->ccb[tag].req_type & PASSTHRU_REQ_TYPE) {
1216 if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ)) 1209 if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ)) {
1210 hba->ccb[tag].req_type = 0;
1217 return; 1211 return;
1218 msleep(10); 1212 }
1213 msleep(1);
1219 } 1214 }
1220} 1215}
1221 1216