Commit a465537a authored by Sawan Chandak's avatar Sawan Chandak Committed by Martin K. Petersen

qla2xxx: Disable the adapter and skip error recovery in case of register disconnect.

If there is error recovery going on due to command timeout and
there is register disconnect, then disable the adapter.
Signed-off-by: default avatarSawan Chandak <sawan.chandak@qlogic.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@qlogic.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 9e052e2d
...@@ -1769,6 +1769,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) ...@@ -1769,6 +1769,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
if (!fcport) if (!fcport)
return; return;
if (test_bit(UNLOADING, &fcport->vha->dpc_flags))
return;
if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags))
return; return;
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
* | | | 0x70ad-0x70ae | * | | | 0x70ad-0x70ae |
* | | | 0x70d0-0x70d6 | * | | | 0x70d0-0x70d6 |
* | | | 0x70d7-0x70db | * | | | 0x70d7-0x70db |
* | Task Management | 0x803d | 0x8000,0x800b | * | Task Management | 0x8042 | 0x8000,0x800b |
* | | | 0x8019 | * | | | 0x8019 |
* | | | 0x8025,0x8026 | * | | | 0x8025,0x8026 |
* | | | 0x8031,0x8032 | * | | | 0x8031,0x8032 |
......
...@@ -943,6 +943,30 @@ sp_get(struct srb *sp) ...@@ -943,6 +943,30 @@ sp_get(struct srb *sp)
atomic_inc(&sp->ref_count); 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 * qla2xxx_eh_abort
* *
...@@ -970,6 +994,11 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) ...@@ -970,6 +994,11 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
int rval, wait = 0; int rval, wait = 0;
struct qla_hw_data *ha = vha->hw; 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)) if (!CMD_SP(cmd))
return SUCCESS; return SUCCESS;
...@@ -1153,6 +1182,12 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) ...@@ -1153,6 +1182,12 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
scsi_qla_host_t *vha = shost_priv(cmd->device->host); scsi_qla_host_t *vha = shost_priv(cmd->device->host);
struct qla_hw_data *ha = vha->hw; 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, return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd,
ha->isp_ops->lun_reset); ha->isp_ops->lun_reset);
} }
...@@ -1163,6 +1198,12 @@ qla2xxx_eh_target_reset(struct scsi_cmnd *cmd) ...@@ -1163,6 +1198,12 @@ qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
scsi_qla_host_t *vha = shost_priv(cmd->device->host); scsi_qla_host_t *vha = shost_priv(cmd->device->host);
struct qla_hw_data *ha = vha->hw; 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, return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd,
ha->isp_ops->target_reset); ha->isp_ops->target_reset);
} }
...@@ -1190,6 +1231,13 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) ...@@ -1190,6 +1231,13 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
int ret = FAILED; int ret = FAILED;
unsigned int id; unsigned int id;
uint64_t lun; 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; id = cmd->device->id;
lun = cmd->device->lun; lun = cmd->device->lun;
...@@ -1259,6 +1307,13 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) ...@@ -1259,6 +1307,13 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
uint64_t lun; uint64_t lun;
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); 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; id = cmd->device->id;
lun = cmd->device->lun; lun = cmd->device->lun;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment