All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rob Herring <robh@kernel.org>
To: Alan Mikhak <alan.mikhak@sifive.com>
Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
	kishon@ti.com, lorenzo.pieralisi@arm.com, bhelgaas@google.com,
	efremov@linux.com, b.zolnierkie@samsung.com, vidyas@nvidia.com,
	paul.walmsley@sifive.com
Subject: Re: [PATCH] PCI: endpoint: functions/pci-epf-test: Support slave DMA transfer
Date: Thu, 7 May 2020 16:44:18 -0500	[thread overview]
Message-ID: <20200507214418.GA22159@bogus> (raw)
In-Reply-To: <1588379352-22550-1-git-send-email-alan.mikhak@sifive.com>

On Fri, May 01, 2020 at 05:29:12PM -0700, Alan Mikhak wrote:
> From: Alan Mikhak <alan.mikhak@sifive.com>
> 
> Modify pci_epf_test_data_transfer() to also support slave DMA transfers.
> Adds a direction parameter so caller can specify one of the supported DMA
> transfer directions: DMA_MEM_TO_MEM, DMA_MEM_TO_DEV, and DMA_DEV_TO_MEM.
> For DMA_MEM_TO_MEM, the function calls dmaengine_prep_dma_memcpy() as it
> did before. For DMA_MEM_TO_DEV or DMA_DEV_TO_MEM direction, the function
> calls dmaengine_slave_config() to configure the slave channel before it
> calls dmaengine_prep_slave_single().
> 
> Modify existing callers to specify DMA_MEM_TO_MEM since that is the only
> possible option so far. Rename the phys_addr local variable in some of the
> callers for more readability. Tighten some of the timing function calls to
> avoid counting error print time in case of error.

Looks fine, but also needs a user. The last sentence sounds like a 
separate change.

