}
 
        if (atomic_read(&instance->fw_outstanding)) {
+               /*
+               * Send signal to FW to stop processing any pending cmds.
+               * The controller will be taken offline by the OS now.
+               */
+               writel(MFI_STOP_ADP,
+                               &instance->reg_set->inbound_doorbell);
                instance->hw_crit_error = 1;
                return FAILED;
        }
 
        fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
 
+       if (fw_state != MFI_STATE_READY)
+               printk(KERN_INFO "megasas: Waiting for FW to come to ready"
+                      " state\n");
+
        while (fw_state != MFI_STATE_READY) {
 
-               printk(KERN_INFO "megasas: Waiting for FW to come to ready"
-                      " state\n");
                switch (fw_state) {
 
                case MFI_STATE_FAULT:
                        /*
                         * Set the CLR bit in inbound doorbell
                         */
-                       writel(MFI_INIT_CLEAR_HANDSHAKE,
+                       writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
                                &instance->reg_set->inbound_doorbell);
 
                        max_wait = 2;
                        cur_state = MFI_STATE_WAIT_HANDSHAKE;
                        break;
 
+               case MFI_STATE_BOOT_MESSAGE_PENDING:
+                       writel(MFI_INIT_HOTPLUG,
+                               &instance->reg_set->inbound_doorbell);
+
+                       max_wait = 10;
+                       cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
+                       break;
+
                case MFI_STATE_OPERATIONAL:
                        /*
-                        * Bring it to READY state; assuming max wait 2 secs
+                        * Bring it to READY state; assuming max wait 10 secs
                         */
                        megasas_disable_intr(instance);
-                       writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell);
+                       writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
 
                        max_wait = 10;
                        cur_state = MFI_STATE_OPERATIONAL;
                        return -ENODEV;
                }
        };
+       printk(KERN_INFO "megasas: FW now in Ready state\n");
 
        return 0;
 }
                                      cmd->frame_phys_addr);
 
                if (cmd->sense)
-                       pci_pool_free(instance->sense_dma_pool, cmd->frame,
+                       pci_pool_free(instance->sense_dma_pool, cmd->sense,
                                      cmd->sense_phys_addr);
        }
 
         * Get various operational parameters from status register
         */
        instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
+       /*
+        * Reduce the max supported cmds by 1. This is to ensure that the
+        * reply_q_sz (1 more than the max cmd that driver may send)
+        * does not exceed max cmds that the FW can support
+        */
+       instance->max_fw_cmds = instance->max_fw_cmds-1;
        instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> 
                                        0x10;
        /*
 
 #define MFI_STATE_WAIT_HANDSHAKE               0x60000000
 #define MFI_STATE_FW_INIT_2                    0x70000000
 #define MFI_STATE_DEVICE_SCAN                  0x80000000
+#define MFI_STATE_BOOT_MESSAGE_PENDING         0x90000000
 #define MFI_STATE_FLUSH_CACHE                  0xA0000000
 #define MFI_STATE_READY                                0xB0000000
 #define MFI_STATE_OPERATIONAL                  0xC0000000
  * READY       : Move from OPERATIONAL to READY state; discard queue info
  * MFIMODE     : Discard (possible) low MFA posted in 64-bit mode (??)
  * CLR_HANDSHAKE: FW is waiting for HANDSHAKE from BIOS or Driver
+ * HOTPLUG     : Resume from Hotplug
+ * MFI_STOP_ADP        : Send signal to FW to stop processing
  */
-#define MFI_INIT_ABORT                         0x00000000
+#define MFI_INIT_ABORT                         0x00000001
 #define MFI_INIT_READY                         0x00000002
 #define MFI_INIT_MFIMODE                       0x00000004
 #define MFI_INIT_CLEAR_HANDSHAKE               0x00000008
-#define MFI_RESET_FLAGS                                MFI_INIT_READY|MFI_INIT_MFIMODE
+#define MFI_INIT_HOTPLUG                       0x00000010
+#define MFI_STOP_ADP                           0x00000020
+#define MFI_RESET_FLAGS                                MFI_INIT_READY| \
+                                               MFI_INIT_MFIMODE| \
+                                               MFI_INIT_ABORT
 
 /**
  * MFI frame flags