qla2xxx: Remove wait for online from host reset handler.
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / qla2xxx / qla_os.c
index 19e99cc33724c526f30de23d0e98d0757cf2f99d..5a430c7bc02715166a987a7aeb2b957a0795de09 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2013 QLogic Corporation
+ * Copyright (c)  2003-2014 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
@@ -616,7 +616,7 @@ qla2x00_sp_free_dma(void *vha, void *ptr)
 
        if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
                /* List assured to be having elements */
-               qla2x00_clean_dsd_pool(ha, sp);
+               qla2x00_clean_dsd_pool(ha, sp, NULL);
                sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
        }
 
@@ -781,7 +781,7 @@ static int
 qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd)
 {
 #define ABORT_POLLING_PERIOD   1000
-#define ABORT_WAIT_ITER                ((10 * 1000) / (ABORT_POLLING_PERIOD))
+#define ABORT_WAIT_ITER                ((2 * 1000) / (ABORT_POLLING_PERIOD))
        unsigned long wait_iter = ABORT_WAIT_ITER;
        scsi_qla_host_t *vha = shost_priv(cmd->device->host);
        struct qla_hw_data *ha = vha->hw;
@@ -844,11 +844,8 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
 }
 
 /*
- * qla2x00_wait_for_reset_ready
- *    Wait till the HBA is online after going through
- *    <= MAX_RETRIES_OF_ISP_ABORT  or
- *    finally HBA is disabled ie marked offline or flash
- *    operations are in progress.
+ * qla2x00_wait_for_hba_ready
+ * Wait till the HBA is ready before doing driver unload
  *
  * Input:
  *     ha - pointer to host adapter structure
@@ -857,35 +854,15 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
  *    Does context switching-Release SPIN_LOCK
  *    (if any) before calling this routine.
  *
- * Return:
- *    Success (Adapter is online/no flash ops) : 0
- *    Failed  (Adapter is offline/disabled/flash ops in progress) : 1
  */
-static int
-qla2x00_wait_for_reset_ready(scsi_qla_host_t *vha)
+static void
+qla2x00_wait_for_hba_ready(scsi_qla_host_t *vha)
 {
-       int             return_status;
-       unsigned long   wait_online;
        struct qla_hw_data *ha = vha->hw;
-       scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
 
-       wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ);
-       while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) ||
-           test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
-           test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
-           ha->optrom_state != QLA_SWAITING ||
-           ha->dpc_active) && time_before(jiffies, wait_online))
+       while ((!(vha->flags.online) || ha->dpc_active ||
+           ha->flags.mbox_busy))
                msleep(1000);
-
-       if (base_vha->flags.online &&  ha->optrom_state == QLA_SWAITING)
-               return_status = QLA_SUCCESS;
-       else
-               return_status = QLA_FUNCTION_FAILED;
-
-       ql_dbg(ql_dbg_taskm, vha, 0x8019,
-           "%s return status=%d.\n", __func__, return_status);
-
-       return return_status;
 }
 
 int
@@ -945,7 +922,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        int ret;
        unsigned int id, lun;
        unsigned long flags;
-       int wait = 0;
+       int rval, wait = 0;
        struct qla_hw_data *ha = vha->hw;
 
        if (!CMD_SP(cmd))
@@ -974,10 +951,20 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        sp_get(sp);
 
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
-       if (ha->isp_ops->abort_command(sp)) {
-               ret = FAILED;
+       rval = ha->isp_ops->abort_command(sp);
+       if (rval) {
+               if (rval == QLA_FUNCTION_PARAMETER_ERROR) {
+                       /*
+                        * Decrement the ref_count since we can't find the
+                        * command
+                        */
+                       atomic_dec(&sp->ref_count);
+                       ret = SUCCESS;
+               } else
+                       ret = FAILED;
+
                ql_dbg(ql_dbg_taskm, vha, 0x8003,
-                   "Abort command mbx failed cmd=%p.\n", cmd);
+                   "Abort command mbx failed cmd=%p, rval=%x.\n", cmd, rval);
        } else {
                ql_dbg(ql_dbg_taskm, vha, 0x8004,
                    "Abort command mbx success cmd=%p.\n", cmd);
@@ -985,6 +972,12 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        }
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
+       /*
+        * Clear the slot in the oustanding_cmds array if we can't find the
+        * command to reclaim the resources.
+        */
+       if (rval == QLA_FUNCTION_PARAMETER_ERROR)
+               vha->req->outstanding_cmds[sp->handle] = NULL;
        sp->done(ha, sp, 0);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
