Merge tag 'block-5.15-2021-09-05' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / sound / core / pcm_native.c
index 71323d8..d233cb3 100644 (file)
@@ -243,13 +243,18 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream,
 
 static bool hw_support_mmap(struct snd_pcm_substream *substream)
 {
+       struct snd_dma_buffer *dmabuf;
+
        if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_MMAP))
                return false;
 
        if (substream->ops->mmap || substream->ops->page)
                return true;
 
-       switch (substream->dma_buffer.dev.type) {
+       dmabuf = snd_pcm_get_dma_buf(substream);
+       if (!dmabuf)
+               dmabuf = &substream->dma_buffer;
+       switch (dmabuf->dev.type) {
        case SNDRV_DMA_TYPE_UNKNOWN:
                /* we can't know the device, so just assume that the driver does
                 * everything right
@@ -259,7 +264,7 @@ static bool hw_support_mmap(struct snd_pcm_substream *substream)
        case SNDRV_DMA_TYPE_VMALLOC:
                return true;
        default:
-               return dma_can_mmap(substream->dma_buffer.dev.dev);
+               return dma_can_mmap(dmabuf->dev.dev);
        }
 }
 
@@ -3616,6 +3621,12 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
 
 static bool pcm_status_mmap_allowed(struct snd_pcm_file *pcm_file)
 {
+       /* If drivers require the explicit sync (typically for non-coherent
+        * pages), we have to disable the mmap of status and control data
+        * to enforce the control via SYNC_PTR ioctl.
+        */
+       if (pcm_file->substream->runtime->hw.info & SNDRV_PCM_INFO_EXPLICIT_SYNC)
+               return false;
        /* See pcm_control_mmap_allowed() below.
         * Since older alsa-lib requires both status and control mmaps to be
         * coupled, we have to disable the status mmap for old alsa-lib, too.
@@ -3630,6 +3641,9 @@ static bool pcm_control_mmap_allowed(struct snd_pcm_file *pcm_file)
 {
        if (pcm_file->no_compat_mmap)
                return false;
+       /* see above */
+       if (pcm_file->substream->runtime->hw.info & SNDRV_PCM_INFO_EXPLICIT_SYNC)
+               return false;
        /* Disallow the control mmap when SYNC_APPLPTR flag is set;
         * it enforces the user-space to fall back to snd_pcm_sync_ptr(),
         * thus it effectively assures the manual update of appl_ptr.