[PATCH] ALSA: snd-usb: fix calls to usb_set_interface

Daniel Mack zonque at gmail.com
Tue Jul 10 22:52:56 CEST 2012


Don't call usb_set_interface() on snd_usb_endpoint creation and also
drop it from snd_usb_endpoint_deactivate(). Rather unselect the the
active interface before choosing a new alt setting upon the next stream
start.

Signed-off-by: Daniel Mack <zonque at gmail.com>
---
 sound/usb/endpoint.c |   45 ++++++++++++++-------------------------------
 1 file changed, 14 insertions(+), 31 deletions(-)

diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index e690690..2226769 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -414,7 +414,7 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
 {
 	struct list_head *p;
 	struct snd_usb_endpoint *ep;
-	int ret, is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK;
+	int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK;
 
 	mutex_lock(&chip->mutex);
 
@@ -434,16 +434,6 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
 		    type == SND_USB_ENDPOINT_TYPE_DATA ? "data" : "sync",
 		    ep_num);
 
-	/* select the alt setting once so the endpoints become valid */
-	ret = usb_set_interface(chip->dev, alts->desc.bInterfaceNumber,
-				alts->desc.bAlternateSetting);
-	if (ret < 0) {
-		snd_printk(KERN_ERR "%s(): usb_set_interface() failed, ret = %d\n",
-					__func__, ret);
-		ep = NULL;
-		goto __exit_unlock;
-	}
-
 	ep = kzalloc(sizeof(*ep), GFP_KERNEL);
 	if (!ep)
 		goto __exit_unlock;
@@ -936,8 +926,8 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
  *
  * In case of any active users, this functions does nothing.
  *
- * Returns an error if usb_set_interface() failed, 0 in all other
- * cases.
+ * Returns an error if any of the usb_set_interface() calls failed, 0 in
+ * all other cases.
  */
 int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep)
 {
@@ -948,6 +938,14 @@ int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep)
 	    !test_and_set_bit(EP_FLAG_ACTIVATED, &ep->flags)) {
 		int ret;
 
+		ret = usb_set_interface(ep->chip->dev, ep->iface, 0);
+		if (ret < 0) {
+			snd_printk(KERN_ERR "%s() usb_set_interface() failed, ret = %d\n",
+						__func__, ret);
+			clear_bit(EP_FLAG_ACTIVATED, &ep->flags);
+			return ret;
+		}
+
 		ret = usb_set_interface(ep->chip->dev, ep->iface, ep->alt_idx);
 		if (ret < 0) {
 			snd_printk(KERN_ERR "%s() usb_set_interface() failed, ret = %d\n",
@@ -967,13 +965,8 @@ int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep)
  *
  * @ep: the endpoint to deactivate
  *
- * If the endpoint is not currently in use, this functions will select the
- * alternate interface setting 0 for the interface of this endpoint.
- *
- * In case of any active users, this functions does nothing.
- *
- * Returns an error if usb_set_interface() failed, 0 in all other
- * cases.
+ * Returns 0 on success, -EINVAL if ep was NULL and -EBUSY if the endpoint
+ * is still in use.
  */
 int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep)
 {
@@ -984,18 +977,8 @@ int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep)
 		return 0;
 
 	if (!ep->chip->shutdown &&
-	    test_and_clear_bit(EP_FLAG_ACTIVATED, &ep->flags)) {
-		int ret;
-
-		ret = usb_set_interface(ep->chip->dev, ep->iface, 0);
-		if (ret < 0) {
-			snd_printk(KERN_ERR "%s(): usb_set_interface() failed, ret = %d\n",
-						__func__, ret);
-			return ret;
-		}
-
+	    test_and_clear_bit(EP_FLAG_ACTIVATED, &ep->flags))
 		return 0;
-	}
 
 	return -EBUSY;
 }
-- 
1.7.10.4


--------------080102090909090401070304--


More information about the Alsa-devel mailing list