aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-02-21 16:38:56 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-02-21 16:38:56 -0500
commitfa4e998999322bc1b11d2c8b19b9fa2016fd1548 (patch)
tree88ffcfce4eb62df4ac2994351c7525df83bc76f2
parent308d333ad6cc12e39adaed22dc10bac48e17742a (diff)
[ARM] dma: RiscPC: don't modify DMA SG entries
We should not be modifying the scatterlist passed to us from the driver code; doing so breaks assumptions made by the DMA API code, and could cause problems if the driver retries a transfer using an old scatterlist. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mach-rpc/dma.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c
index 1f77cdca26e9..c47d974d52bd 100644
--- a/arch/arm/mach-rpc/dma.c
+++ b/arch/arm/mach-rpc/dma.c
@@ -32,6 +32,8 @@ struct iomd_dma {
32 unsigned long base; /* Controller base address */ 32 unsigned long base; /* Controller base address */
33 int irq; /* Controller IRQ */ 33 int irq; /* Controller IRQ */
34 struct scatterlist cur_sg; /* Current controller buffer */ 34 struct scatterlist cur_sg; /* Current controller buffer */
35 dma_addr_t dma_addr;
36 unsigned int dma_len;
35}; 37};
36 38
37#if 0 39#if 0
@@ -57,10 +59,10 @@ static void iomd_get_next_sg(struct scatterlist *sg, struct iomd_dma *idma)
57 unsigned long end, offset, flags = 0; 59 unsigned long end, offset, flags = 0;
58 60
59 if (idma->dma.sg) { 61 if (idma->dma.sg) {
60 sg->dma_address = idma->dma.sg->dma_address; 62 sg->dma_address = idma->dma_addr;
61 offset = sg->dma_address & ~PAGE_MASK; 63 offset = sg->dma_address & ~PAGE_MASK;
62 64
63 end = offset + idma->dma.sg->length; 65 end = offset + idma->dma_len;
64 66
65 if (end > PAGE_SIZE) 67 if (end > PAGE_SIZE)
66 end = PAGE_SIZE; 68 end = PAGE_SIZE;
@@ -70,12 +72,14 @@ static void iomd_get_next_sg(struct scatterlist *sg, struct iomd_dma *idma)
70 72
71 sg->length = end - TRANSFER_SIZE; 73 sg->length = end - TRANSFER_SIZE;
72 74
73 idma->dma.sg->length -= end - offset; 75 idma->dma_len -= end - offset;
74 idma->dma.sg->dma_address += end - offset; 76 idma->dma_addr += end - offset;
75 77
76 if (idma->dma.sg->length == 0) { 78 if (idma->dma_len == 0) {
77 if (idma->dma.sgcount > 1) { 79 if (idma->dma.sgcount > 1) {
78 idma->dma.sg = sg_next(idma->dma.sg); 80 idma->dma.sg = sg_next(idma->dma.sg);
81 idma->dma_addr = idma->dma.sg->dma_address;
82 idma->dma_len = idma->dma.sg->length;
79 idma->dma.sgcount--; 83 idma->dma.sgcount--;
80 } else { 84 } else {
81 idma->dma.sg = NULL; 85 idma->dma.sg = NULL;