From: Martin Wilck <mwilck@xxxxxxxx> Since commit 45235022da99 ("scsi: qla2xxx: Fix driver unload by shutting down chip"), it is possible that FC commands are scheduled after the adapter firmware has been shut down. IO sent to the firmware in this situation may hang. Only certain mailbox commands should be sent in this situation. This patch identifies the mailbox commands sent during adapter initialization (before QLA_FW_STARTED() is called) and allows only these to be sent to the firmware in stopped state. Signed-off-by: Martin Wilck <mwilck@xxxxxxxx> --- drivers/scsi/qla2xxx/qla_mbx.c | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 9fd83d1..4a9a583 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -77,6 +77,45 @@ static int is_rom_cmd(uint16_t cmd) return 0; } +/* + * Mailbox commands that must (and can) be sent to the Firmware + * even if it isn't running. IOW, commands that are sent before + * QLA_FW_STARTED() is called. + */ +static uint16_t fw_stopped_cmds[] = { + MBC_EXECUTE_FIRMWARE, + MBC_READ_RAM_WORD, + MBC_MAILBOX_REGISTER_TEST, + MBC_VERIFY_CHECKSUM, + MBC_GET_FIRMWARE_VERSION, + MBC_LOAD_RISC_RAM, + MBC_LOAD_RISC_RAM_EXTENDED, + MBC_WRITE_RAM_WORD_EXTENDED, + MBC_READ_RAM_EXTENDED, + MBC_GET_ADAPTER_LOOP_ID, + MBC_GET_SET_ZIO_THRESHOLD, + MBC_GET_FIRMWARE_OPTION, + MBC_GET_MEM_OFFLOAD_CNTRL_STAT, + MBC_SET_FIRMWARE_OPTION, + MBC_GET_RESOURCE_COUNTS, + MBC_INITIALIZE_FIRMWARE, + MBC_TRACE_CONTROL, + MBC_READ_SFP, + MBC_MID_INITIALIZE_FIRMWARE, + MBC_FLASH_ACCESS_CTRL, +}; + +static bool must_send_if_fw_stopped(uint16_t cmd) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(fw_stopped_cmds); i++) { + if (fw_stopped_cmds[i] == cmd) + return true; + } + return false; +} + /* * qla2x00_mailbox_command * Issue mailbox command and waits for completion. @@ -169,6 +208,13 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) return QLA_FUNCTION_TIMEOUT; } + if (!ha->flags.fw_started && !must_send_if_fw_stopped(mcp->mb[0])) { + ql_log(ql_log_info, vha, 0x1006, + "Cmd 0x%x skipped with timeout since FW is stopped\n", + mcp->mb[0]); + return QLA_FUNCTION_TIMEOUT; + } + atomic_inc(&ha->num_pend_mbx_stage1); /* * Wait for active mailbox commands to finish by waiting at most tov -- 2.25.1