|
@@ -37,7 +37,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
|
|
device_reg_t __iomem *reg;
|
|
|
uint8_t abort_active;
|
|
|
uint8_t io_lock_on;
|
|
|
- uint16_t command;
|
|
|
+ uint16_t command = 0;
|
|
|
uint16_t *iptr;
|
|
|
uint16_t __iomem *optr;
|
|
|
uint32_t cnt;
|
|
@@ -83,6 +83,13 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
|
|
return QLA_FUNCTION_TIMEOUT;
|
|
|
}
|
|
|
|
|
|
+ if (IS_QLA82XX(ha) && ha->flags.fw_hung) {
|
|
|
+ /* Setting Link-Down error */
|
|
|
+ mcp->mb[0] = MBS_LINK_DOWN_ERROR;
|
|
|
+ rval = QLA_FUNCTION_FAILED;
|
|
|
+ goto premature_exit;
|
|
|
+ }
|
|
|
+
|
|
|
ha->flags.mbox_busy = 1;
|
|
|
/* Save mailbox command for debug */
|
|
|
ha->mcp = mcp;
|
|
@@ -151,7 +158,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
|
|
DEBUG2_3_11(printk(KERN_INFO
|
|
|
"%s(%ld): Pending Mailbox timeout. "
|
|
|
"Exiting.\n", __func__, base_vha->host_no));
|
|
|
- return QLA_FUNCTION_TIMEOUT;
|
|
|
+ rval = QLA_FUNCTION_TIMEOUT;
|
|
|
+ goto premature_exit;
|
|
|
}
|
|
|
WRT_REG_DWORD(®->isp82.hint, HINT_MBX_INT_PENDING);
|
|
|
} else if (IS_FWI2_CAPABLE(ha))
|
|
@@ -176,7 +184,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
|
|
DEBUG2_3_11(printk(KERN_INFO
|
|
|
"%s(%ld): Pending Mailbox timeout. "
|
|
|
"Exiting.\n", __func__, base_vha->host_no));
|
|
|
- return QLA_FUNCTION_TIMEOUT;
|
|
|
+ rval = QLA_FUNCTION_TIMEOUT;
|
|
|
+ goto premature_exit;
|
|
|
}
|
|
|
WRT_REG_DWORD(®->isp82.hint, HINT_MBX_INT_PENDING);
|
|
|
} else if (IS_FWI2_CAPABLE(ha))
|
|
@@ -214,6 +223,15 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
|
|
ha->flags.mbox_int = 0;
|
|
|
clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
|
|
|
|
|
|
+ if (IS_QLA82XX(ha) && ha->flags.fw_hung) {
|
|
|
+ ha->flags.mbox_busy = 0;
|
|
|
+ /* Setting Link-Down error */
|
|
|
+ mcp->mb[0] = MBS_LINK_DOWN_ERROR;
|
|
|
+ ha->mcp = NULL;
|
|
|
+ rval = QLA_FUNCTION_FAILED;
|
|
|
+ goto premature_exit;
|
|
|
+ }
|
|
|
+
|
|
|
if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
|
|
|
rval = QLA_FUNCTION_FAILED;
|
|
|
|
|
@@ -279,35 +297,51 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
|
|
DEBUG2_3_11(printk("%s(%ld): timeout schedule "
|
|
|
"isp_abort_needed.\n", __func__,
|
|
|
base_vha->host_no));
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Mailbox command timeout occurred. Scheduling ISP "
|
|
|
- "abort. eeh_busy: 0x%x\n", ha->flags.eeh_busy);
|
|
|
- set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
|
|
|
- qla2xxx_wake_dpc(vha);
|
|
|
+
|
|
|
+ if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
|
|
|
+ !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
|
|
|
+ !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
|
|
|
+
|
|
|
+ qla_printk(KERN_WARNING, ha,
|
|
|
+ "Mailbox command timeout occured. "
|
|
|
+ "Scheduling ISP " "abort. eeh_busy: 0x%x\n",
|
|
|
+ ha->flags.eeh_busy);
|
|
|
+ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
|
|
+ qla2xxx_wake_dpc(vha);
|
|
|
+ }
|
|
|
} else if (!abort_active) {
|
|
|
/* call abort directly since we are in the DPC thread */
|
|
|
DEBUG(printk("%s(%ld): timeout calling abort_isp\n",
|
|
|
__func__, base_vha->host_no));
|
|
|
DEBUG2_3_11(printk("%s(%ld): timeout calling "
|
|
|
"abort_isp\n", __func__, base_vha->host_no));
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Mailbox command timeout occurred. Issuing ISP "
|
|
|
- "abort.\n");
|
|
|
-
|
|
|
- set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
|
|
|
- clear_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
|
|
|
- if (ha->isp_ops->abort_isp(base_vha)) {
|
|
|
- /* Failed. retry later. */
|
|
|
- set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
|
|
|
+
|
|
|
+ if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
|
|
|
+ !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
|
|
|
+ !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
|
|
|
+
|
|
|
+ qla_printk(KERN_WARNING, ha,
|
|
|
+ "Mailbox command timeout occured. "
|
|
|
+ "Issuing ISP abort.\n");
|
|
|
+
|
|
|
+ set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
|
|
|
+ clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
|
|
+ if (ha->isp_ops->abort_isp(vha)) {
|
|
|
+ /* Failed. retry later. */
|
|
|
+ set_bit(ISP_ABORT_NEEDED,
|
|
|
+ &vha->dpc_flags);
|
|
|
+ }
|
|
|
+ clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
|
|
|
+ DEBUG(printk("%s(%ld): finished abort_isp\n",
|
|
|
+ __func__, vha->host_no));
|
|
|
+ DEBUG2_3_11(printk(
|
|
|
+ "%s(%ld): finished abort_isp\n",
|
|
|
+ __func__, vha->host_no));
|
|
|
}
|
|
|
- clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
|
|
|
- DEBUG(printk("%s(%ld): finished abort_isp\n", __func__,
|
|
|
- base_vha->host_no));
|
|
|
- DEBUG2_3_11(printk("%s(%ld): finished abort_isp\n",
|
|
|
- __func__, base_vha->host_no));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+premature_exit:
|
|
|
/* Allow next mbx cmd to come in. */
|
|
|
complete(&ha->mbx_cmd_comp);
|
|
|
|