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", |
