History

Merge tag 'sound-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai: "Containing the regression fixes for USB-audio due to the transition to the new streaming logic, mostly found on Logitech webcams." * tag 'sound-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: snd-usb: move calls to usb_set_interface ALSA: usb-audio: Fix the first PCM interface assignment

Linus Torvalds committed 14 years ago

Commit 1daaa5e2 parents c5b01ac 68e67f42 files · +43 −91Browse files

Unified · Split

2 files
  1. sound/usb/endpoint.c +6 −67
  2. sound/usb/pcm.c +37 −24
sound/usb/endpoint.c+6−67
@@ -414,7 +414,7 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, · 413 unmodified lines
414414 {
415415 struct list_head *p;
416416 struct snd_usb_endpoint *ep;
417− int ret, is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK;
417+ int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK;
418418
419419 mutex_lock(&chip->mutex);
420420
@@ -434,16 +434,6 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, · 13 unmodified lines
434434 type == SND_USB_ENDPOINT_TYPE_DATA ? "data" : "sync",
435435 ep_num);
436436
437− /* select the alt setting once so the endpoints become valid */
438− ret = usb_set_interface(chip->dev, alts->desc.bInterfaceNumber,
439− alts->desc.bAlternateSetting);
440− if (ret < 0) {
441− snd_printk(KERN_ERR "%s(): usb_set_interface() failed, ret = %d\n",
442− __func__, ret);
443− ep = NULL;
444− goto __exit_unlock;
445− }
446−
447437 ep = kzalloc(sizeof(*ep), GFP_KERNEL);
448438 if (!ep)
449439 goto __exit_unlock;
@@ -831,9 +821,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) · 381 unmodified lines
831821 if (++ep->use_count != 1)
832822 return 0;
833823
834− if (snd_BUG_ON(!test_bit(EP_FLAG_ACTIVATED, &ep->flags)))
835− return -EINVAL;
836−
837824 /* just to be sure */
838825 deactivate_urbs(ep, 0, 1);
839826 wait_clear_urbs(ep);
@@ -911,9 +898,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, · 71 unmodified lines
911898 if (snd_BUG_ON(ep->use_count == 0))
912899 return;
913900
914− if (snd_BUG_ON(!test_bit(EP_FLAG_ACTIVATED, &ep->flags)))
915− return;
916−
917901 if (--ep->use_count == 0) {
918902 deactivate_urbs(ep, force, can_sleep);
919903 ep->data_subs = NULL;
@@ -926,42 +910,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, · 6 unmodified lines
926910 }
927911 }
928912
929−/**
930− * snd_usb_endpoint_activate: activate an snd_usb_endpoint
931− *
932− * @ep: the endpoint to activate
933− *
934− * If the endpoint is not currently in use, this functions will select the
935− * correct alternate interface setting for the interface of this endpoint.
936− *
937− * In case of any active users, this functions does nothing.
938− *
939− * Returns an error if usb_set_interface() failed, 0 in all other
940− * cases.
941− */
942−int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep)
943−{
944− if (ep->use_count != 0)
945− return 0;
946−
947− if (!ep->chip->shutdown &&
948− !test_and_set_bit(EP_FLAG_ACTIVATED, &ep->flags)) {
949− int ret;
950−
951− ret = usb_set_interface(ep->chip->dev, ep->iface, ep->alt_idx);
952− if (ret < 0) {
953− snd_printk(KERN_ERR "%s() usb_set_interface() failed, ret = %d\n",
954− __func__, ret);
955− clear_bit(EP_FLAG_ACTIVATED, &ep->flags);
956− return ret;
957− }
958−
959− return 0;
960− }
961−
962− return -EBUSY;
963−}
964−
965913 /**
966914 * snd_usb_endpoint_deactivate: deactivate an snd_usb_endpoint
967915 *
@@ -980,24 +928,15 @@ int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) · 12 unmodified lines
980928 if (!ep)
981929 return -EINVAL;
982930
931+ deactivate_urbs(ep, 1, 1);
932+ wait_clear_urbs(ep);
933+
983934 if (ep->use_count != 0)
984935 return 0;
985936
986− if (!ep->chip->shutdown &&
987− test_and_clear_bit(EP_FLAG_ACTIVATED, &ep->flags)) {
988− int ret;
989−
990− ret = usb_set_interface(ep->chip->dev, ep->iface, 0);
991− if (ret < 0) {
992− snd_printk(KERN_ERR "%s(): usb_set_interface() failed, ret = %d\n",
993− __func__, ret);
994− return ret;
995− }
937+ clear_bit(EP_FLAG_ACTIVATED, &ep->flags);
996938
997− return 0;
998− }
999−
1000− return -EBUSY;
939+ return 0;
1001940 }
1002941
1003942 /**
sound/usb/pcm.c+37−24
@@ -261,19 +261,6 @@ static void stop_endpoints(struct snd_usb_substream *subs, · 260 unmodified lines
261261 force, can_sleep, wait);
262262 }
263263
264−static int activate_endpoints(struct snd_usb_substream *subs)
265−{
266− if (subs->sync_endpoint) {
267− int ret;
268−
269− ret = snd_usb_endpoint_activate(subs->sync_endpoint);
270− if (ret < 0)
271− return ret;
272− }
273−
274− return snd_usb_endpoint_activate(subs->data_endpoint);
275−}
276−
277264 static int deactivate_endpoints(struct snd_usb_substream *subs)
278265 {
279266 int reta, retb;
@@ -314,6 +301,33 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) · 34 unmodified lines
314301 if (fmt == subs->cur_audiofmt)
315302 return 0;
316303
304+ /* close the old interface */
305+ if (subs->interface >= 0 && subs->interface != fmt->iface) {
306+ err = usb_set_interface(subs->dev, subs->interface, 0);
307+ if (err < 0) {
308+ snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed (%d)\n",
309+ dev->devnum, fmt->iface, fmt->altsetting, err);
310+ return -EIO;
311+ }
312+ subs->interface = -1;
313+ subs->altset_idx = 0;
314+ }
315+
316+ /* set interface */
317+ if (subs->interface != fmt->iface ||
318+ subs->altset_idx != fmt->altset_idx) {
319+ err = usb_set_interface(dev, fmt->iface, fmt->altsetting);
320+ if (err < 0) {
321+ snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed (%d)\n",
322+ dev->devnum, fmt->iface, fmt->altsetting, err);
323+ return -EIO;
324+ }
325+ snd_printdd(KERN_INFO "setting usb interface %d:%d\n",
326+ fmt->iface, fmt->altsetting);
327+ subs->interface = fmt->iface;
328+ subs->altset_idx = fmt->altset_idx;
329+ }
330+
317331 subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip,
318332 alts, fmt->endpoint, subs->direction,
319333 SND_USB_ENDPOINT_TYPE_DATA);
@@ -387,7 +401,7 @@ add_sync_ep: · 67 unmodified lines
387401 subs->data_endpoint->sync_master = subs->sync_endpoint;
388402 }
389403
390− if ((err = snd_usb_init_pitch(subs->stream->chip, subs->interface, alts, fmt)) < 0)
404+ if ((err = snd_usb_init_pitch(subs->stream->chip, fmt->iface, alts, fmt)) < 0)
391405 return err;
392406
393407 subs->cur_audiofmt = fmt;
@@ -450,7 +464,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, · 56 unmodified lines
450464 struct usb_interface *iface;
451465 iface = usb_ifnum_to_if(subs->dev, fmt->iface);
452466 alts = &iface->altsetting[fmt->altset_idx];
453− ret = snd_usb_init_sample_rate(subs->stream->chip, subs->interface, alts, fmt, rate);
467+ ret = snd_usb_init_sample_rate(subs->stream->chip, fmt->iface, alts, fmt, rate);
454468 if (ret < 0)
455469 return ret;
456470 subs->cur_rate = rate;
@@ -460,12 +474,6 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, · 3 unmodified lines
460474 mutex_lock(&subs->stream->chip->shutdown_mutex);
461475 /* format changed */
462476 stop_endpoints(subs, 0, 0, 0);
463− deactivate_endpoints(subs);
464−
465− ret = activate_endpoints(subs);
466− if (ret < 0)
467− goto unlock;
468−
469477 ret = snd_usb_endpoint_set_params(subs->data_endpoint, hw_params, fmt,
470478 subs->sync_endpoint);
471479 if (ret < 0)
@@ -500,6 +508,7 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) · 28 unmodified lines
500508 subs->period_bytes = 0;
501509 mutex_lock(&subs->stream->chip->shutdown_mutex);
502510 stop_endpoints(subs, 0, 1, 1);
511+ deactivate_endpoints(subs);
503512 mutex_unlock(&subs->stream->chip->shutdown_mutex);
504513 return snd_pcm_lib_free_vmalloc_buffer(substream);
505514 }
@@ -938,16 +947,20 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) · 432 unmodified lines
938947
939948 static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
940949 {
941− int ret;
942950 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
943951 struct snd_usb_substream *subs = &as->substream[direction];
944952
945953 stop_endpoints(subs, 0, 0, 0);
946− ret = deactivate_endpoints(subs);
954+
955+ if (!as->chip->shutdown && subs->interface >= 0) {
956+ usb_set_interface(subs->dev, subs->interface, 0);
957+ subs->interface = -1;
958+ }
959+
947960 subs->pcm_substream = NULL;
948961 snd_usb_autosuspend(subs->stream->chip);
949962
950− return ret;
963+ return 0;
951964 }
952965
953966 /* Since a URB can handle only a single linear buffer, we must use double

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t