[SCSI] mpt2sas: Freeze the sdev IO queue when firmware sends internal dev reset
authorKashyap, Desai <kashyap.desai@lsi.com>
Wed, 23 Sep 2009 12:05:41 +0000 (17:35 +0530)
committerJames Bottomley <James.Bottomley@suse.de>
Thu, 29 Oct 2009 17:03:15 +0000 (13:03 -0400)
When receiving the MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET event,
the driver will set the tm_busy flag in the sdev private host data, When
tm_busy flag is set, the driver will return SCSI_MLQUEUE_DEVICE_BUSY,
effectly freezing the IO to the device. The tm_busy flag is cleared with the
MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET event.

Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: Eric Moore <Eric.moore@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/mpt2sas/mpt2sas_scsih.c

index d0d6672..c81e842 100644 (file)
@@ -4308,11 +4308,43 @@ static void
 _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
     struct fw_event_work *fw_event)
 {
+       struct MPT2SAS_TARGET *target_priv_data;
+       struct _sas_device *sas_device;
+       __le64 sas_address;
+       unsigned long flags;
+       Mpi2EventDataSasDeviceStatusChange_t *event_data =
+           fw_event->event_data;
+
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
        if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
                _scsih_sas_device_status_change_event_debug(ioc,
-                    fw_event->event_data);
+                    event_data);
 #endif
+
+       if (!(event_data->ReasonCode ==
+           MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
+          event_data->ReasonCode ==
+           MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET))
+               return;
+
+       spin_lock_irqsave(&ioc->sas_device_lock, flags);
+       sas_address = le64_to_cpu(event_data->SASAddress);
+       sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
+           sas_address);
+       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+       if (!sas_device || !sas_device->starget)
+               return;
+
+       target_priv_data = sas_device->starget->hostdata;
+       if (!target_priv_data)
+               return;
+
+       if (event_data->ReasonCode ==
+           MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET)
+               target_priv_data->tm_busy = 1;
+       else
+               target_priv_data->tm_busy = 0;
 }
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING