diff options
Diffstat (limited to 'sound/core/pcm_native.c')
-rw-r--r-- | sound/core/pcm_native.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 71323d807dbf..d233cb3b41d8 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -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. |