]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ALSA: pcm: Apply power lock globally to common ioctls
authorTakashi Iwai <tiwai@suse.de>
Tue, 24 May 2016 13:07:39 +0000 (15:07 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 14 Jun 2017 05:43:44 +0000 (07:43 +0200)
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: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/core/pcm_native.c

index 798bca967c0e5ee5fcbe710d4e71574dd0953a25..bd1b74aa20682df02b91a8dd8363c34a3f75b253 100644 (file)
@@ -1540,14 +1540,7 @@ static const struct action_ops snd_pcm_action_resume = {
 
 static int snd_pcm_resume(struct snd_pcm_substream *substream)
 {
-       struct snd_card *card = substream->pcm->card;
-       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;
+       return snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0);
 }
 
 #else
@@ -1566,17 +1559,9 @@ static int snd_pcm_resume(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;
        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);
        switch (runtime->status->state) {
        case SNDRV_PCM_STATE_XRUN:
@@ -1589,8 +1574,6 @@ static int snd_pcm_xrun(struct snd_pcm_substream *substream)
                result = -EBADFD;
        }
        snd_pcm_stream_unlock_irq(substream);
- _unlock:
-       snd_power_unlock(card);
        return result;
 }
 
@@ -1694,8 +1677,6 @@ static const struct action_ops snd_pcm_action_prepare = {
 static int snd_pcm_prepare(struct snd_pcm_substream *substream,
                           struct file *file)
 {
-       int res;
-       struct snd_card *card = substream->pcm->card;
        int f_flags;
 
        if (file)
@@ -1703,12 +1684,8 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream,
        else
                f_flags = substream->f_flags;
 
-       snd_power_lock(card);
-       if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
-               res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
-                                              substream, f_flags);
-       snd_power_unlock(card);
-       return res;
+       return snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
+                                       substream, f_flags);
 }
 
 /*
@@ -1805,15 +1782,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
                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->f_flags & O_NONBLOCK)
                        nonblock = 1;
@@ -1896,7 +1864,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
  unlock:
        snd_pcm_stream_unlock_irq(substream);
        up_read(&snd_pcm_link_rwsem);
-       snd_power_unlock(card);
 
        return result;
 }
@@ -2798,7 +2765,7 @@ static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
        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,
                                 unsigned int cmd, void __user *arg)
 {
@@ -2873,6 +2840,21 @@ static int snd_pcm_common_ioctl1(struct file *file,
        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,
                                   struct snd_pcm_substream *substream,
                                   unsigned int cmd, void __user *arg)