|
@@ -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(®->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;
|
|
|
|