- snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_OPEN:
- res = -EBADFD;
- break;
- case SNDRV_PCM_STATE_PREPARED:
- snd_pcm_change_state(substream, SNDRV_PCM_STATE_SETUP);
- break;
- case SNDRV_PCM_STATE_SETUP:
- case SNDRV_PCM_STATE_DRAINING:
- break;
- case SNDRV_PCM_STATE_PAUSED:
- snd_pcm_pause(substream, 0);
- /* Fall through */
- case SNDRV_PCM_STATE_RUNNING:
- if (snd_pcm_update_hw_ptr(substream) >= 0) {
- snd_pcm_stop(substream,
- snd_pcm_capture_avail(runtime) > 0 ?
- SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP);
- break;
- }
- /* Fall through */
- case SNDRV_PCM_STATE_XRUN:
- _xrun_recovery:
- snd_pcm_change_state(substream,
- snd_pcm_capture_avail(runtime) > 0 ?
- SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP);
- break;
- case SNDRV_PCM_STATE_SUSPENDED:
- snd_pcm_stream_unlock_irq(substream);
- res = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile);
- snd_pcm_stream_lock_irq(substream);
- if (res >= 0)
- goto _xrun_recovery;
- break;
- default:
- break;