All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFCv3 0/4] dma: add support for scatterlist to scatterlist copy
@ 2010-09-27 22:57 Ira W. Snyder
  2010-09-27 22:57 ` [PATCH 1/4] " Ira W. Snyder
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Ira W. Snyder @ 2010-09-27 22:57 UTC (permalink / raw)
  To: linux-kernel; +Cc: Dan Williams, linuxppc-dev

This series adds support for scatterlist to scatterlist copies to the
generic DMAEngine API. Both the fsldma and ste_dma40 drivers currently
implement a similar API using different, non-generic methods. This series
converts both of them to the new, standardized API.

By doing this as part of the core DMAEngine API, the individual drivers
have control over how to chain their descriptors together. This is
different to the previous implementation, which called
device_prep_dma_memcpy() multiple times.

Neither implementation has been tested on real hardware. I attempted a
conversion of the ste_dma40 driver which should do the right thing, but the
authors should check and make sure.

Ira W. Snyder (4):
  dma: add support for scatterlist to scatterlist copy
  fsldma: implement support for scatterlist to scatterlist copy
  fsldma: remove DMA_SLAVE support
  ste_dma40: implement support for scatterlist to scatterlist copy

 arch/powerpc/include/asm/fsldma.h |  115 ++------------
 drivers/dma/dmaengine.c           |    2 +
 drivers/dma/fsldma.c              |  321 +++++++++++++++++--------------------
 drivers/dma/ste_dma40.c           |   17 ++
 include/linux/dmaengine.h         |    6 +
 5 files changed, 185 insertions(+), 276 deletions(-)


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/4] dma: add support for scatterlist to scatterlist copy
  2010-09-27 22:57 [PATCH RFCv3 0/4] dma: add support for scatterlist to scatterlist copy Ira W. Snyder
@ 2010-09-27 22:57 ` Ira W. Snyder
  2010-09-27 22:57 ` [PATCH 2/4] fsldma: implement " Ira W. Snyder
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Ira W. Snyder @ 2010-09-27 22:57 UTC (permalink / raw)
  To: linux-kernel; +Cc: Dan Williams, linuxppc-dev

This adds support for scatterlist to scatterlist DMA transfers. A
similar interface is exposed by the fsldma driver (through the DMA_SLAVE
API) and by the ste_dma40 driver (through an exported function).

This patch paves the way for making this type of copy operation a part
of the generic DMAEngine API. Futher patches will add support in
individual drivers.

Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
---
 drivers/dma/dmaengine.c   |    2 ++
 include/linux/dmaengine.h |    6 ++++++
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 9d31d5e..db403b8 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -690,6 +690,8 @@ int dma_async_device_register(struct dma_device *device)
 		!device->device_prep_dma_memset);
 	BUG_ON(dma_has_cap(DMA_INTERRUPT, device->cap_mask) &&
 		!device->device_prep_dma_interrupt);
+	BUG_ON(dma_has_cap(DMA_SG, device->cap_mask) &&
+		!device->device_prep_dma_sg);
 	BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) &&
 		!device->device_prep_slave_sg);
 	BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) &&
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index c61d4ca..7c44620 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -64,6 +64,7 @@ enum dma_transaction_type {
 	DMA_PQ_VAL,
 	DMA_MEMSET,
 	DMA_INTERRUPT,
+	DMA_SG,
 	DMA_PRIVATE,
 	DMA_ASYNC_TX,
 	DMA_SLAVE,
@@ -473,6 +474,11 @@ struct dma_device {
 		unsigned long flags);
 	struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)(
 		struct dma_chan *chan, unsigned long flags);
+	struct dma_async_tx_descriptor *(*device_prep_dma_sg)(
+		struct dma_chan *chan,
+		struct scatterlist *dst_sg, unsigned int dst_nents,
+		struct scatterlist *src_sg, unsigned int src_nents,
+		unsigned long flags);
 
 	struct dma_async_tx_descriptor *(*device_prep_slave_sg)(
 		struct dma_chan *chan, struct scatterlist *sgl,
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/4] fsldma: implement support for scatterlist to scatterlist copy
  2010-09-27 22:57 [PATCH RFCv3 0/4] dma: add support for scatterlist to scatterlist copy Ira W. Snyder
  2010-09-27 22:57 ` [PATCH 1/4] " Ira W. Snyder
