diff mbox

[5/6] mpt3sas: Introduce function to clone mpi request.

Message ID 1516365462-14708-6-git-send-email-suganath-prabu.subramani@broadcom.com (mailing list archive)
State Changes Requested
Headers show

Commit Message

Suganath Prabu S Jan. 19, 2018, 12:37 p.m. UTC
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@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 131 +++++++++++++++++++++++++++++++++---
 1 file changed, 123 insertions(+), 8 deletions(-)

Comments

kernel test robot Jan. 20, 2018, 6:38 p.m. UTC | #1
Hi Suganath,

I love your patch! Perhaps something to improve:

[auto build test WARNING on scsi/for-next]
[also build test WARNING on v4.15-rc8 next-20180119]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Suganath-Prabu-S/mpt3sas-Add-PCI-device-ID-for-Andromeda/20180121-002454
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   drivers/scsi/mpt3sas/mpt3sas_base.c:143:24: sparse: cast from restricted __le32
   drivers/scsi/mpt3sas/mpt3sas_base.c:143:24: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int val @@ got restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:143:24: expected unsigned int val
   drivers/scsi/mpt3sas/mpt3sas_base.c:143:24: got restricted __le32 <noident>
   drivers/scsi/mpt3sas/mpt3sas_base.c:143:64: sparse: incorrect type in argument 2 (different address spaces) @@ expected void volatile @@ got @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:143:64: expected void volatile
   drivers/scsi/mpt3sas/mpt3sas_base.c:143:64: got void COPYING CREDITS Documentation Kbuild Kconfig MAINTAINERS Makefile README arch block certs crypto drivers firmware fs include init ipc kernel lib mm net samples scripts security sound tools usr virt
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:24: sparse: cast from restricted __le32
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:24: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int val @@ got restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:24: expected unsigned int val
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:24: got restricted __le32 <noident>
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:64: sparse: incorrect type in argument 2 (different address spaces) @@ expected void volatile @@ got @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:64: expected void volatile
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:64: got void COPYING CREDITS Documentation Kbuild Kconfig MAINTAINERS Makefile README arch block certs crypto drivers firmware fs include init ipc kernel lib mm net samples scripts security sound tools usr virt
   drivers/scsi/mpt3sas/mpt3sas_base.c:180:24: sparse: cast removes address space of expression
   drivers/scsi/mpt3sas/mpt3sas_base.c:333:24: sparse: undefined identifier 'mpt3sas_scsih_scsi_lookup_get'
   drivers/scsi/mpt3sas/mpt3sas_base.c:1182:42: sparse: incorrect type in assignment (different base types) @@ expected unsigned short Event @@ got short Event @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:1183:49: sparse: incorrect type in assignment (different base types) @@ expected unsigned int EventContext @@ got ed int EventContext @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:1401:64: sparse: incorrect type in argument 2 (different address spaces) @@ expected void volatile @@ got oid volatile @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:1450:52: sparse: incorrect type in argument 2 (different address spaces) @@ expected void volatile @@ got oid volatile @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:2982:32: sparse: cast removes address space of expression
   drivers/scsi/mpt3sas/mpt3sas_base.c:3330:26: sparse: cast removes address space of expression
>> drivers/scsi/mpt3sas/mpt3sas_base.c:3274:26: sparse: incorrect type in initializer (different base types) @@ expected unsigned long long data_out @@ got g long data_out @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3297:16: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned long val @@ got restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3297:16: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned long val @@ got restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3414:34: sparse: cast removes address space of expression
>> drivers/scsi/mpt3sas/mpt3sas_base.c:3274:26: sparse: incorrect type in initializer (different base types) @@ expected unsigned long long data_out @@ got g long data_out @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3297:16: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned long val @@ got restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3297:16: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned long val @@ got restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3483:34: sparse: cast removes address space of expression
>> drivers/scsi/mpt3sas/mpt3sas_base.c:3274:26: sparse: incorrect type in initializer (different base types) @@ expected unsigned long long data_out @@ got g long data_out @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3297:16: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned long val @@ got restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3523:16: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int val @@ got restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3545:16: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int val @@ got restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3568:16: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int val @@ got restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3589:16: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int val @@ got restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3610:16: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int val @@ got restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:5062:24: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int val @@ got restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:5083:20: sparse: cast to restricted __le16
   drivers/scsi/mpt3sas/mpt3sas_base.c:5092:20: sparse: cast to restricted __le16
   drivers/scsi/mpt3sas/mpt3sas_base.c:5106:36: sparse: cast to restricted __le16
   drivers/scsi/mpt3sas/mpt3sas_base.c:6287:55: sparse: incorrect type in argument 2 (different address spaces) @@ expected void volatile @@ got oid volatile @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:333:53: sparse: call with no type!
   drivers/scsi/mpt3sas/mpt3sas_base.c: In function '_clone_sg_entries':
   drivers/scsi/mpt3sas/mpt3sas_base.c:333:10: error: implicit declaration of function 'mpt3sas_scsih_scsi_lookup_get'; did you mean
    scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    mpt3sas_scsih_issue_locked_tm
   drivers/scsi/mpt3sas/mpt3sas_base.c:333:8: warning: assignment makes pointer from integer without a cast
    scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);
    ^
   cc1: some warnings being treated as errors

vim +3274 drivers/scsi/mpt3sas/mpt3sas_base.c

  3258	
  3259	/**
  3260	 * _base_mpi_ep_writeq - 32 bit write to MMIO
  3261	 * @b: data payload
  3262	 * @addr: address in MMIO space
  3263	 * @writeq_lock: spin lock
  3264	 *
  3265	 * This special handling for MPI EP to take care of 32 bit
  3266	 * environment where its not quarenteed to send the entire word
  3267	 * in one transfer.
  3268	 */
  3269	static inline void
  3270	_base_mpi_ep_writeq(__u64 b, volatile void __iomem *addr,
  3271						spinlock_t *writeq_lock)
  3272	{
  3273		unsigned long flags;
> 3274		__u64 data_out = cpu_to_le64(b);
  3275	
  3276		spin_lock_irqsave(writeq_lock, flags);
  3277		writel((u32)(data_out), addr);
  3278		writel((u32)(data_out >> 32), (addr + 4));
  3279		spin_unlock_irqrestore(writeq_lock, flags);
  3280	}
  3281	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Tomas Henzl Jan. 22, 2018, 2:38 p.m. UTC | #2
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@broadcom.com>
> ---
>  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;
Suganath Prabu S Feb. 23, 2018, 10:15 a.m. UTC | #3
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@redhat.com> 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@broadcom.com>
>> ---
>>  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;
>
>
diff mbox

Patch

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.
+ */
+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;