]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
qla2xxx: Disable the adapter and skip error recovery in case of register disconnect.
authorSawan Chandak <sawan.chandak@qlogic.com>
Fri, 3 Jun 2016 05:57:54 +0000 (11:27 +0530)
committerChuck Anderson <chuck.anderson@oracle.com>
Wed, 13 Jul 2016 07:41:38 +0000 (00:41 -0700)
Orabug: 23755773

If there is error recovery going on due to command timeout and
there is register disconnect, then disable the adapter.

Signed-off-by: Sawan Chandak <sawan.chandak@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: Ethan Zhao <ethan.zhao@oracle.com>
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_os.c

index 9335474971ab82071b83f124d4c3cefef3d81563..2a9904dd737556cbd9a6138536354da1abccbc40 100644 (file)
@@ -1733,6 +1733,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
        if (!fcport)
                return;
 
+       if (test_bit(UNLOADING, &fcport->vha->dpc_flags))
+               return;
+
        if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags))
                return;
 
index 2a0e75e98e95d4392b1c8083828d49951ad59a6d..b16c0dc29ce533370706ad8fa09183f978dae509 100644 (file)
@@ -40,7 +40,7 @@
  * |                              |                    | 0x70ad-0x70ae  |
  * |                              |                    | 0x70d0-0x70d6 |
  * |                              |                    | 0x70d7-0x70db  |
- * | Task Management              |       0x803d       | 0x8000,0x800b  |
+ * | Task Management              |       0x8042       | 0x8000,0x800b  |
  * |                              |                    | 0x8019         |
  * |                              |                    | 0x8025,0x8026  |
  * |                              |                    | 0x8031,0x8032  |
index e962cb7958899b67b1b2ca8ab9dc3111b1531a91..6fcdedb25840bcd4b4933fb819efb323d2a24ba1 100644 (file)
@@ -926,6 +926,30 @@ sp_get(struct srb *sp)
        atomic_inc(&sp->ref_count);
 }
 
+#define ISP_REG_DISCONNECT 0xffffffffU
+/**************************************************************************
+* qla2x00_isp_reg_stat
+*
+* Description:
+*      Read the host status register of ISP before aborting the command.
+*
+* Input:
+*      ha = pointer to host adapter structure.
+*
+*
+* Returns:
+*      Either true or false.
+*
+* Note:        Return true if there is register disconnect.
+**************************************************************************/
+static inline
+uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
+{
+       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+       return ((RD_REG_DWORD(&reg->host_status)) == ISP_REG_DISCONNECT);
+}
+
 /**************************************************************************
 * qla2xxx_eh_abort
 *
@@ -953,6 +977,11 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        int rval, wait = 0;
        struct qla_hw_data *ha = vha->hw;
 
+       if (qla2x00_isp_reg_stat(ha)) {
+               ql_log(ql_log_info, vha, 0x8042,
+                   "PCI/Register disconnect, exiting.\n");
+               return FAILED;
+       }
        if (!CMD_SP(cmd))
                return SUCCESS;
 
@@ -1136,6 +1165,12 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
        scsi_qla_host_t *vha = shost_priv(cmd->device->host);
        struct qla_hw_data *ha = vha->hw;
 
+       if (qla2x00_isp_reg_stat(ha)) {
+               ql_log(ql_log_info, vha, 0x803e,
+                   "PCI/Register disconnect, exiting.\n");
+               return FAILED;
+       }
+
        return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd,
            ha->isp_ops->lun_reset);
 }
@@ -1146,6 +1181,12 @@ qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
        scsi_qla_host_t *vha = shost_priv(cmd->device->host);
        struct qla_hw_data *ha = vha->hw;
 
+       if (qla2x00_isp_reg_stat(ha)) {
+               ql_log(ql_log_info, vha, 0x803f,
+                   "PCI/Register disconnect, exiting.\n");
+               return FAILED;
+       }
+
        return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd,
            ha->isp_ops->target_reset);
 }
@@ -1173,6 +1214,13 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
        int ret = FAILED;
        unsigned int id;
        uint64_t lun;
+       struct qla_hw_data *ha = vha->hw;
+
+       if (qla2x00_isp_reg_stat(ha)) {
+               ql_log(ql_log_info, vha, 0x8040,
+                   "PCI/Register disconnect, exiting.\n");
+               return FAILED;
+       }
 
        id = cmd->device->id;
        lun = cmd->device->lun;
@@ -1242,6 +1290,13 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
        uint64_t lun;
        scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
 
+       if (qla2x00_isp_reg_stat(ha)) {
+               ql_log(ql_log_info, vha, 0x8041,
+                   "PCI/Register disconnect, exiting.\n");
+               schedule_work(&ha->board_disable);
+               return SUCCESS;
+       }
+
        id = cmd->device->id;
        lun = cmd->device->lun;