scsi: mpt3sas: Introduce function to clone mpi request.
authorSuganath Prabu Subramani <suganath-prabu.subramani@broadcom.com>
Wed, 7 Feb 2018 10:51:49 +0000 (02:51 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 28 Feb 2018 03:26:15 +0000 (22:26 -0500)
1) Added function _base_clone_mpi_to_sys_mem to clone
MPI request into system BAR0 mapped region.

2) Separate out MPI Endpoint IO submissions to function
_base_put_smid_mpi_ep_scsi_io.

3) MPI EP requests are submitted in two 32 bit MMIO writes.
from _base_mpi_ep_writeq.

 For 32 bit Arch,_base_writeq function is identical
to _base_mpi_ep_writeq, Removed duplicate code as suggested.

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.c

index 484bb98..bb2f2a4 100644 (file)
@@ -126,6 +126,25 @@ module_param_call(mpt3sas_fwfault_debug, _scsih_set_fwfault_debug,
        param_get_int, &mpt3sas_fwfault_debug, 0644);
 
 /**
+ * _base_clone_mpi_to_sys_mem - Writes/copies MPI frames
+ *                             to system/BAR0 region.
+ *
+ * @dst_iomem: Pointer to the destinaltion location in BAR0 space.
+ * @src: Pointer to the Source data.
+ * @size: Size of data to be copied.
+ */
+static void
+_base_clone_mpi_to_sys_mem(void *dst_iomem, void *src, u32 size)
+{
+       int i;
+       u32 *src_virt_mem = (u32 *)src;
+
+       for (i = 0; i < size/4; i++)
+               writel((u32)src_virt_mem[i],
+                               (void __iomem *)dst_iomem + (i * 4));
+}
+
+/**
  * _base_clone_to_sys_mem - Writes/copies data to system/BAR0 region
  *
  * @dst_iomem: Pointer to the destination location in BAR0 space.
@@ -3268,6 +3287,29 @@ mpt3sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 }
 
 /**
+ * _base_mpi_ep_writeq - 32 bit write to MMIO
+ * @b: data payload
+ * @addr: address in MMIO space
+ * @writeq_lock: spin lock
+ *
+ * This special handling for MPI EP to take care of 32 bit
+ * environment where its not quarenteed to send the entire word
+ * in one transfer.
+ */
+static inline void
+_base_mpi_ep_writeq(__u64 b, volatile void __iomem *addr,
+                                       spinlock_t *writeq_lock)
+{
+       unsigned long flags;
+       __u64 data_out = cpu_to_le64(b);
+
+       spin_lock_irqsave(writeq_lock, flags);
+       writel((u32)(data_out), addr);
+       writel((u32)(data_out >> 32), (addr + 4));
+       spin_unlock_irqrestore(writeq_lock, flags);
+}
+
+/**
  * _base_writeq - 64 bit write to MMIO
  * @ioc: per adapter object
  * @b: data payload
@@ -3288,17 +3330,41 @@ _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock)
 static inline void
 _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock)
 {
-       unsigned long flags;
-       __u64 data_out = cpu_to_le64(b);
-
-       spin_lock_irqsave(writeq_lock, flags);
-       writel((u32)(data_out), addr);
-       writel((u32)(data_out >> 32), (addr + 4));
-       spin_unlock_irqrestore(writeq_lock, flags);
+       _base_mpi_ep_writeq(b, addr, writeq_lock);
 }
 #endif
 
 /**
+ * _base_put_smid_mpi_ep_scsi_io - send SCSI_IO request to firmware
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @handle: device handle
+ *
+ * Return nothing.
+ */
+static void
+_base_put_smid_mpi_ep_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 handle)
+{
+       Mpi2RequestDescriptorUnion_t descriptor;
+       u64 *request = (u64 *)&descriptor;
+       void *mpi_req_iomem;
+       __le32 *mfp = (__le32 *)mpt3sas_base_get_msg_frame(ioc, smid);
+
+       _clone_sg_entries(ioc, (void *) mfp, smid);
+       mpi_req_iomem = (void *)ioc->chip +
+                       MPI_FRAME_START_OFFSET + (smid * ioc->request_sz);
+       _base_clone_mpi_to_sys_mem(mpi_req_iomem, (void *)mfp,
+                                       ioc->request_sz);
+       descriptor.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
+       descriptor.SCSIIO.MSIxIndex =  _base_get_msix_index(ioc);
+       descriptor.SCSIIO.SMID = cpu_to_le16(smid);
+       descriptor.SCSIIO.DevHandle = cpu_to_le16(handle);
+       descriptor.SCSIIO.LMID = 0;
+       _base_mpi_ep_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
+           &ioc->scsi_lookup_lock);
+}
+
+/**
  * _base_put_smid_scsi_io - send SCSI_IO request to firmware
  * @ioc: per adapter object
  * @smid: system request message index
@@ -3359,7 +3425,23 @@ _base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
        u16 msix_task)
 {
        Mpi2RequestDescriptorUnion_t descriptor;
-       u64 *request = (u64 *)&descriptor;
+       void *mpi_req_iomem;
+       u64 *request;
+
+       if (ioc->is_mcpu_endpoint) {
+               MPI2RequestHeader_t *request_hdr;
+
+               __le32 *mfp = (__le32 *)mpt3sas_base_get_msg_frame(ioc, smid);
+
+               request_hdr = (MPI2RequestHeader_t *)mfp;
+               /* TBD 256 is offset within sys register. */
+               mpi_req_iomem = (void *)ioc->chip + MPI_FRAME_START_OFFSET
+                                       + (smid * ioc->request_sz);
+               _base_clone_mpi_to_sys_mem(mpi_req_iomem, (void *)mfp,
+                                                       ioc->request_sz);
+       }
+
+       request = (u64 *)&descriptor;
 
        descriptor.HighPriority.RequestFlags =
            MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
@@ -3367,8 +3449,13 @@ _base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
        descriptor.HighPriority.SMID = cpu_to_le16(smid);
        descriptor.HighPriority.LMID = 0;
        descriptor.HighPriority.Reserved1 = 0;
-       _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
-           &ioc->scsi_lookup_lock);
+       if (ioc->is_mcpu_endpoint)
+               _base_mpi_ep_writeq(*request,
+                               &ioc->chip->RequestDescriptorPostLow,
+                               &ioc->scsi_lookup_lock);
+       else
+               _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
+                   &ioc->scsi_lookup_lock);
 }
 
 /**
@@ -3406,15 +3493,35 @@ static void
 _base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 {
        Mpi2RequestDescriptorUnion_t descriptor;
-       u64 *request = (u64 *)&descriptor;
+       void *mpi_req_iomem;
+       u64 *request;
+       MPI2RequestHeader_t *request_hdr;
+
+       if (ioc->is_mcpu_endpoint) {
+               __le32 *mfp = (__le32 *)mpt3sas_base_get_msg_frame(ioc, smid);
+
+               request_hdr = (MPI2RequestHeader_t *)mfp;
 
+               _clone_sg_entries(ioc, (void *) mfp, smid);
+               /* TBD 256 is offset within sys register */
+               mpi_req_iomem = (void *)ioc->chip +
+                       MPI_FRAME_START_OFFSET + (smid * ioc->request_sz);
+               _base_clone_mpi_to_sys_mem(mpi_req_iomem, (void *)mfp,
+                                                       ioc->request_sz);
+       }
+       request = (u64 *)&descriptor;
        descriptor.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
        descriptor.Default.MSIxIndex =  _base_get_msix_index(ioc);
        descriptor.Default.SMID = cpu_to_le16(smid);
        descriptor.Default.LMID = 0;
        descriptor.Default.DescriptorTypeDependent = 0;
-       _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
-           &ioc->scsi_lookup_lock);
+       if (ioc->is_mcpu_endpoint)
+               _base_mpi_ep_writeq(*request,
+                               &ioc->chip->RequestDescriptorPostLow,
+                               &ioc->scsi_lookup_lock);
+       else
+               _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
+                               &ioc->scsi_lookup_lock);
 }
 
 /**
@@ -3508,7 +3615,7 @@ _base_put_smid_nvme_encap_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 
 /**
  * _base_put_smid_default - Default, primarily used for config pages
- *                             use Atomic Request Descriptor
+ * use Atomic Request Descriptor
  * @ioc: per adapter object
  * @smid: system request message index
  *
@@ -6333,7 +6440,10 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
                ioc->put_smid_nvme_encap = &_base_put_smid_nvme_encap_atomic;
        } else {
                ioc->put_smid_default = &_base_put_smid_default;
-               ioc->put_smid_scsi_io = &_base_put_smid_scsi_io;
+               if (ioc->is_mcpu_endpoint)
+                       ioc->put_smid_scsi_io = &_base_put_smid_mpi_ep_scsi_io;
+               else
+                       ioc->put_smid_scsi_io = &_base_put_smid_scsi_io;
                ioc->put_smid_fast_path = &_base_put_smid_fast_path;
                ioc->put_smid_hi_priority = &_base_put_smid_hi_priority;
                ioc->put_smid_nvme_encap = &_base_put_smid_nvme_encap;