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.c83
1 files changed, 15 insertions, 68 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 654430edf74d..f308a0308829 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -33,6 +33,7 @@
33#include <scsi/scsi_host.h> 33#include <scsi/scsi_host.h>
34#include <scsi/scsi_tcq.h> 34#include <scsi/scsi_tcq.h>
35#include <scsi/scsi_dbg.h> 35#include <scsi/scsi_dbg.h>
36#include <scsi/scsi_eh.h>
36 37
37#define DRV_NAME "stex" 38#define DRV_NAME "stex"
38#define ST_DRIVER_VERSION "3.6.0000.1" 39#define ST_DRIVER_VERSION "3.6.0000.1"
@@ -362,22 +363,14 @@ static struct status_msg *stex_get_status(struct st_hba *hba)
362 return status; 363 return status;
363} 364}
364 365
365static void stex_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
366{
367 cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
368
369 cmd->sense_buffer[0] = 0x70; /* fixed format, current */
370 cmd->sense_buffer[2] = sk;
371 cmd->sense_buffer[7] = 18 - 8; /* additional sense length */
372 cmd->sense_buffer[12] = asc;
373 cmd->sense_buffer[13] = ascq;
374}
375
376static void stex_invalid_field(struct scsi_cmnd *cmd, 366static void stex_invalid_field(struct scsi_cmnd *cmd,
377 void (*done)(struct scsi_cmnd *)) 367 void (*done)(struct scsi_cmnd *))
378{ 368{
369 cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
370
379 /* "Invalid field in cbd" */ 371 /* "Invalid field in cbd" */
380 stex_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0); 372 scsi_build_sense_buffer(0, cmd->sense_buffer, ILLEGAL_REQUEST, 0x24,
373 0x0);
381 done(cmd); 374 done(cmd);
382} 375}
383 376
@@ -426,49 +419,13 @@ static int stex_map_sg(struct st_hba *hba,
426 return 0; 419 return 0;
427} 420}
428 421
429static void stex_internal_copy(struct scsi_cmnd *cmd,
430 const void *src, size_t *count, int sg_count, int direction)
431{
432 size_t lcount;
433 size_t len;
434 void *s, *d, *base = NULL;
435 size_t offset;
436
437 if (*count > scsi_bufflen(cmd))
438 *count = scsi_bufflen(cmd);
439 lcount = *count;
440 while (lcount) {
441 len = lcount;
442 s = (void *)src;
443
444 offset = *count - lcount;
445 s += offset;
446 base = scsi_kmap_atomic_sg(scsi_sglist(cmd),
447 sg_count, &offset, &len);
448 if (!base) {
449 *count -= lcount;
450 return;
451 }
452 d = base + offset;
453
454 if (direction == ST_TO_CMD)
455 memcpy(d, s, len);
456 else
457 memcpy(s, d, len);
458
459 lcount -= len;
460 scsi_kunmap_atomic_sg(base);
461 }
462}
463
464static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) 422static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
465{ 423{
466 struct st_frame *p; 424 struct st_frame *p;
467 size_t count = sizeof(struct st_frame); 425 size_t count = sizeof(struct st_frame);
468 426
469 p = hba->copy_buffer; 427 p = hba->copy_buffer;
470 stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd), 428 count = scsi_sg_copy_to_buffer(ccb->cmd, p, count);
471 ST_FROM_CMD);
472 memset(p->base, 0, sizeof(u32)*6); 429 memset(p->base, 0, sizeof(u32)*6);
473 *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); 430 *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0);
474 p->rom_addr = 0; 431 p->rom_addr = 0;
@@ -486,8 +443,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
486 p->subid = 443 p->subid =
487 hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; 444 hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device;
488 445
489 stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd), 446 count = scsi_sg_copy_from_buffer(ccb->cmd, p, count);
490 ST_TO_CMD);
491} 447}
492 448
493static void 449static void
@@ -554,10 +510,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
554 unsigned char page; 510 unsigned char page;
555 page = cmd->cmnd[2] & 0x3f; 511 page = cmd->cmnd[2] & 0x3f;
556 if (page == 0x8 || page == 0x3f) { 512 if (page == 0x8 || page == 0x3f) {
557 size_t cp_len = sizeof(ms10_caching_page); 513 scsi_sg_copy_from_buffer(cmd, ms10_caching_page,
558 stex_internal_copy(cmd, ms10_caching_page, 514 sizeof(ms10_caching_page));
559 &cp_len, scsi_sg_count(cmd),
560 ST_TO_CMD);
561 cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; 515 cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
562 done(cmd); 516 done(cmd);
563 } else 517 } else
@@ -586,10 +540,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
586 if (id != host->max_id - 1) 540 if (id != host->max_id - 1)
587 break; 541 break;
588 if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { 542 if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
589 size_t cp_len = sizeof(console_inq_page); 543 scsi_sg_copy_from_buffer(cmd, (void *)console_inq_page,
590 stex_internal_copy(cmd, console_inq_page, 544 sizeof(console_inq_page));
591 &cp_len, scsi_sg_count(cmd),
592 ST_TO_CMD);
593 cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; 545 cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
594 done(cmd); 546 done(cmd);
595 } else 547 } else
@@ -606,8 +558,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
606 ver.signature[0] = PASSTHRU_SIGNATURE; 558 ver.signature[0] = PASSTHRU_SIGNATURE;
607 ver.console_id = host->max_id - 1; 559 ver.console_id = host->max_id - 1;
608 ver.host_no = hba->host->host_no; 560 ver.host_no = hba->host->host_no;
609 stex_internal_copy(cmd, &ver, &cp_len, 561 cp_len = scsi_sg_copy_from_buffer(cmd, &ver, cp_len);
610 scsi_sg_count(cmd), ST_TO_CMD);
611 cmd->result = sizeof(ver) == cp_len ? 562 cmd->result = sizeof(ver) == cp_len ?
612 DID_OK << 16 | COMMAND_COMPLETE << 8 : 563 DID_OK << 16 | COMMAND_COMPLETE << 8 :
613 DID_ERROR << 16 | COMMAND_COMPLETE << 8; 564 DID_ERROR << 16 | COMMAND_COMPLETE << 8;
@@ -700,15 +651,12 @@ static void stex_copy_data(struct st_ccb *ccb,
700 651
701 if (ccb->cmd == NULL) 652 if (ccb->cmd == NULL)
702 return; 653 return;
703 stex_internal_copy(ccb->cmd, 654 count = scsi_sg_copy_from_buffer(ccb->cmd, resp->variable, count);
704 resp->variable, &count, scsi_sg_count(ccb->cmd), ST_TO_CMD);
705} 655}
706 656
707static void stex_ys_commands(struct st_hba *hba, 657static void stex_ys_commands(struct st_hba *hba,
708 struct st_ccb *ccb, struct status_msg *resp) 658 struct st_ccb *ccb, struct status_msg *resp)
709{ 659{
710 size_t count;
711
712 if (ccb->cmd->cmnd[0] == MGT_CMD && 660 if (ccb->cmd->cmnd[0] == MGT_CMD &&
713 resp->scsi_status != SAM_STAT_CHECK_CONDITION) { 661 resp->scsi_status != SAM_STAT_CHECK_CONDITION) {
714 scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) - 662 scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) -
@@ -724,9 +672,8 @@ static void stex_ys_commands(struct st_hba *hba,
724 resp->scsi_status == SAM_STAT_GOOD) { 672 resp->scsi_status == SAM_STAT_GOOD) {
725 ST_INQ *inq_data; 673 ST_INQ *inq_data;
726 674
727 count = STEX_EXTRA_SIZE; 675 scsi_sg_copy_to_buffer(ccb->cmd, hba->copy_buffer,
728 stex_internal_copy(ccb->cmd, hba->copy_buffer, 676 STEX_EXTRA_SIZE);
729 &count, scsi_sg_count(ccb->cmd), ST_FROM_CMD);
730 inq_data = (ST_INQ *)hba->copy_buffer; 677 inq_data = (ST_INQ *)hba->copy_buffer;
731 if (inq_data->DeviceTypeQualifier != 0) 678 if (inq_data->DeviceTypeQualifier != 0)
732 ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; 679 ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;