@ 2010-09-27 22:57 ` Ira W. Snyder
  2010-09-27 22:57 ` [PATCH 3/4] fsldma: remove DMA_SLAVE support Ira W. Snyder
  2010-09-27 22:57   ` Ira W. Snyder
  3 siblings, 0 replies; 14+ messages in thread
From: Ira W. Snyder @ 2010-09-27 22:57 UTC (permalink / raw)
  To: linux-kernel; +Cc: Dan Williams, linuxppc-dev

Now that the DMAEngine API has support for scatterlist to scatterlist
copy, implement support for the Freescale DMA controller.

Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
---
 drivers/dma/fsldma.c |  128 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 125 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index cea08be..1ed29d1 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -38,6 +38,8 @@
 #include <asm/fsldma.h>
 #include "fsldma.h"
 
+static const char msg_ld_oom[] = "No free memory for link descriptor\n";
+
 static void dma_init(struct fsldma_chan *chan)
 {
 	/* Reset the channel */
@@ -499,7 +501,7 @@ fsl_dma_prep_interrupt(struct dma_chan *dchan, unsigned long flags)
 
 	new = fsl_dma_alloc_descriptor(chan);
 	if (!new) {
-		dev_err(chan->dev, "No free memory for link descriptor\n");
+		dev_err(chan->dev, msg_ld_oom);
 		return NULL;
 	}
 
@@ -536,8 +538,7 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
 		/* Allocate the link descriptor from DMA pool */
 		new = fsl_dma_alloc_descriptor(chan);
 		if (!new) {
-			dev_err(chan->dev,
-					"No free memory for link descriptor\n");
+			dev_err(chan->dev, msg_ld_oom);
 			goto fail;
 		}
 #ifdef FSL_DMA_LD_DEBUG
@@ -583,6 +584,125 @@ fail:
 	return NULL;
 }
 
+static struct dma_async_tx_descriptor *fsl_dma_prep_sg(struct dma_chan *dchan,
+	struct scatterlist *dst_sg, unsigned int dst_nents,
+	struct scatterlist *src_sg, unsigned int src_nents,
+	unsigned long flags)
+{
+	struct fsl_desc_sw *first = NULL, *prev = NULL, *new = NULL;
+	struct fsldma_chan *chan = to_fsl_chan(dchan);
+	size_t dst_avail, src_avail;
+	dma_addr_t dst, src;
+	size_t len;
+
+	/* basic sanity checks */
+	if (dst_nents == 0 || src_nents == 0)
+		return NULL;
+
+	if (dst_sg == NULL || src_sg == NULL)
+		return NULL;
+
+	/*
+	 * TODO: should we check that both scatterlists have the same
+	 * TODO: number of bytes in total? Is that really an error?
+	 */
+
+	/* get prepared for the loop */
+	dst_avail = sg_dma_len(dst_sg);
+	src_avail = sg_dma_len(src_sg);
+
+	/* run until we are out of scatterlist entries */
+	while (true) {
+
+		/* create the largest transaction possible */
+		len = min_t(size_t, src_avail, dst_avail);
+		len = min_t(size_t, len, FSL_DMA_BCR_MAX_CNT);
+		if (len == 0)
+			goto fetch;
+
+		dst = sg_dma_address(dst_sg) + sg_dma_len(dst_sg) - dst_avail;
+		src = sg_dma_address(src_sg) + sg_dma_len(src_sg) - src_avail;
+
+		/* allocate and populate the descriptor */
+		new = fsl_dma_alloc_descriptor(chan);
+		if (!new) {
+			dev_err(chan->dev, msg_ld_oom);
+			goto fail;
+		}
+#ifdef FSL_DMA_LD_DEBUG
+		dev_dbg(chan->dev, "new link desc alloc %p\n", new);
+#endif
+
+		set_desc_cnt(chan, &new->hw, len);
+		set_desc_src(chan, &new->hw, src);
+		set_desc_dst(chan, &new->hw, dst);
+
+		if (!first)
+			first = new;
+		else
+			set_desc_next(chan, &prev->hw, new->async_tx.phys);
+
+		new->async_tx.cookie = 0;
+		async_tx_ack(&new->async_tx);
+		prev = new;
+
+		/* Insert the link descriptor to the LD ring */
+		list_add_tail(&new->node, &first->tx_list);
+
+		/* update metadata */
+		dst_avail -= len;
+		src_avail -= len;
+
+fetch:
+		/* fetch the next dst scatterlist entry */
+		if (dst_avail == 0) {
+
+			/* no more entries: we're done */
+			if (dst_nents == 0)
+				break;
+
+			/* fetch the next entry: if there are no more: done */
+			dst_sg = sg_next(dst_sg);
+			if (dst_sg == NULL)
+				break;
+
+			dst_nents--;
+			dst_avail = sg_dma_len(dst_sg);
+		}
+
+		/* fetch the next src scatterlist entry */
+		if (src_avail == 0) {
+
+			/* no more entries: we're done */
+			if (src_nents == 0)
+				break;
+
+			/* fetch the next entry: if there are no more: done */
+			src_sg = sg_next(src_sg);
+			if (src_sg == NULL)
+				break;
+
+			src_nents--;
+			src_avail = sg_dma_len(src_sg);
+		}
+	}
+
+	new->async_tx.flags = flags; /* client is in control of this ack */
+	new->async_tx.cookie = -EBUSY;
+
+	/* Set End-of-link to the last link descriptor of new list */
+	set_ld_eol(chan, new);
+
+	return &first->async_tx;
+
+fail:
+	if (!first)
+		return NULL;
+
+	fsldma_free_desc_list_reverse(chan, &first->tx_list);
+	return NULL;
+}
+
 /**
  * fsl_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction
  * @chan: DMA channel
@@ -1327,11 +1447,13 @@ static int __devinit fsldma_of_probe(struct platform_device *op,
 
 	dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask);
 	dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask);
+	dma_cap_set(DMA_SG, fdev->common.cap_mask);
 	dma_cap_set(DMA_SLAVE, fdev->common.cap_mask);
 	fdev->common.device_alloc_chan_resources = fsl_dma_alloc_chan_resources;
 	fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources;
 	fdev->common.device_prep_dma_interrupt = fsl_dma_prep_interrupt;
 	fdev->common.device_prep_dma_memcpy = fsl_dma_prep_memcpy;
+	fdev->common.device_prep_dma_sg = fsl_dma_prep_sg;
 	fdev->common.device_tx_status = fsl_tx_status;
 	fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending;
 	fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/4] fsldma: remove DMA_SLAVE support
  2010-09-27 22:57 [PATCH RFCv3 0/4] dma: add support for scatterlist to scatterlist copy Ira W. Snyder
  2010-09-27 22:57 ` [PATCH 1/4] " Ira W. Snyder
  2010-09-27 22:57 ` [PATCH 2/4] fsldma: implement " Ira W. Snyder
@ 2010-09-27 22:57 ` Ira W. Snyder
  2010-09-29 21:52     ` Dan Williams
  2010-09-27 22:57   ` Ira W. Snyder
  3 siblings, 1 reply; 14+ messages in thread
From: Ira W. Snyder @ 2010-09-27 22:57 UTC (permalink / raw)
  To: linux-kernel; +Cc: Dan Williams, linuxppc-dev

Now that the generic DMAEngine API has support for scatterlist to
scatterlist copying, this implementation of the DMA_SLAVE API is no
longer necessary.

In order to let device_control() continue to function, a stub
device_prep_slave_sg() function is provided. This allows custom device
configuration, such as enabling external control.

Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
---
 arch/powerpc/include/asm/fsldma.h |  115 ++------------------
 drivers/dma/fsldma.c              |  219 +++++++------------------------------
 2 files changed, 48 insertions(+), 286 deletions(-)

diff --git a/arch/powerpc/include/asm/fsldma.h b/arch/powerpc/include/asm/fsldma.h
index debc5ed..dc0bd27 100644
--- a/arch/powerpc/include/asm/fsldma.h
+++ b/arch/powerpc/include/asm/fsldma.h
@@ -1,7 +1,7 @@
 /*
  * Freescale MPC83XX / MPC85XX DMA Controller
  *
- * Copyright (c) 2009 Ira W. Snyder <iws@ovro.caltech.edu>
+ * Copyright (c) 2009-2010 Ira W. Snyder <iws@ovro.caltech.edu>
  *
  * This file is licensed under the terms of the GNU General Public License
  * version 2. This program is licensed "as is" without any warranty of any
@@ -11,127 +11,32 @@
 #ifndef __ARCH_POWERPC_ASM_FSLDMA_H__
 #define __ARCH_POWERPC_ASM_FSLDMA_H__
 
-#include <linux/slab.h>
 #include <linux/dmaengine.h>
 
 /*
- * Definitions for the Freescale DMA controller's DMA_SLAVE implemention
+ * The Freescale DMA controller has several features that are not accomodated
+ * in the Linux DMAEngine API. Therefore, the generic structure is expanded
+ * to allow drivers to use these features.
  *
- * The Freescale DMA_SLAVE implementation was designed to handle many-to-many
- * transfers. An example usage would be an accelerated copy between two
- * scatterlists. Another example use would be an accelerated copy from
- * multiple non-contiguous device buffers into a single scatterlist.
+ * This structure should be passed into the DMAEngine routine device_control()
+ * as in this example:
  *
- * A DMA_SLAVE transaction is defined by a struct fsl_dma_slave. This
- * structure contains a list of hardware addresses that should be copied
- * to/from the scatterlist passed into device_prep_slave_sg(). The structure
- * also has some fields to enable hardware-specific features.
+ * chan->device->device_control(chan, DMA_SLAVE_CONFIG, (unsigned long)cfg);
  */
 
 /**
- * struct fsl_dma_hw_addr
- * @entry: linked list entry
- * @address: the hardware address
- * @length: length to transfer
- *
- * Holds a single physical hardware address / length pair for use
- * with the DMAEngine DMA_SLAVE API.
- */
-struct fsl_dma_hw_addr {
-	struct list_head entry;
-
-	dma_addr_t address;
-	size_t length;
-};
-
-/**
  * struct fsl_dma_slave
- * @addresses: a linked list of struct fsl_dma_hw_addr structures
+ * @config: the standard Linux DMAEngine API DMA_SLAVE configuration
  * @request_count: value for DMA request count
- * @src_loop_size: setup and enable constant source-address DMA transfers
- * @dst_loop_size: setup and enable constant destination address DMA transfers
  * @external_start: enable externally started DMA transfers
  * @external_pause: enable externally paused DMA transfers
- *
- * Holds a list of address / length pairs for use with the DMAEngine
- * DMA_SLAVE API implementation for the Freescale DMA controller.
  */
-struct fsl_dma_slave {
+struct fsldma_slave_config {
+	struct dma_slave_config config;
 
-	/* List of hardware address/length pairs */
-	struct list_head addresses;
-
-	/* Support for extra controller features */
 	unsigned int request_count;
-	unsigned int src_loop_size;
-	unsigned int dst_loop_size;
 	bool external_start;
 	bool external_pause;
 };
 
-/**
- * fsl_dma_slave_append - add an address/length pair to a struct fsl_dma_slave
- * @slave: the &struct fsl_dma_slave to add to
- * @address: the hardware address to add
- * @length: the length of bytes to transfer from @address
- *
- * Add a hardware address/length pair to a struct fsl_dma_slave. Returns 0 on
- * success, -ERRNO otherwise.
- */
-static inline int fsl_dma_slave_append(struct fsl_dma_slave *slave,
-				       dma_addr_t address, size_t length)
-{
-	struct fsl_dma_hw_addr *addr;
-
-	addr = kzalloc(sizeof(*addr), GFP_ATOMIC);
-	if (!addr)
-		return -ENOMEM;
-
-	INIT_LIST_HEAD(&addr->entry);
-	addr->address = address;
-	addr->length = length;
-
-	list_add_tail(&addr->entry, &slave->addresses);
-	return 0;
-}
-
-/**
- * fsl_dma_slave_free - free a struct fsl_dma_slave
- * @slave: the struct fsl_dma_slave to free
- *
- * Free a struct fsl_dma_slave and all associated address/length pairs
- */
-static inline void fsl_dma_slave_free(struct fsl_dma_slave *slave)
-{
-	struct fsl_dma_hw_addr *addr, *tmp;
-
-	if (slave) {
-		list_for_each_entry_safe(addr, tmp, &slave->addresses, entry) {
-			list_del(&addr->entry);
-			kfree(addr);
-		}
-
-		kfree(slave);
-	}
-}
-
-/**
- * fsl_dma_slave_alloc - allocate a struct fsl_dma_slave
- * @gfp: the flags to pass to kmalloc when allocating this structure
- *
- * Allocate a struct fsl_dma_slave for use by the DMA_SLAVE API. Returns a new
- * struct fsl_dma_slave on success, or NULL on failure.
- */
-static inline struct fsl_dma_slave *fsl_dma_slave_alloc(gfp_t gfp)
-{
-	struct fsl_dma_slave *slave;
-
-	slave = kzalloc(sizeof(*slave), gfp);
-	if (!slave)
-		return NULL;
-
-	INIT_LIST_HEAD(&slave->addresses);
-	return slave;
-}
-
 #endif /* __ARCH_POWERPC_ASM_FSLDMA_H__ */
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 1ed29d1..d3ce25b 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -719,207 +719,64 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_slave_sg(
 	struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
 	enum dma_data_direction direction, unsigned long flags)
 {
-	struct fsldma_chan *chan;
-	struct fsl_desc_sw *first = NULL, *prev = NULL, *new = NULL;
-	struct fsl_dma_slave *slave;
-	size_t copy;
-
-	int i;
-	struct scatterlist *sg;
-	size_t sg_used;
-	size_t hw_used;
-	struct fsl_dma_hw_addr *hw;
-	dma_addr_t dma_dst, dma_src;
-
-	if (!dchan)
-		return NULL;
-
-	if (!dchan->private)
-		return NULL;
-
-	chan = to_fsl_chan(dchan);
-	slave = dchan->private;
-
-	if (list_empty(&slave->addresses))
-		return NULL;
-
-	hw = list_first_entry(&slave->addresses, struct fsl_dma_hw_addr, entry);
-	hw_used = 0;
-
 	/*
-	 * Build the hardware transaction to copy from the scatterlist to
-	 * the hardware, or from the hardware to the scatterlist
-	 *
-	 * If you are copying from the hardware to the scatterlist and it
-	 * takes two hardware entries to fill an entire page, then both
-	 * hardware entries will be coalesced into the same page
+	 * This operation is not supported on the Freescale DMA controller
 	 *
-	 * If you are copying from the scatterlist to the hardware and a
-	 * single page can fill two hardware entries, then the data will
-	 * be read out of the page into the first hardware entry, and so on
+	 * However, we need to provide the function pointer to allow the
+	 * device_control() method to work.
 	 */
-	for_each_sg(sgl, sg, sg_len, i) {
-		sg_used = 0;
-
-		/* Loop until the entire scatterlist entry is used */
-		while (sg_used < sg_dma_len(sg)) {
-
-			/*
-			 * If we've used up the current hardware address/length
-			 * pair, we need to load a new one
-			 *
-			 * This is done in a while loop so that descriptors with
-			 * length == 0 will be skipped
-			 */
-			while (hw_used >= hw->length) {
-
-				/*
-				 * If the current hardware entry is the last
-				 * entry in the list, we're finished
-				 */
-				if (list_is_last(&hw->entry, &slave->addresses))
-					goto finished;
-
-				/* Get the next hardware address/length pair */
-				hw = list_entry(hw->entry.next,
-						struct fsl_dma_hw_addr, entry);
-				hw_used = 0;
-			}
-
-			/* Allocate the link descriptor from DMA pool */
-			new = fsl_dma_alloc_descriptor(chan);
-			if (!new) {
-				dev_err(chan->dev, "No free memory for "
-						       "link descriptor\n");
-				goto fail;
-			}
-#ifdef FSL_DMA_LD_DEBUG
-			dev_dbg(chan->dev, "new link desc alloc %p\n", new);
-#endif
-
-			/*
-			 * Calculate the maximum number of bytes to transfer,
-			 * making sure it is less than the DMA controller limit
-			 */
-			copy = min_t(size_t, sg_dma_len(sg) - sg_used,
-					     hw->length - hw_used);
-			copy = min_t(size_t, copy, FSL_DMA_BCR_MAX_CNT);
-
-			/*
-			 * DMA_FROM_DEVICE
-			 * from the hardware to the scatterlist
-			 *
-			 * DMA_TO_DEVICE
-			 * from the scatterlist to the hardware
-			 */
-			if (direction == DMA_FROM_DEVICE) {
-				dma_src = hw->address + hw_used;
-				dma_dst = sg_dma_address(sg) + sg_used;
-			} else {
-				dma_src = sg_dma_address(sg) + sg_used;
-				dma_dst = hw->address + hw_used;
-			}
-
-			/* Fill in the descriptor */
-			set_desc_cnt(chan, &new->hw, copy);
-			set_desc_src(chan, &new->hw, dma_src);
-			set_desc_dst(chan, &new->hw, dma_dst);
-
-			/*
-			 * If this is not the first descriptor, chain the
-			 * current descriptor after the previous descriptor
-			 */
-			if (!first) {
-				first = new;
-			} else {
-				set_desc_next(chan, &prev->hw,
-					      new->async_tx.phys);
-			}
-
-			new->async_tx.cookie = 0;
-			async_tx_ack(&new->async_tx);
-
-			prev = new;
-			sg_used += copy;
-			hw_used += copy;
-
-			/* Insert the link descriptor into the LD ring */
-			list_add_tail(&new->node, &first->tx_list);
-		}
-	}
-
-finished:
-
-	/* All of the hardware address/length pairs had length == 0 */
-	if (!first || !new)
-		return NULL;
-
-	new->async_tx.flags = flags;
-	new->async_tx.cookie = -EBUSY;
-
-	/* Set End-of-link to the last link descriptor of new list */
-	set_ld_eol(chan, new);
-
-	/* Enable extra controller features */
-	if (chan->set_src_loop_size)
-		chan->set_src_loop_size(chan, slave->src_loop_size);
-
-	if (chan->set_dst_loop_size)
-		chan->set_dst_loop_size(chan, slave->dst_loop_size);
-
-	if (chan->toggle_ext_start)
-		chan->toggle_ext_start(chan, slave->external_start);
-
-	if (chan->toggle_ext_pause)
-		chan->toggle_ext_pause(chan, slave->external_pause);
-
-	if (chan->set_request_count)
-		chan->set_request_count(chan, slave->request_count);
-
-	return &first->async_tx;
-
-fail:
-	/* If first was not set, then we failed to allocate the very first
-	 * descriptor, and we're done */
-	if (!first)
-		return NULL;
-
-	/*
-	 * First is set, so all of the descriptors we allocated have been added
-	 * to first->tx_list, INCLUDING "first" itself. Therefore we
-	 * must traverse the list backwards freeing each descriptor in turn
-	 *
-	 * We're re-using variables for the loop, oh well
-	 */
-	fsldma_free_desc_list_reverse(chan, &first->tx_list);
 	return NULL;
 }
 
 static int fsl_dma_device_control(struct dma_chan *dchan,
 				  enum dma_ctrl_cmd cmd, unsigned long arg)
 {
+	struct fsldma_slave_config *cfg;
 	struct fsldma_chan *chan;
 	unsigned long flags;
 
-	/* Only supports DMA_TERMINATE_ALL */
-	if (cmd != DMA_TERMINATE_ALL)
-		return -ENXIO;
-
 	if (!dchan)
 		return -EINVAL;
 
 	chan = to_fsl_chan(dchan);
 
-	/* Halt the DMA engine */
-	dma_halt(chan);
+	switch (cmd) {
+	case DMA_TERMINATE_ALL:
+		/* Halt the DMA engine */
+		dma_halt(chan);
 
-	spin_lock_irqsave(&chan->desc_lock, flags);
+		spin_lock_irqsave(&chan->desc_lock, flags);
 
-	/* Remove and free all of the descriptors in the LD queue */
-	fsldma_free_desc_list(chan, &chan->ld_pending);
-	fsldma_free_desc_list(chan, &chan->ld_running);
+		/* Remove and free all of the descriptors in the LD queue */
+		fsldma_free_desc_list(chan, &chan->ld_pending);
+		fsldma_free_desc_list(chan, &chan->ld_running);
 
-	spin_unlock_irqrestore(&chan->desc_lock, flags);
+		spin_unlock_irqrestore(&chan->desc_lock, flags);
+		return 0;
+
+	case DMA_SLAVE_CONFIG:
+
+		cfg = (struct fsldma_slave_config *)arg;
+		if (chan->set_request_count)
+			chan->set_request_count(chan, cfg->request_count);
+
+		if (chan->toggle_ext_start)
+			chan->toggle_ext_start(chan, cfg->external_start);
+
+		if (chan->toggle_ext_pause)
+			chan->toggle_ext_pause(chan, cfg->external_pause);
+
+		/*
+		 * TODO: add other features
+		 *
+		 * I'm not sure how to use the members dma_slave_config to
+		 * control the src/dst address hold features.
+		 */
+		return 0;
+
+	default:
+		return -ENXIO;
+	}
 
 	return 0;
 }
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/4] ste_dma40: implement support for scatterlist to scatterlist copy
  2010-09-27 22:57 [PATCH RFCv3 0/4] dma: add support for scatterlist to scatterlist copy Ira W. Snyder
