Commit 68b4acd3 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: pcm: Apply power lock globally to common ioctls

All PCM common ioctls should run only in the powered up state, but
currently only a few ioctls do the proper snd_power_lock() and
snd_power_wait() invocations.  Instead of adding to each place, do it
commonly in the caller side, so that all these ioctls are assured to
be operated at the power up state.
Reviewed-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 34bcc44a
...@@ -1540,14 +1540,7 @@ static const struct action_ops snd_pcm_action_resume = { ...@@ -1540,14 +1540,7 @@ static const struct action_ops snd_pcm_action_resume = {
static int snd_pcm_resume(struct snd_pcm_substream *substream) static int snd_pcm_resume(struct snd_pcm_substream *substream)
{ {
struct snd_card *card = substream->pcm->card; return snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0);
int res;
snd_power_lock(card);
if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
res = snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0);
snd_power_unlock(card);
return res;
} }
#else #else
...@@ -1566,17 +1559,9 @@ static int snd_pcm_resume(struct snd_pcm_substream *substream) ...@@ -1566,17 +1559,9 @@ static int snd_pcm_resume(struct snd_pcm_substream *substream)
*/ */
static int snd_pcm_xrun(struct snd_pcm_substream *substream) static int snd_pcm_xrun(struct snd_pcm_substream *substream)
{ {
struct snd_card *card = substream->pcm->card;
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
int result; int result;
snd_power_lock(card);
if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
if (result < 0)
goto _unlock;
}
snd_pcm_stream_lock_irq(substream); snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) { switch (runtime->status->state) {
case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN:
...@@ -1589,8 +1574,6 @@ static int snd_pcm_xrun(struct snd_pcm_substream *substream) ...@@ -1589,8 +1574,6 @@ static int snd_pcm_xrun(struct snd_pcm_substream *substream)
result = -EBADFD; result = -EBADFD;
} }
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
_unlock:
snd_power_unlock(card);
return result; return result;
} }
...@@ -1694,8 +1677,6 @@ static const struct action_ops snd_pcm_action_prepare = { ...@@ -1694,8 +1677,6 @@ static const struct action_ops snd_pcm_action_prepare = {
static int snd_pcm_prepare(struct snd_pcm_substream *substream, static int snd_pcm_prepare(struct snd_pcm_substream *substream,
struct file *file) struct file *file)
{ {
int res;
struct snd_card *card = substream->pcm->card;
int f_flags; int f_flags;
if (file) if (file)
...@@ -1703,12 +1684,8 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream, ...@@ -1703,12 +1684,8 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream,
else else
f_flags = substream->f_flags; f_flags = substream->f_flags;
snd_power_lock(card); return snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) substream, f_flags);
res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
substream, f_flags);
snd_power_unlock(card);
return res;
} }
/* /*
...@@ -1805,15 +1782,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, ...@@ -1805,15 +1782,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD; return -EBADFD;
snd_power_lock(card);
if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
if (result < 0) {
snd_power_unlock(card);
return result;
}
}
if (file) { if (file) {
if (file->f_flags & O_NONBLOCK) if (file->f_flags & O_NONBLOCK)
nonblock = 1; nonblock = 1;
...@@ -1896,7 +1864,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, ...@@ -1896,7 +1864,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
unlock: unlock:
snd_pcm_stream_unlock_irq(substream); snd_pcm_stream_unlock_irq(substream);
up_read(&snd_pcm_link_rwsem); up_read(&snd_pcm_link_rwsem);
snd_power_unlock(card);
return result; return result;
} }
...@@ -2798,7 +2765,7 @@ static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg) ...@@ -2798,7 +2765,7 @@ static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
return 0; return 0;
} }
static int snd_pcm_common_ioctl1(struct file *file, static int snd_pcm_common_ioctl(struct file *file,
struct snd_pcm_substream *substream, struct snd_pcm_substream *substream,
unsigned int cmd, void __user *arg) unsigned int cmd, void __user *arg)
{ {
...@@ -2873,6 +2840,21 @@ static int snd_pcm_common_ioctl1(struct file *file, ...@@ -2873,6 +2840,21 @@ static int snd_pcm_common_ioctl1(struct file *file,
return -ENOTTY; return -ENOTTY;
} }
static int snd_pcm_common_ioctl1(struct file *file,
struct snd_pcm_substream *substream,
unsigned int cmd, void __user *arg)
{
struct snd_card *card = substream->pcm->card;
int res;
snd_power_lock(card);
res = snd_power_wait(card, SNDRV_CTL_POWER_D0);
if (res >= 0)
res = snd_pcm_common_ioctl(file, substream, cmd, arg);
snd_power_unlock(card);
return res;
}
static int snd_pcm_playback_ioctl1(struct file *file, static int snd_pcm_playback_ioctl1(struct file *file,
struct snd_pcm_substream *substream, struct snd_pcm_substream *substream,
unsigned int cmd, void __user *arg) unsigned int cmd, void __user *arg)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment