[SCSI] qla2xxx: Limit excessive DPC cycles.
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / qla2xxx / qla_os.c
index fd14c7bfc62665f698d9950210dfa3b2e1cf1f42..51c4655420926e3f12b10d821b4cd7e531707789 100644 (file)
@@ -83,6 +83,9 @@ MODULE_PARM_DESC(ql2xextended_error_logging,
                "\t\t0x00080000 - P3P Specific.  0x00040000 - Virtual Port.\n"
                "\t\t0x00020000 - Buffer Dump.   0x00010000 - Misc.\n"
                "\t\t0x7fffffff - For enabling all logs, can be too many logs.\n"
+               "\t\t0x1e400000 - Preferred value for capturing essential "
+               "debug information (equivalent to old "
+               "ql2xextended_error_logging=1).\n"
                "\t\tDo LOGICAL OR of the value to enable more than one level");
 
 int ql2xshiftctondsd = 6;
@@ -201,12 +204,12 @@ MODULE_PARM_DESC(ql2xmdcapmask,
                "Set the Minidump driver capture mask level. "
                "Default is 0x7F - Can be set to 0x3, 0x7, 0xF, 0x1F, 0x7F.");
 
-int ql2xmdenable;
+int ql2xmdenable = 1;
 module_param(ql2xmdenable, int, S_IRUGO);
 MODULE_PARM_DESC(ql2xmdenable,
                "Enable/disable MiniDump. "
-               "0 (Default) - MiniDump disabled. "
-               "1 - MiniDump enabled.");
+               "0 - MiniDump disabled. "
+               "1 (Default) - MiniDump enabled.");
 
 /*
  * SCSI host template entry points
@@ -423,6 +426,7 @@ fail2:
        qla25xx_delete_queues(vha);
        destroy_workqueue(ha->wq);
        ha->wq = NULL;
+       vha->req = ha->req_q_map[0];
 fail:
        ha->mqenable = 0;
        kfree(ha->req_q_map);
@@ -814,49 +818,6 @@ qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha)
        return return_status;
 }
 
-/*
- * qla2x00_wait_for_loop_ready
- *    Wait for MAX_LOOP_TIMEOUT(5 min) value for loop
- *    to be in LOOP_READY state.
- * Input:
- *     ha - pointer to host adapter structure
- *
- * Note:
- *    Does context switching-Release SPIN_LOCK
- *    (if any) before calling this routine.
- *
- *
- * Return:
- *    Success (LOOP_READY) : 0
- *    Failed  (LOOP_NOT_READY) : 1
- */
-static inline int
-qla2x00_wait_for_loop_ready(scsi_qla_host_t *vha)
-{
-       int      return_status = QLA_SUCCESS;
-       unsigned long loop_timeout ;
-       struct qla_hw_data *ha = vha->hw;
-       scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
-
-       /* wait for 5 min at the max for loop to be ready */
-       loop_timeout = jiffies + (MAX_LOOP_TIMEOUT * HZ);
-
-       while ((!atomic_read(&base_vha->loop_down_timer) &&
-           atomic_read(&base_vha->loop_state) == LOOP_DOWN) ||
-           atomic_read(&base_vha->loop_state) != LOOP_READY) {
-               if (atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
-                       return_status = QLA_FUNCTION_FAILED;
-                       break;
-               }
-               msleep(1000);
-               if (time_after_eq(jiffies, loop_timeout)) {
-                       return_status = QLA_FUNCTION_FAILED;
-                       break;
-               }
-       }
-       return (return_status);
-}
-
 static void
 sp_get(struct srb *sp)
 {
@@ -889,14 +850,10 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        int wait = 0;
        struct qla_hw_data *ha = vha->hw;
 
-       ql_dbg(ql_dbg_taskm, vha, 0x8000,
-           "Entered %s for cmd=%p.\n", __func__, cmd);
        if (!CMD_SP(cmd))
                return SUCCESS;
 
        ret = fc_block_scsi_eh(cmd);
-       ql_dbg(ql_dbg_taskm, vha, 0x8001,
-           "Return value of fc_block_scsi_eh=%d.\n", ret);
        if (ret != 0)
                return ret;
        ret = SUCCESS;
@@ -912,7 +869,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        }
 
        ql_dbg(ql_dbg_taskm, vha, 0x8002,
-           "Aborting sp=%p cmd=%p from RISC ", sp, cmd);
+           "Aborting from RISC nexus=%ld:%d:%d sp=%p cmd=%p\n",
+           vha->host_no, id, lun, sp, cmd);
 
        /* Get a reference to the sp and drop the lock.*/
        sp_get(sp);
@@ -920,10 +878,10 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
        if (ha->isp_ops->abort_command(sp)) {
                ql_dbg(ql_dbg_taskm, vha, 0x8003,
-                   "Abort command mbx failed for cmd=%p.\n", cmd);
+                   "Abort command mbx failed cmd=%p.\n", cmd);
        } else {
                ql_dbg(ql_dbg_taskm, vha, 0x8004,
-                   "Abort command mbx success.\n");
+                   "Abort command mbx success cmd=%p.\n", cmd);
                wait = 1;
        }
 
@@ -939,13 +897,14 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        if (wait) {
                if (qla2x00_eh_wait_on_command(cmd) != QLA_SUCCESS) {
                        ql_log(ql_log_warn, vha, 0x8006,
-                           "Abort handler timed out for cmd=%p.\n", cmd);
+                           "Abort handler timed out cmd=%p.\n", cmd);
                        ret = FAILED;
                }
        }
 
        ql_log(ql_log_info, vha, 0x801c,
-           "Abort command issued --  %d %x.\n", wait, ret);
+           "Abort command issued nexus=%ld:%d:%d --  %d %x.\n",
+           vha->host_no, id, lun, wait, ret);
 
        return ret;
 }
@@ -1014,19 +973,15 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
        int err;
 
        if (!fcport) {
-               ql_log(ql_log_warn, vha, 0x8007,
-                   "fcport is NULL.\n");
                return FAILED;
        }
 
        err = fc_block_scsi_eh(cmd);
-       ql_dbg(ql_dbg_taskm, vha, 0x8008,
-           "fc_block_scsi_eh ret=%d.\n", err);
        if (err != 0)
                return err;
 
        ql_log(ql_log_info, vha, 0x8009,
-           "%s RESET ISSUED for id %d lun %d cmd=%p.\n", name,
+           "%s RESET ISSUED nexus=%ld:%d:%d cmd=%p.\n", name, vha->host_no,
            cmd->device->id, cmd->device->lun, cmd);
 
        err = 0;
@@ -1035,12 +990,6 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
                    "Wait for hba online failed for cmd=%p.\n", cmd);
                goto eh_reset_failed;
        }
-       err = 1;
-       if (qla2x00_wait_for_loop_ready(vha) != QLA_SUCCESS) {
-               ql_log(ql_log_warn, vha, 0x800b,
-                   "Wait for loop ready failed for cmd=%p.\n", cmd);
-               goto eh_reset_failed;
-       }
        err = 2;
        if (do_reset(fcport, cmd->device->lun, cmd->request->cpu + 1)
                != QLA_SUCCESS) {
@@ -1057,15 +1006,16 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
        }
 
        ql_log(ql_log_info, vha, 0x800e,
-           "%s RESET SUCCEEDED for id %d lun %d cmd=%p.\n", name,
-           cmd->device->id, cmd->device->lun, cmd);
+           "%s RESET SUCCEEDED nexus:%ld:%d:%d cmd=%p.\n", name,
+           vha->host_no, cmd->device->id, cmd->device->lun, cmd);
 
        return SUCCESS;
 
 eh_reset_failed:
        ql_log(ql_log_info, vha, 0x800f,
-           "%s RESET FAILED: %s for id %d lun %d cmd=%p.\n", name,
-           reset_errors[err], cmd->device->id, cmd->device->lun);
+           "%s RESET FAILED: %s nexus=%ld:%d:%d cmd=%p.\n", name,
+           reset_errors[err], vha->host_no, cmd->device->id, cmd->device->lun,
+           cmd);
        return FAILED;
 }
 
@@ -1116,20 +1066,16 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
        lun = cmd->device->lun;
 
        if (!fcport) {
-               ql_log(ql_log_warn, vha, 0x8010,
-                   "fcport is NULL.\n");
                return ret;
        }
 
        ret = fc_block_scsi_eh(cmd);
-       ql_dbg(ql_dbg_taskm, vha, 0x8011,
-           "fc_block_scsi_eh ret=%d.\n", ret);
        if (ret != 0)
                return ret;
        ret = FAILED;
 
        ql_log(ql_log_info, vha, 0x8012,
-           "BUS RESET ISSUED for id %d lun %d.\n", id, lun);
+           "BUS RESET ISSUED nexus=%ld:%d%d.\n", vha->host_no, id, lun);
 
        if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
                ql_log(ql_log_fatal, vha, 0x8013,
@@ -1137,10 +1083,9 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
                goto eh_bus_reset_done;
        }
 
-       if (qla2x00_wait_for_loop_ready(vha) == QLA_SUCCESS) {
-               if (qla2x00_loop_reset(vha) == QLA_SUCCESS)
-                       ret = SUCCESS;
-       }
+       if (qla2x00_loop_reset(vha) == QLA_SUCCESS)
+               ret = SUCCESS;
+
        if (ret == FAILED)
                goto eh_bus_reset_done;
 
@@ -1154,7 +1099,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
 
 eh_bus_reset_done:
        ql_log(ql_log_warn, vha, 0x802b,
-           "BUS RESET %s.\n", (ret == FAILED) ? "FAILED" : "SUCCEDED");
+           "BUS RESET %s nexus=%ld:%d:%d.\n",
+           (ret == FAILED) ? "FAILED" : "SUCCEDED", vha->host_no, id, lun);
 
        return ret;
 }
@@ -1188,33 +1134,20 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
        lun = cmd->device->lun;
 
        if (!fcport) {
-               ql_log(ql_log_warn, vha, 0x8016,
-                   "fcport is NULL.\n");
                return ret;
        }
 
        ret = fc_block_scsi_eh(cmd);
-       ql_dbg(ql_dbg_taskm, vha, 0x8017,
-           "fc_block_scsi_eh ret=%d.\n", ret);
        if (ret != 0)
                return ret;
        ret = FAILED;
 
        ql_log(ql_log_info, vha, 0x8018,
-           "ADAPTER RESET ISSUED for id %d lun %d.\n", id, lun);
+           "ADAPTER RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun);
 
        if (qla2x00_wait_for_reset_ready(vha) != QLA_SUCCESS)
                goto eh_host_reset_lock;
 
-       /*
-        * Fixme-may be dpc thread is active and processing
-        * loop_resync,so wait a while for it to
-        * be completed and then issue big hammer.Otherwise
-        * it may cause I/O failure as big hammer marks the
-        * devices as lost kicking of the port_down_timer
-        * while dpc is stuck for the mailbox to complete.
-        */
-       qla2x00_wait_for_loop_ready(vha);
        if (vha != base_vha) {
                if (qla2x00_vp_abort_isp(vha))
                        goto eh_host_reset_lock;
@@ -1251,8 +1184,9 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
                ret = SUCCESS;
 
 eh_host_reset_lock:
-       qla_printk(KERN_INFO, ha, "%s: reset %s.\n", __func__,
-           (ret == FAILED) ? "failed" : "succeeded");
+       ql_log(ql_log_info, vha, 0x8017,
+           "ADAPTER RESET %s nexus=%ld:%d:%d.\n",
+           (ret == FAILED) ? "FAILED" : "SUCCEEDED", vha->host_no, id, lun);
 
        return ret;
 }
@@ -1297,16 +1231,13 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
                atomic_set(&vha->loop_state, LOOP_DOWN);
                atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
                qla2x00_mark_all_devices_lost(vha, 0);
-               qla2x00_wait_for_loop_ready(vha);
        }
 
        if (ha->flags.enable_lip_reset) {
                ret = qla2x00_lip_reset(vha);
-               if (ret != QLA_SUCCESS) {
+               if (ret != QLA_SUCCESS)
                        ql_dbg(ql_dbg_taskm, vha, 0x802e,
                            "lip_reset failed (%d).\n", ret);
-               } else
-                       qla2x00_wait_for_loop_ready(vha);
        }
 
        /* Issue marker command only when we are going to start the I/O */
@@ -1405,10 +1336,8 @@ static void qla2x00_handle_queue_full(struct scsi_device *sdev, int qdepth)
                return;
 
        ql_dbg(ql_dbg_io, fcport->vha, 0x3029,
-           "Queue depth adjusted-down "
-           "to %d for scsi(%ld:%d:%d:%d).\n",
-           sdev->queue_depth, fcport->vha->host_no,
-           sdev->channel, sdev->id, sdev->lun);
+           "Queue depth adjusted-down to %d for nexus=%ld:%d:%d.\n",
+           sdev->queue_depth, fcport->vha->host_no, sdev->id, sdev->lun);
 }
 
 static void qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, int qdepth)
@@ -1430,10 +1359,8 @@ static void qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, int qdepth)
                scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, qdepth);
 
        ql_dbg(ql_dbg_io, vha, 0x302a,
-           "Queue depth adjusted-up to %d for "
-           "scsi(%ld:%d:%d:%d).\n",
-           sdev->queue_depth, fcport->vha->host_no,
-           sdev->channel, sdev->id, sdev->lun);
+           "Queue depth adjusted-up to %d for nexus=%ld:%d:%d.\n",
+           sdev->queue_depth, fcport->vha->host_no, sdev->id, sdev->lun);
 }
 
 static int
@@ -1880,7 +1807,7 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha)
        else
                ha->flags.port0 = 0;
        ql_dbg_pci(ql_dbg_init, ha->pdev, 0x000b,
-           "device_type=0x%x port=%d fw_srisc_address=%p.\n",
+           "device_type=0x%x port=%d fw_srisc_address=0x%x.\n",
            ha->device_type, ha->flags.port0, ha->fw_srisc_address);
 }
 
@@ -1921,8 +1848,8 @@ qla2x00_iospace_config(struct qla_hw_data *ha)
        }
        ha->pio_address = pio;
        ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0014,
-           "PIO address=%p.\n",
-           ha->pio_address);
+           "PIO address=%llu.\n",
+           (unsigned long long)ha->pio_address);
 
 skip_pio:
        /* Use MMIO operations for all accesses. */
@@ -2288,7 +2215,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        ql_dbg(ql_dbg_init, base_vha, 0x0033,
            "max_id=%d this_id=%d "
            "cmd_per_len=%d unique_id=%d max_cmd_len=%d max_channel=%d "
-           "max_lun=%d transportt=%p, vendor_id=%d.\n", host->max_id,
+           "max_lun=%d transportt=%p, vendor_id=%llu.\n", host->max_id,
            host->this_id, host->cmd_per_lun, host->unique_id,
            host->max_cmd_len, host->max_channel, host->max_lun,
            host->transportt, sht->vendor_id);
@@ -2443,9 +2370,6 @@ skip_dpc:
 
        qla2x00_dfs_setup(base_vha);
 
-       ql_log(ql_log_info, base_vha, 0x00fa,
-           "QLogic Fibre Channed HBA Driver: %s.\n",
-           qla2x00_version_str);
        ql_log(ql_log_info, base_vha, 0x00fb,
            "QLogic %s - %s.\n",
            ha->model_number, ha->model_desc ? ha->model_desc : "");
@@ -2894,7 +2818,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
                if (!ha->sns_cmd)
                        goto fail_dma_pool;
                ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0026,
-                   "sns_cmd.\n", ha->sns_cmd);
+                   "sns_cmd: %p.\n", ha->sns_cmd);
        } else {
        /* Get consistent memory allocated for MS IOCB */
                ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
@@ -3521,27 +3445,21 @@ qla2x00_do_dpc(void *data)
                schedule();
                __set_current_state(TASK_RUNNING);
 
-               ql_dbg(ql_dbg_dpc, base_vha, 0x4001,
-                   "DPC handler waking up.\n");
-               ql_dbg(ql_dbg_dpc, base_vha, 0x4002,
-                   "dpc_flags=0x%lx.\n", base_vha->dpc_flags);
-
-               /* Initialization not yet finished. Don't do anything yet. */
-               if (!base_vha->flags.init_done)
-                       continue;
+               if (!base_vha->flags.init_done || ha->flags.mbox_busy)
+                       goto end_loop;
 
                if (ha->flags.eeh_busy) {
                        ql_dbg(ql_dbg_dpc, base_vha, 0x4003,
                            "eeh_busy=%d.\n", ha->flags.eeh_busy);
-                       continue;
+                       goto end_loop;
                }
 
                ha->dpc_active = 1;
 
-               if (ha->flags.mbox_busy) {
-                       ha->dpc_active = 0;
-                       continue;
-               }
+               ql_dbg(ql_dbg_dpc, base_vha, 0x4001,
+                   "DPC handler waking up.\n");
+               ql_dbg(ql_dbg_dpc, base_vha, 0x4002,
+                   "dpc_flags=0x%lx.\n", base_vha->dpc_flags);
 
                qla2x00_do_work(base_vha);
 
@@ -3683,6 +3601,7 @@ qla2x00_do_dpc(void *data)
                qla2x00_do_dpc_all_vps(base_vha);
 
                ha->dpc_active = 0;
+end_loop:
                set_current_state(TASK_INTERRUPTIBLE);
        } /* End of while(1) */
        __set_current_state(TASK_RUNNING);
@@ -3766,16 +3685,6 @@ qla2x00_sp_free_dma(srb_t *sp)
                sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
        }
 
-       CMD_SP(cmd) = NULL;
-}
-
-static void
-qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
-{
-       struct scsi_cmnd *cmd = sp->cmd;
-
-       qla2x00_sp_free_dma(sp);
-
        if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
                struct ct6_dsd *ctx = sp->ctx;
                dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd,
@@ -3787,6 +3696,15 @@ qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
                sp->ctx = NULL;
        }
 
+       CMD_SP(cmd) = NULL;
+}
+
+static void
+qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
+{
+       struct scsi_cmnd *cmd = sp->cmd;
+
+       qla2x00_sp_free_dma(sp);
        mempool_free(sp, ha->srb_mempool);
        cmd->scsi_done(cmd);
 }
@@ -4070,13 +3988,8 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
                /* For ISP82XX complete any pending mailbox cmd */
                if (IS_QLA82XX(ha)) {
                        ha->flags.isp82xx_fw_hung = 1;
-                       if (ha->flags.mbox_busy) {
-                               ha->flags.mbox_int = 1;
-                               ql_dbg(ql_dbg_aer, vha, 0x9001,
-                                   "Due to pci channel io frozen, doing premature "
-                                   "completion of mbx command.\n");
-                               complete(&ha->mbx_intr_comp);
-                       }
+                       ql_dbg(ql_dbg_aer, vha, 0x9001, "Pci channel io frozen\n");
+                       qla82xx_clear_pending_mbx(vha);
                }
                qla2x00_free_irqs(vha);
                pci_disable_device(pdev);