From: Sawan Chandak Date: Fri, 3 Jun 2016 05:57:54 +0000 (+0530) Subject: qla2xxx: Disable the adapter and skip error recovery in case of register disconnect. X-Git-Tag: v4.1.12-92~109^2~20 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=99baf6bb46de27b850ec87efeb11a9399b0af989;p=users%2Fjedix%2Flinux-maple.git qla2xxx: Disable the adapter and skip error recovery in case of register disconnect. 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 Signed-off-by: Himanshu Madhani Signed-off-by: Ethan Zhao --- diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 9335474971ab..2a9904dd7375 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -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; diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 2a0e75e98e95..b16c0dc29ce5 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -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 | diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index e962cb795889..6fcdedb25840 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -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(®->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;