At Thu, 25 Sep 2008 15:55:53 +0100, Pawel MOLL wrote:
One thing we can try is a patch like below. But, I'm not sure whether this is correct over all architectures, too. At best, a generic API would be helpful for such a thing...
- area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
Well, it's not enough, because the kernel mapping of buffer is still cached... A hack below does the job, but it is not nice as well...
Yeah, that's not sexy, but maybe the only working case right now (better with arch-specific ifdefs).
IIRC, a similar buffer handling (via vmalloc) is used in video drivers. I suppose they don't work as well, right? DRM driver uses __vmalloc() with PAGE_KERNEL_NOCACHE, but it's only for PPC32 non-coherent.
Takashi
Cheers
Paweł
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 59b29cd..304f9e5 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -3159,6 +3159,9 @@ 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) { +#ifdef pgprot_noncached
area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
+#endif area->vm_ops = &snd_pcm_vm_ops_data; area->vm_private_data = substream; area->vm_flags |= VM_RESERVED; diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 7bd5852..c98a4ec 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -714,7 +714,8 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s return 0; /* already large enough */ vfree(runtime->dma_area); }
runtime->dma_area = vmalloc(size);
runtime->dma_area = __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM,
PAGE_KERNEL_NOCACHE); if (! runtime->dma_area) return -ENOMEM; runtime->dma_bytes = size;