Hi, I've been trying to fix a long-standing bug in ALSA, the mmap of pages via dma_mmap_coherent(). Since the sound drivers need to expose the whole buffer via mmap and the buffers are allocated via dma_alloc_coherent(), it causes Oops on some architectures like MIPS. One of the fix patches is this one, the addition of dma_mmap_coherent() to MIPS architecture. This implementation is pretty lazy (and untested) as you see below. The whole patches are found on topic/dma-fix branch on sound-2.6 git tree git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git The gitweb URL of the branch is: http://git.kernel.org/?p=linux/kernel/git/tiwai/sound-2.6.git;a=shortlog;h=topic/dma-fix Any review and comments would be appreciated. Thanks in advance, Takashi [PATCH] mips: implement dma_mmap_coherent() A lazy version of dma_mmap_coherent() implementation for MIPS. Signed-off-by: Takashi Iwai <tiwai@xxxxxxx> diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 891312f..723dd64 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -387,3 +387,15 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, } EXPORT_SYMBOL(dma_cache_sync); + +int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t handle, size_t size) +{ + struct page *pg; + cpu_addr = (void *)dma_addr_to_virt(handle); + pg = virt_to_page(cpu_addr); + return remap_pfn_range(vma, vma->vm_start, + page_to_pfn(pg) + vma->vm_pgoff, + size, vma->vm_page_prot); +} +EXPORT_SYMBOL(dma_mmap_coherent); diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h index c64afb4..ab12cd4 100644 --- a/include/asm-mips/dma-mapping.h +++ b/include/asm-mips/dma-mapping.h @@ -68,6 +68,9 @@ extern int dma_is_consistent(struct device *dev, dma_addr_t dma_addr); extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction); +extern int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t handle, size_t size); + #if 0 #define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY