ALSA: usb-audio: Avoid unnecessary EP setups in prepare
authorTakashi Iwai <tiwai@suse.de>
Tue, 18 Sep 2012 12:49:31 +0000 (14:49 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 19 Sep 2012 06:08:16 +0000 (08:08 +0200)
The recent fix for USB suspend breakage moved the code to set up EP
from hw_params to prepare, but it means also the EP setup might be
called multiple times unnecessarily because the prepare callback can
be called multiple times without starting the stream (e.g. OSS
emulation).

This patch adds a new flag to struct snd_usb_substream indicating
whether the setup of EP is required, and do it only when necessary,
i.e. right after hw_params or suspend.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/card.c
sound/usb/card.h
sound/usb/pcm.c

index 4a469f0cb6d4750b03fab852d13515022fe0b4af..561bb74fd364ae388cb8dc2af548e014b0bb801b 100644 (file)
@@ -646,6 +646,8 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
                        list_for_each(p, &chip->pcm_list) {
                                as = list_entry(p, struct snd_usb_stream, list);
                                snd_pcm_suspend_all(as->pcm);
+                               as->substream[0].need_setup_ep =
+                                       as->substream[1].need_setup_ep = true;
                        }
                }
        } else {
index 6cc883c3567dff7f7a2b24640f9da9c8045608d2..afa4f9e9b27a2673b1fc955d680859cb7f964f02 100644 (file)
@@ -125,6 +125,7 @@ struct snd_usb_substream {
        struct snd_usb_endpoint *data_endpoint;
        struct snd_usb_endpoint *sync_endpoint;
        unsigned long flags;
+       bool need_setup_ep;             /* (re)configure EP at prepare? */
 
        u64 formats;                    /* format bitmasks (all or'ed) */
        unsigned int num_formats;               /* number of supported audio formats (list) */
index ae783d40f55aa31e0995999f330052367c646f0a..55e19e1b80ec4eeb282c91cea482ef7434cf8dce 100644 (file)
@@ -510,6 +510,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
 
        subs->interface = fmt->iface;
        subs->altset_idx = fmt->altset_idx;
+       subs->need_setup_ep = true;
 
        return 0;
 }
@@ -568,9 +569,12 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
        if (ret < 0)
                return ret;
 
-       ret = configure_endpoint(subs);
-       if (ret < 0)
-               return ret;
+       if (subs->need_setup_ep) {
+               ret = configure_endpoint(subs);
+               if (ret < 0)
+                       return ret;
+               subs->need_setup_ep = false;
+       }
 
        /* some unit conversions in runtime */
        subs->data_endpoint->maxframesize =