aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMoger, Babu <Babu.Moger@netapp.com>2012-01-24 15:38:46 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 09:08:59 -0500
commit2082ebc45af9c9c648383b8cde0dc1948eadbf31 (patch)
tree1c010bb75da085c84cf5223035b2624dc6fbd7d6 /drivers/scsi
parent3384db9eb8b1e4f94a02c2a0ce3c0efe6142f3ba (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.c4
-rw-r--r--drivers/scsi/scsi_lib.c4
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: