#define megasas_resume NULL
 #endif
 
+static inline int
+megasas_wait_for_adapter_operational(struct megasas_instance *instance)
+{
+       int wait_time = MEGASAS_RESET_WAIT_TIME * 2;
+       int i;
+
+       if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)
+               return 1;
+
+       for (i = 0; i < wait_time; i++) {
+               if (atomic_read(&instance->adprecovery) == MEGASAS_HBA_OPERATIONAL)
+                       break;
+
+               if (!(i % MEGASAS_RESET_NOTICE_INTERVAL))
+                       dev_notice(&instance->pdev->dev, "waiting for controller reset to finish\n");
+
+               msleep(1000);
+       }
+
+       if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
+               dev_info(&instance->pdev->dev, "%s timed out while waiting for HBA to recover.\n",
+                       __func__);
+               return 1;
+       }
+
+       return 0;
+}
+
 /**
  * megasas_detach_one -        PCI hot"un"plug entry point
  * @pdev:              PCI device structure
        if (instance->fw_crash_state != UNAVAILABLE)
                megasas_free_host_crash_buffer(instance);
        scsi_remove_host(instance->host);
+
+       if (megasas_wait_for_adapter_operational(instance))
+               goto skip_firing_dcmds;
+
        megasas_flush_cache(instance);
        megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
 
+skip_firing_dcmds:
        /* cancel the delayed work if this work still in queue*/
        if (instance->ev != NULL) {
                struct megasas_aen_event *ev = instance->ev;
        struct megasas_instance *instance = pci_get_drvdata(pdev);
 
        instance->unload = 1;
+
+       if (megasas_wait_for_adapter_operational(instance))
+               goto skip_firing_dcmds;
+
        megasas_flush_cache(instance);
        megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
+
+skip_firing_dcmds:
        instance->instancet->disable_intr(instance);
        megasas_destroy_irqs(instance);
 
 
                        /* Start collecting crash, if DMA bit is done */
                        if ((fw_state == MFI_STATE_FAULT) && dma_state)
                                schedule_work(&instance->crash_init);
-                       else if (fw_state == MFI_STATE_FAULT)
-                               schedule_work(&instance->work_init);
+                       else if (fw_state == MFI_STATE_FAULT) {
+                               if (instance->unload == 0)
+                                       schedule_work(&instance->work_init);
+                       }
                } else if (fw_state == MFI_STATE_FAULT) {
                        dev_warn(&instance->pdev->dev, "Iop2SysDoorbellInt"
                               "for scsi%d\n", instance->host->host_no);
-                       schedule_work(&instance->work_init);
+                       if (instance->unload == 0)
+                               schedule_work(&instance->work_init);
                }
        }