megaraid_sas: fix a small problem when reading state value from hw
authorTomas Henzl <thenzl@redhat.com>
Tue, 1 Apr 2014 11:59:50 +0000 (13:59 +0200)
committerChristoph Hellwig <hch@lst.de>
Mon, 19 May 2014 11:30:59 +0000 (13:30 +0200)
When the driver reads state values from the hw it might happen that
different values are read in subsequent reads and this can cause problems,
this may lead to a timeout in this function and a non working adapter.

Cc: Adam Radford <aradford@gmail.com>
Signed-off-by: Tomas Henzl <thenzl@redhat.com>
Reviewed-by: Shintaro Minemoto <fj3207hq@aa.jp.fujitsu.com>
Acked-by: Sumit Saxena <sumit.saxena@lsi.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/scsi/megaraid/megaraid_sas_base.c

index d84d02c2aad9f53554362d0c11faa9d5b40af978..112799b131a93253d1b06170e2d7e1d5a1d998c2 100644 (file)
@@ -3061,7 +3061,8 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
        u32 cur_state;
        u32 abs_state, curr_abs_state;
 
-       fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
+       abs_state = instance->instancet->read_fw_status_reg(instance->reg_set);
+       fw_state = abs_state & MFI_STATE_MASK;
 
        if (fw_state != MFI_STATE_READY)
                printk(KERN_INFO "megasas: Waiting for FW to come to ready"
@@ -3069,9 +3070,6 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
 
        while (fw_state != MFI_STATE_READY) {
 
-               abs_state =
-               instance->instancet->read_fw_status_reg(instance->reg_set);
-
                switch (fw_state) {
 
                case MFI_STATE_FAULT:
@@ -3223,10 +3221,8 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
                 * The cur_state should not last for more than max_wait secs
                 */
                for (i = 0; i < (max_wait * 1000); i++) {
-                       fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
-                                       MFI_STATE_MASK ;
-               curr_abs_state =
-               instance->instancet->read_fw_status_reg(instance->reg_set);
+                       curr_abs_state = instance->instancet->
+                               read_fw_status_reg(instance->reg_set);
 
                        if (abs_state == curr_abs_state) {
                                msleep(1);
@@ -3242,6 +3238,9 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
                               "in %d secs\n", fw_state, max_wait);
                        return -ENODEV;
                }
+
+               abs_state = curr_abs_state;
+               fw_state = curr_abs_state & MFI_STATE_MASK;
        }
        printk(KERN_INFO "megasas: FW now in Ready state\n");