public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Nicolas Ferre <nicolas.ferre@atmel.com>
To: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Cc: Dan Williams <dan.j.williams@intel.com>,
	linux-kernel@vger.kernel.org,
	Maciej Sosnowski <maciej.sosnowski@intel.com>,
	Haavard Skinnemoen <haavard.skinnemoen@atmel.com>,
	Pierre Ossman <pierre@ossman.eu>
Subject: Re: [PATCH] dmaengine: Move all map_sg/unmap_sg for slave channel to its client
Date: Tue, 25 Aug 2009 18:17:30 +0200	[thread overview]
Message-ID: <4A940E9A.8010807@atmel.com> (raw)
In-Reply-To: <1249012788-965-1-git-send-email-anemo@mba.ocn.ne.jp>

Hi,

Atsushi Nemoto :
> Dan Williams wrote:
> ... DMA-slave clients request specific channels and know the hardware
> details at a low level, so it should not be too high an expectation to
> push dma mapping responsibility to the client.
> 
> Also this patch includes DMA_COMPL_{SRC,DEST}_UNMAP_SINGLE support for
> dw_dmac driver.
> 
> Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>

I have tested it and it is ok.

Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>

> ---
> This patch is against next branch of async_tx tree.
> This patch is not tested.  I appreciate if someone test this patch with those
> devices.
> 
>  drivers/dma/at_hdmac.c       |   43 +++++++++++++++++++++--------------------
>  drivers/dma/dw_dmac.c        |   31 ++++++++++++++++++-----------
>  drivers/mmc/host/atmel-mci.c |    9 +++++++-
>  3 files changed, 49 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
> index 9a1e5fb..3d10525 100644
> --- a/drivers/dma/at_hdmac.c
> +++ b/drivers/dma/at_hdmac.c
> @@ -252,25 +252,28 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
>  	list_move(&desc->desc_node, &atchan->free_list);
>  
>  	/* unmap dma addresses */
> -	if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
> -		if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
> -			dma_unmap_single(chan2parent(&atchan->chan_common),
> -					desc->lli.daddr,
> -					desc->len, DMA_FROM_DEVICE);
> -		else
> -			dma_unmap_page(chan2parent(&atchan->chan_common),
> -					desc->lli.daddr,
> -					desc->len, DMA_FROM_DEVICE);
> -	}
> -	if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
> -		if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
> -			dma_unmap_single(chan2parent(&atchan->chan_common),
> -					desc->lli.saddr,
> -					desc->len, DMA_TO_DEVICE);
> -		else
> -			dma_unmap_page(chan2parent(&atchan->chan_common),
> -					desc->lli.saddr,
> -					desc->len, DMA_TO_DEVICE);
> +	if (!atchan->chan_common.private) {
> +		struct device *parent = chan2parent(&atchan->chan_common);
> +		if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
> +			if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
> +				dma_unmap_single(parent,
> +						desc->lli.daddr,
> +						desc->len, DMA_FROM_DEVICE);
> +			else
> +				dma_unmap_page(parent,
> +						desc->lli.daddr,
> +						desc->len, DMA_FROM_DEVICE);
> +		}
> +		if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
> +			if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
> +				dma_unmap_single(parent,
> +						desc->lli.saddr,
> +						desc->len, DMA_TO_DEVICE);
> +			else
> +				dma_unmap_page(parent,
> +						desc->lli.saddr,
> +						desc->len, DMA_TO_DEVICE);
> +		}
>  	}
>  
>  	/*
> @@ -646,8 +649,6 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
>  
>  	reg_width = atslave->reg_width;
>  
> -	sg_len = dma_map_sg(chan2parent(chan), sgl, sg_len, direction);
> -
>  	ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla;
>  	ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN;
>  
> diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
> index 98c9a84..a5a5050 100644
> --- a/drivers/dma/dw_dmac.c
> +++ b/drivers/dma/dw_dmac.c
> @@ -212,16 +212,25 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc)
>  	list_splice_init(&txd->tx_list, &dwc->free_list);
>  	list_move(&desc->desc_node, &dwc->free_list);
>  
> -	/*
> -	 * We use dma_unmap_page() regardless of how the buffers were
> -	 * mapped before they were submitted...
> -	 */
> -	if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP))
> -		dma_unmap_page(chan2parent(&dwc->chan), desc->lli.dar,
> -			       desc->len, DMA_FROM_DEVICE);
> -	if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP))
> -		dma_unmap_page(chan2parent(&dwc->chan), desc->lli.sar,
> -			       desc->len, DMA_TO_DEVICE);
> +	if (!dwc->chan.private) {
> +		struct device *parent = chan2parent(&dwc->chan);
> +		if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
> +			if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
> +				dma_unmap_single(parent, desc->lli.dar,
> +						desc->len, DMA_FROM_DEVICE);
> +			else
> +				dma_unmap_page(parent, desc->lli.dar,
> +						desc->len, DMA_FROM_DEVICE);
> +		}
> +		if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
> +			if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
> +				dma_unmap_single(parent, desc->lli.sar,
> +						desc->len, DMA_TO_DEVICE);
> +			else
> +				dma_unmap_page(parent, desc->lli.sar,
> +						desc->len, DMA_TO_DEVICE);
> +		}
> +	}
>  
>  	/*
>  	 * The API requires that no submissions are done from a
> @@ -658,8 +667,6 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
>  	reg_width = dws->reg_width;
>  	prev = first = NULL;
>  
> -	sg_len = dma_map_sg(chan2parent(chan), sgl, sg_len, direction);
> -
>  	switch (direction) {
>  	case DMA_TO_DEVICE:
>  		ctllo = (DWC_DEFAULT_CTLLO
> diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
> index cf6a100..2ec3803 100644
> --- a/drivers/mmc/host/atmel-mci.c
> +++ b/drivers/mmc/host/atmel-mci.c
> @@ -574,6 +574,7 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
>  	struct scatterlist		*sg;
>  	unsigned int			i;
>  	enum dma_data_direction		direction;
> +	unsigned int			sglen;
>  
>  	/*
>  	 * We don't do DMA on "complex" transfers, i.e. with
> @@ -603,11 +604,14 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
>  	else
>  		direction = DMA_TO_DEVICE;
>  
> +	sglen = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, direction);
> +	if (sglen != data->sg_len)
> +		goto unmap_exit;
>  	desc = chan->device->device_prep_slave_sg(chan,
>  			data->sg, data->sg_len, direction,
>  			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
>  	if (!desc)
> -		return -ENOMEM;
> +		goto unmap_exit;
>  
>  	host->dma.data_desc = desc;
>  	desc->callback = atmci_dma_complete;
> @@ -618,6 +622,9 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
>  	chan->device->device_issue_pending(chan);
>  
>  	return 0;
> +unmap_exit:
> +	dma_unmap_sg(&host->pdev->dev, data->sg, sglen, direction);
> +	return -ENOMEM;
>  }
>  
>  #else /* CONFIG_MMC_ATMELMCI_DMA */


-- 
Nicolas Ferre


  parent reply	other threads:[~2009-08-25 16:17 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-31  3:59 [PATCH] dmaengine: Move all map_sg/unmap_sg for slave channel to its client Atsushi Nemoto
2009-07-31 12:56 ` Sosnowski, Maciej
2009-08-25 16:17 ` Nicolas Ferre [this message]
2009-08-27 14:33   ` Atsushi Nemoto

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=4A940E9A.8010807@atmel.com \
    --to=nicolas.ferre@atmel.com \
    --cc=anemo@mba.ocn.ne.jp \
    --cc=dan.j.williams@intel.com \
    --cc=haavard.skinnemoen@atmel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maciej.sosnowski@intel.com \
    --cc=pierre@ossman.eu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox