diff mbox series

[v3,5/5] scsi: qla2xxx: only send certain mailbox commands to stopped firmware

Message ID 20200327164711.5358-6-mwilck@suse.com (mailing list archive)
State Superseded
Headers show
Series scsi: qla2xxx: fixes for driver unloading | expand

Commit Message

Martin Wilck March 27, 2020, 4:47 p.m. UTC
From: Martin Wilck <mwilck@suse.com>

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@suse.com>
---
 drivers/scsi/qla2xxx/qla_mbx.c | 46 ++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

Comments

Martin Wilck March 30, 2020, 8:15 p.m. UTC | #1
On Fri, 2020-03-27 at 17:47 +0100, mwilck@suse.com wrote:
> From: Martin Wilck <mwilck@suse.com>
> 
> 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@suse.com>
> ---
>  drivers/scsi/qla2xxx/qla_mbx.c | 46
> ++++++++++++++++++++++++++++++++++
>  1 file changed, 46 insertions(+)

Testing with different HW revealed that the list of allowed commands
needs to be extended. Forget this patch for now, please.

Regards
Martin
diff mbox series

Patch

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