diff options
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_def.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_glbl.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_mbx.c | 39 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_nx.c | 3 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 3 |
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); | |||
93 | void qla4xxx_process_response_queue(struct scsi_qla_host *ha); | 93 | void qla4xxx_process_response_queue(struct scsi_qla_host *ha); |
94 | void qla4xxx_wake_dpc(struct scsi_qla_host *ha); | 94 | void qla4xxx_wake_dpc(struct scsi_qla_host *ha); |
95 | void qla4xxx_get_conn_event_log(struct scsi_qla_host *ha); | 95 | void qla4xxx_get_conn_event_log(struct scsi_qla_host *ha); |
96 | void qla4xxx_mailbox_premature_completion(struct scsi_qla_host *ha); | ||
96 | 97 | ||
97 | void qla4_8xxx_pci_config(struct scsi_qla_host *); | 98 | void qla4_8xxx_pci_config(struct scsi_qla_host *); |
98 | int qla4_8xxx_iospace_config(struct scsi_qla_host *ha); | 99 | int 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 | ||
266 | void 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 | |||
249 | static uint8_t | 288 | static uint8_t |
250 | qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, | 289 | qla4xxx_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", |