summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-rpc/dma.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-02-21 22:38:56 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-02-21 22:38:56 +0100
commitfa4e998999322bc1b11d2c8b19b9fa2016fd1548 (patch)
tree88ffcfce4eb62df4ac2994351c7525df83bc76f2 /arch/arm/mach-rpc/dma.c
parent[ARM] dma: move IOMD and floppy DMA structures to RiscPC DMA code (diff)
downloadlinux-fa4e998999322bc1b11d2c8b19b9fa2016fd1548.tar.xz
linux-fa4e998999322bc1b11d2c8b19b9fa2016fd1548.zip
[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/mach-rpc/dma.c')
-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 {
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;