[SCSI] fix the new host byte settings (DID_TARGET_FAILURE and DID_NEXUS_FAILURE)
authorMoger, Babu <Babu.Moger@netapp.com>
Tue, 24 Jan 2012 20:38:46 +0000 (20:38 +0000)
committerJames Bottomley <JBottomley@Parallels.com>
Sun, 19 Feb 2012 14:08:59 +0000 (08:08 -0600)
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>
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c

index 5f84a14..6ae3b5d 100644 (file)
@@ -1540,7 +1540,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
                         * Need to modify host byte to signal a
                         * permanent target failure
                         */
-                       scmd->result |= (DID_TARGET_FAILURE << 16);
+                       set_host_byte(scmd, DID_TARGET_FAILURE);
                        rtn = SUCCESS;
                }
                /* if rtn == FAILED, we have no sense information;
@@ -1560,7 +1560,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
        case RESERVATION_CONFLICT:
                sdev_printk(KERN_INFO, scmd->device,
                            "reservation conflict\n");
-               scmd->result |= (DID_NEXUS_FAILURE << 16);
+               set_host_byte(scmd, DID_NEXUS_FAILURE);
                return SUCCESS; /* causes immediate i/o error */
        default:
                return FAILED;
index b2c95db..5b770e9 100644 (file)
@@ -682,11 +682,11 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)
                error = -ENOLINK;
                break;
        case DID_TARGET_FAILURE:
-               cmd->result |= (DID_OK << 16);
+               set_host_byte(cmd, DID_OK);
                error = -EREMOTEIO;
                break;
        case DID_NEXUS_FAILURE:
-               cmd->result |= (DID_OK << 16);
+               set_host_byte(cmd, DID_OK);
                error = -EBADE;
                break;
        default: