[SCSI] qla4xxx: ISP8xxx: Correct retry of adapter initialization
authorNilesh Javali <nilesh.javali@qlogic.com>
Mon, 16 Dec 2013 11:49:31 +0000 (06:49 -0500)
committerJames Bottomley <JBottomley@Parallels.com>
Sat, 15 Mar 2014 17:19:11 +0000 (10:19 -0700)
Issue:

For ISP8xxx, adapter initialization is not retried if
qla4xxx_initialize_adapter fails.

Fix:

If qla4xxx_initialize_adapter fails, first check if failure is due to IRQs not
attached in order to skip retrial, then free the IRQs and then retry
initializing the adapter.

Signed-off-by: Nilesh Javali <nilesh.javali@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/qla4xxx/ql4_glbl.h
drivers/scsi/qla4xxx/ql4_init.c
drivers/scsi/qla4xxx/ql4_nx.c
drivers/scsi/qla4xxx/ql4_os.c

index d67c50e0b896ae2bfc08f7f36d1ec7d9392d24be..6d72e1dde19f91c48bd90fde5fe69f8d7d4e60b8 100644 (file)
@@ -279,6 +279,7 @@ int qla4_83xx_ms_mem_write_128b(struct scsi_qla_host *ha,
 uint8_t qla4xxx_set_ipaddr_state(uint8_t fw_ipaddr_state);
 int qla4_83xx_get_port_config(struct scsi_qla_host *ha, uint32_t *config);
 int qla4_83xx_set_port_config(struct scsi_qla_host *ha, uint32_t *config);
+int qla4_8xxx_check_init_adapter_retry(struct scsi_qla_host *ha);
 
 extern int ql4xextended_error_logging;
 extern int ql4xdontresethba;
index 7456eeb2e58a3bcca9328205ae58d15705cdcf28..28fbece7e08fe8158872eb9cd74dd17cbd19b85f 100644 (file)
@@ -959,13 +959,8 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, int is_reset)
                qla4xxx_build_ddb_list(ha, is_reset);
 
        set_bit(AF_ONLINE, &ha->flags);
-exit_init_hba:
-       if (is_qla80XX(ha) && (status == QLA_ERROR)) {
-               /* Since interrupts are registered in start_firmware for
-                * 80XX, release them here if initialize_adapter fails */
-               qla4xxx_free_irqs(ha);
-       }
 
+exit_init_hba:
        DEBUG2(printk("scsi%ld: initialize adapter: %s\n", ha->host_no,
            status == QLA_ERROR ? "FAILED" : "SUCCEEDED"));
        return status;
index d001202d3565fd7871729c7d18f9f636c58eba9d..bbe836146837dbe62f994e3b542562846f6e15a5 100644 (file)
@@ -3836,3 +3836,24 @@ qla4_8xxx_enable_msix(struct scsi_qla_host *ha)
 msix_out:
        return ret;
 }
+
+int qla4_8xxx_check_init_adapter_retry(struct scsi_qla_host *ha)
+{
+       int status = QLA_SUCCESS;
+
+       /* Dont retry adapter initialization if IRQ allocation failed */
+       if (!test_bit(AF_IRQ_ATTACHED, &ha->flags)) {
+               ql4_printk(KERN_WARNING, ha, "%s: Skipping retry of adapter initialization as IRQs are not attached\n",
+                          __func__);
+               status = QLA_ERROR;
+               goto exit_init_adapter_failure;
+       }
+
+       /* Since interrupts are registered in start_firmware for
+        * 8xxx, release them here if initialize_adapter fails
+        * and retry adapter initialization */
+       qla4xxx_free_irqs(ha);
+
+exit_init_adapter_failure:
+       return status;
+}
index c21adc338cf1a93e8c3da62d12febae96c9acd25..9803c9e3bc394777956967d4dd876c8a626779ca 100644 (file)
@@ -4881,8 +4881,21 @@ recover_ha_init_adapter:
                        ssleep(6);
 
                /* NOTE: AF_ONLINE flag set upon successful completion of
-                *       qla4xxx_initialize_adapter */
+                * qla4xxx_initialize_adapter */
                status = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
+               if (is_qla80XX(ha) && (status == QLA_ERROR)) {
+                       status = qla4_8xxx_check_init_adapter_retry(ha);
+                       if (status == QLA_ERROR) {
+                               ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Don't retry recover adapter\n",
+                                          ha->host_no, __func__);
+                               qla4xxx_dead_adapter_cleanup(ha);
+                               clear_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags);
+                               clear_bit(DPC_RESET_HA, &ha->dpc_flags);
+                               clear_bit(DPC_RESET_HA_FW_CONTEXT,
+                                         &ha->dpc_flags);
+                               goto exit_recover;
+                       }
+               }
        }
 
        /* Retry failed adapter initialization, if necessary
@@ -8681,11 +8694,8 @@ static int qla4xxx_probe_adapter(struct pci_dev *pdev,
        status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER);
 
        /* Dont retry adapter initialization if IRQ allocation failed */
-       if (is_qla80XX(ha) && !test_bit(AF_IRQ_ATTACHED, &ha->flags)) {
-               ql4_printk(KERN_WARNING, ha, "%s: Skipping retry of adapter initialization\n",
-                          __func__);
+       if (is_qla80XX(ha) && (status == QLA_ERROR))
                goto skip_retry_init;
-       }
 
        while ((!test_bit(AF_ONLINE, &ha->flags)) &&
            init_retry_count++ < MAX_INIT_RETRIES) {
@@ -8709,6 +8719,10 @@ static int qla4xxx_probe_adapter(struct pci_dev *pdev,
                        continue;
 
                status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER);
+               if (is_qla80XX(ha) && (status == QLA_ERROR)) {
+                       if (qla4_8xxx_check_init_adapter_retry(ha) == QLA_ERROR)
+                               goto skip_retry_init;
+               }
        }
 
 skip_retry_init:
@@ -9615,6 +9629,7 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
                if (rval != QLA_SUCCESS) {
                        ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: "
                            "FAILED\n", ha->host_no, __func__);
+                       qla4xxx_free_irqs(ha);
                        ha->isp_ops->idc_lock(ha);
                        qla4_8xxx_clear_drv_active(ha);
                        qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
@@ -9642,6 +9657,8 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
                        rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
                        if (rval == QLA_SUCCESS)
                                ha->isp_ops->enable_intrs(ha);
+                       else
+                               qla4xxx_free_irqs(ha);
 
                        ha->isp_ops->idc_lock(ha);
                        qla4_8xxx_set_drv_active(ha);