> 
> Signed-off-by: Alan Mikhak <alan.mikhak@sifive.com>
> ---
>  drivers/pci/endpoint/functions/pci-epf-test.c | 67 ++++++++++++++++++---------
>  1 file changed, 44 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
> index 60330f3e3751..1d026682febb 100644
> --- a/drivers/pci/endpoint/functions/pci-epf-test.c
> +++ b/drivers/pci/endpoint/functions/pci-epf-test.c
> @@ -104,25 +104,41 @@ static void pci_epf_test_dma_callback(void *param)
>   * The function returns '0' on success and negative value on failure.
>   */
>  static int pci_epf_test_data_transfer(struct pci_epf_test *epf_test,
> -				      dma_addr_t dma_dst, dma_addr_t dma_src,
> -				      size_t len)
> +				      dma_addr_t dma_dst,
> +				      dma_addr_t dma_src,
> +				      size_t len,
> +				      enum dma_transfer_direction dir)
>  {
>  	enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
>  	struct dma_chan *chan = epf_test->dma_chan;
>  	struct pci_epf *epf = epf_test->epf;
> +	struct dma_slave_config sconf;
>  	struct dma_async_tx_descriptor *tx;
>  	struct device *dev = &epf->dev;
>  	dma_cookie_t cookie;
> +	dma_addr_t buf;
>  	int ret;
>  
>  	if (IS_ERR_OR_NULL(chan)) {
> -		dev_err(dev, "Invalid DMA memcpy channel\n");
> +		dev_err(dev, "Invalid DMA channel\n");
>  		return -EINVAL;
>  	}
>  
> -	tx = dmaengine_prep_dma_memcpy(chan, dma_dst, dma_src, len, flags);
> +	if (dir == DMA_MEM_TO_MEM) {
> +		tx = dmaengine_prep_dma_memcpy(chan, dma_dst, dma_src,
> +					       len, flags);
> +	} else {
> +		memset(&sconf, 0, sizeof(sconf));
> +		sconf.direction = dir;
> +		sconf.dst_addr = dma_dst;
> +		sconf.src_addr = dma_src;
> +		dmaengine_slave_config(chan, &sconf);
> +
> +		buf = (dir == DMA_MEM_TO_DEV) ? dma_dst : dma_src;
> +		tx = dmaengine_prep_slave_single(chan, buf, len, dir, flags);
> +	}
>  	if (!tx) {
> -		dev_err(dev, "Failed to prepare DMA memcpy\n");
> +		dev_err(dev, "Failed to prepare DMA transfer\n");
>  		return -EIO;
>  	}
>  
> @@ -268,7 +284,6 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
>  		goto err_dst_addr;
>  	}
>  
> -	ktime_get_ts64(&start);
>  	use_dma = !!(reg->flags & FLAG_USE_DMA);
>  	if (use_dma) {
>  		if (!epf_test->dma_supported) {
> @@ -277,14 +292,18 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
>  			goto err_map_addr;
>  		}
>  
> +		ktime_get_ts64(&start);
>  		ret = pci_epf_test_data_transfer(epf_test, dst_phys_addr,
> -						 src_phys_addr, reg->size);
> +						 src_phys_addr, reg->size,
> +						 DMA_MEM_TO_MEM);
> +		ktime_get_ts64(&end);
>  		if (ret)
>  			dev_err(dev, "Data transfer failed\n");
>  	} else {
> +		ktime_get_ts64(&start);
>  		memcpy(dst_addr, src_addr, reg->size);
> +		ktime_get_ts64(&end);
>  	}
> -	ktime_get_ts64(&end);
>  	pci_epf_test_print_rate("COPY", reg->size, &start, &end, use_dma);
>  
>  err_map_addr:
> @@ -310,7 +329,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
>  	void *buf;
>  	u32 crc32;
>  	bool use_dma;
> -	phys_addr_t phys_addr;
> +	phys_addr_t src_phys_addr;
>  	phys_addr_t dst_phys_addr;
>  	struct timespec64 start, end;
>  	struct pci_epf *epf = epf_test->epf;
> @@ -319,8 +338,9 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
>  	struct device *dma_dev = epf->epc->dev.parent;
>  	enum pci_barno test_reg_bar = epf_test->test_reg_bar;
>  	struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
> +	enum dma_transfer_direction dir = DMA_MEM_TO_MEM;
>  
> -	src_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size);
> +	src_addr = pci_epc_mem_alloc_addr(epc, &src_phys_addr, reg->size);
>  	if (!src_addr) {
>  		dev_err(dev, "Failed to allocate address\n");
>  		reg->status = STATUS_SRC_ADDR_INVALID;
> @@ -328,7 +348,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
>  		goto err;
>  	}
>  
> -	ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->src_addr,
> +	ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr,
>  			       reg->size);
>  	if (ret) {
>  		dev_err(dev, "Failed to map address\n");
> @@ -360,10 +380,10 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
>  
>  		ktime_get_ts64(&start);
>  		ret = pci_epf_test_data_transfer(epf_test, dst_phys_addr,
> -						 phys_addr, reg->size);
> +						 src_phys_addr, reg->size, dir);
> +		ktime_get_ts64(&end);
>  		if (ret)
>  			dev_err(dev, "Data transfer failed\n");
> -		ktime_get_ts64(&end);
>  
>  		dma_unmap_single(dma_dev, dst_phys_addr, reg->size,
>  				 DMA_FROM_DEVICE);
> @@ -383,10 +403,10 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
>  	kfree(buf);
>  
>  err_map_addr:
> -	pci_epc_unmap_addr(epc, epf->func_no, phys_addr);
> +	pci_epc_unmap_addr(epc, epf->func_no, src_phys_addr);
>  
>  err_addr:
> -	pci_epc_mem_free_addr(epc, phys_addr, src_addr, reg->size);
> +	pci_epc_mem_free_addr(epc, src_phys_addr, src_addr, reg->size);
>  
>  err:
>  	return ret;
> @@ -398,7 +418,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
>  	void __iomem *dst_addr;
>  	void *buf;
>  	bool use_dma;
> -	phys_addr_t phys_addr;
> +	phys_addr_t dst_phys_addr;
>  	phys_addr_t src_phys_addr;
>  	struct timespec64 start, end;
>  	struct pci_epf *epf = epf_test->epf;
> @@ -407,8 +427,9 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
>  	struct device *dma_dev = epf->epc->dev.parent;
>  	enum pci_barno test_reg_bar = epf_test->test_reg_bar;
>  	struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
> +	enum dma_transfer_direction dir = DMA_MEM_TO_MEM;
>  
> -	dst_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size);
> +	dst_addr = pci_epc_mem_alloc_addr(epc, &dst_phys_addr, reg->size);
>  	if (!dst_addr) {
>  		dev_err(dev, "Failed to allocate address\n");
>  		reg->status = STATUS_DST_ADDR_INVALID;
> @@ -416,7 +437,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
>  		goto err;
>  	}
>  
> -	ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->dst_addr,
> +	ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr,
>  			       reg->size);
>  	if (ret) {
>  		dev_err(dev, "Failed to map address\n");
> @@ -450,11 +471,11 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
>  		}
>  
>  		ktime_get_ts64(&start);
> -		ret = pci_epf_test_data_transfer(epf_test, phys_addr,
> -						 src_phys_addr, reg->size);
> +		ret = pci_epf_test_data_transfer(epf_test, dst_phys_addr,
> +						 src_phys_addr,	reg->size, dir);
> +		ktime_get_ts64(&end);
>  		if (ret)
>  			dev_err(dev, "Data transfer failed\n");
> -		ktime_get_ts64(&end);
>  
>  		dma_unmap_single(dma_dev, src_phys_addr, reg->size,
>  				 DMA_TO_DEVICE);
> @@ -476,10 +497,10 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
>  	kfree(buf);
>  
>  err_map_addr:
> -	pci_epc_unmap_addr(epc, epf->func_no, phys_addr);
> +	pci_epc_unmap_addr(epc, epf->func_no, dst_phys_addr);
>  
>  err_addr:
> -	pci_epc_mem_free_addr(epc, phys_addr, dst_addr, reg->size);
> +	pci_epc_mem_free_addr(epc, dst_phys_addr, dst_addr, reg->size);
>  
>  err:
>  	return ret;
> -- 
> 2.7.4
> 

  reply	other threads:[~2020-05-07 21:45 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-02  0:29 [PATCH] PCI: endpoint: functions/pci-epf-test: Support slave DMA transfer Alan Mikhak
2020-05-07 21:44 ` Rob Herring [this message]
2020-05-11 18:02   ` Alan Mikhak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200507214418.GA22159@bogus \
    --to=robh@kernel.org \
    --cc=alan.mikhak@sifive.com \
    --cc=b.zolnierkie@samsung.com \
    --cc=bhelgaas@google.com \
    --cc=efremov@linux.com \
    --cc=kishon@ti.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=paul.walmsley@sifive.com \
    --cc=vidyas@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.