aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Lin <ed.lin@promise.com>2006-09-27 07:23:41 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-10-01 16:05:52 -0400
commitfb4f66be59f3dcc66fda2e681f1fc77b5cc4508d (patch)
tree89f40c17fdb8b1f334ec3350c30186a0e4e3348e
parentf903d7b7a80b7c3103335d506533790a322da87b (diff)
[SCSI] stex: add new device (id 0x8650) support
A new device (id 0x8650, nickname 'yosemite') support is added. It's basically the same, except for following items: - mapping of id and lun by firmware - special handling for some commands in interrupt routine - change of internal copy function for these special commands - different reset handling code - different shutdown notification command Signed-off-by: Ed Lin <ed.lin@promise.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/stex.c194
1 files changed, 164 insertions, 30 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index cfb29716b5e2..a54e6c1026b7 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -11,7 +11,7 @@
11 * Written By: 11 * Written By:
12 * Ed Lin <promise_linux@promise.com> 12 * Ed Lin <promise_linux@promise.com>
13 * 13 *
14 * Version: 2.9.0.13 14 * Version: 3.0.0.1
15 * 15 *
16 */ 16 */
17 17
@@ -37,11 +37,11 @@
37#include <scsi/scsi_tcq.h> 37#include <scsi/scsi_tcq.h>
38 38
39#define DRV_NAME "stex" 39#define DRV_NAME "stex"
40#define ST_DRIVER_VERSION "2.9.0.13" 40#define ST_DRIVER_VERSION "3.0.0.1"
41#define ST_VER_MAJOR 2 41#define ST_VER_MAJOR 3
42#define ST_VER_MINOR 9 42#define ST_VER_MINOR 0
43#define ST_OEM 0 43#define ST_OEM 0
44#define ST_BUILD_VER 13 44#define ST_BUILD_VER 1
45 45
46enum { 46enum {
47 /* MU register offset */ 47 /* MU register offset */
@@ -120,12 +120,18 @@ enum {
120 120
121 st_shasta = 0, 121 st_shasta = 0,
122 st_vsc = 1, 122 st_vsc = 1,
123 st_yosemite = 2,
123 124
124 PASSTHRU_REQ_TYPE = 0x00000001, 125 PASSTHRU_REQ_TYPE = 0x00000001,
125 PASSTHRU_REQ_NO_WAKEUP = 0x00000100, 126 PASSTHRU_REQ_NO_WAKEUP = 0x00000100,
126 ST_INTERNAL_TIMEOUT = 30, 127 ST_INTERNAL_TIMEOUT = 30,
127 128
129 ST_TO_CMD = 0,
130 ST_FROM_CMD = 1,
131
128 /* vendor specific commands of Promise */ 132 /* vendor specific commands of Promise */
133 MGT_CMD = 0xd8,
134 SINBAND_MGT_CMD = 0xd9,
129 ARRAY_CMD = 0xe0, 135 ARRAY_CMD = 0xe0,
130 CONTROLLER_CMD = 0xe1, 136 CONTROLLER_CMD = 0xe1,
131 DEBUGGING_CMD = 0xe2, 137 DEBUGGING_CMD = 0xe2,
@@ -133,14 +139,48 @@ enum {
133 139
134 PASSTHRU_GET_ADAPTER = 0x05, 140 PASSTHRU_GET_ADAPTER = 0x05,
135 PASSTHRU_GET_DRVVER = 0x10, 141 PASSTHRU_GET_DRVVER = 0x10,
142
143 CTLR_CONFIG_CMD = 0x03,
144 CTLR_SHUTDOWN = 0x0d,
145
136 CTLR_POWER_STATE_CHANGE = 0x0e, 146 CTLR_POWER_STATE_CHANGE = 0x0e,
137 CTLR_POWER_SAVING = 0x01, 147 CTLR_POWER_SAVING = 0x01,
138 148
139 PASSTHRU_SIGNATURE = 0x4e415041, 149 PASSTHRU_SIGNATURE = 0x4e415041,
150 MGT_CMD_SIGNATURE = 0xba,
140 151
141 INQUIRY_EVPD = 0x01, 152 INQUIRY_EVPD = 0x01,
142}; 153};
143 154
155/* SCSI inquiry data */
156typedef struct st_inq {
157 u8 DeviceType :5;
158 u8 DeviceTypeQualifier :3;
159 u8 DeviceTypeModifier :7;
160 u8 RemovableMedia :1;
161 u8 Versions;
162 u8 ResponseDataFormat :4;
163 u8 HiSupport :1;
164 u8 NormACA :1;
165 u8 ReservedBit :1;
166 u8 AERC :1;
167 u8 AdditionalLength;
168 u8 Reserved[2];
169 u8 SoftReset :1;
170 u8 CommandQueue :1;
171 u8 Reserved2 :1;
172 u8 LinkedCommands :1;
173 u8 Synchronous :1;
174 u8 Wide16Bit :1;
175 u8 Wide32Bit :1;
176 u8 RelativeAddressing :1;
177 u8 VendorId[8];
178 u8 ProductId[16];
179 u8 ProductRevisionLevel[4];
180 u8 VendorSpecific[20];
181 u8 Reserved3[40];
182} ST_INQ;
183
144struct st_sgitem { 184struct st_sgitem {
145 u8 ctrl; /* SG_CF_xxx */ 185 u8 ctrl; /* SG_CF_xxx */
146 u8 reserved[3]; 186 u8 reserved[3];
@@ -242,7 +282,8 @@ struct st_drvver {
242#define MU_REQ_BUFFER_SIZE (MU_REQ_COUNT * sizeof(struct req_msg)) 282#define MU_REQ_BUFFER_SIZE (MU_REQ_COUNT * sizeof(struct req_msg))
243#define MU_STATUS_BUFFER_SIZE (MU_STATUS_COUNT * sizeof(struct status_msg)) 283#define MU_STATUS_BUFFER_SIZE (MU_STATUS_COUNT * sizeof(struct status_msg))
244#define MU_BUFFER_SIZE (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE) 284#define MU_BUFFER_SIZE (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE)
245#define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + sizeof(struct st_frame)) 285#define STEX_EXTRA_SIZE max(sizeof(struct st_frame), sizeof(ST_INQ))
286#define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + STEX_EXTRA_SIZE)
246 287
247struct st_ccb { 288struct st_ccb {
248 struct req_msg *req; 289 struct req_msg *req;
@@ -403,7 +444,7 @@ static int stex_map_sg(struct st_hba *hba,
403} 444}
404 445
405static void stex_internal_copy(struct scsi_cmnd *cmd, 446static void stex_internal_copy(struct scsi_cmnd *cmd,
406 const void *src, size_t *count, int sg_count) 447 const void *src, size_t *count, int sg_count, int direction)
407{ 448{
408 size_t lcount; 449 size_t lcount;
409 size_t len; 450 size_t len;
@@ -427,7 +468,10 @@ static void stex_internal_copy(struct scsi_cmnd *cmd,
427 } else 468 } else
428 d = cmd->request_buffer; 469 d = cmd->request_buffer;
429 470
430 memcpy(d, s, len); 471 if (direction == ST_TO_CMD)
472 memcpy(d, s, len);
473 else
474 memcpy(s, d, len);
431 475
432 lcount -= len; 476 lcount -= len;
433 if (cmd->use_sg) 477 if (cmd->use_sg)
@@ -449,7 +493,7 @@ static int stex_direct_copy(struct scsi_cmnd *cmd,
449 return 0; 493 return 0;
450 } 494 }
451 495
452 stex_internal_copy(cmd, src, &cp_len, n_elem); 496 stex_internal_copy(cmd, src, &cp_len, n_elem, ST_TO_CMD);
453 497
454 if (cmd->use_sg) 498 if (cmd->use_sg)
455 pci_unmap_sg(hba->pdev, cmd->request_buffer, 499 pci_unmap_sg(hba->pdev, cmd->request_buffer,
@@ -480,7 +524,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
480 p->subid = 524 p->subid =
481 hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; 525 hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device;
482 526
483 stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count); 527 stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_TO_CMD);
484} 528}
485 529
486static void 530static void
@@ -594,8 +638,14 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
594 return SCSI_MLQUEUE_HOST_BUSY; 638 return SCSI_MLQUEUE_HOST_BUSY;
595 639
596 req = stex_alloc_req(hba); 640 req = stex_alloc_req(hba);
597 req->lun = lun; 641
598 req->target = id; 642 if (hba->cardtype == st_yosemite) {
643 req->lun = lun * (ST_MAX_TARGET_NUM - 1) + id;
644 req->target = 0;
645 } else {
646 req->lun = lun;
647 req->target = id;
648 }
599 649
600 /* cdb */ 650 /* cdb */
601 memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH); 651 memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH);
@@ -679,7 +729,51 @@ static void stex_copy_data(struct st_ccb *ccb,
679 729
680 if (ccb->cmd == NULL) 730 if (ccb->cmd == NULL)
681 return; 731 return;
682 stex_internal_copy(ccb->cmd, resp->variable, &count, ccb->sg_count); 732 stex_internal_copy(ccb->cmd,
733 resp->variable, &count, ccb->sg_count, ST_TO_CMD);
734}
735
736static void stex_ys_commands(struct st_hba *hba,
737 struct st_ccb *ccb, struct status_msg *resp)
738{
739 size_t count;
740
741 if (ccb->cmd->cmnd[0] == MGT_CMD &&
742 resp->scsi_status != SAM_STAT_CHECK_CONDITION) {
743 ccb->cmd->request_bufflen =
744 le32_to_cpu(*(__le32 *)&resp->variable[0]);
745 return;
746 }
747
748 if (resp->srb_status != 0)
749 return;
750
751 /* determine inquiry command status by DeviceTypeQualifier */
752 if (ccb->cmd->cmnd[0] == INQUIRY &&
753 resp->scsi_status == SAM_STAT_GOOD) {
754 ST_INQ *inq_data;
755
756 count = STEX_EXTRA_SIZE;
757 stex_internal_copy(ccb->cmd, hba->copy_buffer,
758 &count, ccb->sg_count, ST_FROM_CMD);
759 inq_data = (ST_INQ *)hba->copy_buffer;
760 if (inq_data->DeviceTypeQualifier != 0)
761 ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
762 else
763 ccb->srb_status = SRB_STATUS_SUCCESS;
764 } else if (ccb->cmd->cmnd[0] == REPORT_LUNS) {
765 u8 *report_lun_data = (u8 *)hba->copy_buffer;
766
767 count = STEX_EXTRA_SIZE;
768 stex_internal_copy(ccb->cmd, report_lun_data,
769 &count, ccb->sg_count, ST_FROM_CMD);
770 if (report_lun_data[2] || report_lun_data[3]) {
771 report_lun_data[2] = 0x00;
772 report_lun_data[3] = 0x08;
773 stex_internal_copy(ccb->cmd, report_lun_data,
774 &count, ccb->sg_count, ST_TO_CMD);
775 }
776 }
683} 777}
684 778
685static void stex_mu_intr(struct st_hba *hba, u32 doorbell) 779static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
@@ -701,8 +795,17 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
701 return; 795 return;
702 } 796 }
703 797
704 if (unlikely(hba->mu_status != MU_STATE_STARTED || 798 /*
705 hba->out_req_cnt <= 0)) { 799 * it's not a valid status payload if:
800 * 1. there are no pending requests(e.g. during init stage)
801 * 2. there are some pending requests, but the controller is in
802 * reset status, and its type is not st_yosemite
803 * firmware of st_yosemite in reset status will return pending requests
804 * to driver, so we allow it to pass
805 */
806 if (unlikely(hba->out_req_cnt <= 0 ||
807 (hba->mu_status == MU_STATE_RESETTING &&
808 hba->cardtype != st_yosemite))) {
706 hba->status_tail = hba->status_head; 809 hba->status_tail = hba->status_head;
707 goto update_status; 810 goto update_status;
708 } 811 }
@@ -722,6 +825,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
722 if (unlikely(ccb->req == NULL)) { 825 if (unlikely(ccb->req == NULL)) {
723 printk(KERN_WARNING DRV_NAME 826 printk(KERN_WARNING DRV_NAME
724 "(%s): lagging req\n", pci_name(hba->pdev)); 827 "(%s): lagging req\n", pci_name(hba->pdev));
828 hba->out_req_cnt--;
725 continue; 829 continue;
726 } 830 }
727 831
@@ -740,9 +844,13 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
740 ccb->scsi_status = resp->scsi_status; 844 ccb->scsi_status = resp->scsi_status;
741 845
742 if (likely(ccb->cmd != NULL)) { 846 if (likely(ccb->cmd != NULL)) {
847 if (hba->cardtype == st_yosemite)
848 stex_ys_commands(hba, ccb, resp);
849
743 if (unlikely(ccb->cmd->cmnd[0] == PASSTHRU_CMD && 850 if (unlikely(ccb->cmd->cmnd[0] == PASSTHRU_CMD &&
744 ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER)) 851 ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER))
745 stex_controller_info(hba, ccb); 852 stex_controller_info(hba, ccb);
853
746 stex_unmap_sg(hba, ccb->cmd); 854 stex_unmap_sg(hba, ccb->cmd);
747 stex_scsi_done(ccb); 855 stex_scsi_done(ccb);
748 hba->out_req_cnt--; 856 hba->out_req_cnt--;
@@ -947,6 +1055,7 @@ static int stex_reset(struct scsi_cmnd *cmd)
947{ 1055{
948 struct st_hba *hba; 1056 struct st_hba *hba;
949 unsigned long flags; 1057 unsigned long flags;
1058 unsigned long before;
950 hba = (struct st_hba *) &cmd->device->host->hostdata[0]; 1059 hba = (struct st_hba *) &cmd->device->host->hostdata[0];
951 1060
952 hba->mu_status = MU_STATE_RESETTING; 1061 hba->mu_status = MU_STATE_RESETTING;
@@ -954,20 +1063,37 @@ static int stex_reset(struct scsi_cmnd *cmd)
954 if (hba->cardtype == st_shasta) 1063 if (hba->cardtype == st_shasta)
955 stex_hard_reset(hba); 1064 stex_hard_reset(hba);
956 1065
957 if (stex_handshake(hba)) { 1066 if (hba->cardtype != st_yosemite) {
958 printk(KERN_WARNING DRV_NAME 1067 if (stex_handshake(hba)) {
959 "(%s): resetting: handshake failed\n", 1068 printk(KERN_WARNING DRV_NAME
960 pci_name(hba->pdev)); 1069 "(%s): resetting: handshake failed\n",
961 return FAILED; 1070 pci_name(hba->pdev));
1071 return FAILED;
1072 }
1073 spin_lock_irqsave(hba->host->host_lock, flags);
1074 hba->req_head = 0;
1075 hba->req_tail = 0;
1076 hba->status_head = 0;
1077 hba->status_tail = 0;
1078 hba->out_req_cnt = 0;
1079 spin_unlock_irqrestore(hba->host->host_lock, flags);
1080 return SUCCESS;
962 } 1081 }
963 spin_lock_irqsave(hba->host->host_lock, flags);
964 hba->req_head = 0;
965 hba->req_tail = 0;
966 hba->status_head = 0;
967 hba->status_tail = 0;
968 hba->out_req_cnt = 0;
969 spin_unlock_irqrestore(hba->host->host_lock, flags);
970 1082
1083 /* st_yosemite */
1084 writel(MU_INBOUND_DOORBELL_RESET, hba->mmio_base + IDBL);
1085 readl(hba->mmio_base + IDBL); /* flush */
1086 before = jiffies;
1087 while (hba->out_req_cnt > 0) {
1088 if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ)) {
1089 printk(KERN_WARNING DRV_NAME
1090 "(%s): reset timeout\n", pci_name(hba->pdev));
1091 return FAILED;
1092 }
1093 msleep(1);
1094 }
1095
1096 hba->mu_status = MU_STATE_STARTED;
971 return SUCCESS; 1097 return SUCCESS;
972} 1098}
973 1099
@@ -1155,9 +1281,16 @@ static void stex_hba_stop(struct st_hba *hba)
1155 req = stex_alloc_req(hba); 1281 req = stex_alloc_req(hba);
1156 memset(req->cdb, 0, STEX_CDB_LENGTH); 1282 memset(req->cdb, 0, STEX_CDB_LENGTH);
1157 1283
1158 req->cdb[0] = CONTROLLER_CMD; 1284 if (hba->cardtype == st_yosemite) {
1159 req->cdb[1] = CTLR_POWER_STATE_CHANGE; 1285 req->cdb[0] = MGT_CMD;
1160 req->cdb[2] = CTLR_POWER_SAVING; 1286 req->cdb[1] = MGT_CMD_SIGNATURE;
1287 req->cdb[2] = CTLR_CONFIG_CMD;
1288 req->cdb[3] = CTLR_SHUTDOWN;
1289 } else {
1290 req->cdb[0] = CONTROLLER_CMD;
1291 req->cdb[1] = CTLR_POWER_STATE_CHANGE;
1292 req->cdb[2] = CTLR_POWER_SAVING;
1293 }
1161 1294
1162 hba->ccb[tag].cmd = NULL; 1295 hba->ccb[tag].cmd = NULL;
1163 hba->ccb[tag].sg_count = 0; 1296 hba->ccb[tag].sg_count = 0;
@@ -1221,6 +1354,7 @@ static struct pci_device_id stex_pci_tbl[] = {
1221 { 0x105a, 0x8301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, 1354 { 0x105a, 0x8301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta },
1222 { 0x105a, 0x8302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, 1355 { 0x105a, 0x8302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta },
1223 { 0x1725, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc }, 1356 { 0x1725, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc },
1357 { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite },
1224 { } /* terminate list */ 1358 { } /* terminate list */
1225}; 1359};
1226MODULE_DEVICE_TABLE(pci, stex_pci_tbl); 1360MODULE_DEVICE_TABLE(pci, stex_pci_tbl);