@ 2010-09-27 22:57   ` Ira W. Snyder
  2010-09-27 22:57 ` [PATCH 2/4] fsldma: implement " Ira W. Snyder
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Ira W. Snyder @ 2010-09-27 22:57 UTC (permalink / raw)
  To: linux-kernel; +Cc: Dan Williams, linuxppc-dev, Linus Walleij, Per Fridén

Now that the DMAEngine API has support for scatterlist to scatterlist
copy, implement support for the STE DMA40 DMA controller.

Cc: Linus Walleij <linus.ml.walleij@gmail.com>
Cc: Per Fridén <per.friden@stericsson.com>
Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
---
 drivers/dma/ste_dma40.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 17e2600..cd48859 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -1857,6 +1857,18 @@ err:
 	return NULL;
 }
 
+static struct dma_async_tx_descriptor *
+d40_prep_sg(struct dma_chan *chan,
+	    struct scatterlist *dst_sg, unsigned int dst_nents,
+	    struct scatterlist *src_sg, unsigned int src_nents,
+	    unsigned long dma_flags)
+{
+	if (dst_nents != src_nents)
+		return -EINVAL;
+
+	return stedma40_memcpy_sg(chan, dst_sg, src_sg, dst_nents, dma_flags);
+}
+
 static int d40_prep_slave_sg_log(struct d40_desc *d40d,
 				 struct d40_chan *d40c,
 				 struct scatterlist *sgl,
@@ -2281,6 +2293,7 @@ static int __init d40_dmaengine_init(struct d40_base *base,
 	base->dma_slave.device_alloc_chan_resources = d40_alloc_chan_resources;
 	base->dma_slave.device_free_chan_resources = d40_free_chan_resources;
 	base->dma_slave.device_prep_dma_memcpy = d40_prep_memcpy;
+	base->dma_slave.device_prep_dma_sg = d40_prep_sg;
 	base->dma_slave.device_prep_slave_sg = d40_prep_slave_sg;
 	base->dma_slave.device_tx_status = d40_tx_status;
 	base->dma_slave.device_issue_pending = d40_issue_pending;
@@ -2301,10 +2314,12 @@ static int __init d40_dmaengine_init(struct d40_base *base,
 
 	dma_cap_zero(base->dma_memcpy.cap_mask);
 	dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask);
+	dma_cap_set(DMA_SG, base->dma_slave.cap_mask);
 
 	base->dma_memcpy.device_alloc_chan_resources = d40_alloc_chan_resources;
 	base->dma_memcpy.device_free_chan_resources = d40_free_chan_resources;
 	base->dma_memcpy.device_prep_dma_memcpy = d40_prep_memcpy;
+	base->dma_slave.device_prep_dma_sg = d40_prep_sg;
 	base->dma_memcpy.device_prep_slave_sg = d40_prep_slave_sg;
 	base->dma_memcpy.device_tx_status = d40_tx_status;
 	base->dma_memcpy.device_issue_pending = d40_issue_pending;
@@ -2331,10 +2346,12 @@ static int __init d40_dmaengine_init(struct d40_base *base,
 	dma_cap_zero(base->dma_both.cap_mask);
 	dma_cap_set(DMA_SLAVE, base->dma_both.cap_mask);
 	dma_cap_set(DMA_MEMCPY, base->dma_both.cap_mask);
+	dma_cap_set(DMA_SG, base->dma_slave.cap_mask);
 
 	base->dma_both.device_alloc_chan_resources = d40_alloc_chan_resources;
 	base->dma_both.device_free_chan_resources = d40_free_chan_resources;
 	base->dma_both.device_prep_dma_memcpy = d40_prep_memcpy;
+	base->dma_slave.device_prep_dma_sg = d40_prep_sg;
 	base->dma_both.device_prep_slave_sg = d40_prep_slave_sg;
 	base->dma_both.device_tx_status = d40_tx_status;
 	base->dma_both.device_issue_pending = d40_issue_pending;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/4] ste_dma40: implement support for scatterlist to scatterlist copy
@ 2010-09-27 22:57   ` Ira W. Snyder
  0 siblings, 0 replies; 14+ messages in thread
From: Ira W. Snyder @ 2010-09-27 22:57 UTC (permalink / raw)
  To: linux-kernel; +Cc: Per Fridén, Linus Walleij, Dan Williams, linuxppc-dev

Now that the DMAEngine API has support for scatterlist to scatterlist
copy, implement support for the STE DMA40 DMA controller.

Cc: Linus Walleij <linus.ml.walleij@gmail.com>
Cc: Per Fridén <per.friden@stericsson.com>
Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
---
 drivers/dma/ste_dma40.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 17e2600..cd48859 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -1857,6 +1857,18 @@ err:
 	return NULL;
 }
 
+static struct dma_async_tx_descriptor *
+d40_prep_sg(struct dma_chan *chan,
+	    struct scatterlist *dst_sg, unsigned int dst_nents,
+	    struct scatterlist *src_sg, unsigned int src_nents,
+	    unsigned long dma_flags)
+{
+	if (dst_nents != src_nents)
+		return -EINVAL;
+
+	return stedma40_memcpy_sg(chan, dst_sg, src_sg, dst_nents, dma_flags);
+}
+
 static int d40_prep_slave_sg_log(struct d40_desc *d40d,
 				 struct d40_chan *d40c,
 				 struct scatterlist *sgl,
@@ -2281,6 +2293,7 @@ static int __init d40_dmaengine_init(struct d40_base *base,
 	base->dma_slave.device_alloc_chan_resources = d40_alloc_chan_resources;
 	base->dma_slave.device_free_chan_resources = d40_free_chan_resources;
 	base->dma_slave.device_prep_dma_memcpy = d40_prep_memcpy;
+	base->dma_slave.device_prep_dma_sg = d40_prep_sg;
 	base->dma_slave.device_prep_slave_sg = d40_prep_slave_sg;
 	base->dma_slave.device_tx_status = d40_tx_status;
 	base->dma_slave.device_issue_pending = d40_issue_pending;
@@ -2301,10 +2314,12 @@ static int __init d40_dmaengine_init(struct d40_base *base,
 
 	dma_cap_zero(base->dma_memcpy.cap_mask);
 	dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask);
+	dma_cap_set(DMA_SG, base->dma_slave.cap_mask);
 
 	base->dma_memcpy.device_alloc_chan_resources = d40_alloc_chan_resources;
 	base->dma_memcpy.device_free_chan_resources = d40_free_chan_resources;
 	base->dma_memcpy.device_prep_dma_memcpy = d40_prep_memcpy;
+	base->dma_slave.device_prep_dma_sg = d40_prep_sg;
 	base->dma_memcpy.device_prep_slave_sg = d40_prep_slave_sg;
 	base->dma_memcpy.device_tx_status = d40_tx_status;
 	base->dma_memcpy.device_issue_pending = d40_issue_pending;
@@ -2331,10 +2346,12 @@ static int __init d40_dmaengine_init(struct d40_base *base,
 	dma_cap_zero(base->dma_both.cap_mask);
 	dma_cap_set(DMA_SLAVE, base->dma_both.cap_mask);
 	dma_cap_set(DMA_MEMCPY, base->dma_both.cap_mask);
+	dma_cap_set(DMA_SG, base->dma_slave.cap_mask);
 
 	base->dma_both.device_alloc_chan_resources = d40_alloc_chan_resources;
 	base->dma_both.device_free_chan_resources = d40_free_chan_resources;
 	base->dma_both.device_prep_dma_memcpy = d40_prep_memcpy;
+	base->dma_slave.device_prep_dma_sg = d40_prep_sg;
 	base->dma_both.device_prep_slave_sg = d40_prep_slave_sg;
 	base->dma_both.device_tx_status = d40_tx_status;
 	base->dma_both.device_issue_pending = d40_issue_pending;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/4] ste_dma40: implement support for scatterlist to scatterlist copy
  2010-09-27 22:57   ` Ira W. Snyder
@ 2010-09-29 21:19     ` Dan Williams
  -1 siblings, 0 replies; 14+ messages in thread
From: Dan Williams @ 2010-09-29 21:19 UTC (permalink / raw)
  To: Ira W. Snyder; +Cc: linux-kernel, linuxppc-dev, Linus Walleij, Per Fridén

On Mon, Sep 27, 2010 at 3:57 PM, Ira W. Snyder <iws@ovro.caltech.edu> wrote:
> Now that the DMAEngine API has support for scatterlist to scatterlist
> copy, implement support for the STE DMA40 DMA controller.
>
> Cc: Linus Walleij <linus.ml.walleij@gmail.com>
> Cc: Per Fridén <per.friden@stericsson.com>
> Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
> ---
>  drivers/dma/ste_dma40.c |   17 +++++++++++++++++
>  1 files changed, 17 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
> index 17e2600..cd48859 100644
> --- a/drivers/dma/ste_dma40.c
> +++ b/drivers/dma/ste_dma40.c
> @@ -1857,6 +1857,18 @@ err:
>        return NULL;
>  }
>
> +static struct dma_async_tx_descriptor *
> +d40_prep_sg(struct dma_chan *chan,
> +           struct scatterlist *dst_sg, unsigned int dst_nents,
> +           struct scatterlist *src_sg, unsigned int src_nents,
> +           unsigned long dma_flags)
> +{
> +       if (dst_nents != src_nents)
> +               return -EINVAL;

I suspect you wanted "return NULL;" here.  I can fix that up.

Linus, Per ack?

--
Dan

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/4] ste_dma40: implement support for scatterlist to scatterlist copy
@ 2010-09-29 21:19     ` Dan Williams
  0 siblings, 0 replies; 14+ messages in thread
From: Dan Williams @ 2010-09-29 21:19 UTC (permalink / raw)
  To: Ira W. Snyder; +Cc: Per Fridén, Linus Walleij, linuxppc-dev, linux-kernel

On Mon, Sep 27, 2010 at 3:57 PM, Ira W. Snyder <iws@ovro.caltech.edu> wrote=
:
> Now that the DMAEngine API has support for scatterlist to scatterlist
> copy, implement support for the STE DMA40 DMA controller.
>
> Cc: Linus Walleij <linus.ml.walleij@gmail.com>
> Cc: Per Frid=E9n <per.friden@stericsson.com>
> Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
> ---
> =A0drivers/dma/ste_dma40.c | =A0 17 +++++++++++++++++
> =A01 files changed, 17 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
> index 17e2600..cd48859 100644
> --- a/drivers/dma/ste_dma40.c
> +++ b/drivers/dma/ste_dma40.c
> @@ -1857,6 +1857,18 @@ err:
> =A0 =A0 =A0 =A0return NULL;
> =A0}
>
> +static struct dma_async_tx_descriptor *
> +d40_prep_sg(struct dma_chan *chan,
> + =A0 =A0 =A0 =A0 =A0 struct scatterlist *dst_sg, unsigned int dst_nents,
> + =A0 =A0 =A0 =A0 =A0 struct scatterlist *src_sg, unsigned int src_nents,
> + =A0 =A0 =A0 =A0 =A0 unsigned long dma_flags)
> +{
> + =A0 =A0 =A0 if (dst_nents !=3D src_nents)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EINVAL;

I suspect you wanted "return NULL;" here.  I can fix that up.

Linus, Per ack?

--
Dan

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/4] fsldma: remove DMA_SLAVE support
  2010-09-27 22:57 ` [PATCH 3/4] fsldma: remove DMA_SLAVE support Ira W. Snyder
@ 2010-09-29 21:52     ` Dan Williams
  0 siblings, 0 replies; 14+ messages in thread
From: Dan Williams @ 2010-09-29 21:52 UTC (permalink / raw)
  To: Ira W. Snyder; +Cc: linux-kernel, linuxppc-dev

On Mon, Sep 27, 2010 at 3:57 PM, Ira W. Snyder <iws@ovro.caltech.edu> wrote:
> Now that the generic DMAEngine API has support for scatterlist to
> scatterlist copying, this implementation of the DMA_SLAVE API is no
> longer necessary.
>
> In order to let device_control() continue to function, a stub
> device_prep_slave_sg() function is provided. This allows custom device
> configuration, such as enabling external control.
>

> +       case DMA_SLAVE_CONFIG:
> +
> +               cfg = (struct fsldma_slave_config *)arg;

Now that I actually see someone trying to use the recommended
extension model it comes across as unsafe, what guarantees that arg is
pointing to a fsldma_slave_config.  At at minimum you could ensure
that this channel has been claimed for private usage which loosely
implies that the client knows that it is talking to an fsldma channel.
 Even safer is to just assign you a one-off dma_ctrl_cmd
(FSLDMA_EXTERNAL_START) for this purpose.  Otherwise this and the
other patches look good.

--
Dan

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/4] fsldma: remove DMA_SLAVE support
@ 2010-09-29 21:52     ` Dan Williams
  0 siblings, 0 replies; 14+ messages in thread
From: Dan Williams @ 2010-09-29 21:52 UTC (permalink / raw)
  To: Ira W. Snyder; +Cc: linuxppc-dev, linux-kernel

On Mon, Sep 27, 2010 at 3:57 PM, Ira W. Snyder <iws@ovro.caltech.edu> wrote=
:
> Now that the generic DMAEngine API has support for scatterlist to
> scatterlist copying, this implementation of the DMA_SLAVE API is no
> longer necessary.
>
> In order to let device_control() continue to function, a stub
> device_prep_slave_sg() function is provided. This allows custom device
> configuration, such as enabling external control.
>

> + =A0 =A0 =A0 case DMA_SLAVE_CONFIG:
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 cfg =3D (struct fsldma_slave_config *)arg;

Now that I actually see someone trying to use the recommended
extension model it comes across as unsafe, what guarantees that arg is
pointing to a fsldma_slave_config.  At at minimum you could ensure
that this channel has been claimed for private usage which loosely
implies that the client knows that it is talking to an fsldma channel.
 Even safer is to just assign you a one-off dma_ctrl_cmd
(FSLDMA_EXTERNAL_START) for this purpose.  Otherwise this and the
other patches look good.

--
Dan

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/4] fsldma: remove DMA_SLAVE support
  2010-09-29 21:52     ` Dan Williams
