diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2007-10-08 10:35:19 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-10-12 14:54:51 -0400 |
commit | 55db6c1b8ed52bfc876e87971de8c67c42f36909 (patch) | |
tree | 3acfaf8a15c608d7744b826ff081445cc332c0be /drivers | |
parent | 2ca482302f2080e6861eaf753051ac35b6b411ad (diff) |
[SCSI] scsi_error: code cleanup before refactoring of scsi_send_eh_cmnd()
- regrouped variables for easier reviewing of next patch
- Support of cmnd==NULL in call to scsi_send_eh_cmnd()
- In the @sense_bytes case set transfer size to the minimum
size of sense_buffer and passed @sense_bytes. cmnd[4] is
set accordingly.
- REQUEST_SENSE is set into cmnd[0] so if @sense_bytes is
not Zero passed @cmnd should be NULL.
- Also save/restore resid of failed command.
- Adjust caller
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/scsi_error.c | 71 |
1 files changed, 39 insertions, 32 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index f49feb9351d0..4d535019e04b 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -592,36 +592,39 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) | |||
592 | /** | 592 | /** |
593 | * scsi_send_eh_cmnd - submit a scsi command as part of error recory | 593 | * scsi_send_eh_cmnd - submit a scsi command as part of error recory |
594 | * @scmd: SCSI command structure to hijack | 594 | * @scmd: SCSI command structure to hijack |
595 | * @cmnd: CDB to send | 595 | * @cmnd: CDB to send. Can be NULL if no new cmnd is needed |
596 | * @cmnd_size: size in bytes of @cmnd | 596 | * @cmnd_size: size in bytes of @cmnd |
597 | * @timeout: timeout for this request | 597 | * @timeout: timeout for this request |
598 | * @copy_sense: request sense data if set to 1 | 598 | * @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored) |
599 | * | 599 | * |
600 | * This function is used to send a scsi command down to a target device | 600 | * This function is used to send a scsi command down to a target device |
601 | * as part of the error recovery process. If @copy_sense is 0 the command | 601 | * as part of the error recovery process. If @sense_bytes is 0 the command |
602 | * sent must be one that does not transfer any data. If @copy_sense is 1 | 602 | * sent must be one that does not transfer any data. If @sense_bytes != 0 |
603 | * the command must be REQUEST_SENSE and this functions copies out the | 603 | * @cmnd is ignored and this functions sets up a REQUEST_SENSE command |
604 | * sense buffer it got into @scmd->sense_buffer. | 604 | * and cmnd buffers to read @sense_bytes into @scmd->sense_buffer. |
605 | * | 605 | * |
606 | * Return value: | 606 | * Return value: |
607 | * SUCCESS or FAILED or NEEDS_RETRY | 607 | * SUCCESS or FAILED or NEEDS_RETRY |
608 | **/ | 608 | **/ |
609 | static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | 609 | static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, |
610 | int cmnd_size, int timeout, int copy_sense) | 610 | int cmnd_size, int timeout, unsigned sense_bytes) |
611 | { | 611 | { |
612 | struct scsi_device *sdev = scmd->device; | 612 | struct scsi_device *sdev = scmd->device; |
613 | struct Scsi_Host *shost = sdev->host; | 613 | struct Scsi_Host *shost = sdev->host; |
614 | int old_result = scmd->result; | ||
615 | DECLARE_COMPLETION_ONSTACK(done); | 614 | DECLARE_COMPLETION_ONSTACK(done); |
616 | unsigned long timeleft; | 615 | unsigned long timeleft; |
617 | unsigned long flags; | 616 | unsigned long flags; |
618 | struct scatterlist sgl; | 617 | |
618 | unsigned char old_cmd_len; | ||
619 | unsigned char old_cmnd[MAX_COMMAND_SIZE]; | 619 | unsigned char old_cmnd[MAX_COMMAND_SIZE]; |
620 | enum dma_data_direction old_data_direction; | 620 | enum dma_data_direction old_data_direction; |
621 | unsigned short old_use_sg; | ||
622 | unsigned char old_cmd_len; | ||
623 | unsigned old_bufflen; | 621 | unsigned old_bufflen; |
624 | void *old_buffer; | 622 | void *old_buffer; |
623 | unsigned short old_use_sg; | ||
624 | int old_resid; | ||
625 | int old_result; | ||
626 | |||
627 | struct scatterlist sgl; | ||
625 | int rtn; | 628 | int rtn; |
626 | 629 | ||
627 | /* | 630 | /* |
@@ -631,35 +634,41 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
631 | * we will need to restore these values prior to running the actual | 634 | * we will need to restore these values prior to running the actual |
632 | * command. | 635 | * command. |
633 | */ | 636 | */ |
634 | old_buffer = scmd->request_buffer; | 637 | old_cmd_len = scmd->cmd_len; |
635 | old_bufflen = scmd->request_bufflen; | ||
636 | memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd)); | 638 | memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd)); |
637 | old_data_direction = scmd->sc_data_direction; | 639 | old_data_direction = scmd->sc_data_direction; |
638 | old_cmd_len = scmd->cmd_len; | 640 | old_bufflen = scmd->request_bufflen; |
641 | old_buffer = scmd->request_buffer; | ||
639 | old_use_sg = scmd->use_sg; | 642 | old_use_sg = scmd->use_sg; |
643 | old_resid = scmd->resid; | ||
644 | old_result = scmd->result; | ||
640 | 645 | ||
641 | memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); | 646 | if (sense_bytes) { |
642 | memcpy(scmd->cmnd, cmnd, cmnd_size); | 647 | scmd->request_bufflen = min_t(unsigned, |
643 | 648 | sizeof(scmd->sense_buffer), sense_bytes); | |
644 | if (copy_sense) { | 649 | sg_init_one(&sgl, scmd->sense_buffer, scmd->request_bufflen); |
645 | sg_init_one(&sgl, scmd->sense_buffer, | ||
646 | sizeof(scmd->sense_buffer)); | ||
647 | |||
648 | scmd->sc_data_direction = DMA_FROM_DEVICE; | ||
649 | scmd->request_bufflen = sgl.length; | ||
650 | scmd->request_buffer = &sgl; | 650 | scmd->request_buffer = &sgl; |
651 | scmd->sc_data_direction = DMA_FROM_DEVICE; | ||
651 | scmd->use_sg = 1; | 652 | scmd->use_sg = 1; |
653 | memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); | ||
654 | scmd->cmnd[0] = REQUEST_SENSE; | ||
655 | scmd->cmnd[4] = scmd->request_bufflen; | ||
656 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | ||
652 | } else { | 657 | } else { |
653 | scmd->request_buffer = NULL; | 658 | scmd->request_buffer = NULL; |
654 | scmd->request_bufflen = 0; | 659 | scmd->request_bufflen = 0; |
655 | scmd->sc_data_direction = DMA_NONE; | 660 | scmd->sc_data_direction = DMA_NONE; |
656 | scmd->use_sg = 0; | 661 | scmd->use_sg = 0; |
662 | if (cmnd) { | ||
663 | memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); | ||
664 | memcpy(scmd->cmnd, cmnd, cmnd_size); | ||
665 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | ||
666 | } | ||
657 | } | 667 | } |
658 | 668 | ||
659 | scmd->underflow = 0; | 669 | scmd->underflow = 0; |
660 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | ||
661 | 670 | ||
662 | if (sdev->scsi_level <= SCSI_2) | 671 | if (sdev->scsi_level <= SCSI_2 && sdev->scsi_level != SCSI_UNKNOWN) |
663 | scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | | 672 | scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | |
664 | (sdev->lun << 5 & 0xe0); | 673 | (sdev->lun << 5 & 0xe0); |
665 | 674 | ||
@@ -716,12 +725,13 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
716 | /* | 725 | /* |
717 | * Restore original data | 726 | * Restore original data |
718 | */ | 727 | */ |
719 | scmd->request_buffer = old_buffer; | 728 | scmd->cmd_len = old_cmd_len; |
720 | scmd->request_bufflen = old_bufflen; | ||
721 | memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd)); | 729 | memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd)); |
722 | scmd->sc_data_direction = old_data_direction; | 730 | scmd->sc_data_direction = old_data_direction; |
723 | scmd->cmd_len = old_cmd_len; | 731 | scmd->request_bufflen = old_bufflen; |
732 | scmd->request_buffer = old_buffer; | ||
724 | scmd->use_sg = old_use_sg; | 733 | scmd->use_sg = old_use_sg; |
734 | scmd->resid = old_resid; | ||
725 | scmd->result = old_result; | 735 | scmd->result = old_result; |
726 | return rtn; | 736 | return rtn; |
727 | } | 737 | } |
@@ -737,10 +747,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
737 | **/ | 747 | **/ |
738 | static int scsi_request_sense(struct scsi_cmnd *scmd) | 748 | static int scsi_request_sense(struct scsi_cmnd *scmd) |
739 | { | 749 | { |
740 | static unsigned char generic_sense[6] = | 750 | return scsi_send_eh_cmnd(scmd, NULL, 0, SENSE_TIMEOUT, ~0); |
741 | {REQUEST_SENSE, 0, 0, 0, 252, 0}; | ||
742 | |||
743 | return scsi_send_eh_cmnd(scmd, generic_sense, 6, SENSE_TIMEOUT, 1); | ||
744 | } | 751 | } |
745 | 752 | ||
746 | /** | 753 | /** |