ALSA: pcm: Avoid reference to status->state

In the PCM core and driver code, there are lots place referring to the
current PCM state via runtime->status->state.  This patch introduced a
local PCM state in runtime itself and replaces those references with
runtime->state.  It has improvements in two aspects:

- The reduction of a indirect access leads to more code optimization

- It avoids a possible (unexpected) modification of the state via mmap
  of the status record

The status->state is updated together with runtime->state, so that
user-space can still read the current state via mmap like before,
too.

This patch touches only the ALSA core code.  The changes in each
driver will follow in later patches.

Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20220926135558.26580-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2022-09-26 15:55:48 +02:00
Родитель 69ab6f5b00
Коммит f0061c18c1
6 изменённых файлов: 118 добавлений и 100 удалений

Просмотреть файл

@ -346,6 +346,8 @@ static inline void snd_pcm_pack_audio_tstamp_report(__u32 *data, __u32 *accuracy
struct snd_pcm_runtime { struct snd_pcm_runtime {
/* -- Status -- */ /* -- Status -- */
snd_pcm_state_t state; /* stream state */
snd_pcm_state_t suspended_state; /* suspended stream state */
struct snd_pcm_substream *trigger_master; struct snd_pcm_substream *trigger_master;
struct timespec64 trigger_tstamp; /* trigger timestamp */ struct timespec64 trigger_tstamp; /* trigger timestamp */
bool trigger_tstamp_latched; /* trigger timestamp latched in low-level driver/hardware */ bool trigger_tstamp_latched; /* trigger timestamp latched in low-level driver/hardware */
@ -678,11 +680,25 @@ void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
*/ */
static inline int snd_pcm_running(struct snd_pcm_substream *substream) static inline int snd_pcm_running(struct snd_pcm_substream *substream)
{ {
return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING || return (substream->runtime->state == SNDRV_PCM_STATE_RUNNING ||
(substream->runtime->status->state == SNDRV_PCM_STATE_DRAINING && (substream->runtime->state == SNDRV_PCM_STATE_DRAINING &&
substream->stream == SNDRV_PCM_STREAM_PLAYBACK)); substream->stream == SNDRV_PCM_STREAM_PLAYBACK));
} }
/**
* __snd_pcm_set_state - Change the current PCM state
* @runtime: PCM runtime to set
* @state: the current state to set
*
* Call within the stream lock
*/
static inline void __snd_pcm_set_state(struct snd_pcm_runtime *runtime,
snd_pcm_state_t state)
{
runtime->state = state;
runtime->status->state = state; /* copy for mmap */
}
/** /**
* bytes_to_samples - Unit conversion of the size from bytes to samples * bytes_to_samples - Unit conversion of the size from bytes to samples
* @runtime: PCM runtime instance * @runtime: PCM runtime instance

Просмотреть файл

@ -1237,12 +1237,12 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
int ret; int ret;
while (1) { while (1) {
if (runtime->status->state == SNDRV_PCM_STATE_XRUN || if (runtime->state == SNDRV_PCM_STATE_XRUN ||
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { runtime->state == SNDRV_PCM_STATE_SUSPENDED) {
#ifdef OSS_DEBUG #ifdef OSS_DEBUG
pcm_dbg(substream->pcm, pcm_dbg(substream->pcm,
"pcm_oss: write: recovering from %s\n", "pcm_oss: write: recovering from %s\n",
runtime->status->state == SNDRV_PCM_STATE_XRUN ? runtime->state == SNDRV_PCM_STATE_XRUN ?
"XRUN" : "SUSPEND"); "XRUN" : "SUSPEND");
#endif #endif
ret = snd_pcm_oss_prepare(substream); ret = snd_pcm_oss_prepare(substream);
@ -1257,7 +1257,7 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const
break; break;
/* test, if we can't store new data, because the stream */ /* test, if we can't store new data, because the stream */
/* has not been started */ /* has not been started */
if (runtime->status->state == SNDRV_PCM_STATE_PREPARED) if (runtime->state == SNDRV_PCM_STATE_PREPARED)
return -EAGAIN; return -EAGAIN;
} }
return ret; return ret;
@ -1269,18 +1269,18 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p
snd_pcm_sframes_t delay; snd_pcm_sframes_t delay;
int ret; int ret;
while (1) { while (1) {
if (runtime->status->state == SNDRV_PCM_STATE_XRUN || if (runtime->state == SNDRV_PCM_STATE_XRUN ||
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { runtime->state == SNDRV_PCM_STATE_SUSPENDED) {
#ifdef OSS_DEBUG #ifdef OSS_DEBUG
pcm_dbg(substream->pcm, pcm_dbg(substream->pcm,
"pcm_oss: read: recovering from %s\n", "pcm_oss: read: recovering from %s\n",
runtime->status->state == SNDRV_PCM_STATE_XRUN ? runtime->state == SNDRV_PCM_STATE_XRUN ?
"XRUN" : "SUSPEND"); "XRUN" : "SUSPEND");
#endif #endif
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
if (ret < 0) if (ret < 0)
break; break;
} else if (runtime->status->state == SNDRV_PCM_STATE_SETUP) { } else if (runtime->state == SNDRV_PCM_STATE_SETUP) {
ret = snd_pcm_oss_prepare(substream); ret = snd_pcm_oss_prepare(substream);
if (ret < 0) if (ret < 0)
break; break;
@ -1293,7 +1293,7 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p
frames, in_kernel); frames, in_kernel);
mutex_lock(&runtime->oss.params_lock); mutex_lock(&runtime->oss.params_lock);
if (ret == -EPIPE) { if (ret == -EPIPE) {
if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { if (runtime->state == SNDRV_PCM_STATE_DRAINING) {
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
if (ret < 0) if (ret < 0)
break; break;
@ -1312,12 +1312,12 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
int ret; int ret;
while (1) { while (1) {
if (runtime->status->state == SNDRV_PCM_STATE_XRUN || if (runtime->state == SNDRV_PCM_STATE_XRUN ||
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { runtime->state == SNDRV_PCM_STATE_SUSPENDED) {
#ifdef OSS_DEBUG #ifdef OSS_DEBUG
pcm_dbg(substream->pcm, pcm_dbg(substream->pcm,
"pcm_oss: writev: recovering from %s\n", "pcm_oss: writev: recovering from %s\n",
runtime->status->state == SNDRV_PCM_STATE_XRUN ? runtime->state == SNDRV_PCM_STATE_XRUN ?
"XRUN" : "SUSPEND"); "XRUN" : "SUSPEND");
#endif #endif
ret = snd_pcm_oss_prepare(substream); ret = snd_pcm_oss_prepare(substream);
@ -1330,7 +1330,7 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void
/* test, if we can't store new data, because the stream */ /* test, if we can't store new data, because the stream */
/* has not been started */ /* has not been started */
if (runtime->status->state == SNDRV_PCM_STATE_PREPARED) if (runtime->state == SNDRV_PCM_STATE_PREPARED)
return -EAGAIN; return -EAGAIN;
} }
return ret; return ret;
@ -1341,18 +1341,18 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void *
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
int ret; int ret;
while (1) { while (1) {
if (runtime->status->state == SNDRV_PCM_STATE_XRUN || if (runtime->state == SNDRV_PCM_STATE_XRUN ||
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { runtime->state == SNDRV_PCM_STATE_SUSPENDED) {
#ifdef OSS_DEBUG #ifdef OSS_DEBUG
pcm_dbg(substream->pcm, pcm_dbg(substream->pcm,
"pcm_oss: readv: recovering from %s\n", "pcm_oss: readv: recovering from %s\n",
runtime->status->state == SNDRV_PCM_STATE_XRUN ? runtime->state == SNDRV_PCM_STATE_XRUN ?
"XRUN" : "SUSPEND"); "XRUN" : "SUSPEND");
#endif #endif
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
if (ret < 0) if (ret < 0)
break; break;
} else if (runtime->status->state == SNDRV_PCM_STATE_SETUP) { } else if (runtime->state == SNDRV_PCM_STATE_SETUP) {
ret = snd_pcm_oss_prepare(substream); ret = snd_pcm_oss_prepare(substream);
if (ret < 0) if (ret < 0)
break; break;
@ -1635,7 +1635,7 @@ static int snd_pcm_oss_sync1(struct snd_pcm_substream *substream, size_t size)
result = 0; result = 0;
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
state = runtime->status->state; state = runtime->state;
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
if (state != SNDRV_PCM_STATE_RUNNING) { if (state != SNDRV_PCM_STATE_RUNNING) {
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
@ -2854,8 +2854,8 @@ static __poll_t snd_pcm_oss_poll(struct file *file, poll_table * wait)
struct snd_pcm_runtime *runtime = psubstream->runtime; struct snd_pcm_runtime *runtime = psubstream->runtime;
poll_wait(file, &runtime->sleep, wait); poll_wait(file, &runtime->sleep, wait);
snd_pcm_stream_lock_irq(psubstream); snd_pcm_stream_lock_irq(psubstream);
if (runtime->status->state != SNDRV_PCM_STATE_DRAINING && if (runtime->state != SNDRV_PCM_STATE_DRAINING &&
(runtime->status->state != SNDRV_PCM_STATE_RUNNING || (runtime->state != SNDRV_PCM_STATE_RUNNING ||
snd_pcm_oss_playback_ready(psubstream))) snd_pcm_oss_playback_ready(psubstream)))
mask |= EPOLLOUT | EPOLLWRNORM; mask |= EPOLLOUT | EPOLLWRNORM;
snd_pcm_stream_unlock_irq(psubstream); snd_pcm_stream_unlock_irq(psubstream);
@ -2865,7 +2865,7 @@ static __poll_t snd_pcm_oss_poll(struct file *file, poll_table * wait)
snd_pcm_state_t ostate; snd_pcm_state_t ostate;
poll_wait(file, &runtime->sleep, wait); poll_wait(file, &runtime->sleep, wait);
snd_pcm_stream_lock_irq(csubstream); snd_pcm_stream_lock_irq(csubstream);
ostate = runtime->status->state; ostate = runtime->state;
if (ostate != SNDRV_PCM_STATE_RUNNING || if (ostate != SNDRV_PCM_STATE_RUNNING ||
snd_pcm_oss_capture_ready(csubstream)) snd_pcm_oss_capture_ready(csubstream))
mask |= EPOLLIN | EPOLLRDNORM; mask |= EPOLLIN | EPOLLRDNORM;

Просмотреть файл

@ -387,7 +387,7 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
snd_iprintf(buffer, "closed\n"); snd_iprintf(buffer, "closed\n");
goto unlock; goto unlock;
} }
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { if (runtime->state == SNDRV_PCM_STATE_OPEN) {
snd_iprintf(buffer, "no setup\n"); snd_iprintf(buffer, "no setup\n");
goto unlock; goto unlock;
} }
@ -424,7 +424,7 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
snd_iprintf(buffer, "closed\n"); snd_iprintf(buffer, "closed\n");
goto unlock; goto unlock;
} }
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { if (runtime->state == SNDRV_PCM_STATE_OPEN) {
snd_iprintf(buffer, "no setup\n"); snd_iprintf(buffer, "no setup\n");
goto unlock; goto unlock;
} }
@ -970,7 +970,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
init_waitqueue_head(&runtime->sleep); init_waitqueue_head(&runtime->sleep);
init_waitqueue_head(&runtime->tsleep); init_waitqueue_head(&runtime->tsleep);
runtime->status->state = SNDRV_PCM_STATE_OPEN; __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_OPEN);
mutex_init(&runtime->buffer_mutex); mutex_init(&runtime->buffer_mutex);
atomic_set(&runtime->buffer_accessing, 0); atomic_set(&runtime->buffer_accessing, 0);
@ -1112,7 +1112,8 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
if (snd_pcm_running(substream)) if (snd_pcm_running(substream))
snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
/* to be sure, set the state unconditionally */ /* to be sure, set the state unconditionally */
substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; __snd_pcm_set_state(substream->runtime,
SNDRV_PCM_STATE_DISCONNECTED);
wake_up(&substream->runtime->sleep); wake_up(&substream->runtime->sleep);
wake_up(&substream->runtime->tsleep); wake_up(&substream->runtime->tsleep);
} }

Просмотреть файл

@ -295,7 +295,7 @@ static int snd_pcm_ioctl_xferi_compat(struct snd_pcm_substream *substream,
return -ENOTTY; return -ENOTTY;
if (substream->stream != dir) if (substream->stream != dir)
return -EINVAL; return -EINVAL;
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) if (substream->runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD; return -EBADFD;
if (get_user(buf, &data32->buf) || if (get_user(buf, &data32->buf) ||
@ -341,7 +341,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
return -ENOTTY; return -ENOTTY;
if (substream->stream != dir) if (substream->stream != dir)
return -EINVAL; return -EINVAL;
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) if (substream->runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD; return -EBADFD;
ch = substream->runtime->channels; ch = substream->runtime->channels;

Просмотреть файл

@ -186,7 +186,7 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
avail = snd_pcm_avail(substream); avail = snd_pcm_avail(substream);
if (avail > runtime->avail_max) if (avail > runtime->avail_max)
runtime->avail_max = avail; runtime->avail_max = avail;
if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { if (runtime->state == SNDRV_PCM_STATE_DRAINING) {
if (avail >= runtime->buffer_size) { if (avail >= runtime->buffer_size) {
snd_pcm_drain_done(substream); snd_pcm_drain_done(substream);
return -EPIPE; return -EPIPE;
@ -1911,7 +1911,7 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
switch (runtime->status->state) { switch (runtime->state) {
case SNDRV_PCM_STATE_SUSPENDED: case SNDRV_PCM_STATE_SUSPENDED:
err = -ESTRPIPE; err = -ESTRPIPE;
goto _endloop; goto _endloop;
@ -2099,14 +2099,14 @@ static int pcm_sanity_check(struct snd_pcm_substream *substream)
runtime = substream->runtime; runtime = substream->runtime;
if (snd_BUG_ON(!substream->ops->copy_user && !runtime->dma_area)) if (snd_BUG_ON(!substream->ops->copy_user && !runtime->dma_area))
return -EINVAL; return -EINVAL;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) if (runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD; return -EBADFD;
return 0; return 0;
} }
static int pcm_accessible_state(struct snd_pcm_runtime *runtime) static int pcm_accessible_state(struct snd_pcm_runtime *runtime)
{ {
switch (runtime->status->state) { switch (runtime->state) {
case SNDRV_PCM_STATE_PREPARED: case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_RUNNING: case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_PAUSED: case SNDRV_PCM_STATE_PAUSED:
@ -2225,7 +2225,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
goto _end_unlock; goto _end_unlock;
runtime->twake = runtime->control->avail_min ? : 1; runtime->twake = runtime->control->avail_min ? : 1;
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) if (runtime->state == SNDRV_PCM_STATE_RUNNING)
snd_pcm_update_hw_ptr(substream); snd_pcm_update_hw_ptr(substream);
/* /*
@ -2233,7 +2233,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
* thread may start capture * thread may start capture
*/ */
if (!is_playback && if (!is_playback &&
runtime->status->state == SNDRV_PCM_STATE_PREPARED && runtime->state == SNDRV_PCM_STATE_PREPARED &&
size >= runtime->start_threshold) { size >= runtime->start_threshold) {
err = snd_pcm_start(substream); err = snd_pcm_start(substream);
if (err < 0) if (err < 0)
@ -2247,7 +2247,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
snd_pcm_uframes_t cont; snd_pcm_uframes_t cont;
if (!avail) { if (!avail) {
if (!is_playback && if (!is_playback &&
runtime->status->state == SNDRV_PCM_STATE_DRAINING) { runtime->state == SNDRV_PCM_STATE_DRAINING) {
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
goto _end_unlock; goto _end_unlock;
} }
@ -2303,7 +2303,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
xfer += frames; xfer += frames;
avail -= frames; avail -= frames;
if (is_playback && if (is_playback &&
runtime->status->state == SNDRV_PCM_STATE_PREPARED && runtime->state == SNDRV_PCM_STATE_PREPARED &&
snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) { snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) {
err = snd_pcm_start(substream); err = snd_pcm_start(substream);
if (err < 0) if (err < 0)

Просмотреть файл

@ -595,8 +595,8 @@ static void snd_pcm_set_state(struct snd_pcm_substream *substream,
snd_pcm_state_t state) snd_pcm_state_t state)
{ {
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED) if (substream->runtime->state != SNDRV_PCM_STATE_DISCONNECTED)
substream->runtime->status->state = state; __snd_pcm_set_state(substream->runtime, state);
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
} }
@ -724,7 +724,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
if (err < 0) if (err < 0)
return err; return err;
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) { switch (runtime->state) {
case SNDRV_PCM_STATE_OPEN: case SNDRV_PCM_STATE_OPEN:
case SNDRV_PCM_STATE_SETUP: case SNDRV_PCM_STATE_SETUP:
case SNDRV_PCM_STATE_PREPARED: case SNDRV_PCM_STATE_PREPARED:
@ -889,7 +889,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
if (result < 0) if (result < 0)
return result; return result;
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) { switch (runtime->state) {
case SNDRV_PCM_STATE_SETUP: case SNDRV_PCM_STATE_SETUP:
case SNDRV_PCM_STATE_PREPARED: case SNDRV_PCM_STATE_PREPARED:
if (atomic_read(&substream->mmap_count)) if (atomic_read(&substream->mmap_count))
@ -920,7 +920,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
return -ENXIO; return -ENXIO;
runtime = substream->runtime; runtime = substream->runtime;
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { if (runtime->state == SNDRV_PCM_STATE_OPEN) {
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
return -EBADFD; return -EBADFD;
} }
@ -1013,8 +1013,8 @@ int snd_pcm_status64(struct snd_pcm_substream *substream,
} else } else
runtime->audio_tstamp_report.valid = 1; runtime->audio_tstamp_report.valid = 1;
status->state = runtime->status->state; status->state = runtime->state;
status->suspended_state = runtime->status->suspended_state; status->suspended_state = runtime->suspended_state;
if (status->state == SNDRV_PCM_STATE_OPEN) if (status->state == SNDRV_PCM_STATE_OPEN)
goto _end; goto _end;
status->trigger_tstamp_sec = runtime->trigger_tstamp.tv_sec; status->trigger_tstamp_sec = runtime->trigger_tstamp.tv_sec;
@ -1148,7 +1148,7 @@ static int snd_pcm_channel_info(struct snd_pcm_substream *substream,
channel = info->channel; channel = info->channel;
runtime = substream->runtime; runtime = substream->runtime;
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { if (runtime->state == SNDRV_PCM_STATE_OPEN) {
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
return -EBADFD; return -EBADFD;
} }
@ -1411,7 +1411,7 @@ static int snd_pcm_pre_start(struct snd_pcm_substream *substream,
snd_pcm_state_t state) snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
if (runtime->status->state != SNDRV_PCM_STATE_PREPARED) if (runtime->state != SNDRV_PCM_STATE_PREPARED)
return -EBADFD; return -EBADFD;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
!snd_pcm_playback_data(substream)) !snd_pcm_playback_data(substream))
@ -1444,7 +1444,7 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream,
runtime->hw_ptr_jiffies = jiffies; runtime->hw_ptr_jiffies = jiffies;
runtime->hw_ptr_buffer_jiffies = (runtime->buffer_size * HZ) / runtime->hw_ptr_buffer_jiffies = (runtime->buffer_size * HZ) /
runtime->rate; runtime->rate;
runtime->status->state = state; __snd_pcm_set_state(runtime, state);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
runtime->silence_size > 0) runtime->silence_size > 0)
snd_pcm_playback_silence(substream, ULONG_MAX); snd_pcm_playback_silence(substream, ULONG_MAX);
@ -1485,7 +1485,7 @@ static int snd_pcm_pre_stop(struct snd_pcm_substream *substream,
snd_pcm_state_t state) snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) if (runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD; return -EBADFD;
runtime->trigger_master = substream; runtime->trigger_master = substream;
return 0; return 0;
@ -1506,9 +1506,9 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream,
snd_pcm_state_t state) snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
if (runtime->status->state != state) { if (runtime->state != state) {
snd_pcm_trigger_tstamp(substream); snd_pcm_trigger_tstamp(substream);
runtime->status->state = state; __snd_pcm_set_state(runtime, state);
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP); snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP);
} }
wake_up(&runtime->sleep); wake_up(&runtime->sleep);
@ -1584,9 +1584,9 @@ static int snd_pcm_pre_pause(struct snd_pcm_substream *substream,
if (!(runtime->info & SNDRV_PCM_INFO_PAUSE)) if (!(runtime->info & SNDRV_PCM_INFO_PAUSE))
return -ENOSYS; return -ENOSYS;
if (pause_pushed(state)) { if (pause_pushed(state)) {
if (runtime->status->state != SNDRV_PCM_STATE_RUNNING) if (runtime->state != SNDRV_PCM_STATE_RUNNING)
return -EBADFD; return -EBADFD;
} else if (runtime->status->state != SNDRV_PCM_STATE_PAUSED) } else if (runtime->state != SNDRV_PCM_STATE_PAUSED)
return -EBADFD; return -EBADFD;
runtime->trigger_master = substream; runtime->trigger_master = substream;
return 0; return 0;
@ -1628,12 +1628,12 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream); snd_pcm_trigger_tstamp(substream);
if (pause_pushed(state)) { if (pause_pushed(state)) {
runtime->status->state = SNDRV_PCM_STATE_PAUSED; __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_PAUSED);
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MPAUSE); snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MPAUSE);
wake_up(&runtime->sleep); wake_up(&runtime->sleep);
wake_up(&runtime->tsleep); wake_up(&runtime->tsleep);
} else { } else {
runtime->status->state = SNDRV_PCM_STATE_RUNNING; __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_RUNNING);
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MCONTINUE); snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MCONTINUE);
} }
} }
@ -1668,7 +1668,7 @@ static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream,
snd_pcm_state_t state) snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
switch (runtime->status->state) { switch (runtime->state) {
case SNDRV_PCM_STATE_SUSPENDED: case SNDRV_PCM_STATE_SUSPENDED:
return -EBUSY; return -EBUSY;
/* unresumable PCM state; return -EBUSY for skipping suspend */ /* unresumable PCM state; return -EBUSY for skipping suspend */
@ -1699,8 +1699,9 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream,
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream); snd_pcm_trigger_tstamp(substream);
runtime->status->suspended_state = runtime->status->state; runtime->suspended_state = runtime->state;
runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; runtime->status->suspended_state = runtime->suspended_state;
__snd_pcm_set_state(runtime, SNDRV_PCM_STATE_SUSPENDED);
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSUSPEND); snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSUSPEND);
wake_up(&runtime->sleep); wake_up(&runtime->sleep);
wake_up(&runtime->tsleep); wake_up(&runtime->tsleep);
@ -1791,8 +1792,8 @@ static int snd_pcm_do_resume(struct snd_pcm_substream *substream,
if (runtime->trigger_master != substream) if (runtime->trigger_master != substream)
return 0; return 0;
/* DMA not running previously? */ /* DMA not running previously? */
if (runtime->status->suspended_state != SNDRV_PCM_STATE_RUNNING && if (runtime->suspended_state != SNDRV_PCM_STATE_RUNNING &&
(runtime->status->suspended_state != SNDRV_PCM_STATE_DRAINING || (runtime->suspended_state != SNDRV_PCM_STATE_DRAINING ||
substream->stream != SNDRV_PCM_STREAM_PLAYBACK)) substream->stream != SNDRV_PCM_STREAM_PLAYBACK))
return 0; return 0;
return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME); return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME);
@ -1811,7 +1812,7 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream,
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream); snd_pcm_trigger_tstamp(substream);
runtime->status->state = runtime->status->suspended_state; __snd_pcm_set_state(runtime, runtime->suspended_state);
snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME); snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME);
} }
@ -1848,7 +1849,7 @@ static int snd_pcm_xrun(struct snd_pcm_substream *substream)
int result; int result;
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) { switch (runtime->state) {
case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN:
result = 0; /* already there */ result = 0; /* already there */
break; break;
@ -1871,7 +1872,7 @@ static int snd_pcm_pre_reset(struct snd_pcm_substream *substream,
snd_pcm_state_t state) snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
switch (runtime->status->state) { switch (runtime->state) {
case SNDRV_PCM_STATE_RUNNING: case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_PREPARED: case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_PAUSED: case SNDRV_PCM_STATE_PAUSED:
@ -1933,8 +1934,8 @@ static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
int f_flags = (__force int)state; int f_flags = (__force int)state;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN || if (runtime->state == SNDRV_PCM_STATE_OPEN ||
runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD; return -EBADFD;
if (snd_pcm_running(substream)) if (snd_pcm_running(substream))
return -EBUSY; return -EBUSY;
@ -1985,7 +1986,7 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream,
f_flags = substream->f_flags; f_flags = substream->f_flags;
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
switch (substream->runtime->status->state) { switch (substream->runtime->state) {
case SNDRV_PCM_STATE_PAUSED: case SNDRV_PCM_STATE_PAUSED:
snd_pcm_pause(substream, false); snd_pcm_pause(substream, false);
fallthrough; fallthrough;
@ -2009,7 +2010,7 @@ static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream,
snd_pcm_state_t state) snd_pcm_state_t state)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
switch (runtime->status->state) { switch (runtime->state) {
case SNDRV_PCM_STATE_OPEN: case SNDRV_PCM_STATE_OPEN:
case SNDRV_PCM_STATE_DISCONNECTED: case SNDRV_PCM_STATE_DISCONNECTED:
case SNDRV_PCM_STATE_SUSPENDED: case SNDRV_PCM_STATE_SUSPENDED:
@ -2024,28 +2025,28 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream,
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
switch (runtime->status->state) { switch (runtime->state) {
case SNDRV_PCM_STATE_PREPARED: case SNDRV_PCM_STATE_PREPARED:
/* start playback stream if possible */ /* start playback stream if possible */
if (! snd_pcm_playback_empty(substream)) { if (! snd_pcm_playback_empty(substream)) {
snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING); snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING);
snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING); snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING);
} else { } else {
runtime->status->state = SNDRV_PCM_STATE_SETUP; __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_SETUP);
} }
break; break;
case SNDRV_PCM_STATE_RUNNING: case SNDRV_PCM_STATE_RUNNING:
runtime->status->state = SNDRV_PCM_STATE_DRAINING; __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_DRAINING);
break; break;
case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN:
runtime->status->state = SNDRV_PCM_STATE_SETUP; __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_SETUP);
break; break;
default: default:
break; break;
} }
} else { } else {
/* stop running stream */ /* stop running stream */
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) { if (runtime->state == SNDRV_PCM_STATE_RUNNING) {
snd_pcm_state_t new_state; snd_pcm_state_t new_state;
new_state = snd_pcm_capture_avail(runtime) > 0 ? new_state = snd_pcm_capture_avail(runtime) > 0 ?
@ -2055,7 +2056,7 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream,
} }
} }
if (runtime->status->state == SNDRV_PCM_STATE_DRAINING && if (runtime->state == SNDRV_PCM_STATE_DRAINING &&
runtime->trigger_master == substream && runtime->trigger_master == substream &&
(runtime->hw.info & SNDRV_PCM_INFO_DRAIN_TRIGGER)) (runtime->hw.info & SNDRV_PCM_INFO_DRAIN_TRIGGER))
return substream->ops->trigger(substream, return substream->ops->trigger(substream,
@ -2096,7 +2097,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
card = substream->pcm->card; card = substream->pcm->card;
runtime = substream->runtime; runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) if (runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD; return -EBADFD;
if (file) { if (file) {
@ -2107,7 +2108,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
/* resume pause */ /* resume pause */
if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) if (runtime->state == SNDRV_PCM_STATE_PAUSED)
snd_pcm_pause(substream, false); snd_pcm_pause(substream, false);
/* pre-start/stop - all running streams are changed to DRAINING state */ /* pre-start/stop - all running streams are changed to DRAINING state */
@ -2135,7 +2136,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
if (s->stream != SNDRV_PCM_STREAM_PLAYBACK) if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
continue; continue;
runtime = s->runtime; runtime = s->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { if (runtime->state == SNDRV_PCM_STATE_DRAINING) {
to_check = runtime; to_check = runtime;
break; break;
} }
@ -2174,7 +2175,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
break; break;
} }
if (tout == 0) { if (tout == 0) {
if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) if (substream->runtime->state == SNDRV_PCM_STATE_SUSPENDED)
result = -ESTRPIPE; result = -ESTRPIPE;
else { else {
dev_dbg(substream->pcm->card->dev, dev_dbg(substream->pcm->card->dev,
@ -2206,13 +2207,13 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
return -ENXIO; return -ENXIO;
runtime = substream->runtime; runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN || if (runtime->state == SNDRV_PCM_STATE_OPEN ||
runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD; return -EBADFD;
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
/* resume pause */ /* resume pause */
if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) if (runtime->state == SNDRV_PCM_STATE_PAUSED)
snd_pcm_pause(substream, false); snd_pcm_pause(substream, false);
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
@ -2275,8 +2276,8 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
snd_pcm_group_init(group); snd_pcm_group_init(group);
down_write(&snd_pcm_link_rwsem); down_write(&snd_pcm_link_rwsem);
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN || if (substream->runtime->state == SNDRV_PCM_STATE_OPEN ||
substream->runtime->status->state != substream1->runtime->status->state || substream->runtime->state != substream1->runtime->state ||
substream->pcm->nonatomic != substream1->pcm->nonatomic) { substream->pcm->nonatomic != substream1->pcm->nonatomic) {
res = -EBADFD; res = -EBADFD;
goto _end; goto _end;
@ -2700,7 +2701,7 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream)
snd_pcm_drop(substream); snd_pcm_drop(substream);
if (substream->hw_opened) { if (substream->hw_opened) {
if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) if (substream->runtime->state != SNDRV_PCM_STATE_OPEN)
do_hw_free(substream); do_hw_free(substream);
substream->ops->close(substream); substream->ops->close(substream);
substream->hw_opened = 0; substream->hw_opened = 0;
@ -2904,7 +2905,7 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
*/ */
static int do_pcm_hwsync(struct snd_pcm_substream *substream) static int do_pcm_hwsync(struct snd_pcm_substream *substream)
{ {
switch (substream->runtime->status->state) { switch (substream->runtime->state) {
case SNDRV_PCM_STATE_DRAINING: case SNDRV_PCM_STATE_DRAINING:
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
return -EBADFD; return -EBADFD;
@ -3203,7 +3204,7 @@ static int snd_pcm_xferi_frames_ioctl(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_sframes_t result; snd_pcm_sframes_t result;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) if (runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD; return -EBADFD;
if (put_user(0, &_xferi->result)) if (put_user(0, &_xferi->result))
return -EFAULT; return -EFAULT;
@ -3226,7 +3227,7 @@ static int snd_pcm_xfern_frames_ioctl(struct snd_pcm_substream *substream,
void *bufs; void *bufs;
snd_pcm_sframes_t result; snd_pcm_sframes_t result;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) if (runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD; return -EBADFD;
if (runtime->channels > 128) if (runtime->channels > 128)
return -EINVAL; return -EINVAL;
@ -3290,7 +3291,7 @@ static int snd_pcm_common_ioctl(struct file *file,
if (PCM_RUNTIME_CHECK(substream)) if (PCM_RUNTIME_CHECK(substream))
return -ENXIO; return -ENXIO;
if (substream->runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) if (substream->runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD; return -EBADFD;
res = snd_power_wait(substream->pcm->card); res = snd_power_wait(substream->pcm->card);
@ -3421,7 +3422,7 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
snd_pcm_uframes_t *frames = arg; snd_pcm_uframes_t *frames = arg;
snd_pcm_sframes_t result; snd_pcm_sframes_t result;
if (substream->runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) if (substream->runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD; return -EBADFD;
switch (cmd) { switch (cmd) {
@ -3466,8 +3467,8 @@ static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
if (PCM_RUNTIME_CHECK(substream)) if (PCM_RUNTIME_CHECK(substream))
return -ENXIO; return -ENXIO;
runtime = substream->runtime; runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN || if (runtime->state == SNDRV_PCM_STATE_OPEN ||
runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD; return -EBADFD;
if (!frame_aligned(runtime, count)) if (!frame_aligned(runtime, count))
return -EINVAL; return -EINVAL;
@ -3491,8 +3492,8 @@ static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
if (PCM_RUNTIME_CHECK(substream)) if (PCM_RUNTIME_CHECK(substream))
return -ENXIO; return -ENXIO;
runtime = substream->runtime; runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN || if (runtime->state == SNDRV_PCM_STATE_OPEN ||
runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD; return -EBADFD;
if (!frame_aligned(runtime, count)) if (!frame_aligned(runtime, count))
return -EINVAL; return -EINVAL;
@ -3518,8 +3519,8 @@ static ssize_t snd_pcm_readv(struct kiocb *iocb, struct iov_iter *to)
if (PCM_RUNTIME_CHECK(substream)) if (PCM_RUNTIME_CHECK(substream))
return -ENXIO; return -ENXIO;
runtime = substream->runtime; runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN || if (runtime->state == SNDRV_PCM_STATE_OPEN ||
runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD; return -EBADFD;
if (!iter_is_iovec(to)) if (!iter_is_iovec(to))
return -EINVAL; return -EINVAL;
@ -3555,8 +3556,8 @@ static ssize_t snd_pcm_writev(struct kiocb *iocb, struct iov_iter *from)
if (PCM_RUNTIME_CHECK(substream)) if (PCM_RUNTIME_CHECK(substream))
return -ENXIO; return -ENXIO;
runtime = substream->runtime; runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN || if (runtime->state == SNDRV_PCM_STATE_OPEN ||
runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD; return -EBADFD;
if (!iter_is_iovec(from)) if (!iter_is_iovec(from))
return -EINVAL; return -EINVAL;
@ -3595,7 +3596,7 @@ static __poll_t snd_pcm_poll(struct file *file, poll_table *wait)
return ok | EPOLLERR; return ok | EPOLLERR;
runtime = substream->runtime; runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) if (runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return ok | EPOLLERR; return ok | EPOLLERR;
poll_wait(file, &runtime->sleep, wait); poll_wait(file, &runtime->sleep, wait);
@ -3603,7 +3604,7 @@ static __poll_t snd_pcm_poll(struct file *file, poll_table *wait)
mask = 0; mask = 0;
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
avail = snd_pcm_avail(substream); avail = snd_pcm_avail(substream);
switch (runtime->status->state) { switch (runtime->state) {
case SNDRV_PCM_STATE_RUNNING: case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_PREPARED: case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_PAUSED: case SNDRV_PCM_STATE_PAUSED:
@ -3874,7 +3875,7 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
return -EINVAL; return -EINVAL;
} }
runtime = substream->runtime; runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) if (runtime->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD; return -EBADFD;
if (!(runtime->info & SNDRV_PCM_INFO_MMAP)) if (!(runtime->info & SNDRV_PCM_INFO_MMAP))
return -ENXIO; return -ENXIO;
@ -3911,7 +3912,7 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
substream = pcm_file->substream; substream = pcm_file->substream;
if (PCM_RUNTIME_CHECK(substream)) if (PCM_RUNTIME_CHECK(substream))
return -ENXIO; return -ENXIO;
if (substream->runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) if (substream->runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD; return -EBADFD;
offset = area->vm_pgoff << PAGE_SHIFT; offset = area->vm_pgoff << PAGE_SHIFT;
@ -3949,7 +3950,7 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
if (PCM_RUNTIME_CHECK(substream)) if (PCM_RUNTIME_CHECK(substream))
return -ENXIO; return -ENXIO;
runtime = substream->runtime; runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) if (runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return -EBADFD; return -EBADFD;
return snd_fasync_helper(fd, file, on, &runtime->fasync); return snd_fasync_helper(fd, file, on, &runtime->fasync);
} }