diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2009-02-21 21:38:56 +0000 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-02-21 21:38:56 +0000 |
commit | fa4e998999322bc1b11d2c8b19b9fa2016fd1548 (patch) | |
tree | 88ffcfce4eb62df4ac2994351c7525df83bc76f2 /arch/arm | |
parent | 308d333ad6cc12e39adaed22dc10bac48e17742a (diff) | |
download | op-kernel-dev-fa4e998999322bc1b11d2c8b19b9fa2016fd1548.zip op-kernel-dev-fa4e998999322bc1b11d2c8b19b9fa2016fd1548.tar.gz |
[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>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-rpc/dma.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c index 1f77cdc..c47d974 100644 --- a/arch/arm/mach-rpc/dma.c +++ b/arch/arm/mach-rpc/dma.c @@ -32,6 +32,8 @@ struct iomd_dma { unsigned long base; /* Controller base address */ int irq; /* Controller IRQ */ struct scatterlist cur_sg; /* Current controller buffer */ + dma_addr_t dma_addr; + unsigned int dma_len; }; #if 0 @@ -57,10 +59,10 @@ static void iomd_get_next_sg(struct scatterlist *sg, struct iomd_dma *idma) unsigned long end, offset, flags = 0; if (idma->dma.sg) { - sg->dma_address = idma->dma.sg->dma_address; + sg->dma_address = idma->dma_addr; offset = sg->dma_address & ~PAGE_MASK; - end = offset + idma->dma.sg->length; + end = offset + idma->dma_len; if (end > PAGE_SIZE) end = PAGE_SIZE; @@ -70,12 +72,14 @@ static void iomd_get_next_sg(struct scatterlist *sg, struct iomd_dma *idma) sg->length = end - TRANSFER_SIZE; - idma->dma.sg->length -= end - offset; - idma->dma.sg->dma_address += end - offset; + idma->dma_len -= end - offset; + idma->dma_addr += end - offset; - if (idma->dma.sg->length == 0) { + if (idma->dma_len == 0) { if (idma->dma.sgcount > 1) { idma->dma.sg = sg_next(idma->dma.sg); + idma->dma_addr = idma->dma.sg->dma_address; + idma->dma_len = idma->dma.sg->length; idma->dma.sgcount--; } else { idma->dma.sg = NULL; |