scsi: mpi3mr: Debug ability improvements
authorRanjan Kumar <ranjan.kumar@broadcom.com>
Wed, 13 Mar 2024 10:07:44 +0000 (15:37 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 25 Mar 2024 22:14:32 +0000 (18:14 -0400)
Update driver to include OS type in fault/reset reason code.  MPI request
sent through ioctl now automatically dumped on timeout.

Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202403081903.q3Dq54zZ-lkp@intel.com/
Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prakash@broadcom.com>
Link: https://lore.kernel.org/r/20240313100746.128951-6-ranjan.kumar@broadcom.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/mpi3mr/mpi3mr.h
drivers/scsi/mpi3mr/mpi3mr_app.c
drivers/scsi/mpi3mr/mpi3mr_fw.c

index 06359915a48d4b8c1daf7c4cc471b92024aa5f6a..dca8390c33ecf5365d259241418a9cf2f6476ba6 100644 (file)
@@ -63,7 +63,7 @@ extern atomic64_t event_counter;
 #define MPI3MR_DRIVER_AUTHOR   "Broadcom Inc. <mpi3mr-linuxdrv.pdl@broadcom.com>"
 #define MPI3MR_DRIVER_DESC     "MPI3 Storage Controller Device Driver"
 
-#define MPI3MR_NAME_LENGTH     32
+#define MPI3MR_NAME_LENGTH     64
 #define IOCNAME                        "%s: "
 
 #define MPI3MR_DEFAULT_MAX_IO_SIZE     (1 * 1024 * 1024)
@@ -294,6 +294,10 @@ enum mpi3mr_reset_reason {
        MPI3MR_RESET_FROM_SAS_TRANSPORT_TIMEOUT = 30,
 };
 
+#define MPI3MR_RESET_REASON_OSTYPE_LINUX       1
+#define MPI3MR_RESET_REASON_OSTYPE_SHIFT       28
+#define MPI3MR_RESET_REASON_IOCNUM_SHIFT       20
+
 /* Queue type definitions */
 enum queue_type {
        MPI3MR_DEFAULT_QUEUE = 0,
@@ -1142,7 +1146,7 @@ struct mpi3mr_ioc {
        spinlock_t fwevt_lock;
        struct list_head fwevt_list;
 
-       char watchdog_work_q_name[20];
+       char watchdog_work_q_name[50];
        struct workqueue_struct *watchdog_work_q;
        struct delayed_work watchdog_work;
        spinlock_t watchdog_lock;
@@ -1336,7 +1340,7 @@ void mpi3mr_start_watchdog(struct mpi3mr_ioc *mrioc);
 void mpi3mr_stop_watchdog(struct mpi3mr_ioc *mrioc);
 
 int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
-                             u32 reset_reason, u8 snapdump);
+                             u16 reset_reason, u8 snapdump);
 void mpi3mr_ioc_disable_intr(struct mpi3mr_ioc *mrioc);
 void mpi3mr_ioc_enable_intr(struct mpi3mr_ioc *mrioc);
 
index 0380996b5ad27aee4740f03431b4157b3526f6bf..38f63bc7ef3bf12d61a792e845eaba52071e75a4 100644 (file)
@@ -1598,26 +1598,33 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
                rval = -EAGAIN;
                if (mrioc->bsg_cmds.state & MPI3MR_CMD_RESET)
                        goto out_unlock;
-               dprint_bsg_err(mrioc,
-                   "%s: bsg request timedout after %d seconds\n", __func__,
-                   karg->timeout);
-               if (mrioc->logging_level & MPI3_DEBUG_BSG_ERROR) {
-                       dprint_dump(mpi_req, MPI3MR_ADMIN_REQ_FRAME_SZ,
+               if (((mpi_header->function != MPI3_FUNCTION_SCSI_IO) &&
+                   (mpi_header->function != MPI3_FUNCTION_NVME_ENCAPSULATED))
+                   || (mrioc->logging_level & MPI3_DEBUG_BSG_ERROR)) {
+                       ioc_info(mrioc, "%s: bsg request timedout after %d seconds\n",
+                           __func__, karg->timeout);
+                       if (!(mrioc->logging_level & MPI3_DEBUG_BSG_INFO)) {
+                               dprint_dump(mpi_req, MPI3MR_ADMIN_REQ_FRAME_SZ,
                            "bsg_mpi3_req");
                        if (mpi_header->function ==
-                           MPI3_BSG_FUNCTION_MGMT_PASSTHROUGH) {
+                           MPI3_FUNCTION_MGMT_PASSTHROUGH) {
                                drv_buf_iter = &drv_bufs[0];
                                dprint_dump(drv_buf_iter->kern_buf,
                                    rmc_size, "mpi3_mgmt_req");
+                               }
                        }
                }
                if ((mpi_header->function == MPI3_BSG_FUNCTION_NVME_ENCAPSULATED) ||
-                   (mpi_header->function == MPI3_BSG_FUNCTION_SCSI_IO))
+                       (mpi_header->function == MPI3_BSG_FUNCTION_SCSI_IO)) {
+                       dprint_bsg_err(mrioc, "%s: bsg request timedout after %d seconds,\n"
+                               "issuing target reset to (0x%04x)\n", __func__,
+                               karg->timeout, mpi_header->function_dependent);
                        mpi3mr_issue_tm(mrioc,
                            MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
                            mpi_header->function_dependent, 0,
                            MPI3MR_HOSTTAG_BLK_TMS, MPI3MR_RESETTM_TIMEOUT,
                            &mrioc->host_tm_cmds, &resp_code, NULL);
+               }
                if (!(mrioc->bsg_cmds.state & MPI3MR_CMD_COMPLETE) &&
                    !(mrioc->bsg_cmds.state & MPI3MR_CMD_RESET))
                        mpi3mr_soft_reset_handler(mrioc,
index ae0e2c6cd2af6b88fdc9335e29a53f8d037bf972..fe5ed1a2b9a3637428383645143f7493b1c44b8e 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/io-64-nonatomic-lo-hi.h>
 
 static int
-mpi3mr_issue_reset(struct mpi3mr_ioc *mrioc, u16 reset_type, u32 reset_reason);
+mpi3mr_issue_reset(struct mpi3mr_ioc *mrioc, u16 reset_type, u16 reset_reason);
 static int mpi3mr_setup_admin_qpair(struct mpi3mr_ioc *mrioc);
 static void mpi3mr_process_factsdata(struct mpi3mr_ioc *mrioc,
        struct mpi3_ioc_facts_data *facts_data);
@@ -1195,7 +1195,7 @@ static inline void mpi3mr_clear_reset_history(struct mpi3mr_ioc *mrioc)
 static int mpi3mr_issue_and_process_mur(struct mpi3mr_ioc *mrioc,
        u32 reset_reason)
 {
-       u32 ioc_config, timeout, ioc_status;
+       u32 ioc_config, timeout, ioc_status, scratch_pad0;
        int retval = -1;
 
        ioc_info(mrioc, "Issuing Message unit Reset(MUR)\n");
@@ -1204,7 +1204,11 @@ static int mpi3mr_issue_and_process_mur(struct mpi3mr_ioc *mrioc,
                return retval;
        }
        mpi3mr_clear_reset_history(mrioc);
-       writel(reset_reason, &mrioc->sysif_regs->scratchpad[0]);
+       scratch_pad0 = ((MPI3MR_RESET_REASON_OSTYPE_LINUX <<
+                        MPI3MR_RESET_REASON_OSTYPE_SHIFT) |
+                       (mrioc->facts.ioc_num <<
+                        MPI3MR_RESET_REASON_IOCNUM_SHIFT) | reset_reason);
+       writel(scratch_pad0, &mrioc->sysif_regs->scratchpad[0]);
        ioc_config = readl(&mrioc->sysif_regs->ioc_configuration);
        ioc_config &= ~MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC;
        writel(ioc_config, &mrioc->sysif_regs->ioc_configuration);
@@ -1520,11 +1524,11 @@ static inline void mpi3mr_set_diagsave(struct mpi3mr_ioc *mrioc)
  * Return: 0 on success, non-zero on failure.
  */
 static int mpi3mr_issue_reset(struct mpi3mr_ioc *mrioc, u16 reset_type,
-       u32 reset_reason)
+       u16 reset_reason)
 {
        int retval = -1;
        u8 unlock_retry_count = 0;
-       u32 host_diagnostic, ioc_status, ioc_config;
+       u32 host_diagnostic, ioc_status, ioc_config, scratch_pad0;
        u32 timeout = MPI3MR_RESET_ACK_TIMEOUT * 10;
 
        if ((reset_type != MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET) &&
@@ -1576,6 +1580,9 @@ static int mpi3mr_issue_reset(struct mpi3mr_ioc *mrioc, u16 reset_type,
                    unlock_retry_count, host_diagnostic);
        } while (!(host_diagnostic & MPI3_SYSIF_HOST_DIAG_DIAG_WRITE_ENABLE));
 
+       scratch_pad0 = ((MPI3MR_RESET_REASON_OSTYPE_LINUX <<
+           MPI3MR_RESET_REASON_OSTYPE_SHIFT) | (mrioc->facts.ioc_num <<
+           MPI3MR_RESET_REASON_IOCNUM_SHIFT) | reset_reason);
        writel(reset_reason, &mrioc->sysif_regs->scratchpad[0]);
        writel(host_diagnostic | reset_type,
            &mrioc->sysif_regs->host_diagnostic);
@@ -2581,7 +2588,7 @@ static void mpi3mr_watchdog_work(struct work_struct *work)
        unsigned long flags;
        enum mpi3mr_iocstate ioc_state;
        u32 fault, host_diagnostic, ioc_status;
-       u32 reset_reason = MPI3MR_RESET_FROM_FAULT_WATCH;
+       u16 reset_reason = MPI3MR_RESET_FROM_FAULT_WATCH;
 
        if (mrioc->reset_in_progress)
                return;
@@ -4968,7 +4975,7 @@ cleanup_drv_cmd:
  * Return: 0 on success, non-zero on failure.
  */
 int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
-       u32 reset_reason, u8 snapdump)
+       u16 reset_reason, u8 snapdump)
 {
        int retval = 0, i;
        unsigned long flags;