diff options
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 23698c998699..b31c36b251a6 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -10,6 +10,43 @@ | |||
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <linux/gfp.h> | 11 | #include <linux/gfp.h> |
12 | 12 | ||
13 | struct rom_cmd { | ||
14 | uint16_t cmd; | ||
15 | } rom_cmds[] = { | ||
16 | { MBC_LOAD_RAM }, | ||
17 | { MBC_EXECUTE_FIRMWARE }, | ||
18 | { MBC_READ_RAM_WORD }, | ||
19 | { MBC_MAILBOX_REGISTER_TEST }, | ||
20 | { MBC_VERIFY_CHECKSUM }, | ||
21 | { MBC_GET_FIRMWARE_VERSION }, | ||
22 | { MBC_LOAD_RISC_RAM }, | ||
23 | { MBC_DUMP_RISC_RAM }, | ||
24 | { MBC_LOAD_RISC_RAM_EXTENDED }, | ||
25 | { MBC_DUMP_RISC_RAM_EXTENDED }, | ||
26 | { MBC_WRITE_RAM_WORD_EXTENDED }, | ||
27 | { MBC_READ_RAM_EXTENDED }, | ||
28 | { MBC_GET_RESOURCE_COUNTS }, | ||
29 | { MBC_SET_FIRMWARE_OPTION }, | ||
30 | { MBC_MID_INITIALIZE_FIRMWARE }, | ||
31 | { MBC_GET_FIRMWARE_STATE }, | ||
32 | { MBC_GET_MEM_OFFLOAD_CNTRL_STAT }, | ||
33 | { MBC_GET_RETRY_COUNT }, | ||
34 | { MBC_TRACE_CONTROL }, | ||
35 | }; | ||
36 | |||
37 | static int is_rom_cmd(uint16_t cmd) | ||
38 | { | ||
39 | int i; | ||
40 | struct rom_cmd *wc; | ||
41 | |||
42 | for (i = 0; i < ARRAY_SIZE(rom_cmds); i++) { | ||
43 | wc = rom_cmds + i; | ||
44 | if (wc->cmd == cmd) | ||
45 | return 1; | ||
46 | } | ||
47 | |||
48 | return 0; | ||
49 | } | ||
13 | 50 | ||
14 | /* | 51 | /* |
15 | * qla2x00_mailbox_command | 52 | * qla2x00_mailbox_command |
@@ -92,6 +129,17 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
92 | return QLA_FUNCTION_TIMEOUT; | 129 | return QLA_FUNCTION_TIMEOUT; |
93 | } | 130 | } |
94 | 131 | ||
132 | /* check if ISP abort is active and return cmd with timeout */ | ||
133 | if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || | ||
134 | test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || | ||
135 | test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) && | ||
136 | !is_rom_cmd(mcp->mb[0])) { | ||
137 | ql_log(ql_log_info, vha, 0x1005, | ||
138 | "Cmd 0x%x aborted with timeout since ISP Abort is pending\n", | ||
139 | mcp->mb[0]); | ||
140 | return QLA_FUNCTION_TIMEOUT; | ||
141 | } | ||
142 | |||
95 | /* | 143 | /* |
96 | * Wait for active mailbox commands to finish by waiting at most tov | 144 | * Wait for active mailbox commands to finish by waiting at most tov |
97 | * seconds. This is to serialize actual issuing of mailbox cmds during | 145 | * seconds. This is to serialize actual issuing of mailbox cmds during |
@@ -178,6 +226,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
178 | WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); | 226 | WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); |
179 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 227 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
180 | 228 | ||
229 | wait_time = jiffies; | ||
181 | if (!wait_for_completion_timeout(&ha->mbx_intr_comp, | 230 | if (!wait_for_completion_timeout(&ha->mbx_intr_comp, |
182 | mcp->tov * HZ)) { | 231 | mcp->tov * HZ)) { |
183 | ql_dbg(ql_dbg_mbx, vha, 0x117a, | 232 | ql_dbg(ql_dbg_mbx, vha, 0x117a, |
@@ -186,6 +235,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
186 | clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); | 235 | clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); |
187 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 236 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
188 | } | 237 | } |
238 | if (time_after(jiffies, wait_time + 5 * HZ)) | ||
239 | ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n", | ||
240 | command, jiffies_to_msecs(jiffies - wait_time)); | ||
189 | } else { | 241 | } else { |
190 | ql_dbg(ql_dbg_mbx, vha, 0x1011, | 242 | ql_dbg(ql_dbg_mbx, vha, 0x1011, |
191 | "Cmd=%x Polling Mode.\n", command); | 243 | "Cmd=%x Polling Mode.\n", command); |