@ 2010-09-29 22:19       ` Ira W. Snyder
  -1 siblings, 0 replies; 14+ messages in thread
From: Ira W. Snyder @ 2010-09-29 22:19 UTC (permalink / raw)
  To: Dan Williams; +Cc: linux-kernel, linuxppc-dev

On Wed, Sep 29, 2010 at 02:52:16PM -0700, Dan Williams wrote:
> On Mon, Sep 27, 2010 at 3:57 PM, Ira W. Snyder <iws@ovro.caltech.edu> wrote:
> > Now that the generic DMAEngine API has support for scatterlist to
> > scatterlist copying, this implementation of the DMA_SLAVE API is no
> > longer necessary.
> >
> > In order to let device_control() continue to function, a stub
> > device_prep_slave_sg() function is provided. This allows custom device
> > configuration, such as enabling external control.
> >
> 
> > +       case DMA_SLAVE_CONFIG:
> > +
> > +               cfg = (struct fsldma_slave_config *)arg;
> 
> Now that I actually see someone trying to use the recommended
> extension model it comes across as unsafe, what guarantees that arg is
> pointing to a fsldma_slave_config.  At at minimum you could ensure
> that this channel has been claimed for private usage which loosely
> implies that the client knows that it is talking to an fsldma channel.
>  Even safer is to just assign you a one-off dma_ctrl_cmd
> (FSLDMA_EXTERNAL_START) for this purpose.  Otherwise this and the
> other patches look good.
> 

I agree, it is a very unsafe model.

I'll take your suggestion, and do that instead. A new patch will be
forthcoming shortly.

Thanks,
Ira

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/4] fsldma: remove DMA_SLAVE support
@ 2010-09-29 22:19       ` Ira W. Snyder
  0 siblings, 0 replies; 14+ messages in thread
