diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/stex.c | 66 |
1 files changed, 10 insertions, 56 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 654430edf74d..8c7b1830d9e8 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -426,49 +426,13 @@ static int stex_map_sg(struct st_hba *hba, | |||
426 | return 0; | 426 | return 0; |
427 | } | 427 | } |
428 | 428 | ||
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) | 429 | static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) |
465 | { | 430 | { |
466 | struct st_frame *p; | 431 | struct st_frame *p; |
467 | size_t count = sizeof(struct st_frame); | 432 | size_t count = sizeof(struct st_frame); |
468 | 433 | ||
469 | p = hba->copy_buffer; | 434 | p = hba->copy_buffer; |
470 | stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd), | 435 | count = scsi_sg_copy_to_buffer(ccb->cmd, p, count); |
471 | ST_FROM_CMD); | ||
472 | memset(p->base, 0, sizeof(u32)*6); | 436 | memset(p->base, 0, sizeof(u32)*6); |
473 | *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); | 437 | *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); |
474 | p->rom_addr = 0; | 438 | p->rom_addr = 0; |
@@ -486,8 +450,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) | |||
486 | p->subid = | 450 | p->subid = |
487 | hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; | 451 | hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; |
488 | 452 | ||
489 | stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd), | 453 | count = scsi_sg_copy_from_buffer(ccb->cmd, p, count); |
490 | ST_TO_CMD); | ||
491 | } | 454 | } |
492 | 455 | ||
493 | static void | 456 | static void |
@@ -554,10 +517,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
554 | unsigned char page; | 517 | unsigned char page; |
555 | page = cmd->cmnd[2] & 0x3f; | 518 | page = cmd->cmnd[2] & 0x3f; |
556 | if (page == 0x8 || page == 0x3f) { | 519 | if (page == 0x8 || page == 0x3f) { |
557 | size_t cp_len = sizeof(ms10_caching_page); | 520 | scsi_sg_copy_from_buffer(cmd, ms10_caching_page, |
558 | stex_internal_copy(cmd, ms10_caching_page, | 521 | sizeof(ms10_caching_page)); |
559 | &cp_len, scsi_sg_count(cmd), | ||
560 | ST_TO_CMD); | ||
561 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; | 522 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; |
562 | done(cmd); | 523 | done(cmd); |
563 | } else | 524 | } else |
@@ -586,10 +547,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
586 | if (id != host->max_id - 1) | 547 | if (id != host->max_id - 1) |
587 | break; | 548 | break; |
588 | if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { | 549 | if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { |
589 | size_t cp_len = sizeof(console_inq_page); | 550 | scsi_sg_copy_from_buffer(cmd, (void *)console_inq_page, |
590 | stex_internal_copy(cmd, console_inq_page, | 551 | sizeof(console_inq_page)); |
591 | &cp_len, scsi_sg_count(cmd), | ||
592 | ST_TO_CMD); | ||
593 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; | 552 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; |
594 | done(cmd); | 553 | done(cmd); |
595 | } else | 554 | } else |
@@ -606,8 +565,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
606 | ver.signature[0] = PASSTHRU_SIGNATURE; | 565 | ver.signature[0] = PASSTHRU_SIGNATURE; |
607 | ver.console_id = host->max_id - 1; | 566 | ver.console_id = host->max_id - 1; |
608 | ver.host_no = hba->host->host_no; | 567 | ver.host_no = hba->host->host_no; |
609 | stex_internal_copy(cmd, &ver, &cp_len, | 568 | 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 ? | 569 | cmd->result = sizeof(ver) == cp_len ? |
612 | DID_OK << 16 | COMMAND_COMPLETE << 8 : | 570 | DID_OK << 16 | COMMAND_COMPLETE << 8 : |
613 | DID_ERROR << 16 | COMMAND_COMPLETE << 8; | 571 | DID_ERROR << 16 | COMMAND_COMPLETE << 8; |
@@ -700,15 +658,12 @@ static void stex_copy_data(struct st_ccb *ccb, | |||
700 | 658 | ||
701 | if (ccb->cmd == NULL) | 659 | if (ccb->cmd == NULL) |
702 | return; | 660 | return; |
703 | stex_internal_copy(ccb->cmd, | 661 | count = scsi_sg_copy_from_buffer(ccb->cmd, resp->variable, count); |
704 | resp->variable, &count, scsi_sg_count(ccb->cmd), ST_TO_CMD); | ||
705 | } | 662 | } |
706 | 663 | ||
707 | static void stex_ys_commands(struct st_hba *hba, | 664 | static void stex_ys_commands(struct st_hba *hba, |
708 | struct st_ccb *ccb, struct status_msg *resp) | 665 | struct st_ccb *ccb, struct status_msg *resp) |
709 | { | 666 | { |
710 | size_t count; | ||
711 | |||
712 | if (ccb->cmd->cmnd[0] == MGT_CMD && | 667 | if (ccb->cmd->cmnd[0] == MGT_CMD && |
713 | resp->scsi_status != SAM_STAT_CHECK_CONDITION) { | 668 | resp->scsi_status != SAM_STAT_CHECK_CONDITION) { |
714 | scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) - | 669 | scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) - |
@@ -724,9 +679,8 @@ static void stex_ys_commands(struct st_hba *hba, | |||
724 | resp->scsi_status == SAM_STAT_GOOD) { | 679 | resp->scsi_status == SAM_STAT_GOOD) { |
725 | ST_INQ *inq_data; | 680 | ST_INQ *inq_data; |
726 | 681 | ||
727 | count = STEX_EXTRA_SIZE; | 682 | scsi_sg_copy_to_buffer(ccb->cmd, hba->copy_buffer, |
728 | stex_internal_copy(ccb->cmd, hba->copy_buffer, | 683 | STEX_EXTRA_SIZE); |
729 | &count, scsi_sg_count(ccb->cmd), ST_FROM_CMD); | ||
730 | inq_data = (ST_INQ *)hba->copy_buffer; | 684 | inq_data = (ST_INQ *)hba->copy_buffer; |
731 | if (inq_data->DeviceTypeQualifier != 0) | 685 | if (inq_data->DeviceTypeQualifier != 0) |
732 | ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; | 686 | ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; |