aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/stex.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/stex.c')
-rw-r--r--drivers/scsi/stex.c107
1 files changed, 35 insertions, 72 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index a3a18ad73125..47b614e8580c 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SuperTrak EX Series Storage Controller driver for Linux 2 * SuperTrak EX Series Storage Controller driver for Linux
3 * 3 *
4 * Copyright (C) 2005, 2006 Promise Technology Inc. 4 * Copyright (C) 2005-2009 Promise Technology Inc.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -36,8 +36,8 @@
36#include <scsi/scsi_eh.h> 36#include <scsi/scsi_eh.h>
37 37
38#define DRV_NAME "stex" 38#define DRV_NAME "stex"
39#define ST_DRIVER_VERSION "3.6.0000.1" 39#define ST_DRIVER_VERSION "4.6.0000.1"
40#define ST_VER_MAJOR 3 40#define ST_VER_MAJOR 4
41#define ST_VER_MINOR 6 41#define ST_VER_MINOR 6
42#define ST_OEM 0 42#define ST_OEM 0
43#define ST_BUILD_VER 1 43#define ST_BUILD_VER 1
@@ -103,7 +103,7 @@ enum {
103 MU_REQ_COUNT = (MU_MAX_REQUEST + 1), 103 MU_REQ_COUNT = (MU_MAX_REQUEST + 1),
104 MU_STATUS_COUNT = (MU_MAX_REQUEST + 1), 104 MU_STATUS_COUNT = (MU_MAX_REQUEST + 1),
105 105
106 STEX_CDB_LENGTH = MAX_COMMAND_SIZE, 106 STEX_CDB_LENGTH = 16,
107 REQ_VARIABLE_LEN = 1024, 107 REQ_VARIABLE_LEN = 1024,
108 STATUS_VAR_LEN = 128, 108 STATUS_VAR_LEN = 128,
109 ST_CAN_QUEUE = MU_MAX_REQUEST, 109 ST_CAN_QUEUE = MU_MAX_REQUEST,
@@ -114,15 +114,19 @@ enum {
114 SG_CF_EOT = 0x80, /* end of table */ 114 SG_CF_EOT = 0x80, /* end of table */
115 SG_CF_64B = 0x40, /* 64 bit item */ 115 SG_CF_64B = 0x40, /* 64 bit item */
116 SG_CF_HOST = 0x20, /* sg in host memory */ 116 SG_CF_HOST = 0x20, /* sg in host memory */
117 MSG_DATA_DIR_ND = 0,
118 MSG_DATA_DIR_IN = 1,
119 MSG_DATA_DIR_OUT = 2,
117 120
118 st_shasta = 0, 121 st_shasta = 0,
119 st_vsc = 1, 122 st_vsc = 1,
120 st_vsc1 = 2, 123 st_vsc1 = 2,
121 st_yosemite = 3, 124 st_yosemite = 3,
125 st_seq = 4,
122 126
123 PASSTHRU_REQ_TYPE = 0x00000001, 127 PASSTHRU_REQ_TYPE = 0x00000001,
124 PASSTHRU_REQ_NO_WAKEUP = 0x00000100, 128 PASSTHRU_REQ_NO_WAKEUP = 0x00000100,
125 ST_INTERNAL_TIMEOUT = 30, 129 ST_INTERNAL_TIMEOUT = 180,
126 130
127 ST_TO_CMD = 0, 131 ST_TO_CMD = 0,
128 ST_FROM_CMD = 1, 132 ST_FROM_CMD = 1,
@@ -152,35 +156,6 @@ enum {
152 ST_ADDITIONAL_MEM = 0x200000, 156 ST_ADDITIONAL_MEM = 0x200000,
153}; 157};
154 158
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
184struct st_sgitem { 159struct st_sgitem {
185 u8 ctrl; /* SG_CF_xxx */ 160 u8 ctrl; /* SG_CF_xxx */
186 u8 reserved[3]; 161 u8 reserved[3];
@@ -222,7 +197,7 @@ struct req_msg {
222 u8 target; 197 u8 target;
223 u8 task_attr; 198 u8 task_attr;
224 u8 task_manage; 199 u8 task_manage;
225 u8 prd_entry; 200 u8 data_dir;
226 u8 payload_sz; /* payload size in 4-byte, not used */ 201 u8 payload_sz; /* payload size in 4-byte, not used */
227 u8 cdb[STEX_CDB_LENGTH]; 202 u8 cdb[STEX_CDB_LENGTH];
228 u8 variable[REQ_VARIABLE_LEN]; 203 u8 variable[REQ_VARIABLE_LEN];
@@ -284,7 +259,7 @@ struct st_drvver {
284#define MU_REQ_BUFFER_SIZE (MU_REQ_COUNT * sizeof(struct req_msg)) 259#define MU_REQ_BUFFER_SIZE (MU_REQ_COUNT * sizeof(struct req_msg))
285#define MU_STATUS_BUFFER_SIZE (MU_STATUS_COUNT * sizeof(struct status_msg)) 260#define MU_STATUS_BUFFER_SIZE (MU_STATUS_COUNT * sizeof(struct status_msg))
286#define MU_BUFFER_SIZE (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE) 261#define MU_BUFFER_SIZE (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE)
287#define STEX_EXTRA_SIZE max(sizeof(struct st_frame), sizeof(ST_INQ)) 262#define STEX_EXTRA_SIZE sizeof(struct st_frame)
288#define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + STEX_EXTRA_SIZE) 263#define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + STEX_EXTRA_SIZE)
289 264
290struct st_ccb { 265struct st_ccb {
@@ -346,8 +321,8 @@ MODULE_VERSION(ST_DRIVER_VERSION);
346static void stex_gettime(__le32 *time) 321static void stex_gettime(__le32 *time)
347{ 322{
348 struct timeval tv; 323 struct timeval tv;
349 do_gettimeofday(&tv);
350 324
325 do_gettimeofday(&tv);
351 *time = cpu_to_le32(tv.tv_sec & 0xffffffff); 326 *time = cpu_to_le32(tv.tv_sec & 0xffffffff);
352 *(time + 1) = cpu_to_le32((tv.tv_sec >> 16) >> 16); 327 *(time + 1) = cpu_to_le32((tv.tv_sec >> 16) >> 16);
353} 328}
@@ -368,7 +343,7 @@ static void stex_invalid_field(struct scsi_cmnd *cmd,
368{ 343{
369 cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; 344 cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
370 345
371 /* "Invalid field in cbd" */ 346 /* "Invalid field in cdb" */
372 scsi_build_sense_buffer(0, cmd->sense_buffer, ILLEGAL_REQUEST, 0x24, 347 scsi_build_sense_buffer(0, cmd->sense_buffer, ILLEGAL_REQUEST, 0x24,
373 0x0); 348 0x0);
374 done(cmd); 349 done(cmd);
@@ -497,6 +472,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
497 unsigned int id,lun; 472 unsigned int id,lun;
498 struct req_msg *req; 473 struct req_msg *req;
499 u16 tag; 474 u16 tag;
475
500 host = cmd->device->host; 476 host = cmd->device->host;
501 id = cmd->device->id; 477 id = cmd->device->id;
502 lun = cmd->device->lun; 478 lun = cmd->device->lun;
@@ -508,6 +484,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
508 static char ms10_caching_page[12] = 484 static char ms10_caching_page[12] =
509 { 0, 0x12, 0, 0, 0, 0, 0, 0, 0x8, 0xa, 0x4, 0 }; 485 { 0, 0x12, 0, 0, 0, 0, 0, 0, 0x8, 0xa, 0x4, 0 };
510 unsigned char page; 486 unsigned char page;
487
511 page = cmd->cmnd[2] & 0x3f; 488 page = cmd->cmnd[2] & 0x3f;
512 if (page == 0x8 || page == 0x3f) { 489 if (page == 0x8 || page == 0x3f) {
513 scsi_sg_copy_from_buffer(cmd, ms10_caching_page, 490 scsi_sg_copy_from_buffer(cmd, ms10_caching_page,
@@ -551,6 +528,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
551 if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) { 528 if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) {
552 struct st_drvver ver; 529 struct st_drvver ver;
553 size_t cp_len = sizeof(ver); 530 size_t cp_len = sizeof(ver);
531
554 ver.major = ST_VER_MAJOR; 532 ver.major = ST_VER_MAJOR;
555 ver.minor = ST_VER_MINOR; 533 ver.minor = ST_VER_MINOR;
556 ver.oem = ST_OEM; 534 ver.oem = ST_OEM;
@@ -584,6 +562,13 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
584 /* cdb */ 562 /* cdb */
585 memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH); 563 memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH);
586 564
565 if (cmd->sc_data_direction == DMA_FROM_DEVICE)
566 req->data_dir = MSG_DATA_DIR_IN;
567 else if (cmd->sc_data_direction == DMA_TO_DEVICE)
568 req->data_dir = MSG_DATA_DIR_OUT;
569 else
570 req->data_dir = MSG_DATA_DIR_ND;
571
587 hba->ccb[tag].cmd = cmd; 572 hba->ccb[tag].cmd = cmd;
588 hba->ccb[tag].sense_bufflen = SCSI_SENSE_BUFFERSIZE; 573 hba->ccb[tag].sense_bufflen = SCSI_SENSE_BUFFERSIZE;
589 hba->ccb[tag].sense_buffer = cmd->sense_buffer; 574 hba->ccb[tag].sense_buffer = cmd->sense_buffer;
@@ -642,6 +627,7 @@ static void stex_copy_data(struct st_ccb *ccb,
642 struct status_msg *resp, unsigned int variable) 627 struct status_msg *resp, unsigned int variable)
643{ 628{
644 size_t count = variable; 629 size_t count = variable;
630
645 if (resp->scsi_status != SAM_STAT_GOOD) { 631 if (resp->scsi_status != SAM_STAT_GOOD) {
646 if (ccb->sense_buffer != NULL) 632 if (ccb->sense_buffer != NULL)
647 memcpy(ccb->sense_buffer, resp->variable, 633 memcpy(ccb->sense_buffer, resp->variable,
@@ -661,24 +647,6 @@ static void stex_ys_commands(struct st_hba *hba,
661 resp->scsi_status != SAM_STAT_CHECK_CONDITION) { 647 resp->scsi_status != SAM_STAT_CHECK_CONDITION) {
662 scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) - 648 scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) -
663 le32_to_cpu(*(__le32 *)&resp->variable[0])); 649 le32_to_cpu(*(__le32 *)&resp->variable[0]));
664 return;
665 }
666
667 if (resp->srb_status != 0)
668 return;
669
670 /* determine inquiry command status by DeviceTypeQualifier */
671 if (ccb->cmd->cmnd[0] == INQUIRY &&
672 resp->scsi_status == SAM_STAT_GOOD) {
673 ST_INQ *inq_data;
674
675 scsi_sg_copy_to_buffer(ccb->cmd, hba->copy_buffer,
676 STEX_EXTRA_SIZE);
677 inq_data = (ST_INQ *)hba->copy_buffer;
678 if (inq_data->DeviceTypeQualifier != 0)
679 ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
680 else
681 ccb->srb_status = SRB_STATUS_SUCCESS;
682 } 650 }
683} 651}
684 652
@@ -746,6 +714,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
746 stex_copy_data(ccb, resp, size); 714 stex_copy_data(ccb, resp, size);
747 } 715 }
748 716
717 ccb->req = NULL;
749 ccb->srb_status = resp->srb_status; 718 ccb->srb_status = resp->srb_status;
750 ccb->scsi_status = resp->scsi_status; 719 ccb->scsi_status = resp->scsi_status;
751 720
@@ -983,6 +952,7 @@ static int stex_reset(struct scsi_cmnd *cmd)
983 struct st_hba *hba; 952 struct st_hba *hba;
984 unsigned long flags; 953 unsigned long flags;
985 unsigned long before; 954 unsigned long before;
955
986 hba = (struct st_hba *) &cmd->device->host->hostdata[0]; 956 hba = (struct st_hba *) &cmd->device->host->hostdata[0];
987 957
988 printk(KERN_INFO DRV_NAME 958 printk(KERN_INFO DRV_NAME
@@ -1067,6 +1037,7 @@ static struct scsi_host_template driver_template = {
1067static int stex_set_dma_mask(struct pci_dev * pdev) 1037static int stex_set_dma_mask(struct pci_dev * pdev)
1068{ 1038{
1069 int ret; 1039 int ret;
1040
1070 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) 1041 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)
1071 && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) 1042 && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1072 return 0; 1043 return 0;
@@ -1124,9 +1095,9 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1124 } 1095 }
1125 1096
1126 hba->cardtype = (unsigned int) id->driver_data; 1097 hba->cardtype = (unsigned int) id->driver_data;
1127 if (hba->cardtype == st_vsc && (pdev->subsystem_device & 0xf) == 0x1) 1098 if (hba->cardtype == st_vsc && (pdev->subsystem_device & 1))
1128 hba->cardtype = st_vsc1; 1099 hba->cardtype = st_vsc1;
1129 hba->dma_size = (hba->cardtype == st_vsc1) ? 1100 hba->dma_size = (hba->cardtype == st_vsc1 || hba->cardtype == st_seq) ?
1130 (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE); 1101 (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE);
1131 hba->dma_mem = dma_alloc_coherent(&pdev->dev, 1102 hba->dma_mem = dma_alloc_coherent(&pdev->dev,
1132 hba->dma_size, &hba->dma_handle, GFP_KERNEL); 1103 hba->dma_size, &hba->dma_handle, GFP_KERNEL);
@@ -1146,10 +1117,10 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1146 host->max_lun = 8; 1117 host->max_lun = 8;
1147 host->max_id = 16 + 1; 1118 host->max_id = 16 + 1;
1148 } else if (hba->cardtype == st_yosemite) { 1119 } else if (hba->cardtype == st_yosemite) {
1149 host->max_lun = 128; 1120 host->max_lun = 256;
1150 host->max_id = 1 + 1; 1121 host->max_id = 1 + 1;
1151 } else { 1122 } else {
1152 /* st_vsc and st_vsc1 */ 1123 /* st_vsc , st_vsc1 and st_seq */
1153 host->max_lun = 1; 1124 host->max_lun = 1;
1154 host->max_id = 128 + 1; 1125 host->max_id = 128 + 1;
1155 } 1126 }
@@ -1299,18 +1270,10 @@ static struct pci_device_id stex_pci_tbl[] = {
1299 { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc }, 1270 { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc },
1300 1271
1301 /* st_yosemite */ 1272 /* st_yosemite */
1302 { 0x105a, 0x8650, PCI_ANY_ID, 0x4600, 0, 0, 1273 { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite },
1303 st_yosemite }, /* SuperTrak EX4650 */ 1274
1304 { 0x105a, 0x8650, PCI_ANY_ID, 0x4610, 0, 0, 1275 /* st_seq */
1305 st_yosemite }, /* SuperTrak EX4650o */ 1276 { 0x105a, 0x3360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_seq },
1306 { 0x105a, 0x8650, PCI_ANY_ID, 0x8600, 0, 0,
1307 st_yosemite }, /* SuperTrak EX8650EL */
1308 { 0x105a, 0x8650, PCI_ANY_ID, 0x8601, 0, 0,
1309 st_yosemite }, /* SuperTrak EX8650 */
1310 { 0x105a, 0x8650, PCI_ANY_ID, 0x8602, 0, 0,
1311 st_yosemite }, /* SuperTrak EX8654 */
1312 { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1313 st_yosemite }, /* generic st_yosemite */
1314 { } /* terminate list */ 1277 { } /* terminate list */
1315}; 1278};
1316MODULE_DEVICE_TABLE(pci, stex_pci_tbl); 1279MODULE_DEVICE_TABLE(pci, stex_pci_tbl);