The DMA buffers allocated via dma_alloc_coherent() aren't easily mmappable for many architectures. This is a quick fix for some known archs that don't work properly with the current code.
Signed-off-by: Takashi Iwai <[EMAIL PROTECTED]> --- sound/core/Kconfig | 7 +++++++ sound/core/pcm_native.c | 42 ++++++++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/sound/core/Kconfig b/sound/core/Kconfig index 335d45e..8e4e644 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -174,3 +174,10 @@ config SND_PCM_XRUN_DEBUG config SND_VMASTER bool + +config SND_COHERENT_DMA + def_bool y + depends on !PPC32 || !NOT_COHERENT_CACHE + depends on !ARM + depends on !MIPS + depends on !PARISC diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 61f5d42..e21ad2f 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -3124,6 +3124,12 @@ static struct vm_operations_struct snd_pcm_vm_ops_data = { .open = snd_pcm_mmap_data_open, .close = snd_pcm_mmap_data_close, +}; + +static struct vm_operations_struct snd_pcm_vm_ops_data_fault = +{ + .open = snd_pcm_mmap_data_open, + .close = snd_pcm_mmap_data_close, .fault = snd_pcm_mmap_data_fault, }; @@ -3133,10 +3139,21 @@ static struct vm_operations_struct snd_pcm_vm_ops_data = static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *area) { - area->vm_ops = &snd_pcm_vm_ops_data; - area->vm_private_data = substream; area->vm_flags |= VM_RESERVED; - atomic_inc(&substream->mmap_count); +#ifndef CONFIG_SND_COHERENT_DMA + if (!substream->ops->page) { + switch (substream->dma_buffer.dev.type) { + case SNDRV_DMA_TYPE_DEV: + return dma_mmap_coherent(substream->dma_buffer.dev.dev, + area, + substream->runtime->dma_area, + substream->runtime->dma_addr, + area->vm_end - area->vm_start); + } + } +#endif /* !CONFIG_SND_COHERNT_DMA */ + /* mmap with fault handler */ + area->vm_ops = &snd_pcm_vm_ops_data_fault; return 0; } @@ -3144,12 +3161,6 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, * mmap the DMA buffer on I/O memory area */ #if SNDRV_PCM_INFO_MMAP_IOMEM -static struct vm_operations_struct snd_pcm_vm_ops_data_mmio = -{ - .open = snd_pcm_mmap_data_open, - .close = snd_pcm_mmap_data_close, -}; - int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_struct *area) { @@ -3159,8 +3170,6 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, #ifdef pgprot_noncached area->vm_page_prot = pgprot_noncached(area->vm_page_prot); #endif - area->vm_ops = &snd_pcm_vm_ops_data_mmio; - area->vm_private_data = substream; area->vm_flags |= VM_IO; size = area->vm_end - area->vm_start; offset = area->vm_pgoff << PAGE_SHIFT; @@ -3168,7 +3177,6 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, size, area->vm_page_prot)) return -EAGAIN; - atomic_inc(&substream->mmap_count); return 0; } @@ -3185,6 +3193,7 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, long size; unsigned long offset; size_t dma_bytes; + int err; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (!(area->vm_flags & (VM_WRITE|VM_READ))) @@ -3210,10 +3219,15 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, if (offset > dma_bytes - size) return -EINVAL; + area->vm_ops = &snd_pcm_vm_ops_data; + area->vm_private_data = substream; if (substream->ops->mmap) - return substream->ops->mmap(substream, area); + err = substream->ops->mmap(substream, area); else - return snd_pcm_default_mmap(substream, area); + err = snd_pcm_default_mmap(substream, area); + if (!err) + atomic_inc(&substream->mmap_count); + return err; } EXPORT_SYMBOL(snd_pcm_mmap_data); -- 1.5.4.5 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev