@@ -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