diff options
Diffstat (limited to 'sound/core/pcm_native.c')
-rw-r--r-- | sound/core/pcm_native.c | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index c4aac703dc22..17a85f4815d5 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -209,13 +209,13 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info) info->device = pcm->device; info->stream = substream->stream; info->subdevice = substream->number; - strlcpy(info->id, pcm->id, sizeof(info->id)); - strlcpy(info->name, pcm->name, sizeof(info->name)); + strscpy(info->id, pcm->id, sizeof(info->id)); + strscpy(info->name, pcm->name, sizeof(info->name)); info->dev_class = pcm->dev_class; info->dev_subclass = pcm->dev_subclass; info->subdevices_count = pstr->substream_count; info->subdevices_avail = pstr->substream_count - pstr->substream_opened; - strlcpy(info->subname, substream->name, sizeof(info->subname)); + strscpy(info->subname, substream->name, sizeof(info->subname)); return 0; } @@ -583,13 +583,13 @@ static inline void snd_pcm_timer_notify(struct snd_pcm_substream *substream, #endif } -static void snd_pcm_sync_stop(struct snd_pcm_substream *substream) +void snd_pcm_sync_stop(struct snd_pcm_substream *substream, bool sync_irq) { - if (substream->runtime->stop_operating) { + if (substream->runtime && substream->runtime->stop_operating) { substream->runtime->stop_operating = false; - if (substream->ops->sync_stop) + if (substream->ops && substream->ops->sync_stop) substream->ops->sync_stop(substream); - else if (substream->pcm->card->sync_irq > 0) + else if (sync_irq && substream->pcm->card->sync_irq > 0) synchronize_irq(substream->pcm->card->sync_irq); } } @@ -686,7 +686,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, if (atomic_read(&substream->mmap_count)) return -EBADFD; - snd_pcm_sync_stop(substream); + snd_pcm_sync_stop(substream, true); params->rmask = ~0U; err = snd_pcm_hw_refine(substream, params); @@ -809,7 +809,7 @@ static int do_hw_free(struct snd_pcm_substream *substream) { int result = 0; - snd_pcm_sync_stop(substream); + snd_pcm_sync_stop(substream, true); if (substream->ops->hw_free) result = substream->ops->hw_free(substream); if (substream->managed_buffer_alloc) @@ -1421,8 +1421,10 @@ static int snd_pcm_do_stop(struct snd_pcm_substream *substream, snd_pcm_state_t state) { if (substream->runtime->trigger_master == substream && - snd_pcm_running(substream)) + snd_pcm_running(substream)) { substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP); + substream->runtime->stop_operating = true; + } return 0; /* unconditonally stop all substreams */ } @@ -1435,7 +1437,6 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, runtime->status->state = state; snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP); } - runtime->stop_operating = true; wake_up(&runtime->sleep); wake_up(&runtime->tsleep); } @@ -1615,6 +1616,7 @@ static int snd_pcm_do_suspend(struct snd_pcm_substream *substream, if (! snd_pcm_running(substream)) return 0; substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND); + runtime->stop_operating = true; return 0; /* suspend unconditionally */ } @@ -1672,25 +1674,26 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm) if (! pcm) return 0; - for (stream = 0; stream < 2; stream++) { - for (substream = pcm->streams[stream].substream; - substream; substream = substream->next) { - /* FIXME: the open/close code should lock this as well */ - if (substream->runtime == NULL) - continue; + for_each_pcm_substream(pcm, stream, substream) { + /* FIXME: the open/close code should lock this as well */ + if (!substream->runtime) + continue; - /* - * Skip BE dai link PCM's that are internal and may - * not have their substream ops set. - */ - if (!substream->ops) - 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; - } + err = snd_pcm_suspend(substream); + if (err < 0 && err != -EBUSY) + return err; } + + for_each_pcm_substream(pcm, stream, substream) + snd_pcm_sync_stop(substream, false); + return 0; } EXPORT_SYMBOL(snd_pcm_suspend_all); @@ -1736,7 +1739,6 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream, snd_pcm_trigger_tstamp(substream); runtime->status->state = runtime->status->suspended_state; snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME); - snd_pcm_sync_stop(substream); } static const struct action_ops snd_pcm_action_resume = { @@ -1866,7 +1868,7 @@ static int snd_pcm_do_prepare(struct snd_pcm_substream *substream, snd_pcm_state_t state) { int err; - snd_pcm_sync_stop(substream); + snd_pcm_sync_stop(substream, true); err = substream->ops->prepare(substream); if (err < 0) return err; |