Hello. On 07-09-2010 8:03, Kevin Cernekee wrote:
The MIPS DMA coherency functions do not work properly (i.e. kernel oops) when HIGHMEM pages are passed in as arguments. This patch uses the PPC approach of calling kmap_atomic() with IRQs disabled to temporarily map high pages, in order to flush them out to memory.
Signed-off-by: Dezhong Diao <dediao@xxxxxxxxx> Signed-off-by: Kevin Cernekee <cernekee@xxxxxxxxx> --- arch/mips/mm/dma-default.c | 159 ++++++++++++++++++++++---------------------- 1 files changed, 80 insertions(+), 79 deletions(-)
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 469d401..3f23952 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c
[...]
@@ -191,8 +231,8 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction direction) { if (cpu_is_noncoherent_r10000(dev)) - __dma_sync(dma_addr_to_virt(dev, dma_addr), size, - direction); + __dma_sync(dma_addr_to_page(dev, dma_addr), + (dma_addr & ~PAGE_MASK), size, direction);
Parens are not needed here.
@@ -277,15 +297,10 @@ EXPORT_SYMBOL(dma_sync_single_for_cpu); void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - BUG_ON(direction == DMA_NONE); - plat_extra_sync_for_device(dev); - if (!plat_device_is_coherent(dev)) { - unsigned long addr; - - addr = dma_addr_to_virt(dev, dma_handle); - __dma_sync(addr, size, direction); - } + if (!plat_device_is_coherent(dev)) + __dma_sync(dma_addr_to_page(dev, dma_handle), + (dma_handle & ~PAGE_MASK), size, direction);
Here as well... WBR, Sergei