[SCSI] mpt2sas: Fix drives not getting properly deleted if sas cable is removed while...
authornagalakshmi.nandigama@lsi.com <nagalakshmi.nandigama@lsi.com>
Wed, 19 Oct 2011 10:07:00 +0000 (15:37 +0530)
committerJames Bottomley <JBottomley@Parallels.com>
Sun, 30 Oct 2011 08:48:34 +0000 (12:48 +0400)
The fix is in the driver-firmware handshake device removal code. We
need to read the controller ioc_state to see if controller is OPERATIONAL
prior to sending target reset and OP_REMOVE. Previously it was checking
the flag ioc->shost_recovery flag, which is always set when host reset is
active, thus preventing drives from getting properly deleted.

Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/mpt2sas/mpt2sas_scsih.c

index 8a9c70f21ecd7912bad24592f4b10d784fe82c8c..cd89f42440fe9dabb0efc46adf114b620cfbd177 100644 (file)
@@ -3019,11 +3019,23 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
        struct MPT2SAS_TARGET *sas_target_priv_data;
        unsigned long flags;
        struct _tr_list *delayed_tr;
+       u32 ioc_state;
 
-       if (ioc->shost_recovery || ioc->remove_host ||
-           ioc->pci_error_recovery) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
-                  "progress!\n", __func__, ioc->name));
+       if (ioc->remove_host) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host has been "
+                   "removed: handle(0x%04x)\n", __func__, ioc->name, handle));
+               return;
+       } else if (ioc->pci_error_recovery) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host in pci "
+                   "error recovery: handle(0x%04x)\n", __func__, ioc->name,
+                   handle));
+               return;
+       }
+       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
+       if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host is not "
+                  "operational: handle(0x%04x)\n", __func__, ioc->name,
+                  handle));
                return;
        }
 
@@ -3224,11 +3236,21 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
            mpt2sas_base_get_reply_virt_addr(ioc, reply);
        Mpi2SasIoUnitControlRequest_t *mpi_request;
        u16 smid_sas_ctrl;
+       u32 ioc_state;
 
-       if (ioc->shost_recovery || ioc->remove_host ||
-           ioc->pci_error_recovery) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
-                  "progress!\n", __func__, ioc->name));
+       if (ioc->remove_host) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host has been "
+                  "removed\n", __func__, ioc->name));
+               return 1;
+       } else if (ioc->pci_error_recovery) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host in pci "
+                   "error recovery\n", __func__, ioc->name));
+               return 1;
+       }
+       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
+       if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host is not "
+                   "operational\n", __func__, ioc->name));
                return 1;
        }