diff options
Diffstat (limited to 'sound/core/pcm_native.c')
-rw-r--r-- | sound/core/pcm_native.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 966ac384c3f4..14b1ee29509d 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -720,6 +720,10 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size) runtime->boundary *= 2; + /* clear the buffer for avoiding possible kernel info leaks */ + if (runtime->dma_area && !substream->ops->copy_user) + memset(runtime->dma_area, 0, runtime->dma_bytes); + snd_pcm_timer_resolution_change(substream); snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP); @@ -1395,8 +1399,15 @@ static int snd_pcm_pause(struct snd_pcm_substream *substream, int push) static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state) { struct snd_pcm_runtime *runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) + switch (runtime->status->state) { + case SNDRV_PCM_STATE_SUSPENDED: return -EBUSY; + /* unresumable PCM state; return -EBUSY for skipping suspend */ + case SNDRV_PCM_STATE_OPEN: + case SNDRV_PCM_STATE_SETUP: + case SNDRV_PCM_STATE_DISCONNECTED: + return -EBUSY; + } runtime->trigger_master = substream; return 0; } @@ -1475,6 +1486,14 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm) /* FIXME: the open/close code should lock this as well */ if (substream->runtime == NULL) continue; + + /* + * Skip BE dai link PCM's that are internal and may + * not have their substream ops set. + */ + if (!substream->ops) + continue; + err = snd_pcm_suspend(substream); if (err < 0 && err != -EBUSY) return err; |