diff options
Diffstat (limited to 'drivers/scsi/stex.c')
-rw-r--r-- | drivers/scsi/stex.c | 83 |
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 | ||
365 | static 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 | |||
376 | static void stex_invalid_field(struct scsi_cmnd *cmd, | 366 | static 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 | ||
429 | static 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 | |||
464 | static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) | 422 | static 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 | ||
493 | static void | 449 | static 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 | ||
707 | static void stex_ys_commands(struct st_hba *hba, | 657 | static 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; |