]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
qla2xxx: Disable the adapter and skip error recovery in case of register disconnect.
authorSawan Chandak <sawan.chandak@qlogic.com>
Wed, 6 Jul 2016 15:14:32 +0000 (11:14 -0400)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 15 Jul 2016 19:35:50 +0000 (15:35 -0400)
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>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_os.c

index 8b06ce8fbb0f70721cd4000e87dd6e54b9041aaf..fe7469c901f76ac2d46006eeb208f3c9398d3ee1 100644 (file)
@@ -1769,6 +1769,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 1a042702d34adb8bbff8a0b65028c14c979bc09b..97b0a9da091322c6ee5945edd0289a6b6789d633 100644 (file)
@@ -41,7 +41,7 @@
  * |                              |                    | 0x70ad-0x70ae  |
  * |                              |                    | 0x70d0-0x70d6 |
  * |                              |                    | 0x70d7-0x70db  |
- * | Task Management              |       0x803d       | 0x8000,0x800b  |
+ * | Task Management              |       0x8042       | 0x8000,0x800b  |
  * |                              |                    | 0x8019         |
  * |                              |                    | 0x8025,0x8026  |
  * |                              |                    | 0x8031,0x8032  |
index dc7e5831587058947591cc99e24f9f7977dae898..2674f4c16bc319da17b016783aa5ef10d7c914bb 100644 (file)
@@ -943,6 +943,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
 *
@@ -970,6 +994,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;
 
@@ -1153,6 +1182,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);
 }
@@ -1163,6 +1198,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);
 }
@@ -1190,6 +1231,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;
@@ -1259,6 +1307,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;