diff options
Diffstat (limited to 'drivers/scsi/stex.c')
-rw-r--r-- | drivers/scsi/stex.c | 750 |
1 files changed, 576 insertions, 174 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 47b614e8580c..8d2a95c4e5b5 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -36,11 +36,11 @@ | |||
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 "4.6.0000.1" | 39 | #define ST_DRIVER_VERSION "4.6.0000.3" |
40 | #define ST_VER_MAJOR 4 | 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 3 |
44 | 44 | ||
45 | enum { | 45 | enum { |
46 | /* MU register offset */ | 46 | /* MU register offset */ |
@@ -55,6 +55,13 @@ enum { | |||
55 | OIS = 0x30, /* MU_OUTBOUND_INTERRUPT_STATUS */ | 55 | OIS = 0x30, /* MU_OUTBOUND_INTERRUPT_STATUS */ |
56 | OIM = 0x3c, /* MU_OUTBOUND_INTERRUPT_MASK */ | 56 | OIM = 0x3c, /* MU_OUTBOUND_INTERRUPT_MASK */ |
57 | 57 | ||
58 | YH2I_INT = 0x20, | ||
59 | YINT_EN = 0x34, | ||
60 | YI2H_INT = 0x9c, | ||
61 | YI2H_INT_C = 0xa0, | ||
62 | YH2I_REQ = 0xc0, | ||
63 | YH2I_REQ_HI = 0xc4, | ||
64 | |||
58 | /* MU register value */ | 65 | /* MU register value */ |
59 | MU_INBOUND_DOORBELL_HANDSHAKE = 1, | 66 | MU_INBOUND_DOORBELL_HANDSHAKE = 1, |
60 | MU_INBOUND_DOORBELL_REQHEADCHANGED = 2, | 67 | MU_INBOUND_DOORBELL_REQHEADCHANGED = 2, |
@@ -95,20 +102,14 @@ enum { | |||
95 | TASK_ATTRIBUTE_ORDERED = 0x2, | 102 | TASK_ATTRIBUTE_ORDERED = 0x2, |
96 | TASK_ATTRIBUTE_ACA = 0x4, | 103 | TASK_ATTRIBUTE_ACA = 0x4, |
97 | 104 | ||
98 | /* request count, etc. */ | 105 | SS_STS_NORMAL = 0x80000000, |
99 | MU_MAX_REQUEST = 32, | 106 | SS_STS_DONE = 0x40000000, |
107 | SS_STS_HANDSHAKE = 0x20000000, | ||
100 | 108 | ||
101 | /* one message wasted, use MU_MAX_REQUEST+1 | 109 | SS_HEAD_HANDSHAKE = 0x80, |
102 | to handle MU_MAX_REQUEST messages */ | ||
103 | MU_REQ_COUNT = (MU_MAX_REQUEST + 1), | ||
104 | MU_STATUS_COUNT = (MU_MAX_REQUEST + 1), | ||
105 | 110 | ||
106 | STEX_CDB_LENGTH = 16, | 111 | STEX_CDB_LENGTH = 16, |
107 | REQ_VARIABLE_LEN = 1024, | ||
108 | STATUS_VAR_LEN = 128, | 112 | STATUS_VAR_LEN = 128, |
109 | ST_CAN_QUEUE = MU_MAX_REQUEST, | ||
110 | ST_CMD_PER_LUN = MU_MAX_REQUEST, | ||
111 | ST_MAX_SG = 32, | ||
112 | 113 | ||
113 | /* sg flags */ | 114 | /* sg flags */ |
114 | SG_CF_EOT = 0x80, /* end of table */ | 115 | SG_CF_EOT = 0x80, /* end of table */ |
@@ -120,9 +121,9 @@ enum { | |||
120 | 121 | ||
121 | st_shasta = 0, | 122 | st_shasta = 0, |
122 | st_vsc = 1, | 123 | st_vsc = 1, |
123 | st_vsc1 = 2, | 124 | st_yosemite = 2, |
124 | st_yosemite = 3, | 125 | st_seq = 3, |
125 | st_seq = 4, | 126 | st_yel = 4, |
126 | 127 | ||
127 | PASSTHRU_REQ_TYPE = 0x00000001, | 128 | PASSTHRU_REQ_TYPE = 0x00000001, |
128 | PASSTHRU_REQ_NO_WAKEUP = 0x00000100, | 129 | PASSTHRU_REQ_NO_WAKEUP = 0x00000100, |
@@ -160,26 +161,36 @@ struct st_sgitem { | |||
160 | u8 ctrl; /* SG_CF_xxx */ | 161 | u8 ctrl; /* SG_CF_xxx */ |
161 | u8 reserved[3]; | 162 | u8 reserved[3]; |
162 | __le32 count; | 163 | __le32 count; |
164 | __le64 addr; | ||
165 | }; | ||
166 | |||
167 | struct st_ss_sgitem { | ||
163 | __le32 addr; | 168 | __le32 addr; |
164 | __le32 addr_hi; | 169 | __le32 addr_hi; |
170 | __le32 count; | ||
165 | }; | 171 | }; |
166 | 172 | ||
167 | struct st_sgtable { | 173 | struct st_sgtable { |
168 | __le16 sg_count; | 174 | __le16 sg_count; |
169 | __le16 max_sg_count; | 175 | __le16 max_sg_count; |
170 | __le32 sz_in_byte; | 176 | __le32 sz_in_byte; |
171 | struct st_sgitem table[ST_MAX_SG]; | 177 | }; |
178 | |||
179 | struct st_msg_header { | ||
180 | __le64 handle; | ||
181 | u8 flag; | ||
182 | u8 channel; | ||
183 | __le16 timeout; | ||
184 | u32 reserved; | ||
172 | }; | 185 | }; |
173 | 186 | ||
174 | struct handshake_frame { | 187 | struct handshake_frame { |
175 | __le32 rb_phy; /* request payload queue physical address */ | 188 | __le64 rb_phy; /* request payload queue physical address */ |
176 | __le32 rb_phy_hi; | ||
177 | __le16 req_sz; /* size of each request payload */ | 189 | __le16 req_sz; /* size of each request payload */ |
178 | __le16 req_cnt; /* count of reqs the buffer can hold */ | 190 | __le16 req_cnt; /* count of reqs the buffer can hold */ |
179 | __le16 status_sz; /* size of each status payload */ | 191 | __le16 status_sz; /* size of each status payload */ |
180 | __le16 status_cnt; /* count of status the buffer can hold */ | 192 | __le16 status_cnt; /* count of status the buffer can hold */ |
181 | __le32 hosttime; /* seconds from Jan 1, 1970 (GMT) */ | 193 | __le64 hosttime; /* seconds from Jan 1, 1970 (GMT) */ |
182 | __le32 hosttime_hi; | ||
183 | u8 partner_type; /* who sends this frame */ | 194 | u8 partner_type; /* who sends this frame */ |
184 | u8 reserved0[7]; | 195 | u8 reserved0[7]; |
185 | __le32 partner_ver_major; | 196 | __le32 partner_ver_major; |
@@ -188,7 +199,8 @@ struct handshake_frame { | |||
188 | __le32 partner_ver_build; | 199 | __le32 partner_ver_build; |
189 | __le32 extra_offset; /* NEW */ | 200 | __le32 extra_offset; /* NEW */ |
190 | __le32 extra_size; /* NEW */ | 201 | __le32 extra_size; /* NEW */ |
191 | u32 reserved1[2]; | 202 | __le32 scratch_size; |
203 | u32 reserved1; | ||
192 | }; | 204 | }; |
193 | 205 | ||
194 | struct req_msg { | 206 | struct req_msg { |
@@ -200,7 +212,7 @@ struct req_msg { | |||
200 | u8 data_dir; | 212 | u8 data_dir; |
201 | u8 payload_sz; /* payload size in 4-byte, not used */ | 213 | u8 payload_sz; /* payload size in 4-byte, not used */ |
202 | u8 cdb[STEX_CDB_LENGTH]; | 214 | u8 cdb[STEX_CDB_LENGTH]; |
203 | u8 variable[REQ_VARIABLE_LEN]; | 215 | u32 variable[0]; |
204 | }; | 216 | }; |
205 | 217 | ||
206 | struct status_msg { | 218 | struct status_msg { |
@@ -256,12 +268,6 @@ struct st_drvver { | |||
256 | u32 reserved[3]; | 268 | u32 reserved[3]; |
257 | }; | 269 | }; |
258 | 270 | ||
259 | #define MU_REQ_BUFFER_SIZE (MU_REQ_COUNT * sizeof(struct req_msg)) | ||
260 | #define MU_STATUS_BUFFER_SIZE (MU_STATUS_COUNT * sizeof(struct status_msg)) | ||
261 | #define MU_BUFFER_SIZE (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE) | ||
262 | #define STEX_EXTRA_SIZE sizeof(struct st_frame) | ||
263 | #define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + STEX_EXTRA_SIZE) | ||
264 | |||
265 | struct st_ccb { | 271 | struct st_ccb { |
266 | struct req_msg *req; | 272 | struct req_msg *req; |
267 | struct scsi_cmnd *cmd; | 273 | struct scsi_cmnd *cmd; |
@@ -273,6 +279,7 @@ struct st_ccb { | |||
273 | u32 req_type; | 279 | u32 req_type; |
274 | u8 srb_status; | 280 | u8 srb_status; |
275 | u8 scsi_status; | 281 | u8 scsi_status; |
282 | u8 reserved[2]; | ||
276 | }; | 283 | }; |
277 | 284 | ||
278 | struct st_hba { | 285 | struct st_hba { |
@@ -284,6 +291,10 @@ struct st_hba { | |||
284 | struct Scsi_Host *host; | 291 | struct Scsi_Host *host; |
285 | struct pci_dev *pdev; | 292 | struct pci_dev *pdev; |
286 | 293 | ||
294 | struct req_msg * (*alloc_rq) (struct st_hba *); | ||
295 | int (*map_sg)(struct st_hba *, struct req_msg *, struct st_ccb *); | ||
296 | void (*send) (struct st_hba *, struct req_msg *, u16); | ||
297 | |||
287 | u32 req_head; | 298 | u32 req_head; |
288 | u32 req_tail; | 299 | u32 req_tail; |
289 | u32 status_head; | 300 | u32 status_head; |
@@ -291,16 +302,36 @@ struct st_hba { | |||
291 | 302 | ||
292 | struct status_msg *status_buffer; | 303 | struct status_msg *status_buffer; |
293 | void *copy_buffer; /* temp buffer for driver-handled commands */ | 304 | void *copy_buffer; /* temp buffer for driver-handled commands */ |
294 | struct st_ccb ccb[MU_MAX_REQUEST]; | 305 | struct st_ccb *ccb; |
295 | struct st_ccb *wait_ccb; | 306 | struct st_ccb *wait_ccb; |
296 | wait_queue_head_t waitq; | 307 | __le32 *scratch; |
297 | 308 | ||
298 | unsigned int mu_status; | 309 | unsigned int mu_status; |
310 | unsigned int cardtype; | ||
311 | int msi_enabled; | ||
299 | int out_req_cnt; | 312 | int out_req_cnt; |
313 | u32 extra_offset; | ||
314 | u16 rq_count; | ||
315 | u16 rq_size; | ||
316 | u16 sts_count; | ||
317 | }; | ||
300 | 318 | ||
301 | unsigned int cardtype; | 319 | struct st_card_info { |
320 | struct req_msg * (*alloc_rq) (struct st_hba *); | ||
321 | int (*map_sg)(struct st_hba *, struct req_msg *, struct st_ccb *); | ||
322 | void (*send) (struct st_hba *, struct req_msg *, u16); | ||
323 | unsigned int max_id; | ||
324 | unsigned int max_lun; | ||
325 | unsigned int max_channel; | ||
326 | u16 rq_count; | ||
327 | u16 rq_size; | ||
328 | u16 sts_count; | ||
302 | }; | 329 | }; |
303 | 330 | ||
331 | static int msi; | ||
332 | module_param(msi, int, 0); | ||
333 | MODULE_PARM_DESC(msi, "Enable Message Signaled Interrupts(0=off, 1=on)"); | ||
334 | |||
304 | static const char console_inq_page[] = | 335 | static const char console_inq_page[] = |
305 | { | 336 | { |
306 | 0x03,0x00,0x03,0x03,0xFA,0x00,0x00,0x30, | 337 | 0x03,0x00,0x03,0x03,0xFA,0x00,0x00,0x30, |
@@ -318,22 +349,20 @@ MODULE_DESCRIPTION("Promise Technology SuperTrak EX Controllers"); | |||
318 | MODULE_LICENSE("GPL"); | 349 | MODULE_LICENSE("GPL"); |
319 | MODULE_VERSION(ST_DRIVER_VERSION); | 350 | MODULE_VERSION(ST_DRIVER_VERSION); |
320 | 351 | ||
321 | static void stex_gettime(__le32 *time) | 352 | static void stex_gettime(__le64 *time) |
322 | { | 353 | { |
323 | struct timeval tv; | 354 | struct timeval tv; |
324 | 355 | ||
325 | do_gettimeofday(&tv); | 356 | do_gettimeofday(&tv); |
326 | *time = cpu_to_le32(tv.tv_sec & 0xffffffff); | 357 | *time = cpu_to_le64(tv.tv_sec); |
327 | *(time + 1) = cpu_to_le32((tv.tv_sec >> 16) >> 16); | ||
328 | } | 358 | } |
329 | 359 | ||
330 | static struct status_msg *stex_get_status(struct st_hba *hba) | 360 | static struct status_msg *stex_get_status(struct st_hba *hba) |
331 | { | 361 | { |
332 | struct status_msg *status = | 362 | struct status_msg *status = hba->status_buffer + hba->status_tail; |
333 | hba->status_buffer + hba->status_tail; | ||
334 | 363 | ||
335 | ++hba->status_tail; | 364 | ++hba->status_tail; |
336 | hba->status_tail %= MU_STATUS_COUNT; | 365 | hba->status_tail %= hba->sts_count+1; |
337 | 366 | ||
338 | return status; | 367 | return status; |
339 | } | 368 | } |
@@ -351,47 +380,83 @@ static void stex_invalid_field(struct scsi_cmnd *cmd, | |||
351 | 380 | ||
352 | static struct req_msg *stex_alloc_req(struct st_hba *hba) | 381 | static struct req_msg *stex_alloc_req(struct st_hba *hba) |
353 | { | 382 | { |
354 | struct req_msg *req = ((struct req_msg *)hba->dma_mem) + | 383 | struct req_msg *req = hba->dma_mem + hba->req_head * hba->rq_size; |
355 | hba->req_head; | ||
356 | 384 | ||
357 | ++hba->req_head; | 385 | ++hba->req_head; |
358 | hba->req_head %= MU_REQ_COUNT; | 386 | hba->req_head %= hba->rq_count+1; |
359 | 387 | ||
360 | return req; | 388 | return req; |
361 | } | 389 | } |
362 | 390 | ||
391 | static struct req_msg *stex_ss_alloc_req(struct st_hba *hba) | ||
392 | { | ||
393 | return (struct req_msg *)(hba->dma_mem + | ||
394 | hba->req_head * hba->rq_size + sizeof(struct st_msg_header)); | ||
395 | } | ||
396 | |||
363 | static int stex_map_sg(struct st_hba *hba, | 397 | static int stex_map_sg(struct st_hba *hba, |
364 | struct req_msg *req, struct st_ccb *ccb) | 398 | struct req_msg *req, struct st_ccb *ccb) |
365 | { | 399 | { |
366 | struct scsi_cmnd *cmd; | 400 | struct scsi_cmnd *cmd; |
367 | struct scatterlist *sg; | 401 | struct scatterlist *sg; |
368 | struct st_sgtable *dst; | 402 | struct st_sgtable *dst; |
403 | struct st_sgitem *table; | ||
369 | int i, nseg; | 404 | int i, nseg; |
370 | 405 | ||
371 | cmd = ccb->cmd; | 406 | cmd = ccb->cmd; |
372 | dst = (struct st_sgtable *)req->variable; | 407 | nseg = scsi_dma_map(cmd); |
373 | dst->max_sg_count = cpu_to_le16(ST_MAX_SG); | 408 | BUG_ON(nseg < 0); |
374 | dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd)); | 409 | if (nseg) { |
410 | dst = (struct st_sgtable *)req->variable; | ||
411 | |||
412 | ccb->sg_count = nseg; | ||
413 | dst->sg_count = cpu_to_le16((u16)nseg); | ||
414 | dst->max_sg_count = cpu_to_le16(hba->host->sg_tablesize); | ||
415 | dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd)); | ||
416 | |||
417 | table = (struct st_sgitem *)(dst + 1); | ||
418 | scsi_for_each_sg(cmd, sg, nseg, i) { | ||
419 | table[i].count = cpu_to_le32((u32)sg_dma_len(sg)); | ||
420 | table[i].addr = cpu_to_le64(sg_dma_address(sg)); | ||
421 | table[i].ctrl = SG_CF_64B | SG_CF_HOST; | ||
422 | } | ||
423 | table[--i].ctrl |= SG_CF_EOT; | ||
424 | } | ||
425 | |||
426 | return nseg; | ||
427 | } | ||
428 | |||
429 | static int stex_ss_map_sg(struct st_hba *hba, | ||
430 | struct req_msg *req, struct st_ccb *ccb) | ||
431 | { | ||
432 | struct scsi_cmnd *cmd; | ||
433 | struct scatterlist *sg; | ||
434 | struct st_sgtable *dst; | ||
435 | struct st_ss_sgitem *table; | ||
436 | int i, nseg; | ||
375 | 437 | ||
438 | cmd = ccb->cmd; | ||
376 | nseg = scsi_dma_map(cmd); | 439 | nseg = scsi_dma_map(cmd); |
377 | if (nseg < 0) | 440 | BUG_ON(nseg < 0); |
378 | return -EIO; | ||
379 | if (nseg) { | 441 | if (nseg) { |
442 | dst = (struct st_sgtable *)req->variable; | ||
443 | |||
380 | ccb->sg_count = nseg; | 444 | ccb->sg_count = nseg; |
381 | dst->sg_count = cpu_to_le16((u16)nseg); | 445 | dst->sg_count = cpu_to_le16((u16)nseg); |
446 | dst->max_sg_count = cpu_to_le16(hba->host->sg_tablesize); | ||
447 | dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd)); | ||
382 | 448 | ||
449 | table = (struct st_ss_sgitem *)(dst + 1); | ||
383 | scsi_for_each_sg(cmd, sg, nseg, i) { | 450 | scsi_for_each_sg(cmd, sg, nseg, i) { |
384 | dst->table[i].count = cpu_to_le32((u32)sg_dma_len(sg)); | 451 | table[i].count = cpu_to_le32((u32)sg_dma_len(sg)); |
385 | dst->table[i].addr = | 452 | table[i].addr = |
386 | cpu_to_le32(sg_dma_address(sg) & 0xffffffff); | 453 | cpu_to_le32(sg_dma_address(sg) & 0xffffffff); |
387 | dst->table[i].addr_hi = | 454 | table[i].addr_hi = |
388 | cpu_to_le32((sg_dma_address(sg) >> 16) >> 16); | 455 | cpu_to_le32((sg_dma_address(sg) >> 16) >> 16); |
389 | dst->table[i].ctrl = SG_CF_64B | SG_CF_HOST; | ||
390 | } | 456 | } |
391 | dst->table[--i].ctrl |= SG_CF_EOT; | ||
392 | } | 457 | } |
393 | 458 | ||
394 | return 0; | 459 | return nseg; |
395 | } | 460 | } |
396 | 461 | ||
397 | static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) | 462 | static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) |
@@ -400,7 +465,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) | |||
400 | size_t count = sizeof(struct st_frame); | 465 | size_t count = sizeof(struct st_frame); |
401 | 466 | ||
402 | p = hba->copy_buffer; | 467 | p = hba->copy_buffer; |
403 | count = scsi_sg_copy_to_buffer(ccb->cmd, p, count); | 468 | scsi_sg_copy_to_buffer(ccb->cmd, p, count); |
404 | memset(p->base, 0, sizeof(u32)*6); | 469 | memset(p->base, 0, sizeof(u32)*6); |
405 | *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); | 470 | *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); |
406 | p->rom_addr = 0; | 471 | p->rom_addr = 0; |
@@ -418,15 +483,13 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) | |||
418 | p->subid = | 483 | p->subid = |
419 | hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; | 484 | hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; |
420 | 485 | ||
421 | count = scsi_sg_copy_from_buffer(ccb->cmd, p, count); | 486 | scsi_sg_copy_from_buffer(ccb->cmd, p, count); |
422 | } | 487 | } |
423 | 488 | ||
424 | static void | 489 | static void |
425 | stex_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag) | 490 | stex_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag) |
426 | { | 491 | { |
427 | req->tag = cpu_to_le16(tag); | 492 | req->tag = cpu_to_le16(tag); |
428 | req->task_attr = TASK_ATTRIBUTE_SIMPLE; | ||
429 | req->task_manage = 0; /* not supported yet */ | ||
430 | 493 | ||
431 | hba->ccb[tag].req = req; | 494 | hba->ccb[tag].req = req; |
432 | hba->out_req_cnt++; | 495 | hba->out_req_cnt++; |
@@ -436,13 +499,44 @@ stex_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag) | |||
436 | readl(hba->mmio_base + IDBL); /* flush */ | 499 | readl(hba->mmio_base + IDBL); /* flush */ |
437 | } | 500 | } |
438 | 501 | ||
502 | static void | ||
503 | stex_ss_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag) | ||
504 | { | ||
505 | struct scsi_cmnd *cmd; | ||
506 | struct st_msg_header *msg_h; | ||
507 | dma_addr_t addr; | ||
508 | |||
509 | req->tag = cpu_to_le16(tag); | ||
510 | |||
511 | hba->ccb[tag].req = req; | ||
512 | hba->out_req_cnt++; | ||
513 | |||
514 | cmd = hba->ccb[tag].cmd; | ||
515 | msg_h = (struct st_msg_header *)req - 1; | ||
516 | if (likely(cmd)) { | ||
517 | msg_h->channel = (u8)cmd->device->channel; | ||
518 | msg_h->timeout = cpu_to_le16(cmd->request->timeout/HZ); | ||
519 | } | ||
520 | addr = hba->dma_handle + hba->req_head * hba->rq_size; | ||
521 | addr += (hba->ccb[tag].sg_count+4)/11; | ||
522 | msg_h->handle = cpu_to_le64(addr); | ||
523 | |||
524 | ++hba->req_head; | ||
525 | hba->req_head %= hba->rq_count+1; | ||
526 | |||
527 | writel((addr >> 16) >> 16, hba->mmio_base + YH2I_REQ_HI); | ||
528 | readl(hba->mmio_base + YH2I_REQ_HI); /* flush */ | ||
529 | writel(addr, hba->mmio_base + YH2I_REQ); | ||
530 | readl(hba->mmio_base + YH2I_REQ); /* flush */ | ||
531 | } | ||
532 | |||
439 | static int | 533 | static int |
440 | stex_slave_alloc(struct scsi_device *sdev) | 534 | stex_slave_alloc(struct scsi_device *sdev) |
441 | { | 535 | { |
442 | /* Cheat: usually extracted from Inquiry data */ | 536 | /* Cheat: usually extracted from Inquiry data */ |
443 | sdev->tagged_supported = 1; | 537 | sdev->tagged_supported = 1; |
444 | 538 | ||
445 | scsi_activate_tcq(sdev, ST_CMD_PER_LUN); | 539 | scsi_activate_tcq(sdev, sdev->host->can_queue); |
446 | 540 | ||
447 | return 0; | 541 | return 0; |
448 | } | 542 | } |
@@ -469,7 +563,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
469 | { | 563 | { |
470 | struct st_hba *hba; | 564 | struct st_hba *hba; |
471 | struct Scsi_Host *host; | 565 | struct Scsi_Host *host; |
472 | unsigned int id,lun; | 566 | unsigned int id, lun; |
473 | struct req_msg *req; | 567 | struct req_msg *req; |
474 | u16 tag; | 568 | u16 tag; |
475 | 569 | ||
@@ -516,7 +610,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
516 | case INQUIRY: | 610 | case INQUIRY: |
517 | if (id != host->max_id - 1) | 611 | if (id != host->max_id - 1) |
518 | break; | 612 | break; |
519 | if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { | 613 | if (!lun && !cmd->device->channel && |
614 | (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { | ||
520 | scsi_sg_copy_from_buffer(cmd, (void *)console_inq_page, | 615 | scsi_sg_copy_from_buffer(cmd, (void *)console_inq_page, |
521 | sizeof(console_inq_page)); | 616 | sizeof(console_inq_page)); |
522 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; | 617 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; |
@@ -554,7 +649,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
554 | if (unlikely(tag >= host->can_queue)) | 649 | if (unlikely(tag >= host->can_queue)) |
555 | return SCSI_MLQUEUE_HOST_BUSY; | 650 | return SCSI_MLQUEUE_HOST_BUSY; |
556 | 651 | ||
557 | req = stex_alloc_req(hba); | 652 | req = hba->alloc_rq(hba); |
558 | 653 | ||
559 | req->lun = lun; | 654 | req->lun = lun; |
560 | req->target = id; | 655 | req->target = id; |
@@ -572,12 +667,13 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
572 | hba->ccb[tag].cmd = cmd; | 667 | hba->ccb[tag].cmd = cmd; |
573 | hba->ccb[tag].sense_bufflen = SCSI_SENSE_BUFFERSIZE; | 668 | hba->ccb[tag].sense_bufflen = SCSI_SENSE_BUFFERSIZE; |
574 | hba->ccb[tag].sense_buffer = cmd->sense_buffer; | 669 | hba->ccb[tag].sense_buffer = cmd->sense_buffer; |
575 | hba->ccb[tag].req_type = 0; | ||
576 | 670 | ||
577 | if (cmd->sc_data_direction != DMA_NONE) | 671 | if (!hba->map_sg(hba, req, &hba->ccb[tag])) { |
578 | stex_map_sg(hba, req, &hba->ccb[tag]); | 672 | hba->ccb[tag].sg_count = 0; |
673 | memset(&req->variable[0], 0, 8); | ||
674 | } | ||
579 | 675 | ||
580 | stex_send_cmd(hba, req, tag); | 676 | hba->send(hba, req, tag); |
581 | return 0; | 677 | return 0; |
582 | } | 678 | } |
583 | 679 | ||
@@ -586,7 +682,7 @@ static void stex_scsi_done(struct st_ccb *ccb) | |||
586 | struct scsi_cmnd *cmd = ccb->cmd; | 682 | struct scsi_cmnd *cmd = ccb->cmd; |
587 | int result; | 683 | int result; |
588 | 684 | ||
589 | if (ccb->srb_status == SRB_STATUS_SUCCESS || ccb->srb_status == 0) { | 685 | if (ccb->srb_status == SRB_STATUS_SUCCESS || ccb->srb_status == 0) { |
590 | result = ccb->scsi_status; | 686 | result = ccb->scsi_status; |
591 | switch (ccb->scsi_status) { | 687 | switch (ccb->scsi_status) { |
592 | case SAM_STAT_GOOD: | 688 | case SAM_STAT_GOOD: |
@@ -626,8 +722,6 @@ static void stex_scsi_done(struct st_ccb *ccb) | |||
626 | static void stex_copy_data(struct st_ccb *ccb, | 722 | static void stex_copy_data(struct st_ccb *ccb, |
627 | struct status_msg *resp, unsigned int variable) | 723 | struct status_msg *resp, unsigned int variable) |
628 | { | 724 | { |
629 | size_t count = variable; | ||
630 | |||
631 | if (resp->scsi_status != SAM_STAT_GOOD) { | 725 | if (resp->scsi_status != SAM_STAT_GOOD) { |
632 | if (ccb->sense_buffer != NULL) | 726 | if (ccb->sense_buffer != NULL) |
633 | memcpy(ccb->sense_buffer, resp->variable, | 727 | memcpy(ccb->sense_buffer, resp->variable, |
@@ -637,17 +731,16 @@ static void stex_copy_data(struct st_ccb *ccb, | |||
637 | 731 | ||
638 | if (ccb->cmd == NULL) | 732 | if (ccb->cmd == NULL) |
639 | return; | 733 | return; |
640 | count = scsi_sg_copy_from_buffer(ccb->cmd, resp->variable, count); | 734 | scsi_sg_copy_from_buffer(ccb->cmd, resp->variable, variable); |
641 | } | 735 | } |
642 | 736 | ||
643 | static void stex_ys_commands(struct st_hba *hba, | 737 | static void stex_check_cmd(struct st_hba *hba, |
644 | struct st_ccb *ccb, struct status_msg *resp) | 738 | struct st_ccb *ccb, struct status_msg *resp) |
645 | { | 739 | { |
646 | if (ccb->cmd->cmnd[0] == MGT_CMD && | 740 | if (ccb->cmd->cmnd[0] == MGT_CMD && |
647 | resp->scsi_status != SAM_STAT_CHECK_CONDITION) { | 741 | resp->scsi_status != SAM_STAT_CHECK_CONDITION) |
648 | scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) - | 742 | scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) - |
649 | le32_to_cpu(*(__le32 *)&resp->variable[0])); | 743 | le32_to_cpu(*(__le32 *)&resp->variable[0])); |
650 | } | ||
651 | } | 744 | } |
652 | 745 | ||
653 | static void stex_mu_intr(struct st_hba *hba, u32 doorbell) | 746 | static void stex_mu_intr(struct st_hba *hba, u32 doorbell) |
@@ -658,12 +751,12 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell) | |||
658 | unsigned int size; | 751 | unsigned int size; |
659 | u16 tag; | 752 | u16 tag; |
660 | 753 | ||
661 | if (!(doorbell & MU_OUTBOUND_DOORBELL_STATUSHEADCHANGED)) | 754 | if (unlikely(!(doorbell & MU_OUTBOUND_DOORBELL_STATUSHEADCHANGED))) |
662 | return; | 755 | return; |
663 | 756 | ||
664 | /* status payloads */ | 757 | /* status payloads */ |
665 | hba->status_head = readl(base + OMR1); | 758 | hba->status_head = readl(base + OMR1); |
666 | if (unlikely(hba->status_head >= MU_STATUS_COUNT)) { | 759 | if (unlikely(hba->status_head > hba->sts_count)) { |
667 | printk(KERN_WARNING DRV_NAME "(%s): invalid status head\n", | 760 | printk(KERN_WARNING DRV_NAME "(%s): invalid status head\n", |
668 | pci_name(hba->pdev)); | 761 | pci_name(hba->pdev)); |
669 | return; | 762 | return; |
@@ -693,13 +786,13 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell) | |||
693 | continue; | 786 | continue; |
694 | } | 787 | } |
695 | 788 | ||
789 | hba->out_req_cnt--; | ||
696 | ccb = &hba->ccb[tag]; | 790 | ccb = &hba->ccb[tag]; |
697 | if (hba->wait_ccb == ccb) | 791 | if (unlikely(hba->wait_ccb == ccb)) |
698 | hba->wait_ccb = NULL; | 792 | hba->wait_ccb = NULL; |
699 | if (unlikely(ccb->req == NULL)) { | 793 | if (unlikely(ccb->req == NULL)) { |
700 | printk(KERN_WARNING DRV_NAME | 794 | printk(KERN_WARNING DRV_NAME |
701 | "(%s): lagging req\n", pci_name(hba->pdev)); | 795 | "(%s): lagging req\n", pci_name(hba->pdev)); |
702 | hba->out_req_cnt--; | ||
703 | continue; | 796 | continue; |
704 | } | 797 | } |
705 | 798 | ||
@@ -720,7 +813,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell) | |||
720 | 813 | ||
721 | if (likely(ccb->cmd != NULL)) { | 814 | if (likely(ccb->cmd != NULL)) { |
722 | if (hba->cardtype == st_yosemite) | 815 | if (hba->cardtype == st_yosemite) |
723 | stex_ys_commands(hba, ccb, resp); | 816 | stex_check_cmd(hba, ccb, resp); |
724 | 817 | ||
725 | if (unlikely(ccb->cmd->cmnd[0] == PASSTHRU_CMD && | 818 | if (unlikely(ccb->cmd->cmnd[0] == PASSTHRU_CMD && |
726 | ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER)) | 819 | ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER)) |
@@ -728,17 +821,8 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell) | |||
728 | 821 | ||
729 | scsi_dma_unmap(ccb->cmd); | 822 | scsi_dma_unmap(ccb->cmd); |
730 | stex_scsi_done(ccb); | 823 | stex_scsi_done(ccb); |
731 | hba->out_req_cnt--; | 824 | } 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; | 825 | ccb->req_type = 0; |
739 | if (waitqueue_active(&hba->waitq)) | ||
740 | wake_up(&hba->waitq); | ||
741 | } | ||
742 | } | 826 | } |
743 | 827 | ||
744 | update_status: | 828 | update_status: |
@@ -771,7 +855,103 @@ static irqreturn_t stex_intr(int irq, void *__hba) | |||
771 | return IRQ_RETVAL(handled); | 855 | return IRQ_RETVAL(handled); |
772 | } | 856 | } |
773 | 857 | ||
774 | static int stex_handshake(struct st_hba *hba) | 858 | static void stex_ss_mu_intr(struct st_hba *hba) |
859 | { | ||
860 | struct status_msg *resp; | ||
861 | struct st_ccb *ccb; | ||
862 | __le32 *scratch; | ||
863 | unsigned int size; | ||
864 | int count = 0; | ||
865 | u32 value; | ||
866 | u16 tag; | ||
867 | |||
868 | if (unlikely(hba->out_req_cnt <= 0 || | ||
869 | hba->mu_status == MU_STATE_RESETTING)) | ||
870 | return; | ||
871 | |||
872 | while (count < hba->sts_count) { | ||
873 | scratch = hba->scratch + hba->status_tail; | ||
874 | value = le32_to_cpu(*scratch); | ||
875 | if (unlikely(!(value & SS_STS_NORMAL))) | ||
876 | return; | ||
877 | |||
878 | resp = hba->status_buffer + hba->status_tail; | ||
879 | *scratch = 0; | ||
880 | ++count; | ||
881 | ++hba->status_tail; | ||
882 | hba->status_tail %= hba->sts_count+1; | ||
883 | |||
884 | tag = (u16)value; | ||
885 | if (unlikely(tag >= hba->host->can_queue)) { | ||
886 | printk(KERN_WARNING DRV_NAME | ||
887 | "(%s): invalid tag\n", pci_name(hba->pdev)); | ||
888 | continue; | ||
889 | } | ||
890 | |||
891 | hba->out_req_cnt--; | ||
892 | ccb = &hba->ccb[tag]; | ||
893 | if (unlikely(hba->wait_ccb == ccb)) | ||
894 | hba->wait_ccb = NULL; | ||
895 | if (unlikely(ccb->req == NULL)) { | ||
896 | printk(KERN_WARNING DRV_NAME | ||
897 | "(%s): lagging req\n", pci_name(hba->pdev)); | ||
898 | continue; | ||
899 | } | ||
900 | |||
901 | ccb->req = NULL; | ||
902 | if (likely(value & SS_STS_DONE)) { /* normal case */ | ||
903 | ccb->srb_status = SRB_STATUS_SUCCESS; | ||
904 | ccb->scsi_status = SAM_STAT_GOOD; | ||
905 | } else { | ||
906 | ccb->srb_status = resp->srb_status; | ||
907 | ccb->scsi_status = resp->scsi_status; | ||
908 | size = resp->payload_sz * sizeof(u32); | ||
909 | if (unlikely(size < sizeof(*resp) - STATUS_VAR_LEN || | ||
910 | size > sizeof(*resp))) { | ||
911 | printk(KERN_WARNING DRV_NAME | ||
912 | "(%s): bad status size\n", | ||
913 | pci_name(hba->pdev)); | ||
914 | } else { | ||
915 | size -= sizeof(*resp) - STATUS_VAR_LEN; | ||
916 | if (size) | ||
917 | stex_copy_data(ccb, resp, size); | ||
918 | } | ||
919 | if (likely(ccb->cmd != NULL)) | ||
920 | stex_check_cmd(hba, ccb, resp); | ||
921 | } | ||
922 | |||
923 | if (likely(ccb->cmd != NULL)) { | ||
924 | scsi_dma_unmap(ccb->cmd); | ||
925 | stex_scsi_done(ccb); | ||
926 | } else | ||
927 | ccb->req_type = 0; | ||
928 | } | ||
929 | } | ||
930 | |||
931 | static irqreturn_t stex_ss_intr(int irq, void *__hba) | ||
932 | { | ||
933 | struct st_hba *hba = __hba; | ||
934 | void __iomem *base = hba->mmio_base; | ||
935 | u32 data; | ||
936 | unsigned long flags; | ||
937 | int handled = 0; | ||
938 | |||
939 | spin_lock_irqsave(hba->host->host_lock, flags); | ||
940 | |||
941 | data = readl(base + YI2H_INT); | ||
942 | if (data && data != 0xffffffff) { | ||
943 | /* clear the interrupt */ | ||
944 | writel(data, base + YI2H_INT_C); | ||
945 | stex_ss_mu_intr(hba); | ||
946 | handled = 1; | ||
947 | } | ||
948 | |||
949 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
950 | |||
951 | return IRQ_RETVAL(handled); | ||
952 | } | ||
953 | |||
954 | static int stex_common_handshake(struct st_hba *hba) | ||
775 | { | 955 | { |
776 | void __iomem *base = hba->mmio_base; | 956 | void __iomem *base = hba->mmio_base; |
777 | struct handshake_frame *h; | 957 | struct handshake_frame *h; |
@@ -800,26 +980,27 @@ static int stex_handshake(struct st_hba *hba) | |||
800 | data = readl(base + OMR1); | 980 | data = readl(base + OMR1); |
801 | if ((data & 0xffff0000) == MU_HANDSHAKE_SIGNATURE_HALF) { | 981 | if ((data & 0xffff0000) == MU_HANDSHAKE_SIGNATURE_HALF) { |
802 | data &= 0x0000ffff; | 982 | data &= 0x0000ffff; |
803 | if (hba->host->can_queue > data) | 983 | if (hba->host->can_queue > data) { |
804 | hba->host->can_queue = data; | 984 | hba->host->can_queue = data; |
985 | hba->host->cmd_per_lun = data; | ||
986 | } | ||
805 | } | 987 | } |
806 | 988 | ||
807 | h = (struct handshake_frame *)(hba->dma_mem + MU_REQ_BUFFER_SIZE); | 989 | h = (struct handshake_frame *)hba->status_buffer; |
808 | h->rb_phy = cpu_to_le32(hba->dma_handle); | 990 | h->rb_phy = cpu_to_le64(hba->dma_handle); |
809 | h->rb_phy_hi = cpu_to_le32((hba->dma_handle >> 16) >> 16); | 991 | h->req_sz = cpu_to_le16(hba->rq_size); |
810 | h->req_sz = cpu_to_le16(sizeof(struct req_msg)); | 992 | h->req_cnt = cpu_to_le16(hba->rq_count+1); |
811 | h->req_cnt = cpu_to_le16(MU_REQ_COUNT); | ||
812 | h->status_sz = cpu_to_le16(sizeof(struct status_msg)); | 993 | h->status_sz = cpu_to_le16(sizeof(struct status_msg)); |
813 | h->status_cnt = cpu_to_le16(MU_STATUS_COUNT); | 994 | h->status_cnt = cpu_to_le16(hba->sts_count+1); |
814 | stex_gettime(&h->hosttime); | 995 | stex_gettime(&h->hosttime); |
815 | h->partner_type = HMU_PARTNER_TYPE; | 996 | h->partner_type = HMU_PARTNER_TYPE; |
816 | if (hba->dma_size > STEX_BUFFER_SIZE) { | 997 | if (hba->extra_offset) { |
817 | h->extra_offset = cpu_to_le32(STEX_BUFFER_SIZE); | 998 | h->extra_offset = cpu_to_le32(hba->extra_offset); |
818 | h->extra_size = cpu_to_le32(ST_ADDITIONAL_MEM); | 999 | h->extra_size = cpu_to_le32(ST_ADDITIONAL_MEM); |
819 | } else | 1000 | } else |
820 | h->extra_offset = h->extra_size = 0; | 1001 | h->extra_offset = h->extra_size = 0; |
821 | 1002 | ||
822 | status_phys = hba->dma_handle + MU_REQ_BUFFER_SIZE; | 1003 | status_phys = hba->dma_handle + (hba->rq_count+1) * hba->rq_size; |
823 | writel(status_phys, base + IMR0); | 1004 | writel(status_phys, base + IMR0); |
824 | readl(base + IMR0); | 1005 | readl(base + IMR0); |
825 | writel((status_phys >> 16) >> 16, base + IMR1); | 1006 | writel((status_phys >> 16) >> 16, base + IMR1); |
@@ -851,10 +1032,79 @@ static int stex_handshake(struct st_hba *hba) | |||
851 | readl(base + IMR1); | 1032 | readl(base + IMR1); |
852 | writel(0, base + OMR1); | 1033 | writel(0, base + OMR1); |
853 | readl(base + OMR1); /* flush */ | 1034 | readl(base + OMR1); /* flush */ |
854 | hba->mu_status = MU_STATE_STARTED; | ||
855 | return 0; | 1035 | return 0; |
856 | } | 1036 | } |
857 | 1037 | ||
1038 | static int stex_ss_handshake(struct st_hba *hba) | ||
1039 | { | ||
1040 | void __iomem *base = hba->mmio_base; | ||
1041 | struct st_msg_header *msg_h; | ||
1042 | struct handshake_frame *h; | ||
1043 | __le32 *scratch = hba->scratch; | ||
1044 | u32 data; | ||
1045 | unsigned long before; | ||
1046 | int ret = 0; | ||
1047 | |||
1048 | h = (struct handshake_frame *)(hba->alloc_rq(hba)); | ||
1049 | msg_h = (struct st_msg_header *)h - 1; | ||
1050 | msg_h->handle = cpu_to_le64(hba->dma_handle); | ||
1051 | msg_h->flag = SS_HEAD_HANDSHAKE; | ||
1052 | |||
1053 | h->rb_phy = cpu_to_le64(hba->dma_handle); | ||
1054 | h->req_sz = cpu_to_le16(hba->rq_size); | ||
1055 | h->req_cnt = cpu_to_le16(hba->rq_count+1); | ||
1056 | h->status_sz = cpu_to_le16(sizeof(struct status_msg)); | ||
1057 | h->status_cnt = cpu_to_le16(hba->sts_count+1); | ||
1058 | stex_gettime(&h->hosttime); | ||
1059 | h->partner_type = HMU_PARTNER_TYPE; | ||
1060 | h->extra_offset = h->extra_size = 0; | ||
1061 | h->scratch_size = cpu_to_le32((hba->sts_count+1)*sizeof(u32)); | ||
1062 | |||
1063 | data = readl(base + YINT_EN); | ||
1064 | data &= ~4; | ||
1065 | writel(data, base + YINT_EN); | ||
1066 | writel((hba->dma_handle >> 16) >> 16, base + YH2I_REQ_HI); | ||
1067 | writel(hba->dma_handle, base + YH2I_REQ); | ||
1068 | |||
1069 | scratch = hba->scratch; | ||
1070 | before = jiffies; | ||
1071 | while (!(le32_to_cpu(*scratch) & SS_STS_HANDSHAKE)) { | ||
1072 | if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) { | ||
1073 | printk(KERN_ERR DRV_NAME | ||
1074 | "(%s): no signature after handshake frame\n", | ||
1075 | pci_name(hba->pdev)); | ||
1076 | ret = -1; | ||
1077 | break; | ||
1078 | } | ||
1079 | rmb(); | ||
1080 | msleep(1); | ||
1081 | } | ||
1082 | |||
1083 | *scratch = 0; | ||
1084 | msg_h->flag = 0; | ||
1085 | return ret; | ||
1086 | } | ||
1087 | |||
1088 | static int stex_handshake(struct st_hba *hba) | ||
1089 | { | ||
1090 | int err; | ||
1091 | unsigned long flags; | ||
1092 | |||
1093 | err = (hba->cardtype == st_yel) ? | ||
1094 | stex_ss_handshake(hba) : stex_common_handshake(hba); | ||
1095 | if (err == 0) { | ||
1096 | spin_lock_irqsave(hba->host->host_lock, flags); | ||
1097 | hba->req_head = 0; | ||
1098 | hba->req_tail = 0; | ||
1099 | hba->status_head = 0; | ||
1100 | hba->status_tail = 0; | ||
1101 | hba->out_req_cnt = 0; | ||
1102 | hba->mu_status = MU_STATE_STARTED; | ||
1103 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
1104 | } | ||
1105 | return err; | ||
1106 | } | ||
1107 | |||
858 | static int stex_abort(struct scsi_cmnd *cmd) | 1108 | static int stex_abort(struct scsi_cmnd *cmd) |
859 | { | 1109 | { |
860 | struct Scsi_Host *host = cmd->device->host; | 1110 | struct Scsi_Host *host = cmd->device->host; |
@@ -883,15 +1133,23 @@ static int stex_abort(struct scsi_cmnd *cmd) | |||
883 | goto out; | 1133 | goto out; |
884 | } | 1134 | } |
885 | 1135 | ||
886 | data = readl(base + ODBL); | 1136 | if (hba->cardtype == st_yel) { |
887 | if (data == 0 || data == 0xffffffff) | 1137 | data = readl(base + YI2H_INT); |
888 | goto fail_out; | 1138 | if (data == 0 || data == 0xffffffff) |
1139 | goto fail_out; | ||
889 | 1140 | ||
890 | writel(data, base + ODBL); | 1141 | writel(data, base + YI2H_INT_C); |
891 | readl(base + ODBL); /* flush */ | 1142 | stex_ss_mu_intr(hba); |
1143 | } else { | ||
1144 | data = readl(base + ODBL); | ||
1145 | if (data == 0 || data == 0xffffffff) | ||
1146 | goto fail_out; | ||
892 | 1147 | ||
893 | stex_mu_intr(hba, data); | 1148 | writel(data, base + ODBL); |
1149 | readl(base + ODBL); /* flush */ | ||
894 | 1150 | ||
1151 | stex_mu_intr(hba, data); | ||
1152 | } | ||
895 | if (hba->wait_ccb == NULL) { | 1153 | if (hba->wait_ccb == NULL) { |
896 | printk(KERN_WARNING DRV_NAME | 1154 | printk(KERN_WARNING DRV_NAME |
897 | "(%s): lost interrupt\n", pci_name(hba->pdev)); | 1155 | "(%s): lost interrupt\n", pci_name(hba->pdev)); |
@@ -950,8 +1208,8 @@ static void stex_hard_reset(struct st_hba *hba) | |||
950 | static int stex_reset(struct scsi_cmnd *cmd) | 1208 | static int stex_reset(struct scsi_cmnd *cmd) |
951 | { | 1209 | { |
952 | struct st_hba *hba; | 1210 | struct st_hba *hba; |
953 | unsigned long flags; | 1211 | void __iomem *base; |
954 | unsigned long before; | 1212 | unsigned long flags, before; |
955 | 1213 | ||
956 | hba = (struct st_hba *) &cmd->device->host->hostdata[0]; | 1214 | hba = (struct st_hba *) &cmd->device->host->hostdata[0]; |
957 | 1215 | ||
@@ -971,13 +1229,6 @@ static int stex_reset(struct scsi_cmnd *cmd) | |||
971 | pci_name(hba->pdev)); | 1229 | pci_name(hba->pdev)); |
972 | return FAILED; | 1230 | return FAILED; |
973 | } | 1231 | } |
974 | spin_lock_irqsave(hba->host->host_lock, flags); | ||
975 | hba->req_head = 0; | ||
976 | hba->req_tail = 0; | ||
977 | hba->status_head = 0; | ||
978 | hba->status_tail = 0; | ||
979 | hba->out_req_cnt = 0; | ||
980 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
981 | return SUCCESS; | 1232 | return SUCCESS; |
982 | } | 1233 | } |
983 | 1234 | ||
@@ -994,7 +1245,23 @@ static int stex_reset(struct scsi_cmnd *cmd) | |||
994 | msleep(1); | 1245 | msleep(1); |
995 | } | 1246 | } |
996 | 1247 | ||
1248 | base = hba->mmio_base; | ||
1249 | writel(0, base + IMR0); | ||
1250 | readl(base + IMR0); | ||
1251 | writel(0, base + OMR0); | ||
1252 | readl(base + OMR0); | ||
1253 | writel(0, base + IMR1); | ||
1254 | readl(base + IMR1); | ||
1255 | writel(0, base + OMR1); | ||
1256 | readl(base + OMR1); /* flush */ | ||
1257 | spin_lock_irqsave(hba->host->host_lock, flags); | ||
1258 | hba->req_head = 0; | ||
1259 | hba->req_tail = 0; | ||
1260 | hba->status_head = 0; | ||
1261 | hba->status_tail = 0; | ||
1262 | hba->out_req_cnt = 0; | ||
997 | hba->mu_status = MU_STATE_STARTED; | 1263 | hba->mu_status = MU_STATE_STARTED; |
1264 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
998 | return SUCCESS; | 1265 | return SUCCESS; |
999 | } | 1266 | } |
1000 | 1267 | ||
@@ -1028,30 +1295,157 @@ static struct scsi_host_template driver_template = { | |||
1028 | .slave_destroy = stex_slave_destroy, | 1295 | .slave_destroy = stex_slave_destroy, |
1029 | .eh_abort_handler = stex_abort, | 1296 | .eh_abort_handler = stex_abort, |
1030 | .eh_host_reset_handler = stex_reset, | 1297 | .eh_host_reset_handler = stex_reset, |
1031 | .can_queue = ST_CAN_QUEUE, | ||
1032 | .this_id = -1, | 1298 | .this_id = -1, |
1033 | .sg_tablesize = ST_MAX_SG, | 1299 | }; |
1034 | .cmd_per_lun = ST_CMD_PER_LUN, | 1300 | |
1301 | static struct pci_device_id stex_pci_tbl[] = { | ||
1302 | /* st_shasta */ | ||
1303 | { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
1304 | st_shasta }, /* SuperTrak EX8350/8300/16350/16300 */ | ||
1305 | { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
1306 | st_shasta }, /* SuperTrak EX12350 */ | ||
1307 | { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
1308 | st_shasta }, /* SuperTrak EX4350 */ | ||
1309 | { 0x105a, 0xe350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
1310 | st_shasta }, /* SuperTrak EX24350 */ | ||
1311 | |||
1312 | /* st_vsc */ | ||
1313 | { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc }, | ||
1314 | |||
1315 | /* st_yosemite */ | ||
1316 | { 0x105a, 0x8650, 0x105a, PCI_ANY_ID, 0, 0, st_yosemite }, | ||
1317 | |||
1318 | /* st_seq */ | ||
1319 | { 0x105a, 0x3360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_seq }, | ||
1320 | |||
1321 | /* st_yel */ | ||
1322 | { 0x105a, 0x8650, 0x1033, PCI_ANY_ID, 0, 0, st_yel }, | ||
1323 | { 0x105a, 0x8760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yel }, | ||
1324 | { } /* terminate list */ | ||
1325 | }; | ||
1326 | |||
1327 | static struct st_card_info stex_card_info[] = { | ||
1328 | /* st_shasta */ | ||
1329 | { | ||
1330 | .max_id = 17, | ||
1331 | .max_lun = 8, | ||
1332 | .max_channel = 0, | ||
1333 | .rq_count = 32, | ||
1334 | .rq_size = 1048, | ||
1335 | .sts_count = 32, | ||
1336 | .alloc_rq = stex_alloc_req, | ||
1337 | .map_sg = stex_map_sg, | ||
1338 | .send = stex_send_cmd, | ||
1339 | }, | ||
1340 | |||
1341 | /* st_vsc */ | ||
1342 | { | ||
1343 | .max_id = 129, | ||
1344 | .max_lun = 1, | ||
1345 | .max_channel = 0, | ||
1346 | .rq_count = 32, | ||
1347 | .rq_size = 1048, | ||
1348 | .sts_count = 32, | ||
1349 | .alloc_rq = stex_alloc_req, | ||
1350 | .map_sg = stex_map_sg, | ||
1351 | .send = stex_send_cmd, | ||
1352 | }, | ||
1353 | |||
1354 | /* st_yosemite */ | ||
1355 | { | ||
1356 | .max_id = 2, | ||
1357 | .max_lun = 256, | ||
1358 | .max_channel = 0, | ||
1359 | .rq_count = 256, | ||
1360 | .rq_size = 1048, | ||
1361 | .sts_count = 256, | ||
1362 | .alloc_rq = stex_alloc_req, | ||
1363 | .map_sg = stex_map_sg, | ||
1364 | .send = stex_send_cmd, | ||
1365 | }, | ||
1366 | |||
1367 | /* st_seq */ | ||
1368 | { | ||
1369 | .max_id = 129, | ||
1370 | .max_lun = 1, | ||
1371 | .max_channel = 0, | ||
1372 | .rq_count = 32, | ||
1373 | .rq_size = 1048, | ||
1374 | .sts_count = 32, | ||
1375 | .alloc_rq = stex_alloc_req, | ||
1376 | .map_sg = stex_map_sg, | ||
1377 | .send = stex_send_cmd, | ||
1378 | }, | ||
1379 | |||
1380 | /* st_yel */ | ||
1381 | { | ||
1382 | .max_id = 129, | ||
1383 | .max_lun = 256, | ||
1384 | .max_channel = 3, | ||
1385 | .rq_count = 801, | ||
1386 | .rq_size = 512, | ||
1387 | .sts_count = 801, | ||
1388 | .alloc_rq = stex_ss_alloc_req, | ||
1389 | .map_sg = stex_ss_map_sg, | ||
1390 | .send = stex_ss_send_cmd, | ||
1391 | }, | ||
1035 | }; | 1392 | }; |
1036 | 1393 | ||
1037 | static int stex_set_dma_mask(struct pci_dev * pdev) | 1394 | static int stex_set_dma_mask(struct pci_dev * pdev) |
1038 | { | 1395 | { |
1039 | int ret; | 1396 | int ret; |
1040 | 1397 | ||
1041 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) | 1398 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) |
1042 | && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) | 1399 | && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) |
1043 | return 0; | 1400 | return 0; |
1044 | ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 1401 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
1045 | if (!ret) | 1402 | if (!ret) |
1046 | ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | 1403 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); |
1047 | return ret; | 1404 | return ret; |
1048 | } | 1405 | } |
1049 | 1406 | ||
1407 | static int stex_request_irq(struct st_hba *hba) | ||
1408 | { | ||
1409 | struct pci_dev *pdev = hba->pdev; | ||
1410 | int status; | ||
1411 | |||
1412 | if (msi) { | ||
1413 | status = pci_enable_msi(pdev); | ||
1414 | if (status != 0) | ||
1415 | printk(KERN_ERR DRV_NAME | ||
1416 | "(%s): error %d setting up MSI\n", | ||
1417 | pci_name(pdev), status); | ||
1418 | else | ||
1419 | hba->msi_enabled = 1; | ||
1420 | } else | ||
1421 | hba->msi_enabled = 0; | ||
1422 | |||
1423 | status = request_irq(pdev->irq, hba->cardtype == st_yel ? | ||
1424 | stex_ss_intr : stex_intr, IRQF_SHARED, DRV_NAME, hba); | ||
1425 | |||
1426 | if (status != 0) { | ||
1427 | if (hba->msi_enabled) | ||
1428 | pci_disable_msi(pdev); | ||
1429 | } | ||
1430 | return status; | ||
1431 | } | ||
1432 | |||
1433 | static void stex_free_irq(struct st_hba *hba) | ||
1434 | { | ||
1435 | struct pci_dev *pdev = hba->pdev; | ||
1436 | |||
1437 | free_irq(pdev->irq, hba); | ||
1438 | if (hba->msi_enabled) | ||
1439 | pci_disable_msi(pdev); | ||
1440 | } | ||
1441 | |||
1050 | static int __devinit | 1442 | static int __devinit |
1051 | stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 1443 | stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
1052 | { | 1444 | { |
1053 | struct st_hba *hba; | 1445 | struct st_hba *hba; |
1054 | struct Scsi_Host *host; | 1446 | struct Scsi_Host *host; |
1447 | const struct st_card_info *ci = NULL; | ||
1448 | u32 sts_offset, cp_offset, scratch_offset; | ||
1055 | int err; | 1449 | int err; |
1056 | 1450 | ||
1057 | err = pci_enable_device(pdev); | 1451 | err = pci_enable_device(pdev); |
@@ -1095,10 +1489,17 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1095 | } | 1489 | } |
1096 | 1490 | ||
1097 | hba->cardtype = (unsigned int) id->driver_data; | 1491 | hba->cardtype = (unsigned int) id->driver_data; |
1098 | if (hba->cardtype == st_vsc && (pdev->subsystem_device & 1)) | 1492 | ci = &stex_card_info[hba->cardtype]; |
1099 | hba->cardtype = st_vsc1; | 1493 | sts_offset = scratch_offset = (ci->rq_count+1) * ci->rq_size; |
1100 | hba->dma_size = (hba->cardtype == st_vsc1 || hba->cardtype == st_seq) ? | 1494 | if (hba->cardtype == st_yel) |
1101 | (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE); | 1495 | sts_offset += (ci->sts_count+1) * sizeof(u32); |
1496 | cp_offset = sts_offset + (ci->sts_count+1) * sizeof(struct status_msg); | ||
1497 | hba->dma_size = cp_offset + sizeof(struct st_frame); | ||
1498 | if (hba->cardtype == st_seq || | ||
1499 | (hba->cardtype == st_vsc && (pdev->subsystem_device & 1))) { | ||
1500 | hba->extra_offset = hba->dma_size; | ||
1501 | hba->dma_size += ST_ADDITIONAL_MEM; | ||
1502 | } | ||
1102 | hba->dma_mem = dma_alloc_coherent(&pdev->dev, | 1503 | hba->dma_mem = dma_alloc_coherent(&pdev->dev, |
1103 | hba->dma_size, &hba->dma_handle, GFP_KERNEL); | 1504 | hba->dma_size, &hba->dma_handle, GFP_KERNEL); |
1104 | if (!hba->dma_mem) { | 1505 | if (!hba->dma_mem) { |
@@ -1108,35 +1509,46 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1108 | goto out_iounmap; | 1509 | goto out_iounmap; |
1109 | } | 1510 | } |
1110 | 1511 | ||
1111 | hba->status_buffer = | 1512 | hba->ccb = kcalloc(ci->rq_count, sizeof(struct st_ccb), GFP_KERNEL); |
1112 | (struct status_msg *)(hba->dma_mem + MU_REQ_BUFFER_SIZE); | 1513 | if (!hba->ccb) { |
1113 | hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE; | 1514 | err = -ENOMEM; |
1515 | printk(KERN_ERR DRV_NAME "(%s): ccb alloc failed\n", | ||
1516 | pci_name(pdev)); | ||
1517 | goto out_pci_free; | ||
1518 | } | ||
1519 | |||
1520 | if (hba->cardtype == st_yel) | ||
1521 | hba->scratch = (__le32 *)(hba->dma_mem + scratch_offset); | ||
1522 | hba->status_buffer = (struct status_msg *)(hba->dma_mem + sts_offset); | ||
1523 | hba->copy_buffer = hba->dma_mem + cp_offset; | ||
1524 | hba->rq_count = ci->rq_count; | ||
1525 | hba->rq_size = ci->rq_size; | ||
1526 | hba->sts_count = ci->sts_count; | ||
1527 | hba->alloc_rq = ci->alloc_rq; | ||
1528 | hba->map_sg = ci->map_sg; | ||
1529 | hba->send = ci->send; | ||
1114 | hba->mu_status = MU_STATE_STARTING; | 1530 | hba->mu_status = MU_STATE_STARTING; |
1115 | 1531 | ||
1116 | if (hba->cardtype == st_shasta) { | 1532 | if (hba->cardtype == st_yel) |
1117 | host->max_lun = 8; | 1533 | host->sg_tablesize = 38; |
1118 | host->max_id = 16 + 1; | 1534 | else |
1119 | } else if (hba->cardtype == st_yosemite) { | 1535 | host->sg_tablesize = 32; |
1120 | host->max_lun = 256; | 1536 | host->can_queue = ci->rq_count; |
1121 | host->max_id = 1 + 1; | 1537 | host->cmd_per_lun = ci->rq_count; |
1122 | } else { | 1538 | host->max_id = ci->max_id; |
1123 | /* st_vsc , st_vsc1 and st_seq */ | 1539 | host->max_lun = ci->max_lun; |
1124 | host->max_lun = 1; | 1540 | host->max_channel = ci->max_channel; |
1125 | host->max_id = 128 + 1; | ||
1126 | } | ||
1127 | host->max_channel = 0; | ||
1128 | host->unique_id = host->host_no; | 1541 | host->unique_id = host->host_no; |
1129 | host->max_cmd_len = STEX_CDB_LENGTH; | 1542 | host->max_cmd_len = STEX_CDB_LENGTH; |
1130 | 1543 | ||
1131 | hba->host = host; | 1544 | hba->host = host; |
1132 | hba->pdev = pdev; | 1545 | hba->pdev = pdev; |
1133 | init_waitqueue_head(&hba->waitq); | ||
1134 | 1546 | ||
1135 | err = request_irq(pdev->irq, stex_intr, IRQF_SHARED, DRV_NAME, hba); | 1547 | err = stex_request_irq(hba); |
1136 | if (err) { | 1548 | if (err) { |
1137 | printk(KERN_ERR DRV_NAME "(%s): request irq failed\n", | 1549 | printk(KERN_ERR DRV_NAME "(%s): request irq failed\n", |
1138 | pci_name(pdev)); | 1550 | pci_name(pdev)); |
1139 | goto out_pci_free; | 1551 | goto out_ccb_free; |
1140 | } | 1552 | } |
1141 | 1553 | ||
1142 | err = stex_handshake(hba); | 1554 | err = stex_handshake(hba); |
@@ -1164,7 +1576,9 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1164 | return 0; | 1576 | return 0; |
1165 | 1577 | ||
1166 | out_free_irq: | 1578 | out_free_irq: |
1167 | free_irq(pdev->irq, hba); | 1579 | stex_free_irq(hba); |
1580 | out_ccb_free: | ||
1581 | kfree(hba->ccb); | ||
1168 | out_pci_free: | 1582 | out_pci_free: |
1169 | dma_free_coherent(&pdev->dev, hba->dma_size, | 1583 | dma_free_coherent(&pdev->dev, hba->dma_size, |
1170 | hba->dma_mem, hba->dma_handle); | 1584 | hba->dma_mem, hba->dma_handle); |
@@ -1183,15 +1597,20 @@ out_disable: | |||
1183 | static void stex_hba_stop(struct st_hba *hba) | 1597 | static void stex_hba_stop(struct st_hba *hba) |
1184 | { | 1598 | { |
1185 | struct req_msg *req; | 1599 | struct req_msg *req; |
1600 | struct st_msg_header *msg_h; | ||
1186 | unsigned long flags; | 1601 | unsigned long flags; |
1187 | unsigned long before; | 1602 | unsigned long before; |
1188 | u16 tag = 0; | 1603 | u16 tag = 0; |
1189 | 1604 | ||
1190 | spin_lock_irqsave(hba->host->host_lock, flags); | 1605 | spin_lock_irqsave(hba->host->host_lock, flags); |
1191 | req = stex_alloc_req(hba); | 1606 | req = hba->alloc_rq(hba); |
1192 | memset(req->cdb, 0, STEX_CDB_LENGTH); | 1607 | if (hba->cardtype == st_yel) { |
1608 | msg_h = (struct st_msg_header *)req - 1; | ||
1609 | memset(msg_h, 0, hba->rq_size); | ||
1610 | } else | ||
1611 | memset(req, 0, hba->rq_size); | ||
1193 | 1612 | ||
1194 | if (hba->cardtype == st_yosemite) { | 1613 | if (hba->cardtype == st_yosemite || hba->cardtype == st_yel) { |
1195 | req->cdb[0] = MGT_CMD; | 1614 | req->cdb[0] = MGT_CMD; |
1196 | req->cdb[1] = MGT_CMD_SIGNATURE; | 1615 | req->cdb[1] = MGT_CMD_SIGNATURE; |
1197 | req->cdb[2] = CTLR_CONFIG_CMD; | 1616 | req->cdb[2] = CTLR_CONFIG_CMD; |
@@ -1206,27 +1625,31 @@ static void stex_hba_stop(struct st_hba *hba) | |||
1206 | hba->ccb[tag].sg_count = 0; | 1625 | hba->ccb[tag].sg_count = 0; |
1207 | hba->ccb[tag].sense_bufflen = 0; | 1626 | hba->ccb[tag].sense_bufflen = 0; |
1208 | hba->ccb[tag].sense_buffer = NULL; | 1627 | hba->ccb[tag].sense_buffer = NULL; |
1209 | hba->ccb[tag].req_type |= PASSTHRU_REQ_TYPE; | 1628 | hba->ccb[tag].req_type = PASSTHRU_REQ_TYPE; |
1210 | 1629 | ||
1211 | stex_send_cmd(hba, req, tag); | 1630 | hba->send(hba, req, tag); |
1212 | spin_unlock_irqrestore(hba->host->host_lock, flags); | 1631 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
1213 | 1632 | ||
1214 | before = jiffies; | 1633 | before = jiffies; |
1215 | while (hba->ccb[tag].req_type & PASSTHRU_REQ_TYPE) { | 1634 | while (hba->ccb[tag].req_type & PASSTHRU_REQ_TYPE) { |
1216 | if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ)) | 1635 | if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ)) { |
1636 | hba->ccb[tag].req_type = 0; | ||
1217 | return; | 1637 | return; |
1218 | msleep(10); | 1638 | } |
1639 | msleep(1); | ||
1219 | } | 1640 | } |
1220 | } | 1641 | } |
1221 | 1642 | ||
1222 | static void stex_hba_free(struct st_hba *hba) | 1643 | static void stex_hba_free(struct st_hba *hba) |
1223 | { | 1644 | { |
1224 | free_irq(hba->pdev->irq, hba); | 1645 | stex_free_irq(hba); |
1225 | 1646 | ||
1226 | iounmap(hba->mmio_base); | 1647 | iounmap(hba->mmio_base); |
1227 | 1648 | ||
1228 | pci_release_regions(hba->pdev); | 1649 | pci_release_regions(hba->pdev); |
1229 | 1650 | ||
1651 | kfree(hba->ccb); | ||
1652 | |||
1230 | dma_free_coherent(&hba->pdev->dev, hba->dma_size, | 1653 | dma_free_coherent(&hba->pdev->dev, hba->dma_size, |
1231 | hba->dma_mem, hba->dma_handle); | 1654 | hba->dma_mem, hba->dma_handle); |
1232 | } | 1655 | } |
@@ -1255,27 +1678,6 @@ static void stex_shutdown(struct pci_dev *pdev) | |||
1255 | stex_hba_stop(hba); | 1678 | stex_hba_stop(hba); |
1256 | } | 1679 | } |
1257 | 1680 | ||
1258 | static struct pci_device_id stex_pci_tbl[] = { | ||
1259 | /* st_shasta */ | ||
1260 | { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
1261 | st_shasta }, /* SuperTrak EX8350/8300/16350/16300 */ | ||
1262 | { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
1263 | st_shasta }, /* SuperTrak EX12350 */ | ||
1264 | { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
1265 | st_shasta }, /* SuperTrak EX4350 */ | ||
1266 | { 0x105a, 0xe350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
1267 | st_shasta }, /* SuperTrak EX24350 */ | ||
1268 | |||
1269 | /* st_vsc */ | ||
1270 | { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc }, | ||
1271 | |||
1272 | /* st_yosemite */ | ||
1273 | { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite }, | ||
1274 | |||
1275 | /* st_seq */ | ||
1276 | { 0x105a, 0x3360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_seq }, | ||
1277 | { } /* terminate list */ | ||
1278 | }; | ||
1279 | MODULE_DEVICE_TABLE(pci, stex_pci_tbl); | 1681 | MODULE_DEVICE_TABLE(pci, stex_pci_tbl); |
1280 | 1682 | ||
1281 | static struct pci_driver stex_pci_driver = { | 1683 | static struct pci_driver stex_pci_driver = { |