Hi tomas, We have sent V1 version of patches on 7th of Feb. Please review. Thanks, Suganath Prabu S On Mon, Jan 22, 2018 at 8:08 PM, Tomas Henzl <thenzl@xxxxxxxxxx> wrote: > On 01/19/2018 01:37 PM, Suganath Prabu S wrote: >> 1) Added function _base_clone_mpi_to_sys_mem to clone >> MPI request into system BAR0 mapped region. >> >> 2) Seperate 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. >> >> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@xxxxxxxxxxxx> >> --- >> drivers/scsi/mpt3sas/mpt3sas_base.c | 131 +++++++++++++++++++++++++++++++++--- >> 1 file changed, 123 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c >> index 40a1806..0248058 100644 >> --- a/drivers/scsi/mpt3sas/mpt3sas_base.c >> +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c >> @@ -126,6 +126,24 @@ 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; >> + __le32 *src_virt_mem = (__le32 *)src; >> + >> + for (i = 0; i < size/4; i++) >> + writel(cpu_to_le32(src_virt_mem[i]), dst_iomem + (i * 4)); >> +} >> + >> +/** >> * _base_clone_to_sys_mem - Writes/copies data to system/BAR0 region >> * >> * @dst_iomem: Pointer to the destinaltion location in BAR0 space. >> @@ -3265,6 +3283,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. > > Hi Suganath, > so is a single writeq possible ? There already is a _base_writeq function > which seems to be identical to _base_mpi_ep_writeq. > Also you may want to add a mmiowb() call. > tomash > >> + */ >> +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 >> @@ -3296,6 +3337,36 @@ _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *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 >> @@ -3356,7 +3427,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; >> @@ -3364,8 +3451,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); >> } >> >> /** >> @@ -3403,15 +3495,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); >> } >> >> /** >> @@ -3505,7 +3617,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 >> * >> @@ -6330,7 +6442,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; > >