[SCSI] megaraid_sas: FW transition and q size changes
authorSumant Patro <sumantp@lsil.com>
Tue, 3 Oct 2006 19:28:49 +0000 (12:28 -0700)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Wed, 4 Oct 2006 17:45:19 +0000 (12:45 -0500)
This patch has the following enhancements :
        a. handles new transition states of FW to support controller hotplug.
        b. It reduces by 1 the maximum cmds that the driver may send to FW.
        c. Sends "Stop Processing" cmd to FW before returning failure from reset routine
        d. Adds print in megasas_transition routine
        e. Sends "RESET" flag to FW to do a soft reset of controller
to move from Operational to Ready state.
f. Sending correct pointer (cmd->sense) to pci_pool_free

Signed-off-by: Sumant Patro <Sumant.Patro@lsil.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/megaraid/megaraid_sas.h

index 4cab5b534b259acab51f1f1697e4f72c95f7dbc3..38733b6009a4280f5bb1383eb86fd9b463b735d0 100644 (file)
@@ -832,6 +832,12 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
        }
 
        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;
        }
@@ -1229,10 +1235,12 @@ megasas_transition_to_ready(struct megasas_instance* instance)
 
        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:
@@ -1244,19 +1252,27 @@ megasas_transition_to_ready(struct megasas_instance* instance)
                        /*
                         * 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;
@@ -1323,6 +1339,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
                        return -ENODEV;
                }
        };
+       printk(KERN_INFO "megasas: FW now in Ready state\n");
 
        return 0;
 }
@@ -1352,7 +1369,7 @@ static void megasas_teardown_frame_pool(struct megasas_instance *instance)
                                      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);
        }
 
@@ -1690,6 +1707,12 @@ static int megasas_init_mfi(struct megasas_instance *instance)
         * 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;
        /*
index 3531a14222a737780f8574eae0e010a71c6fd137..930c06d0a4f7442b8eb8ecf2143ebfaf54086431 100644 (file)
@@ -50,6 +50,7 @@
 #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