Commit f5e6d5a3 authored by Sumit Saxena's avatar Sumit Saxena Committed by Martin K. Petersen

scsi: mpi3mr: Add support for driver commands

There are certain bsg commands which need to be completed by the driver
without involving firmware. These requests are termed driver commands. Add
support for these.

Link: https://lore.kernel.org/r/20220429211641.642010-3-sumit.saxena@broadcom.com
Reported by: Stephen Rothwell <sfr@canb.auug.org.au>
Reported-by: default avatarkernel test robot <lkp@intel.com>
Reviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: default avatarSumit Saxena <sumit.saxena@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 4268fa75
......@@ -38,16 +38,6 @@ struct mpi3_ioc_init_request {
#define MPI3_WHOINIT_ROM_BIOS (0x02)
#define MPI3_WHOINIT_HOST_DRIVER (0x03)
#define MPI3_WHOINIT_MANUFACTURER (0x04)
struct mpi3_driver_info_layout {
__le32 information_length;
u8 driver_signature[12];
u8 os_name[16];
u8 os_version[12];
u8 driver_name[20];
u8 driver_version[32];
u8 driver_release_date[20];
__le32 driver_capabilities;
};
struct mpi3_ioc_facts_request {
__le16 host_tag;
......
......@@ -89,7 +89,7 @@ extern int prot_mask;
/* Reserved Host Tag definitions */
#define MPI3MR_HOSTTAG_INVALID 0xFFFF
#define MPI3MR_HOSTTAG_INITCMDS 1
#define MPI3MR_HOSTTAG_IOCTLCMDS 2
#define MPI3MR_HOSTTAG_BSG_CMDS 2
#define MPI3MR_HOSTTAG_BLK_TMS 5
#define MPI3MR_NUM_DEVRMCMD 16
......@@ -202,10 +202,10 @@ enum mpi3mr_iocstate {
enum mpi3mr_reset_reason {
MPI3MR_RESET_FROM_BRINGUP = 1,
MPI3MR_RESET_FROM_FAULT_WATCH = 2,
MPI3MR_RESET_FROM_IOCTL = 3,
MPI3MR_RESET_FROM_APP = 3,
MPI3MR_RESET_FROM_EH_HOS = 4,
MPI3MR_RESET_FROM_TM_TIMEOUT = 5,
MPI3MR_RESET_FROM_IOCTL_TIMEOUT = 6,
MPI3MR_RESET_FROM_APP_TIMEOUT = 6,
MPI3MR_RESET_FROM_MUR_FAILURE = 7,
MPI3MR_RESET_FROM_CTLR_CLEANUP = 8,
MPI3MR_RESET_FROM_CIACTIV_FAULT = 9,
......@@ -698,6 +698,7 @@ struct scmd_priv {
* @chain_bitmap_sz: Chain buffer allocator bitmap size
* @chain_bitmap: Chain buffer allocator bitmap
* @chain_buf_lock: Chain buffer list lock
* @bsg_cmds: Command tracker for BSG command
* @host_tm_cmds: Command tracker for task management commands
* @dev_rmhs_cmds: Command tracker for device removal commands
* @evtack_cmds: Command tracker for event ack commands
......@@ -729,6 +730,10 @@ struct scmd_priv {
* @requested_poll_qcount: User requested poll queue count
* @bsg_dev: BSG device structure
* @bsg_queue: Request queue for BSG device
* @stop_bsgs: Stop BSG request flag
* @logdata_buf: Circular buffer to store log data entries
* @logdata_buf_idx: Index of entry in buffer to store
* @logdata_entry_sz: log data entry size
*/
struct mpi3mr_ioc {
struct list_head list;
......@@ -835,6 +840,7 @@ struct mpi3mr_ioc {
void *chain_bitmap;
spinlock_t chain_buf_lock;
struct mpi3mr_drv_cmd bsg_cmds;
struct mpi3mr_drv_cmd host_tm_cmds;
struct mpi3mr_drv_cmd dev_rmhs_cmds[MPI3MR_NUM_DEVRMCMD];
struct mpi3mr_drv_cmd evtack_cmds[MPI3MR_NUM_EVTACKCMD];
......@@ -872,6 +878,10 @@ struct mpi3mr_ioc {
struct device *bsg_dev;
struct request_queue *bsg_queue;
u8 stop_bsgs;
u8 *logdata_buf;
u16 logdata_buf_idx;
u16 logdata_entry_sz;
};
/**
......
This diff is collapsed.
......@@ -23,8 +23,8 @@
#define MPI3_DEBUG_RESET 0x00000020
#define MPI3_DEBUG_SCSI_ERROR 0x00000040
#define MPI3_DEBUG_REPLY 0x00000080
#define MPI3_DEBUG_IOCTL_ERROR 0x00008000
#define MPI3_DEBUG_IOCTL_INFO 0x00010000
#define MPI3_DEBUG_BSG_ERROR 0x00008000
#define MPI3_DEBUG_BSG_INFO 0x00010000
#define MPI3_DEBUG_SCSI_INFO 0x00020000
#define MPI3_DEBUG 0x01000000
#define MPI3_DEBUG_SG 0x02000000
......@@ -110,15 +110,15 @@
} while (0)
#define dprint_ioctl_info(ioc, fmt, ...) \
#define dprint_bsg_info(ioc, fmt, ...) \
do { \
if (ioc->logging_level & MPI3_DEBUG_IOCTL_INFO) \
if (ioc->logging_level & MPI3_DEBUG_BSG_INFO) \
pr_info("%s: " fmt, (ioc)->name, ##__VA_ARGS__); \
} while (0)
#define dprint_ioctl_err(ioc, fmt, ...) \
#define dprint_bsg_err(ioc, fmt, ...) \
do { \
if (ioc->logging_level & MPI3_DEBUG_IOCTL_ERROR) \
if (ioc->logging_level & MPI3_DEBUG_BSG_ERROR) \
pr_info("%s: " fmt, (ioc)->name, ##__VA_ARGS__); \
} while (0)
......
......@@ -297,6 +297,8 @@ mpi3mr_get_drv_cmd(struct mpi3mr_ioc *mrioc, u16 host_tag,
switch (host_tag) {
case MPI3MR_HOSTTAG_INITCMDS:
return &mrioc->init_cmds;
case MPI3MR_HOSTTAG_BSG_CMDS:
return &mrioc->bsg_cmds;
case MPI3MR_HOSTTAG_BLK_TMS:
return &mrioc->host_tm_cmds;
case MPI3MR_HOSTTAG_INVALID:
......@@ -865,10 +867,10 @@ static const struct {
} mpi3mr_reset_reason_codes[] = {
{ MPI3MR_RESET_FROM_BRINGUP, "timeout in bringup" },
{ MPI3MR_RESET_FROM_FAULT_WATCH, "fault" },
{ MPI3MR_RESET_FROM_IOCTL, "application invocation" },
{ MPI3MR_RESET_FROM_APP, "application invocation" },
{ MPI3MR_RESET_FROM_EH_HOS, "error handling" },
{ MPI3MR_RESET_FROM_TM_TIMEOUT, "TM timeout" },
{ MPI3MR_RESET_FROM_IOCTL_TIMEOUT, "IOCTL timeout" },
{ MPI3MR_RESET_FROM_APP_TIMEOUT, "application command timeout" },
{ MPI3MR_RESET_FROM_MUR_FAILURE, "MUR failure" },
{ MPI3MR_RESET_FROM_CTLR_CLEANUP, "timeout in controller cleanup" },
{ MPI3MR_RESET_FROM_CIACTIV_FAULT, "component image activation fault" },
......@@ -2813,6 +2815,10 @@ static int mpi3mr_alloc_reply_sense_bufs(struct mpi3mr_ioc *mrioc)
if (!mrioc->init_cmds.reply)
goto out_failed;
mrioc->bsg_cmds.reply = kzalloc(mrioc->reply_sz, GFP_KERNEL);
if (!mrioc->bsg_cmds.reply)
goto out_failed;
for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) {
mrioc->dev_rmhs_cmds[i].reply = kzalloc(mrioc->reply_sz,
GFP_KERNEL);
......@@ -3948,6 +3954,8 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc)
if (mrioc->init_cmds.reply) {
memset(mrioc->init_cmds.reply, 0, sizeof(*mrioc->init_cmds.reply));
memset(mrioc->bsg_cmds.reply, 0,
sizeof(*mrioc->bsg_cmds.reply));
memset(mrioc->host_tm_cmds.reply, 0,
sizeof(*mrioc->host_tm_cmds.reply));
for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++)
......@@ -4050,6 +4058,9 @@ void mpi3mr_free_mem(struct mpi3mr_ioc *mrioc)
kfree(mrioc->init_cmds.reply);
mrioc->init_cmds.reply = NULL;
kfree(mrioc->bsg_cmds.reply);
mrioc->bsg_cmds.reply = NULL;
kfree(mrioc->host_tm_cmds.reply);
mrioc->host_tm_cmds.reply = NULL;
......@@ -4235,6 +4246,8 @@ static void mpi3mr_flush_drv_cmds(struct mpi3mr_ioc *mrioc)
cmdptr = &mrioc->init_cmds;
mpi3mr_drv_cmd_comp_reset(mrioc, cmdptr);
cmdptr = &mrioc->bsg_cmds;
mpi3mr_drv_cmd_comp_reset(mrioc, cmdptr);
cmdptr = &mrioc->host_tm_cmds;
mpi3mr_drv_cmd_comp_reset(mrioc, cmdptr);
......@@ -4258,7 +4271,7 @@ static void mpi3mr_flush_drv_cmds(struct mpi3mr_ioc *mrioc)
* This is an handler for recovering controller by issuing soft
* reset are diag fault reset. This is a blocking function and
* when one reset is executed if any other resets they will be
* blocked. All IOCTLs/IO will be blocked during the reset. If
* blocked. All BSG requests will be blocked during the reset. If
* controller reset is successful then the controller will be
* reinitalized, otherwise the controller will be marked as not
* recoverable
......@@ -4305,6 +4318,7 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
mpi3mr_reset_rc_name(reset_reason));
mrioc->reset_in_progress = 1;
mrioc->stop_bsgs = 1;
mrioc->prev_reset_result = -1;
if ((!snapdump) && (reset_reason != MPI3MR_RESET_FROM_FAULT_WATCH) &&
......@@ -4377,6 +4391,7 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
&mrioc->watchdog_work,
msecs_to_jiffies(MPI3MR_WATCHDOG_INTERVAL));
spin_unlock_irqrestore(&mrioc->watchdog_lock, flags);
mrioc->stop_bsgs = 0;
} else {
mpi3mr_issue_reset(mrioc,
MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT, reset_reason);
......
......@@ -3589,6 +3589,7 @@ static int mpi3mr_scan_finished(struct Scsi_Host *shost,
mpi3mr_start_watchdog(mrioc);
mrioc->is_driver_loading = 0;
mrioc->stop_bsgs = 0;
return 1;
}
......@@ -4259,6 +4260,7 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mutex_init(&mrioc->reset_mutex);
mpi3mr_init_drv_cmd(&mrioc->init_cmds, MPI3MR_HOSTTAG_INITCMDS);
mpi3mr_init_drv_cmd(&mrioc->host_tm_cmds, MPI3MR_HOSTTAG_BLK_TMS);
mpi3mr_init_drv_cmd(&mrioc->bsg_cmds, MPI3MR_HOSTTAG_BSG_CMDS);
for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++)
mpi3mr_init_drv_cmd(&mrioc->dev_rmhs_cmds[i],
......@@ -4271,6 +4273,7 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mrioc->logging_level = logging_level;
mrioc->shost = shost;
mrioc->pdev = pdev;
mrioc->stop_bsgs = 1;
/* init shost parameters */
shost->max_cmd_len = MPI3MR_MAX_CDB_LENGTH;
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment