diff options
author | Moger, Babu <Babu.Moger@netapp.com> | 2012-01-24 15:38:46 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 09:08:59 -0500 |
commit | 2082ebc45af9c9c648383b8cde0dc1948eadbf31 (patch) | |
tree | 1c010bb75da085c84cf5223035b2624dc6fbd7d6 /drivers/scsi | |
parent | 3384db9eb8b1e4f94a02c2a0ce3c0efe6142f3ba (diff) |
[SCSI] fix the new host byte settings (DID_TARGET_FAILURE and DID_NEXUS_FAILURE)
This patch fixes the host byte settings DID_TARGET_FAILURE and
DID_NEXUS_FAILURE. The function __scsi_error_from_host_byte, tries to reset
the host byte to DID_OK. But that does not happen because of the OR operation.
Here is the flow.
scsi_softirq_done-> scsi_decide_disposition -> __scsi_error_from_host_byte
Let's take an example with DID_NEXUS_FAILURE. In scsi_decide_disposition,
result will be set as DID_NEXUS_FAILURE (=0x11). Then in
__scsi_error_from_host_byte, when we do OR with DID_OK. Purpose is to reset
it back to DID_OK. But that does not happen. This patch fixes this issue.
Signed-off-by: Babu Moger <babu.moger@netapp.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/scsi_error.c | 4 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 4 |
2 files changed, 4 insertions, 4 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 5f84a148eb14..6ae3b5dbd379 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1540,7 +1540,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) | |||
1540 | * Need to modify host byte to signal a | 1540 | * Need to modify host byte to signal a |
1541 | * permanent target failure | 1541 | * permanent target failure |
1542 | */ | 1542 | */ |
1543 | scmd->result |= (DID_TARGET_FAILURE << 16); | 1543 | set_host_byte(scmd, DID_TARGET_FAILURE); |
1544 | rtn = SUCCESS; | 1544 | rtn = SUCCESS; |
1545 | } | 1545 | } |
1546 | /* if rtn == FAILED, we have no sense information; | 1546 | /* if rtn == FAILED, we have no sense information; |
@@ -1560,7 +1560,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) | |||
1560 | case RESERVATION_CONFLICT: | 1560 | case RESERVATION_CONFLICT: |
1561 | sdev_printk(KERN_INFO, scmd->device, | 1561 | sdev_printk(KERN_INFO, scmd->device, |
1562 | "reservation conflict\n"); | 1562 | "reservation conflict\n"); |
1563 | scmd->result |= (DID_NEXUS_FAILURE << 16); | 1563 | set_host_byte(scmd, DID_NEXUS_FAILURE); |
1564 | return SUCCESS; /* causes immediate i/o error */ | 1564 | return SUCCESS; /* causes immediate i/o error */ |
1565 | default: | 1565 | default: |
1566 | return FAILED; | 1566 | return FAILED; |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index b2c95dbe9d65..5b770e9e82c2 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -682,11 +682,11 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result) | |||
682 | error = -ENOLINK; | 682 | error = -ENOLINK; |
683 | break; | 683 | break; |
684 | case DID_TARGET_FAILURE: | 684 | case DID_TARGET_FAILURE: |
685 | cmd->result |= (DID_OK << 16); | 685 | set_host_byte(cmd, DID_OK); |
686 | error = -EREMOTEIO; | 686 | error = -EREMOTEIO; |
687 | break; | 687 | break; |
688 | case DID_NEXUS_FAILURE: | 688 | case DID_NEXUS_FAILURE: |
689 | cmd->result |= (DID_OK << 16); | 689 | set_host_byte(cmd, DID_OK); |
690 | error = -EBADE; | 690 | error = -EBADE; |
691 | break; | 691 | break; |
692 | default: | 692 | default: |