aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx
diff options
context:
space:
mode:
authorNilesh Javali <nilesh.javali@qlogic.com>2010-07-30 04:58:07 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-08-06 13:00:12 -0400
commit21033639699d883668f6937b03e7b710771ad37e (patch)
tree1eef4627c27ae3c1f8a42e7a009a34455431ac01 /drivers/scsi/qla4xxx
parent2ccdf0dce41a39db3721fe801dac5c5effa8e4be (diff)
[SCSI] qla4xxx: 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: Nilesh Javali <nilesh.javali@qlogic.com> Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Signed-off-by: Ravi Anand <ravi.anand@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla4xxx')
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h1
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h1
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c39
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.c3
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c3
5 files changed, 47 insertions, 0 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index 6af5d04c5290..6c9262753243 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -380,6 +380,7 @@ struct scsi_qla_host {
380#define AF_MSI_ENABLED 16 /* 0x00010000 */ 380#define AF_MSI_ENABLED 16 /* 0x00010000 */
381#define AF_MSIX_ENABLED 17 /* 0x00020000 */ 381#define AF_MSIX_ENABLED 17 /* 0x00020000 */
382#define AF_MBOX_COMMAND_NOPOLL 18 /* 0x00040000 */ 382#define AF_MBOX_COMMAND_NOPOLL 18 /* 0x00040000 */
383#define AF_FW_RECOVERY 19 /* 0x00080000 */
383 384
384 385
385 unsigned long dpc_flags; 386 unsigned long dpc_flags;
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index c9cd5d6db982..ea3db23602e6 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -93,6 +93,7 @@ void qla4xxx_free_irqs(struct scsi_qla_host *ha);
93void qla4xxx_process_response_queue(struct scsi_qla_host *ha); 93void qla4xxx_process_response_queue(struct scsi_qla_host *ha);
94void qla4xxx_wake_dpc(struct scsi_qla_host *ha); 94void qla4xxx_wake_dpc(struct scsi_qla_host *ha);
95void qla4xxx_get_conn_event_log(struct scsi_qla_host *ha); 95void qla4xxx_get_conn_event_log(struct scsi_qla_host *ha);
96void qla4xxx_mailbox_premature_completion(struct scsi_qla_host *ha);
96 97
97void qla4_8xxx_pci_config(struct scsi_qla_host *); 98void qla4_8xxx_pci_config(struct scsi_qla_host *);
98int qla4_8xxx_iospace_config(struct scsi_qla_host *ha); 99int qla4_8xxx_iospace_config(struct scsi_qla_host *ha);
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index c4e036b449c2..1003e48d2200 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -39,6 +39,15 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
39 "pointer\n", ha->host_no, __func__)); 39 "pointer\n", ha->host_no, __func__));
40 return status; 40 return status;
41 } 41 }
42
43 if (is_qla8022(ha) &&
44 test_bit(AF_FW_RECOVERY, &ha->flags)) {
45 DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: prematurely "
46 "completing mbx cmd as firmware recovery detected\n",
47 ha->host_no, __func__));
48 return status;
49 }
50
42 /* Mailbox code active */ 51 /* Mailbox code active */
43 wait_count = MBOX_TOV * 100; 52 wait_count = MBOX_TOV * 100;
44 53
@@ -196,6 +205,14 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
196 205
197 /* Check for mailbox timeout. */ 206 /* Check for mailbox timeout. */
198 if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) { 207 if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) {
208 if (is_qla8022(ha) &&
209 test_bit(AF_FW_RECOVERY, &ha->flags)) {
210 DEBUG2(ql4_printk(KERN_INFO, ha,
211 "scsi%ld: %s: prematurely completing mbx cmd as "
212 "firmware recovery detected\n",
213 ha->host_no, __func__));
214 goto mbox_exit;
215 }
199 DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...," 216 DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...,"
200 " Scheduling Adapter Reset\n", ha->host_no, 217 " Scheduling Adapter Reset\n", ha->host_no,
201 mbx_cmd[0])); 218 mbx_cmd[0]));
@@ -246,6 +263,28 @@ mbox_exit:
246 return status; 263 return status;
247} 264}
248 265
266void qla4xxx_mailbox_premature_completion(struct scsi_qla_host *ha)
267{
268 set_bit(AF_FW_RECOVERY, &ha->flags);
269 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: set FW RECOVERY!\n",
270 ha->host_no, __func__);
271
272 if (test_bit(AF_MBOX_COMMAND, &ha->flags)) {
273 if (test_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags)) {
274 complete(&ha->mbx_intr_comp);
275 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Due to fw "
276 "recovery, doing premature completion of "
277 "mbx cmd\n", ha->host_no, __func__);
278
279 } else {
280 set_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
281 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Due to fw "
282 "recovery, doing premature completion of "
283 "polling mbx cmd\n", ha->host_no, __func__);
284 }
285 }
286}
287
249static uint8_t 288static uint8_t
250qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, 289qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
251 uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma) 290 uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma)
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index ec46651100cb..0830ea9d708c 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -2105,6 +2105,9 @@ qla4_8xxx_isp_reset(struct scsi_qla_host *ha)
2105 qla4_8xxx_clear_rst_ready(ha); 2105 qla4_8xxx_clear_rst_ready(ha);
2106 qla4_8xxx_idc_unlock(ha); 2106 qla4_8xxx_idc_unlock(ha);
2107 2107
2108 if (rval == QLA_SUCCESS)
2109 clear_bit(AF_FW_RECOVERY, &ha->flags);
2110
2108 return rval; 2111 return rval;
2109} 2112}
2110 2113
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index e575d765ba26..2bb362c6e634 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -663,6 +663,7 @@ static void qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
663 ha->seconds_since_last_heartbeat = 0; 663 ha->seconds_since_last_heartbeat = 0;
664 halt_status = qla4_8xxx_rd_32(ha, 664 halt_status = qla4_8xxx_rd_32(ha,
665 QLA82XX_PEG_HALT_STATUS1); 665 QLA82XX_PEG_HALT_STATUS1);
666
666 /* Since we cannot change dev_state in interrupt 667 /* Since we cannot change dev_state in interrupt
667 * context, set appropriate DPC flag then wakeup 668 * context, set appropriate DPC flag then wakeup
668 * DPC */ 669 * DPC */
@@ -674,6 +675,7 @@ static void qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
674 set_bit(DPC_RESET_HA, &ha->dpc_flags); 675 set_bit(DPC_RESET_HA, &ha->dpc_flags);
675 } 676 }
676 qla4xxx_wake_dpc(ha); 677 qla4xxx_wake_dpc(ha);
678 qla4xxx_mailbox_premature_completion(ha);
677 } 679 }
678 } 680 }
679 ha->fw_heartbeat_counter = fw_heartbeat_counter; 681 ha->fw_heartbeat_counter = fw_heartbeat_counter;
@@ -699,6 +701,7 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
699 ha->host_no, __func__); 701 ha->host_no, __func__);
700 set_bit(DPC_RESET_HA, &ha->dpc_flags); 702 set_bit(DPC_RESET_HA, &ha->dpc_flags);
701 qla4xxx_wake_dpc(ha); 703 qla4xxx_wake_dpc(ha);
704 qla4xxx_mailbox_premature_completion(ha);
702 } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT && 705 } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT &&
703 !test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) { 706 !test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) {
704 printk("scsi%ld: %s: HW State: NEED QUIES!\n", 707 printk("scsi%ld: %s: HW State: NEED QUIES!\n",