aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_scsih.c
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2010-04-08 08:24:32 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-04-11 15:00:30 -0400
commit130b958a5dbf0fca361beef5713715a2eba6529f (patch)
treefa48bcdd2b9487d0703056073b8cd688b55b3cf9 /drivers/scsi/mpt2sas/mpt2sas_scsih.c
parenta1172ca2f20074626d7aa77e747824757673cf22 (diff)
[SCSI] mpt2sas: Reworked scmd->result priority for _scsih_qcmd.
we added support to set the deleted flag prior to device scan, then clear the flag for responding devices, leaving the deleted flag only set for missing devices. The problem is for internal generated host resets, IO queues are not blocked at scsi mid layer level. IO will be continued sent to driver, and driver will return SCSI_MLQUEUE_HOST_BUSY. The problem is the driver checks for the deleted flag before it checks for the controller being in reset, so there is a window where the driver would be returning DID_NO_CONNECT for responding devices. This occurs during the time between calling _scsih_prep_device_scan, and _scsih_mark_responding_sas_device & _scsih_mark_responding_raid_device. Fix the queuecommand entry point so ioc->shost_recovery flag sanity check is given higher presidence then the device "deleted flag" check. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index bb5659ca128d..77163bad75f9 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -2957,25 +2957,32 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2957 2957
2958 scmd->scsi_done = done; 2958 scmd->scsi_done = done;
2959 sas_device_priv_data = scmd->device->hostdata; 2959 sas_device_priv_data = scmd->device->hostdata;
2960 if (!sas_device_priv_data) { 2960 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
2961 scmd->result = DID_NO_CONNECT << 16; 2961 scmd->result = DID_NO_CONNECT << 16;
2962 scmd->scsi_done(scmd); 2962 scmd->scsi_done(scmd);
2963 return 0; 2963 return 0;
2964 } 2964 }
2965 2965
2966 sas_target_priv_data = sas_device_priv_data->sas_target; 2966 sas_target_priv_data = sas_device_priv_data->sas_target;
2967 if (!sas_target_priv_data || sas_target_priv_data->handle == 2967 /* invalid device handle */
2968 MPT2SAS_INVALID_DEVICE_HANDLE || sas_target_priv_data->deleted) { 2968 if (sas_target_priv_data->handle == MPT2SAS_INVALID_DEVICE_HANDLE) {
2969 scmd->result = DID_NO_CONNECT << 16; 2969 scmd->result = DID_NO_CONNECT << 16;
2970 scmd->scsi_done(scmd); 2970 scmd->scsi_done(scmd);
2971 return 0; 2971 return 0;
2972 } 2972 }
2973 2973
2974 /* see if we are busy with task managment stuff */ 2974 /* host recovery or link resets sent via IOCTLs */
2975 if (sas_device_priv_data->block || sas_target_priv_data->tm_busy) 2975 if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
2976 return SCSI_MLQUEUE_DEVICE_BUSY;
2977 else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
2978 return SCSI_MLQUEUE_HOST_BUSY; 2976 return SCSI_MLQUEUE_HOST_BUSY;
2977 /* device busy with task managment */
2978 else if (sas_device_priv_data->block || sas_target_priv_data->tm_busy)
2979 return SCSI_MLQUEUE_DEVICE_BUSY;
2980 /* device has been deleted */
2981 else if (sas_target_priv_data->deleted) {
2982 scmd->result = DID_NO_CONNECT << 16;
2983 scmd->scsi_done(scmd);
2984 return 0;
2985 }
2979 2986
2980 if (scmd->sc_data_direction == DMA_FROM_DEVICE) 2987 if (scmd->sc_data_direction == DMA_FROM_DEVICE)
2981 mpi_control = MPI2_SCSIIO_CONTROL_READ; 2988 mpi_control = MPI2_SCSIIO_CONTROL_READ;