aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Lin <ed.lin@promise.com>2009-03-31 21:30:31 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-04-03 10:23:09 -0400
commit591a3a5f604c2bee0ba6a614469575918238f4f9 (patch)
tree18709517d8a5ba3cd951e292fcaae5368ea12c0a
parent99946f8141f65a8bd5034ac5b1a53237aec8743e (diff)
[SCSI] stex: use config struct for parameters of different controllers
Use config struct (st_card_info) for parameters of different controllers Signed-off-by: Ed Lin <ed.lin@promise.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/stex.c201
1 files changed, 125 insertions, 76 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index c4eb5c1cc1bc..75f5079e5696 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -95,19 +95,8 @@ enum {
95 TASK_ATTRIBUTE_ORDERED = 0x2, 95 TASK_ATTRIBUTE_ORDERED = 0x2,
96 TASK_ATTRIBUTE_ACA = 0x4, 96 TASK_ATTRIBUTE_ACA = 0x4,
97 97
98 /* request count, etc. */
99 MU_MAX_REQUEST = 32,
100
101 /* one message wasted, use MU_MAX_REQUEST+1
102 to handle MU_MAX_REQUEST messages */
103 MU_REQ_COUNT = (MU_MAX_REQUEST + 1),
104 MU_STATUS_COUNT = (MU_MAX_REQUEST + 1),
105
106 STEX_CDB_LENGTH = 16, 98 STEX_CDB_LENGTH = 16,
107 REQ_VARIABLE_LEN = 1024,
108 STATUS_VAR_LEN = 128, 99 STATUS_VAR_LEN = 128,
109 ST_CAN_QUEUE = MU_MAX_REQUEST,
110 ST_CMD_PER_LUN = MU_MAX_REQUEST,
111 ST_MAX_SG = 32, 100 ST_MAX_SG = 32,
112 101
113 /* sg flags */ 102 /* sg flags */
@@ -120,9 +109,8 @@ enum {
120 109
121 st_shasta = 0, 110 st_shasta = 0,
122 st_vsc = 1, 111 st_vsc = 1,
123 st_vsc1 = 2, 112 st_yosemite = 2,
124 st_yosemite = 3, 113 st_seq = 3,
125 st_seq = 4,
126 114
127 PASSTHRU_REQ_TYPE = 0x00000001, 115 PASSTHRU_REQ_TYPE = 0x00000001,
128 PASSTHRU_REQ_NO_WAKEUP = 0x00000100, 116 PASSTHRU_REQ_NO_WAKEUP = 0x00000100,
@@ -196,7 +184,7 @@ struct req_msg {
196 u8 data_dir; 184 u8 data_dir;
197 u8 payload_sz; /* payload size in 4-byte, not used */ 185 u8 payload_sz; /* payload size in 4-byte, not used */
198 u8 cdb[STEX_CDB_LENGTH]; 186 u8 cdb[STEX_CDB_LENGTH];
199 u8 variable[REQ_VARIABLE_LEN]; 187 u32 variable[0];
200}; 188};
201 189
202struct status_msg { 190struct status_msg {
@@ -252,12 +240,6 @@ struct st_drvver {
252 u32 reserved[3]; 240 u32 reserved[3];
253}; 241};
254 242
255#define MU_REQ_BUFFER_SIZE (MU_REQ_COUNT * sizeof(struct req_msg))
256#define MU_STATUS_BUFFER_SIZE (MU_STATUS_COUNT * sizeof(struct status_msg))
257#define MU_BUFFER_SIZE (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE)
258#define STEX_EXTRA_SIZE sizeof(struct st_frame)
259#define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + STEX_EXTRA_SIZE)
260
261struct st_ccb { 243struct st_ccb {
262 struct req_msg *req; 244 struct req_msg *req;
263 struct scsi_cmnd *cmd; 245 struct scsi_cmnd *cmd;
@@ -288,13 +270,26 @@ struct st_hba {
288 270
289 struct status_msg *status_buffer; 271 struct status_msg *status_buffer;
290 void *copy_buffer; /* temp buffer for driver-handled commands */ 272 void *copy_buffer; /* temp buffer for driver-handled commands */
291 struct st_ccb ccb[MU_MAX_REQUEST]; 273 struct st_ccb *ccb;
292 struct st_ccb *wait_ccb; 274 struct st_ccb *wait_ccb;
293 275
294 unsigned int mu_status; 276 unsigned int mu_status;
295 unsigned int cardtype; 277 unsigned int cardtype;
296 int msi_enabled; 278 int msi_enabled;
297 int out_req_cnt; 279 int out_req_cnt;
280 u32 extra_offset;
281 u16 rq_count;
282 u16 rq_size;
283 u16 sts_count;
284};
285
286struct st_card_info {
287 unsigned int max_id;
288 unsigned int max_lun;
289 unsigned int max_channel;
290 u16 rq_count;
291 u16 rq_size;
292 u16 sts_count;
298}; 293};
299 294
300static int msi; 295static int msi;
@@ -331,7 +326,7 @@ static struct status_msg *stex_get_status(struct st_hba *hba)
331 struct status_msg *status = hba->status_buffer + hba->status_tail; 326 struct status_msg *status = hba->status_buffer + hba->status_tail;
332 327
333 ++hba->status_tail; 328 ++hba->status_tail;
334 hba->status_tail %= MU_STATUS_COUNT; 329 hba->status_tail %= hba->sts_count+1;
335 330
336 return status; 331 return status;
337} 332}
@@ -349,11 +344,10 @@ static void stex_invalid_field(struct scsi_cmnd *cmd,
349 344
350static struct req_msg *stex_alloc_req(struct st_hba *hba) 345static struct req_msg *stex_alloc_req(struct st_hba *hba)
351{ 346{
352 struct req_msg *req = ((struct req_msg *)hba->dma_mem) + 347 struct req_msg *req = hba->dma_mem + hba->req_head * hba->rq_size;
353 hba->req_head;
354 348
355 ++hba->req_head; 349 ++hba->req_head;
356 hba->req_head %= MU_REQ_COUNT; 350 hba->req_head %= hba->rq_count+1;
357 351
358 return req; 352 return req;
359} 353}
@@ -653,7 +647,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
653 647
654 /* status payloads */ 648 /* status payloads */
655 hba->status_head = readl(base + OMR1); 649 hba->status_head = readl(base + OMR1);
656 if (unlikely(hba->status_head >= MU_STATUS_COUNT)) { 650 if (unlikely(hba->status_head > hba->sts_count)) {
657 printk(KERN_WARNING DRV_NAME "(%s): invalid status head\n", 651 printk(KERN_WARNING DRV_NAME "(%s): invalid status head\n",
658 pci_name(hba->pdev)); 652 pci_name(hba->pdev));
659 return; 653 return;
@@ -789,19 +783,19 @@ static int stex_handshake(struct st_hba *hba)
789 783
790 h = (struct handshake_frame *)hba->status_buffer; 784 h = (struct handshake_frame *)hba->status_buffer;
791 h->rb_phy = cpu_to_le64(hba->dma_handle); 785 h->rb_phy = cpu_to_le64(hba->dma_handle);
792 h->req_sz = cpu_to_le16(sizeof(struct req_msg)); 786 h->req_sz = cpu_to_le16(hba->rq_size);
793 h->req_cnt = cpu_to_le16(MU_REQ_COUNT); 787 h->req_cnt = cpu_to_le16(hba->rq_count+1);
794 h->status_sz = cpu_to_le16(sizeof(struct status_msg)); 788 h->status_sz = cpu_to_le16(sizeof(struct status_msg));
795 h->status_cnt = cpu_to_le16(MU_STATUS_COUNT); 789 h->status_cnt = cpu_to_le16(hba->sts_count+1);
796 stex_gettime(&h->hosttime); 790 stex_gettime(&h->hosttime);
797 h->partner_type = HMU_PARTNER_TYPE; 791 h->partner_type = HMU_PARTNER_TYPE;
798 if (hba->dma_size > STEX_BUFFER_SIZE) { 792 if (hba->extra_offset) {
799 h->extra_offset = cpu_to_le32(STEX_BUFFER_SIZE); 793 h->extra_offset = cpu_to_le32(hba->extra_offset);
800 h->extra_size = cpu_to_le32(ST_ADDITIONAL_MEM); 794 h->extra_size = cpu_to_le32(ST_ADDITIONAL_MEM);
801 } else 795 } else
802 h->extra_offset = h->extra_size = 0; 796 h->extra_offset = h->extra_size = 0;
803 797
804 status_phys = hba->dma_handle + MU_REQ_BUFFER_SIZE; 798 status_phys = hba->dma_handle + (hba->rq_count+1) * hba->rq_size;
805 writel(status_phys, base + IMR0); 799 writel(status_phys, base + IMR0);
806 readl(base + IMR0); 800 readl(base + IMR0);
807 writel((status_phys >> 16) >> 16, base + IMR1); 801 writel((status_phys >> 16) >> 16, base + IMR1);
@@ -1026,10 +1020,72 @@ static struct scsi_host_template driver_template = {
1026 .slave_destroy = stex_slave_destroy, 1020 .slave_destroy = stex_slave_destroy,
1027 .eh_abort_handler = stex_abort, 1021 .eh_abort_handler = stex_abort,
1028 .eh_host_reset_handler = stex_reset, 1022 .eh_host_reset_handler = stex_reset,
1029 .can_queue = ST_CAN_QUEUE,
1030 .this_id = -1, 1023 .this_id = -1,
1031 .sg_tablesize = ST_MAX_SG, 1024 .sg_tablesize = ST_MAX_SG,
1032 .cmd_per_lun = ST_CMD_PER_LUN, 1025};
1026
1027static struct pci_device_id stex_pci_tbl[] = {
1028 /* st_shasta */
1029 { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1030 st_shasta }, /* SuperTrak EX8350/8300/16350/16300 */
1031 { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1032 st_shasta }, /* SuperTrak EX12350 */
1033 { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1034 st_shasta }, /* SuperTrak EX4350 */
1035 { 0x105a, 0xe350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1036 st_shasta }, /* SuperTrak EX24350 */
1037
1038 /* st_vsc */
1039 { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc },
1040
1041 /* st_yosemite */
1042 { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite },
1043
1044 /* st_seq */
1045 { 0x105a, 0x3360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_seq },
1046 { } /* terminate list */
1047};
1048
1049static struct st_card_info stex_card_info[] = {
1050 /* st_shasta */
1051 {
1052 .max_id = 17,
1053 .max_lun = 8,
1054 .max_channel = 0,
1055 .rq_count = 32,
1056 .rq_size = 1048,
1057 .sts_count = 32,
1058 },
1059
1060 /* st_vsc */
1061 {
1062 .max_id = 129,
1063 .max_lun = 1,
1064 .max_channel = 0,
1065 .rq_count = 32,
1066 .rq_size = 1048,
1067 .sts_count = 32,
1068 },
1069
1070 /* st_yosemite */
1071 {
1072 .max_id = 2,
1073 .max_lun = 256,
1074 .max_channel = 0,
1075 .rq_count = 256,
1076 .rq_size = 1048,
1077 .sts_count = 256,
1078 },
1079
1080 /* st_seq */
1081 {
1082 .max_id = 129,
1083 .max_lun = 1,
1084 .max_channel = 0,
1085 .rq_count = 32,
1086 .rq_size = 1048,
1087 .sts_count = 32,
1088 },
1033}; 1089};
1034 1090
1035static int stex_set_dma_mask(struct pci_dev * pdev) 1091static int stex_set_dma_mask(struct pci_dev * pdev)
@@ -1084,6 +1140,8 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1084{ 1140{
1085 struct st_hba *hba; 1141 struct st_hba *hba;
1086 struct Scsi_Host *host; 1142 struct Scsi_Host *host;
1143 const struct st_card_info *ci = NULL;
1144 u32 sts_offset, cp_offset;
1087 int err; 1145 int err;
1088 1146
1089 err = pci_enable_device(pdev); 1147 err = pci_enable_device(pdev);
@@ -1127,10 +1185,15 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1127 } 1185 }
1128 1186
1129 hba->cardtype = (unsigned int) id->driver_data; 1187 hba->cardtype = (unsigned int) id->driver_data;
1130 if (hba->cardtype == st_vsc && (pdev->subsystem_device & 1)) 1188 ci = &stex_card_info[hba->cardtype];
1131 hba->cardtype = st_vsc1; 1189 sts_offset = (ci->rq_count+1) * ci->rq_size;
1132 hba->dma_size = (hba->cardtype == st_vsc1 || hba->cardtype == st_seq) ? 1190 cp_offset = sts_offset + (ci->sts_count+1) * sizeof(struct status_msg);
1133 (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE); 1191 hba->dma_size = cp_offset + sizeof(struct st_frame);
1192 if (hba->cardtype == st_seq ||
1193 (hba->cardtype == st_vsc && (pdev->subsystem_device & 1))) {
1194 hba->extra_offset = hba->dma_size;
1195 hba->dma_size += ST_ADDITIONAL_MEM;
1196 }
1134 hba->dma_mem = dma_alloc_coherent(&pdev->dev, 1197 hba->dma_mem = dma_alloc_coherent(&pdev->dev,
1135 hba->dma_size, &hba->dma_handle, GFP_KERNEL); 1198 hba->dma_size, &hba->dma_handle, GFP_KERNEL);
1136 if (!hba->dma_mem) { 1199 if (!hba->dma_mem) {
@@ -1140,23 +1203,26 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1140 goto out_iounmap; 1203 goto out_iounmap;
1141 } 1204 }
1142 1205
1143 hba->status_buffer = 1206 hba->ccb = kcalloc(ci->rq_count, sizeof(struct st_ccb), GFP_KERNEL);
1144 (struct status_msg *)(hba->dma_mem + MU_REQ_BUFFER_SIZE); 1207 if (!hba->ccb) {
1145 hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE; 1208 err = -ENOMEM;
1209 printk(KERN_ERR DRV_NAME "(%s): ccb alloc failed\n",
1210 pci_name(pdev));
1211 goto out_pci_free;
1212 }
1213
1214 hba->status_buffer = (struct status_msg *)(hba->dma_mem + sts_offset);
1215 hba->copy_buffer = hba->dma_mem + cp_offset;
1216 hba->rq_count = ci->rq_count;
1217 hba->rq_size = ci->rq_size;
1218 hba->sts_count = ci->sts_count;
1146 hba->mu_status = MU_STATE_STARTING; 1219 hba->mu_status = MU_STATE_STARTING;
1147 1220
1148 if (hba->cardtype == st_shasta) { 1221 host->can_queue = ci->rq_count;
1149 host->max_lun = 8; 1222 host->cmd_per_lun = ci->rq_count;
1150 host->max_id = 16 + 1; 1223 host->max_id = ci->max_id;
1151 } else if (hba->cardtype == st_yosemite) { 1224 host->max_lun = ci->max_lun;
1152 host->max_lun = 256; 1225 host->max_channel = ci->max_channel;
1153 host->max_id = 1 + 1;
1154 } else {
1155 /* st_vsc , st_vsc1 and st_seq */
1156 host->max_lun = 1;
1157 host->max_id = 128 + 1;
1158 }
1159 host->max_channel = 0;
1160 host->unique_id = host->host_no; 1226 host->unique_id = host->host_no;
1161 host->max_cmd_len = STEX_CDB_LENGTH; 1227 host->max_cmd_len = STEX_CDB_LENGTH;
1162 1228
@@ -1167,7 +1233,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1167 if (err) { 1233 if (err) {
1168 printk(KERN_ERR DRV_NAME "(%s): request irq failed\n", 1234 printk(KERN_ERR DRV_NAME "(%s): request irq failed\n",
1169 pci_name(pdev)); 1235 pci_name(pdev));
1170 goto out_pci_free; 1236 goto out_ccb_free;
1171 } 1237 }
1172 1238
1173 err = stex_handshake(hba); 1239 err = stex_handshake(hba);
@@ -1196,6 +1262,8 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1196 1262
1197out_free_irq: 1263out_free_irq:
1198 stex_free_irq(hba); 1264 stex_free_irq(hba);
1265out_ccb_free:
1266 kfree(hba->ccb);
1199out_pci_free: 1267out_pci_free:
1200 dma_free_coherent(&pdev->dev, hba->dma_size, 1268 dma_free_coherent(&pdev->dev, hba->dma_size,
1201 hba->dma_mem, hba->dma_handle); 1269 hba->dma_mem, hba->dma_handle);
@@ -1260,6 +1328,8 @@ static void stex_hba_free(struct st_hba *hba)
1260 1328
1261 pci_release_regions(hba->pdev); 1329 pci_release_regions(hba->pdev);
1262 1330
1331 kfree(hba->ccb);
1332
1263 dma_free_coherent(&hba->pdev->dev, hba->dma_size, 1333 dma_free_coherent(&hba->pdev->dev, hba->dma_size,
1264 hba->dma_mem, hba->dma_handle); 1334 hba->dma_mem, hba->dma_handle);
1265} 1335}
@@ -1288,27 +1358,6 @@ static void stex_shutdown(struct pci_dev *pdev)
1288 stex_hba_stop(hba); 1358 stex_hba_stop(hba);
1289} 1359}
1290 1360
1291static struct pci_device_id stex_pci_tbl[] = {
1292 /* st_shasta */
1293 { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1294 st_shasta }, /* SuperTrak EX8350/8300/16350/16300 */
1295 { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1296 st_shasta }, /* SuperTrak EX12350 */
1297 { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1298 st_shasta }, /* SuperTrak EX4350 */
1299 { 0x105a, 0xe350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1300 st_shasta }, /* SuperTrak EX24350 */
1301
1302 /* st_vsc */
1303 { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc },
1304
1305 /* st_yosemite */
1306 { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite },
1307
1308 /* st_seq */
1309 { 0x105a, 0x3360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_seq },
1310 { } /* terminate list */
1311};
1312MODULE_DEVICE_TABLE(pci, stex_pci_tbl); 1361MODULE_DEVICE_TABLE(pci, stex_pci_tbl);
1313 1362
1314static struct pci_driver stex_pci_driver = { 1363static struct pci_driver stex_pci_driver = {