[PATCH] x86_64: GART DMA merging fix
Don't touch the non DMA members in the sg list in dma_map_sg in the IOMMU
Some drivers (in particular ST) ran into problems because they reused the sg
lists after passing them to pci_map_sg(). The merging procedure in the K8
GART IOMMU corrupted the state. This patch changes it to only touch the dma*
entries during merging, but not the other fields. Approach suggested by Dave
Miller.
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 2fe23a6..dd0718d 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -310,7 +310,7 @@
for (i = 0; i < nents; i++) {
struct scatterlist *s = &sg[i];
- if (!s->dma_length || !s->length)
+ if (!s->dma_length)
break;
dma_unmap_single(dev, s->dma_address, s->dma_length, dir);
}
@@ -364,7 +364,6 @@
BUG_ON(i > start && s->offset);
if (i == start) {
- *sout = *s;
sout->dma_address = iommu_bus_base;
sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
sout->dma_length = s->length;
@@ -379,7 +378,7 @@
SET_LEAK(iommu_page);
addr += PAGE_SIZE;
iommu_page++;
- }
+ }
}
BUG_ON(iommu_page - iommu_start != pages);
return 0;
@@ -391,7 +390,6 @@
{
if (!need) {
BUG_ON(stopat - start != 1);
- *sout = sg[start];
sout->dma_length = sg[start].length;
return 0;
}