scsi: mpt3sas: Add functions to check if any cmd is outstanding on Target and LUN
authorSuganath Prabu S <suganath-prabu.subramani@broadcom.com>
Thu, 30 Jul 2020 08:03:47 +0000 (13:33 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 21 Aug 2020 01:41:50 +0000 (21:41 -0400)
Add helper functions to check whether any SCSI command is outstanding on
particular Target, LUN device.

Also add function parameters 'channel', 'id' to function
mpt3sas_scsih_issue_tm().

Link: https://lore.kernel.org/r/1596096229-3341-6-git-send-email-suganath-prabu.subramani@broadcom.com
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/mpt3sas/mpt3sas_base.h
drivers/scsi/mpt3sas/mpt3sas_ctl.c
drivers/scsi/mpt3sas/mpt3sas_scsih.c

index d3062de..bd89223 100644 (file)
@@ -1610,11 +1610,12 @@ void mpt3sas_scsih_clear_outstanding_scsi_tm_commands(
        struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_scsih_reset_done_handler(struct MPT3SAS_ADAPTER *ioc);
 
-int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, u64 lun,
-       u8 type, u16 smid_task, u16 msix_task, u8 timeout, u8 tr_method);
+int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
+       uint channel, uint id, u64 lun, u8 type, u16 smid_task,
+       u16 msix_task, u8 timeout, u8 tr_method);
 int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
-       u64 lun, u8 type, u16 smid_task, u16 msix_task,
-       u8 timeout, u8 tr_method);
+       uint channel, uint id, u64 lun, u8 type, u16 smid_task,
+       u16 msix_task, u8 timeout, u8 tr_method);
 
 void mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 void mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
index 4326030..194ac9d 100644 (file)
@@ -1109,13 +1109,15 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
                            pcie_device->device_info))))
                                mpt3sas_scsih_issue_locked_tm(ioc,
                                  le16_to_cpu(mpi_request->FunctionDependent1),
-                                 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
+                                 0, 0, 0,
+                                 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
                                  0, pcie_device->reset_timeout,
                        MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE);
                        else
                                mpt3sas_scsih_issue_locked_tm(ioc,
                                  le16_to_cpu(mpi_request->FunctionDependent1),
-                                 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
+                                 0, 0, 0,
+                                 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
                                  0, 30, MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET);
                } else
                        mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
index 66b29d4..ce12253 100644 (file)
@@ -1513,6 +1513,66 @@ _scsih_is_nvme_pciescsi_device(u32 device_info)
 }
 
 /**
+ * _scsih_scsi_lookup_find_by_target - search for matching channel:id
+ * @ioc: per adapter object
+ * @id: target id
+ * @channel: channel
+ * Context: This function will acquire ioc->scsi_lookup_lock.
+ *
+ * This will search for a matching channel:id in the scsi_lookup array,
+ * returning 1 if found.
+ */
+static u8
+_scsih_scsi_lookup_find_by_target(struct MPT3SAS_ADAPTER *ioc, int id,
+       int channel)
+{
+       int smid;
+       struct scsi_cmnd *scmd;
+
+       for (smid = 1;
+            smid <= ioc->shost->can_queue; smid++) {
+               scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);
+               if (!scmd)
+                       continue;
+               if (scmd->device->id == id &&
+                   scmd->device->channel == channel)
+                       return 1;
+       }
+       return 0;
+}
+
+/**
+ * _scsih_scsi_lookup_find_by_lun - search for matching channel:id:lun
+ * @ioc: per adapter object
+ * @id: target id
+ * @lun: lun number
+ * @channel: channel
+ * Context: This function will acquire ioc->scsi_lookup_lock.
+ *
+ * This will search for a matching channel:id:lun in the scsi_lookup array,
+ * returning 1 if found.
+ */
+static u8
+_scsih_scsi_lookup_find_by_lun(struct MPT3SAS_ADAPTER *ioc, int id,
+       unsigned int lun, int channel)
+{
+       int smid;
+       struct scsi_cmnd *scmd;
+
+       for (smid = 1; smid <= ioc->shost->can_queue; smid++) {
+
+               scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);
+               if (!scmd)
+                       continue;
+               if (scmd->device->id == id &&
+                   scmd->device->channel == channel &&
+                   scmd->device->lun == lun)
+                       return 1;
+       }
+       return 0;
+}
+
+/**
  * mpt3sas_scsih_scsi_lookup_get - returns scmd entry
  * @ioc: per adapter object
  * @smid: system request message index
@@ -2704,6 +2764,8 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
  * mpt3sas_scsih_issue_tm - main routine for sending tm requests
  * @ioc: per adapter struct
  * @handle: device handle
+ * @channel: the channel assigned by the OS
+ * @id: the id assigned by the OS
  * @lun: lun number
  * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
  * @smid_task: smid assigned to the task
@@ -2720,8 +2782,9 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
  * Return: SUCCESS or FAILED.
  */
 int
-mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, u64 lun,
-       u8 type, u16 smid_task, u16 msix_task, u8 timeout, u8 tr_method)
+mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
+       uint id, u64 lun, u8 type, u16 smid_task, u16 msix_task,
+       u8 timeout, u8 tr_method)
 {
        Mpi2SCSITaskManagementRequest_t *mpi_request;
        Mpi2SCSITaskManagementReply_t *mpi_reply;
@@ -2826,14 +2889,14 @@ out:
 }
 
 int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
-               u64 lun, u8 type, u16 smid_task, u16 msix_task,
-               u8 timeout, u8 tr_method)
+               uint channel, uint id, u64 lun, u8 type, u16 smid_task,
+               u16 msix_task, u8 timeout, u8 tr_method)
 {
        int ret;
 
        mutex_lock(&ioc->tm_cmds.mutex);
-       ret = mpt3sas_scsih_issue_tm(ioc, handle, lun, type, smid_task,
-                       msix_task, timeout, tr_method);
+       ret = mpt3sas_scsih_issue_tm(ioc, handle, channel, id, lun, type,
+                       smid_task, msix_task, timeout, tr_method);
        mutex_unlock(&ioc->tm_cmds.mutex);
 
        return ret;
@@ -2980,7 +3043,8 @@ scsih_abort(struct scsi_cmnd *scmd)
        if (pcie_device && (!ioc->tm_custom_handling) &&
            (!(mpt3sas_scsih_is_pcie_scsi_device(pcie_device->device_info))))
                timeout = ioc->nvme_abort_timeout;
-       r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->lun,
+       r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel,
+               scmd->device->id, scmd->device->lun,
                MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
                st->smid, st->msix_io, timeout, 0);
        /* Command must be cleared after abort */
@@ -3056,7 +3120,8 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
        } else
                tr_method = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
 
-       r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->lun,
+       r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel,
+               scmd->device->id, scmd->device->lun,
                MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 0,
                tr_timeout, tr_method);
        /* Check for busy commands after reset */
@@ -3134,7 +3199,8 @@ scsih_target_reset(struct scsi_cmnd *scmd)
                tr_method = MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE;
        } else
                tr_method = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
-       r = mpt3sas_scsih_issue_locked_tm(ioc, handle, 0,
+       r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel,
+               scmd->device->id, 0,
                MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 0,
            tr_timeout, tr_method);
        /* Check for busy commands after reset */
@@ -7530,7 +7596,7 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
                        goto out;
 
                spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-               r = mpt3sas_scsih_issue_tm(ioc, handle, lun,
+               r = mpt3sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
                        MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, st->smid,
                        st->msix_io, 30, 0);
                if (r == FAILED) {
@@ -7571,9 +7637,9 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
                if (ioc->shost_recovery)
                        goto out_no_lock;
 
-               r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->lun,
-                       MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, st->smid,
-                       st->msix_io, 30, 0);
+               r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
+                       sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
+                       st->smid, st->msix_io, 30, 0);
                if (r == FAILED || st->cb_idx != 0xFF) {
                        sdev_printk(KERN_WARNING, sdev,
                            "mpt3sas_scsih_issue_tm: ABORT_TASK: FAILED : "