From: Ira W. Snyder @ 2010-09-29 22:19 UTC (permalink / raw)
  To: Dan Williams; +Cc: linuxppc-dev, linux-kernel

On Wed, Sep 29, 2010 at 02:52:16PM -0700, Dan Williams wrote:
> On Mon, Sep 27, 2010 at 3:57 PM, Ira W. Snyder <iws@ovro.caltech.edu> wrote:
> > Now that the generic DMAEngine API has support for scatterlist to
> > scatterlist copying, this implementation of the DMA_SLAVE API is no
> > longer necessary.
> >
> > In order to let device_control() continue to function, a stub
> > device_prep_slave_sg() function is provided. This allows custom device
> > configuration, such as enabling external control.
> >
> 
> > +       case DMA_SLAVE_CONFIG:
> > +
> > +               cfg = (struct fsldma_slave_config *)arg;
> 
> Now that I actually see someone trying to use the recommended
> extension model it comes across as unsafe, what guarantees that arg is
> pointing to a fsldma_slave_config.  At at minimum you could ensure
> that this channel has been claimed for private usage which loosely
> implies that the client knows that it is talking to an fsldma channel.
>  Even safer is to just assign you a one-off dma_ctrl_cmd
> (FSLDMA_EXTERNAL_START) for this purpose.  Otherwise this and the
> other patches look good.
> 

I agree, it is a very unsafe model.

I'll take your suggestion, and do that instead. A new patch will be
forthcoming shortly.

Thanks,
Ira

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/4] ste_dma40: implement support for scatterlist to scatterlist copy
  2010-09-29 21:19     ` Dan Williams
@ 2010-09-30  7:13       ` Per Friden
  -1 siblings, 0 replies; 14+ messages in thread
From: Per Friden @ 2010-09-30  7:13 UTC (permalink / raw)
  To: Dan Williams
  Cc: Ira W. Snyder, linux-kernel, linuxppc-dev, Linus Walleij, Per FORLIN

On 09/29/2010 11:19 PM, Dan Williams wrote:
> On Mon, Sep 27, 2010 at 3:57 PM, Ira W. Snyder <iws@ovro.caltech.edu> wrote:
>> Now that the DMAEngine API has support for scatterlist to scatterlist
>> copy, implement support for the STE DMA40 DMA controller.
>>
>> Cc: Linus Walleij <linus.ml.walleij@gmail.com>
>> Cc: Per Fridén <per.friden@stericsson.com>
>> Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
>> ---
>>  drivers/dma/ste_dma40.c |   17 +++++++++++++++++
>>  1 files changed, 17 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
>> index 17e2600..cd48859 100644
>> --- a/drivers/dma/ste_dma40.c
>> +++ b/drivers/dma/ste_dma40.c
>> @@ -1857,6 +1857,18 @@ err:
>>        return NULL;
>>  }
>>
>> +static struct dma_async_tx_descriptor *
>> +d40_prep_sg(struct dma_chan *chan,
>> +           struct scatterlist *dst_sg, unsigned int dst_nents,
>> +           struct scatterlist *src_sg, unsigned int src_nents,
>> +           unsigned long dma_flags)
>> +{
>> +       if (dst_nents != src_nents)
>> +               return -EINVAL;
> 
> I suspect you wanted "return NULL;" here.  I can fix that up.
> 
> Linus, Per ack?
> 
> --
> Dan
Thanks Dan. Acked by Per.

/Per

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/4] ste_dma40: implement support for scatterlist to scatterlist copy
@ 2010-09-30  7:13       ` Per Friden
  0 siblings, 0 replies; 14+ messages in thread
From: Per Friden @ 2010-09-30  7:13 UTC (permalink / raw)
  To: Dan Williams
  Cc: Per FORLIN, Linus Walleij, linuxppc-dev, linux-kernel, Ira W. Snyder

On 09/29/2010 11:19 PM, Dan Williams wrote:
> On Mon, Sep 27, 2010 at 3:57 PM, Ira W. Snyder <iws@ovro.caltech.edu> wrote:
>> Now that the DMAEngine API has support for scatterlist to scatterlist
>> copy, implement support for the STE DMA40 DMA controller.
>>
>> Cc: Linus Walleij <linus.ml.walleij@gmail.com>
>> Cc: Per Fridén <per.friden@stericsson.com>
>> Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
>> ---
>>  drivers/dma/ste_dma40.c |   17 +++++++++++++++++
>>  1 files changed, 17 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
>> index 17e2600..cd48859 100644
>> --- a/drivers/dma/ste_dma40.c
>> +++ b/drivers/dma/ste_dma40.c
>> @@ -1857,6 +1857,18 @@ err:
>>        return NULL;
>>  }
>>
>> +static struct dma_async_tx_descriptor *
>> +d40_prep_sg(struct dma_chan *chan,
>> +           struct scatterlist *dst_sg, unsigned int dst_nents,
>> +           struct scatterlist *src_sg, unsigned int src_nents,
>> +           unsigned long dma_flags)
>> +{
>> +       if (dst_nents != src_nents)
>> +               return -EINVAL;
> 
> I suspect you wanted "return NULL;" here.  I can fix that up.
> 
> Linus, Per ack?
> 
> --
> Dan
Thanks Dan. Acked by Per.

/Per

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2010-09-30  7:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-27 22:57 [PATCH RFCv3 0/4] dma: add support for scatterlist to scatterlist copy Ira W. Snyder
2010-09-27 22:57 ` [PATCH 1/4] " Ira W. Snyder
2010-09-27 22:57 ` [PATCH 2/4] fsldma: implement " Ira W. Snyder
2010-09-27 22:57 ` [PATCH 3/4] fsldma: remove DMA_SLAVE support Ira W. Snyder
2010-09-29 21:52   ` Dan Williams
2010-09-29 21:52     ` Dan Williams
2010-09-29 22:19     ` Ira W. Snyder
2010-09-29 22:19       ` Ira W. Snyder
2010-09-27 22:57 ` [PATCH 4/4] ste_dma40: implement support for scatterlist to scatterlist copy Ira W. Snyder
2010-09-27 22:57   ` Ira W. Snyder
2010-09-29 21:19   ` Dan Williams
2010-09-29 21:19     ` Dan Williams
2010-09-30  7:13     ` Per Friden
2010-09-30  7:13       ` Per Friden

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.