aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-10-22 06:04:46 -0400
committerTakashi Iwai <tiwai@suse.de>2014-10-22 06:11:38 -0400
commit63825f3a879ea2be569471643bb6aac73d9261f0 (patch)
tree14f3a5c5579d5036662203b98c061b4ca8492188 /sound/core
parentc37de55efa1ccf018c27b876560725ff5e9f5701 (diff)
ALSA: pcm: Disable mmap for known broken archs
Some architectures like PARISC is known not to support mmap properly with the DMA buffer, where dma_mmap_coherent() returns -EINVAL unconditionally. From the API POV, we should rather drop the mmap support there and expose it before the user-space tries to call mmap. The patch contains again ugly ifdef's, unfortunately, as there is no global flag indicating this. Once when such macro is defined, we can get rid of this instead. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/pcm_native.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index aa6754da7929..dc9a1355a4ab 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -192,6 +192,21 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream,
192 return err; 192 return err;
193} 193}
194 194
195static bool hw_support_mmap(struct snd_pcm_substream *substream)
196{
197 if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_MMAP))
198 return false;
199 /* check architectures that return -EINVAL from dma_mmap_coherent() */
200 /* FIXME: this should be some global flag */
201#if defined(CONFIG_C6X) || defined(CONFIG_FRV) || defined(CONFIG_MN10300) ||\
202 defined(CONFIG_PARISC) || defined(CONFIG_XTENSA)
203 if (!substream->ops->mmap &&
204 substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
205 return false;
206#endif
207 return true;
208}
209
195#undef RULES_DEBUG 210#undef RULES_DEBUG
196 211
197#ifdef RULES_DEBUG 212#ifdef RULES_DEBUG
@@ -369,8 +384,12 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
369 } 384 }
370 385
371 hw = &substream->runtime->hw; 386 hw = &substream->runtime->hw;
372 if (!params->info) 387 if (!params->info) {
373 params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES; 388 params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES;
389 if (!hw_support_mmap(substream))
390 params->info &= ~(SNDRV_PCM_INFO_MMAP |
391 SNDRV_PCM_INFO_MMAP_VALID);
392 }
374 if (!params->fifo_size) { 393 if (!params->fifo_size) {
375 m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 394 m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
376 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 395 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
@@ -2069,7 +2088,7 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
2069 mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED; 2088 mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED;
2070 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) 2089 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)
2071 mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED; 2090 mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED;
2072 if (hw->info & SNDRV_PCM_INFO_MMAP) { 2091 if (hw_support_mmap(substream)) {
2073 if (hw->info & SNDRV_PCM_INFO_INTERLEAVED) 2092 if (hw->info & SNDRV_PCM_INFO_INTERLEAVED)
2074 mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED; 2093 mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED;
2075 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) 2094 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)