From cdbb0a4f31c486e4f6fb6e673a892f4f5205f91c Mon Sep 17 00:00:00 2001 From: Santosh Vernekar Date: Fri, 28 May 2010 15:08:25 -0700 Subject: [SCSI] qla2xxx: Handle outstanding mbx cmds on hung f/w scenarios. Outstanding mailbox commands, have no way to recover on f/w hung, and we timeout on waiting for mbx response. This in turn affects the recovery process as follows: - We might already be in dpc while waiting for mbx to complete, so recovery for that pci function will never get invoked. Reset Timeout (10 sec) is far less than mbx timeout (30 sec). - Other mbx cmds will get stuck due to serial mbx access. Solution is to identify fw-hung scenario and handle outstanding mbx commands to have an early-exit instead of waiting for response. Other mbx commands waiting for access will also do an early-exit if fw-hung is still applicable. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_nx.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/qla2xxx/qla_nx.c') diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 1a9a7343dffa..512ba8a4ac57 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -3543,6 +3543,14 @@ qla82xx_check_fw_alive(scsi_qla_host_t *vha) set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); } qla2xxx_wake_dpc(vha); + if (ha->flags.mbox_busy) { + ha->flags.fw_hung = 1; + ha->flags.mbox_int = 1; + DEBUG2(qla_printk(KERN_ERR, ha, + "Due to fw hung, doing premature " + "completion of mbx command\n")); + complete(&ha->mbx_intr_comp); + } } } vha->fw_heartbeat_counter = fw_heartbeat_counter; @@ -3646,6 +3654,14 @@ void qla82xx_watchdog(scsi_qla_host_t *vha) "%s(): Adapter reset needed!\n", __func__); set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); qla2xxx_wake_dpc(vha); + if (ha->flags.mbox_busy) { + ha->flags.fw_hung = 1; + ha->flags.mbox_int = 1; + DEBUG2(qla_printk(KERN_ERR, ha, + "Need reset, doing premature " + "completion of mbx command\n")); + complete(&ha->mbx_intr_comp); + } } else { qla82xx_check_fw_alive(vha); } @@ -3701,8 +3717,10 @@ qla82xx_abort_isp(scsi_qla_host_t *vha) qla82xx_clear_rst_ready(ha); qla82xx_idc_unlock(ha); - if (rval == QLA_SUCCESS) + if (rval == QLA_SUCCESS) { + ha->flags.fw_hung = 0; qla82xx_restart_isp(vha); + } if (rval) { vha->flags.online = 1; -- cgit v1.2.3