summaryrefslogtreecommitdiff
path: root/sound/core/pcm_native.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-05-19 20:04:23 +0200
committerTakashi Iwai <tiwai@suse.de>2017-05-21 08:57:31 +0200
commitf839cc1cbd29f2160ef4e621b920e254cc84133a (patch)
tree70c472a4897b282059a54f3efe4f0940cedb62e0 /sound/core/pcm_native.c
parentdcab5fb7a5b0472e035da7dfe21168802c1b9d3b (diff)
ALSA: pcm: Use a common helper for PCM state check and hwsync
The mostly same codes for checking the current PCM state and calling hwsync are found in a few places. This patch simplifies them by creating a common helper function. It also fixes a couple of cases where we missed the proper state check (e.g. PAUSED state wasn't handled in rewind and snd_pcm_hwsync()), too. Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core/pcm_native.c')
-rw-r--r--sound/core/pcm_native.c153
1 files changed, 35 insertions, 118 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index f3a3580eb44c..93bd2c662c1d 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2431,6 +2431,30 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
return 0;
}
+/* check and update PCM state; return 0 or a negative error
+ * call this inside PCM lock
+ */
+static int do_pcm_hwsync(struct snd_pcm_substream *substream)
+{
+ switch (substream->runtime->status->state) {
+ case SNDRV_PCM_STATE_DRAINING:
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ return -EBADFD;
+ /* Fall through */
+ case SNDRV_PCM_STATE_RUNNING:
+ return snd_pcm_update_hw_ptr(substream);
+ case SNDRV_PCM_STATE_PREPARED:
+ case SNDRV_PCM_STATE_PAUSED:
+ return 0;
+ case SNDRV_PCM_STATE_SUSPENDED:
+ return -ESTRPIPE;
+ case SNDRV_PCM_STATE_XRUN:
+ return -EPIPE;
+ default:
+ return -EBADFD;
+ }
+}
+
static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *substream,
snd_pcm_uframes_t frames)
{
@@ -2443,25 +2467,9 @@ static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *subst
return 0;
snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_PREPARED:
- break;
- case SNDRV_PCM_STATE_DRAINING:
- case SNDRV_PCM_STATE_RUNNING:
- if (snd_pcm_update_hw_ptr(substream) >= 0)
- break;
- /* Fall through */
- case SNDRV_PCM_STATE_XRUN:
- ret = -EPIPE;
- goto __end;
- case SNDRV_PCM_STATE_SUSPENDED:
- ret = -ESTRPIPE;
- goto __end;
- default:
- ret = -EBADFD;
+ ret = do_pcm_hwsync(substream);
+ if (ret < 0)
goto __end;
- }
-
hw_avail = snd_pcm_playback_hw_avail(runtime);
if (hw_avail <= 0) {
ret = 0;
@@ -2491,25 +2499,9 @@ static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substr
return 0;
snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_DRAINING:
- break;
- case SNDRV_PCM_STATE_RUNNING:
- if (snd_pcm_update_hw_ptr(substream) >= 0)
- break;
- /* Fall through */
- case SNDRV_PCM_STATE_XRUN:
- ret = -EPIPE;
+ ret = do_pcm_hwsync(substream);
+ if (ret < 0)
goto __end;
- case SNDRV_PCM_STATE_SUSPENDED:
- ret = -ESTRPIPE;
- goto __end;
- default:
- ret = -EBADFD;
- goto __end;
- }
-
hw_avail = snd_pcm_capture_hw_avail(runtime);
if (hw_avail <= 0) {
ret = 0;
@@ -2539,26 +2531,9 @@ static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *subs
return 0;
snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_PAUSED:
- break;
- case SNDRV_PCM_STATE_DRAINING:
- case SNDRV_PCM_STATE_RUNNING:
- if (snd_pcm_update_hw_ptr(substream) >= 0)
- break;
- /* Fall through */
- case SNDRV_PCM_STATE_XRUN:
- ret = -EPIPE;
- goto __end;
- case SNDRV_PCM_STATE_SUSPENDED:
- ret = -ESTRPIPE;
+ ret = do_pcm_hwsync(substream);
+ if (ret < 0)
goto __end;
- default:
- ret = -EBADFD;
- goto __end;
- }
-
avail = snd_pcm_playback_avail(runtime);
if (avail <= 0) {
ret = 0;
@@ -2588,26 +2563,9 @@ static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *subst
return 0;
snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_DRAINING:
- case SNDRV_PCM_STATE_PAUSED:
- break;
- case SNDRV_PCM_STATE_RUNNING:
- if (snd_pcm_update_hw_ptr(substream) >= 0)
- break;
- /* Fall through */
- case SNDRV_PCM_STATE_XRUN:
- ret = -EPIPE;
- goto __end;
- case SNDRV_PCM_STATE_SUSPENDED:
- ret = -ESTRPIPE;
+ ret = do_pcm_hwsync(substream);
+ if (ret < 0)
goto __end;
- default:
- ret = -EBADFD;
- goto __end;
- }
-
avail = snd_pcm_capture_avail(runtime);
if (avail <= 0) {
ret = 0;
@@ -2627,33 +2585,10 @@ static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *subst
static int snd_pcm_hwsync(struct snd_pcm_substream *substream)
{
- struct snd_pcm_runtime *runtime = substream->runtime;
int err;
snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_DRAINING:
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- goto __badfd;
- /* Fall through */
- case SNDRV_PCM_STATE_RUNNING:
- if ((err = snd_pcm_update_hw_ptr(substream)) < 0)
- break;
- /* Fall through */
- case SNDRV_PCM_STATE_PREPARED:
- err = 0;
- break;
- case SNDRV_PCM_STATE_SUSPENDED:
- err = -ESTRPIPE;
- break;
- case SNDRV_PCM_STATE_XRUN:
- err = -EPIPE;
- break;
- default:
- __badfd:
- err = -EBADFD;
- break;
- }
+ err = do_pcm_hwsync(substream);
snd_pcm_stream_unlock_irq(substream);
return err;
}
@@ -2666,31 +2601,13 @@ static int snd_pcm_delay(struct snd_pcm_substream *substream,
snd_pcm_sframes_t n = 0;
snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_DRAINING:
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- goto __badfd;
- /* Fall through */
- case SNDRV_PCM_STATE_RUNNING:
- if ((err = snd_pcm_update_hw_ptr(substream)) < 0)
- break;
- /* Fall through */
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_SUSPENDED:
- err = 0;
+ err = do_pcm_hwsync(substream);
+ if (!err) {
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
n = snd_pcm_playback_hw_avail(runtime);
else
n = snd_pcm_capture_avail(runtime);
n += runtime->delay;
- break;
- case SNDRV_PCM_STATE_XRUN:
- err = -EPIPE;
- break;
- default:
- __badfd:
- err = -EBADFD;
- break;
}
snd_pcm_stream_unlock_irq(substream);
if (!err)