* [PATCH] dmaengine: Move all map_sg/unmap_sg for slave channel to its client
@ 2009-07-31 3:59 Atsushi Nemoto
2009-07-31 12:56 ` Sosnowski, Maciej
2009-08-25 16:17 ` Nicolas Ferre
0 siblings, 2 replies; 4+ messages in thread
From: Atsushi Nemoto @ 2009-07-31 3:59 UTC (permalink / raw)
To: Dan Williams
Cc: linux-kernel, Maciej Sosnowski, Nicolas Ferre, Haavard Skinnemoen,
Pierre Ossman
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>
---
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 */
--
1.5.6.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* RE: [PATCH] dmaengine: Move all map_sg/unmap_sg for slave channel to its client
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
1 sibling, 0 replies; 4+ messages in thread
From: Sosnowski, Maciej @ 2009-07-31 12:56 UTC (permalink / raw)
To: Atsushi Nemoto, Williams, Dan J
Cc: linux-kernel@vger.kernel.org, Nicolas Ferre, Haavard Skinnemoen,
Pierre Ossman
Atsushi Nemoto wrote:
> 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>
> ---
The patch looks fine to me.
Acked-by: Maciej Sosnowski <maciej.sosnowski@intel.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] dmaengine: Move all map_sg/unmap_sg for slave channel to its client
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
2009-08-27 14:33 ` Atsushi Nemoto
1 sibling, 1 reply; 4+ messages in thread
From: Nicolas Ferre @ 2009-08-25 16:17 UTC (permalink / raw)
To: Atsushi Nemoto
Cc: Dan Williams, linux-kernel, Maciej Sosnowski, Haavard Skinnemoen,
Pierre Ossman
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
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] dmaengine: Move all map_sg/unmap_sg for slave channel to its client
2009-08-25 16:17 ` Nicolas Ferre
@ 2009-08-27 14:33 ` Atsushi Nemoto
0 siblings, 0 replies; 4+ messages in thread
From: Atsushi Nemoto @ 2009-08-27 14:33 UTC (permalink / raw)
To: nicolas.ferre
Cc: dan.j.williams, linux-kernel, maciej.sosnowski,
haavard.skinnemoen, pierre
On Tue, 25 Aug 2009 18:17:30 +0200, Nicolas Ferre <nicolas.ferre@atmel.com> wrote:
> > 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>
Thank you for testing and good news!
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-08-27 14:38 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
2009-08-27 14:33 ` Atsushi Nemoto
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox