[alsa-devel] [PATCH 3/4] ALSA: pcm: Handle special page mapping in the default mmap handler

Takashi Iwai tiwai at suse.de
Tue Nov 5 09:01:37 CET 2019


When a driver needs to deal with a special buffer like a SG or a
vmalloc buffer, it has to set up the PCM page ops explicitly for the
corresponding helper function.  This is rather error-prone and many
people forgot or incorrectly used it.

For simplifying the call patterns and avoiding such a potential bug,
this patch enhances the PCM default mmap handler to check the
(pre-)allocated buffer type and handles the page gracefully depending
on the buffer type.  If the PCM page ops is given, the ops is still
used in a higher priority.  The new code path is only for the default
(NULL page ops) case.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 sound/core/pcm_native.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index c3a139436ac2..998c63192ae4 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -13,6 +13,7 @@
 #include <linux/pm_qos.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/info.h>
@@ -3335,7 +3336,18 @@ static inline struct page *
 snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
 {
 	void *vaddr = substream->runtime->dma_area + ofs;
-	return virt_to_page(vaddr);
+
+	switch (substream->dma_buffer.dev.type) {
+#ifdef CONFIG_SND_DMA_SGBUF
+	case SNDRV_DMA_TYPE_DEV_SG:
+	case SNDRV_DMA_TYPE_DEV_UC_SG:
+		return snd_pcm_sgbuf_ops_page(substream, ofs);
+#endif /* CONFIG_SND_DMA_SGBUF */
+	case SNDRV_DMA_TYPE_VMALLOC:
+		return vmalloc_to_page(vaddr);
+	default:
+		return virt_to_page(vaddr);
+	}
 }
 
 /*
-- 
2.16.4



More information about the Alsa-devel mailing list