scsi: qla2xxx: Only allow operational MBX to proceed during RESET.
authorhimanshu.madhani@cavium.com <himanshu.madhani@cavium.com>
Mon, 12 Dec 2016 22:40:05 +0000 (14:40 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 14 Dec 2016 20:37:58 +0000 (15:37 -0500)
This patch is allowing only ROM mailbox command which are
necessary to initialize chip after a reset has been issued.
In a target environment, there could be a user space daemon
which can issue statistics and other management mailbox command
which are non-critical. This patch will timeout non critical
mailbox commands immediately rather than waiting for timeout,
if driver detects that chip reset has been issued or chip reset
is in progress.

Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Giridhar Malavali <giridhar.malavali@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_mbx.c

index 23698c9986998a0a7279e6e256d4c377f6fceab9..b31c36b251a6d3ed0dec3f6107e37e81bf3e0629 100644 (file)
 #include <linux/delay.h>
 #include <linux/gfp.h>
 
+struct rom_cmd {
+       uint16_t cmd;
+} rom_cmds[] = {
+       { MBC_LOAD_RAM },
+       { MBC_EXECUTE_FIRMWARE },
+       { MBC_READ_RAM_WORD },
+       { MBC_MAILBOX_REGISTER_TEST },
+       { MBC_VERIFY_CHECKSUM },
+       { MBC_GET_FIRMWARE_VERSION },
+       { MBC_LOAD_RISC_RAM },
+       { MBC_DUMP_RISC_RAM },
+       { MBC_LOAD_RISC_RAM_EXTENDED },
+       { MBC_DUMP_RISC_RAM_EXTENDED },
+       { MBC_WRITE_RAM_WORD_EXTENDED },
+       { MBC_READ_RAM_EXTENDED },
+       { MBC_GET_RESOURCE_COUNTS },
+       { MBC_SET_FIRMWARE_OPTION },
+       { MBC_MID_INITIALIZE_FIRMWARE },
+       { MBC_GET_FIRMWARE_STATE },
+       { MBC_GET_MEM_OFFLOAD_CNTRL_STAT },
+       { MBC_GET_RETRY_COUNT },
+       { MBC_TRACE_CONTROL },
+};
+
+static int is_rom_cmd(uint16_t cmd)
+{
+       int i;
+       struct  rom_cmd *wc;
+
+       for (i = 0; i < ARRAY_SIZE(rom_cmds); i++) {
+               wc = rom_cmds + i;
+               if (wc->cmd == cmd)
+                       return 1;
+       }
+
+       return 0;
+}
 
 /*
  * qla2x00_mailbox_command
@@ -92,6 +129,17 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
                return QLA_FUNCTION_TIMEOUT;
        }
 
+       /* check if ISP abort is active and return cmd with timeout */
+       if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
+           test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
+           test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) &&
+           !is_rom_cmd(mcp->mb[0])) {
+               ql_log(ql_log_info, vha, 0x1005,
+                   "Cmd 0x%x aborted with timeout since ISP Abort is pending\n",
+                   mcp->mb[0]);
+               return QLA_FUNCTION_TIMEOUT;
+       }
+
        /*
         * Wait for active mailbox commands to finish by waiting at most tov
         * 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)
                        WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
+               wait_time = jiffies;
                if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
                    mcp->tov * HZ)) {
                        ql_dbg(ql_dbg_mbx, vha, 0x117a,
@@ -186,6 +235,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
                        clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
                        spin_unlock_irqrestore(&ha->hardware_lock, flags);
                }
+               if (time_after(jiffies, wait_time + 5 * HZ))
+                       ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n",
+                           command, jiffies_to_msecs(jiffies - wait_time));
        } else {
                ql_dbg(ql_dbg_mbx, vha, 0x1011,
                    "Cmd=%x Polling Mode.\n", command);