@@ -1236,7 +1229,11 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
        ql_log(ql_log_info, vha, 0x8018,
            "ADAPTER RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun);
 
-       if (qla2x00_wait_for_reset_ready(vha) != QLA_SUCCESS)
+       /*
+        * No point in issuing another reset if one is active.  Also do not
+        * attempt a reset if we are updating flash.
+        */
+       if (qla2x00_reset_active(vha) || ha->optrom_state != QLA_SWAITING)
                goto eh_host_reset_lock;
 
        if (vha != base_vha) {
@@ -2270,6 +2267,13 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha)
                ha->device_type |= DT_IIDMA;
                ha->fw_srisc_address = RISC_START_ADDRESS_2400;
                break;
+       case PCI_DEVICE_ID_QLOGIC_ISP2271:
+               ha->device_type |= DT_ISP2271;
+               ha->device_type |= DT_ZIO_SUPPORTED;
+               ha->device_type |= DT_FWI2;
+               ha->device_type |= DT_IIDMA;
+               ha->fw_srisc_address = RISC_START_ADDRESS_2400;
+               break;
        }
 
        if (IS_QLA82XX(ha))
@@ -2346,7 +2350,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
            pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031 ||
            pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001 ||
            pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044 ||
-           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071) {
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071 ||
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2271) {
                bars = pci_select_bars(pdev, IORESOURCE_MEM);
                mem_only = 1;
                ql_dbg_pci(ql_dbg_init, pdev, 0x0007,
@@ -2877,6 +2882,7 @@ skip_dpc:
 
        base_vha->flags.init_done = 1;
        base_vha->flags.online = 1;
+       ha->prev_minidump_failed = 0;
 
        ql_dbg(ql_dbg_init, base_vha, 0x00f2,
            "Init done and hba is online.\n");
@@ -3136,6 +3142,8 @@ qla2x00_remove_one(struct pci_dev *pdev)
        base_vha = pci_get_drvdata(pdev);
        ha = base_vha->hw;
 
+       qla2x00_wait_for_hba_ready(base_vha);
+
        set_bit(UNLOADING, &base_vha->dpc_flags);
 
        if (IS_QLAFX00(ha))
@@ -3645,6 +3653,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha)
        ha->eft = NULL;
        ha->eft_dma = 0;
        ha->fw_dumped = 0;
+       ha->fw_dump_cap_flags = 0;
        ha->fw_dump_reading = 0;
        ha->fw_dump = NULL;
        ha->fw_dump_len = 0;
@@ -5077,8 +5086,10 @@ intr_on_check:
                        ha->isp_ops->enable_intrs(ha);
 
                if (test_and_clear_bit(BEACON_BLINK_NEEDED,
-                                       &base_vha->dpc_flags))
-                       ha->isp_ops->beacon_blink(base_vha);
+                                       &base_vha->dpc_flags)) {
+                       if (ha->beacon_blink_led == 1)
+                               ha->isp_ops->beacon_blink(base_vha);
+               }
 
                if (!IS_QLAFX00(ha))
                        qla2x00_do_dpc_all_vps(base_vha);
@@ -5325,7 +5336,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
 #define FW_ISP82XX     7
 #define FW_ISP2031     8
 #define FW_ISP8031     9
-#define FW_ISP2071     10
+#define FW_ISP27XX     10
 
 #define FW_FILE_ISP21XX        "ql2100_fw.bin"
 #define FW_FILE_ISP22XX        "ql2200_fw.bin"
@@ -5337,7 +5348,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
 #define FW_FILE_ISP82XX        "ql8200_fw.bin"
 #define FW_FILE_ISP2031        "ql2600_fw.bin"
 #define FW_FILE_ISP8031        "ql8300_fw.bin"
-#define FW_FILE_ISP2071        "ql2700_fw.bin"
+#define FW_FILE_ISP27XX        "ql2700_fw.bin"
 
 
 static DEFINE_MUTEX(qla_fw_lock);
@@ -5353,7 +5364,7 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
        { .name = FW_FILE_ISP82XX, },
        { .name = FW_FILE_ISP2031, },
        { .name = FW_FILE_ISP8031, },
-       { .name = FW_FILE_ISP2071, },
+       { .name = FW_FILE_ISP27XX, },
 };
 
 struct fw_blob *
@@ -5382,8 +5393,8 @@ qla2x00_request_firmware(scsi_qla_host_t *vha)
                blob = &qla_fw_blobs[FW_ISP2031];
        } else if (IS_QLA8031(ha)) {
                blob = &qla_fw_blobs[FW_ISP8031];
-       } else if (IS_QLA2071(ha)) {
-               blob = &qla_fw_blobs[FW_ISP2071];
+       } else if (IS_QLA27XX(ha)) {
+               blob = &qla_fw_blobs[FW_ISP27XX];
        } else {
                return NULL;
        }
@@ -5714,6 +5725,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISPF001) },
        { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8044) },
        { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) },
+       { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2271) },
        { 0 },
 };
 MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);