Loading sound/core/pcm_native.c +36 −34 Original line number Diff line number Diff line Loading @@ -1368,43 +1368,32 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; down_read(&snd_pcm_link_rwsem); snd_power_lock(card); if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile); if (result < 0) goto _unlock; if (result < 0) { snd_power_unlock(card); return result; } } /* allocate temporary record for drain sync */ down_read(&snd_pcm_link_rwsem); if (snd_pcm_stream_linked(substream)) { drec = kmalloc(substream->group->count * sizeof(*drec), GFP_KERNEL); if (! drec) { result = -ENOMEM; goto _unlock; up_read(&snd_pcm_link_rwsem); snd_power_unlock(card); return -ENOMEM; } } else drec = &drec_tmp; snd_pcm_stream_lock_irq(substream); /* resume pause */ if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) snd_pcm_pause(substream, 0); /* pre-start/stop - all running streams are changed to DRAINING state */ result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0); if (result < 0) goto _end; /* check streams with PLAYBACK & DRAINING */ /* count only playback streams */ num_drecs = 0; snd_pcm_group_for_each(pos, substream) { snd_pcm_substream_t *s = snd_pcm_group_substream_entry(pos); runtime = s->runtime; if (runtime->status->state != SNDRV_PCM_STATE_DRAINING) { runtime->status->state = SNDRV_PCM_STATE_SETUP; continue; } if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { d = &drec[num_drecs++]; d->substream = s; Loading @@ -1418,9 +1407,21 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) runtime->stop_threshold = runtime->buffer_size; } } up_read(&snd_pcm_link_rwsem); if (! num_drecs) goto _end; goto _error; snd_pcm_stream_lock_irq(substream); /* resume pause */ if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) snd_pcm_pause(substream, 0); /* pre-start/stop - all running streams are changed to DRAINING state */ result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0); if (result < 0) { snd_pcm_stream_unlock_irq(substream); goto _error; } for (;;) { long tout; Loading @@ -1428,6 +1429,15 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) result = -ERESTARTSYS; break; } /* all finished? */ for (i = 0; i < num_drecs; i++) { runtime = drec[i].substream->runtime; if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) break; } if (i == num_drecs) break; /* yes, all drained */ set_current_state(TASK_INTERRUPTIBLE); snd_pcm_stream_unlock_irq(substream); snd_power_unlock(card); Loading @@ -1444,15 +1454,11 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) } break; } /* all finished? */ for (i = 0; i < num_drecs; i++) { runtime = drec[i].substream->runtime; if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) break; } if (i == num_drecs) break; } snd_pcm_stream_unlock_irq(substream); _error: for (i = 0; i < num_drecs; i++) { d = &drec[i]; runtime = d->substream->runtime; Loading @@ -1460,13 +1466,9 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) runtime->stop_threshold = d->stop_threshold; } _end: snd_pcm_stream_unlock_irq(substream); if (drec != &drec_tmp) kfree(drec); _unlock: snd_power_unlock(card); up_read(&snd_pcm_link_rwsem); return result; } Loading Loading
sound/core/pcm_native.c +36 −34 Original line number Diff line number Diff line Loading @@ -1368,43 +1368,32 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; down_read(&snd_pcm_link_rwsem); snd_power_lock(card); if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile); if (result < 0) goto _unlock; if (result < 0) { snd_power_unlock(card); return result; } } /* allocate temporary record for drain sync */ down_read(&snd_pcm_link_rwsem); if (snd_pcm_stream_linked(substream)) { drec = kmalloc(substream->group->count * sizeof(*drec), GFP_KERNEL); if (! drec) { result = -ENOMEM; goto _unlock; up_read(&snd_pcm_link_rwsem); snd_power_unlock(card); return -ENOMEM; } } else drec = &drec_tmp; snd_pcm_stream_lock_irq(substream); /* resume pause */ if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) snd_pcm_pause(substream, 0); /* pre-start/stop - all running streams are changed to DRAINING state */ result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0); if (result < 0) goto _end; /* check streams with PLAYBACK & DRAINING */ /* count only playback streams */ num_drecs = 0; snd_pcm_group_for_each(pos, substream) { snd_pcm_substream_t *s = snd_pcm_group_substream_entry(pos); runtime = s->runtime; if (runtime->status->state != SNDRV_PCM_STATE_DRAINING) { runtime->status->state = SNDRV_PCM_STATE_SETUP; continue; } if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { d = &drec[num_drecs++]; d->substream = s; Loading @@ -1418,9 +1407,21 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) runtime->stop_threshold = runtime->buffer_size; } } up_read(&snd_pcm_link_rwsem); if (! num_drecs) goto _end; goto _error; snd_pcm_stream_lock_irq(substream); /* resume pause */ if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) snd_pcm_pause(substream, 0); /* pre-start/stop - all running streams are changed to DRAINING state */ result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0); if (result < 0) { snd_pcm_stream_unlock_irq(substream); goto _error; } for (;;) { long tout; Loading @@ -1428,6 +1429,15 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) result = -ERESTARTSYS; break; } /* all finished? */ for (i = 0; i < num_drecs; i++) { runtime = drec[i].substream->runtime; if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) break; } if (i == num_drecs) break; /* yes, all drained */ set_current_state(TASK_INTERRUPTIBLE); snd_pcm_stream_unlock_irq(substream); snd_power_unlock(card); Loading @@ -1444,15 +1454,11 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) } break; } /* all finished? */ for (i = 0; i < num_drecs; i++) { runtime = drec[i].substream->runtime; if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) break; } if (i == num_drecs) break; } snd_pcm_stream_unlock_irq(substream); _error: for (i = 0; i < num_drecs; i++) { d = &drec[i]; runtime = d->substream->runtime; Loading @@ -1460,13 +1466,9 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) runtime->stop_threshold = d->stop_threshold; } _end: snd_pcm_stream_unlock_irq(substream); if (drec != &drec_tmp) kfree(drec); _unlock: snd_power_unlock(card); up_read(&snd_pcm_link_rwsem); return result; } Loading