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
Unified · Split
| @@ -414,7 +414,7 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, · 413 unmodified lines | ||
| 414 | 414 | { |
| 415 | 415 | struct list_head *p; |
| 416 | 416 | struct snd_usb_endpoint *ep; |
| 417 | − int ret, is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK; | |
| 417 | + int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK; | |
| 418 | 418 | |
| 419 | 419 | mutex_lock(&chip->mutex); |
| 420 | 420 | |
| @@ -434,16 +434,6 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, · 13 unmodified lines | ||
| 434 | 434 | type == SND_USB_ENDPOINT_TYPE_DATA ? "data" : "sync", |
| 435 | 435 | ep_num); |
| 436 | 436 | |
| 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 | − | |
| 447 | 437 | ep = kzalloc(sizeof(*ep), GFP_KERNEL); |
| 448 | 438 | if (!ep) |
| 449 | 439 | goto __exit_unlock; |
| @@ -831,9 +821,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) · 381 unmodified lines | ||
| 831 | 821 | if (++ep->use_count != 1) |
| 832 | 822 | return 0; |
| 833 | 823 | |
| 834 | − if (snd_BUG_ON(!test_bit(EP_FLAG_ACTIVATED, &ep->flags))) | |
| 835 | − return -EINVAL; | |
| 836 | − | |
| 837 | 824 | /* just to be sure */ |
| 838 | 825 | deactivate_urbs(ep, 0, 1); |
| 839 | 826 | wait_clear_urbs(ep); |
| @@ -911,9 +898,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, · 71 unmodified lines | ||
| 911 | 898 | if (snd_BUG_ON(ep->use_count == 0)) |
| 912 | 899 | return; |
| 913 | 900 | |
| 914 | − if (snd_BUG_ON(!test_bit(EP_FLAG_ACTIVATED, &ep->flags))) | |
| 915 | − return; | |
| 916 | − | |
| 917 | 901 | if (--ep->use_count == 0) { |
| 918 | 902 | deactivate_urbs(ep, force, can_sleep); |
| 919 | 903 | ep->data_subs = NULL; |
| @@ -926,42 +910,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, · 6 unmodified lines | ||
| 926 | 910 | } |
| 927 | 911 | } |
| 928 | 912 | |
| 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 | − | |
| 965 | 913 | /** |
| 966 | 914 | * snd_usb_endpoint_deactivate: deactivate an snd_usb_endpoint |
| 967 | 915 | * |
| @@ -980,24 +928,15 @@ int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) · 12 unmodified lines | ||
| 980 | 928 | if (!ep) |
| 981 | 929 | return -EINVAL; |
| 982 | 930 | |
| 931 | + deactivate_urbs(ep, 1, 1); | |
| 932 | + wait_clear_urbs(ep); | |
| 933 | + | |
| 983 | 934 | if (ep->use_count != 0) |
| 984 | 935 | return 0; |
| 985 | 936 | |
| 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); | |
| 996 | 938 | |
| 997 | − return 0; | |
| 998 | − } | |
| 999 | − | |
| 1000 | − return -EBUSY; | |
| 939 | + return 0; | |
| 1001 | 940 | } |
| 1002 | 941 | |
| 1003 | 942 | /** |
| @@ -261,19 +261,6 @@ static void stop_endpoints(struct snd_usb_substream *subs, · 260 unmodified lines | ||
| 261 | 261 | force, can_sleep, wait); |
| 262 | 262 | } |
| 263 | 263 | |
| 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 | − | |
| 277 | 264 | static int deactivate_endpoints(struct snd_usb_substream *subs) |
| 278 | 265 | { |
| 279 | 266 | int reta, retb; |
| @@ -314,6 +301,33 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) · 34 unmodified lines | ||
| 314 | 301 | if (fmt == subs->cur_audiofmt) |
| 315 | 302 | return 0; |
| 316 | 303 | |
| 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 | + | |
| 317 | 331 | subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, |
| 318 | 332 | alts, fmt->endpoint, subs->direction, |
| 319 | 333 | SND_USB_ENDPOINT_TYPE_DATA); |
| @@ -387,7 +401,7 @@ add_sync_ep: · 67 unmodified lines | ||
| 387 | 401 | subs->data_endpoint->sync_master = subs->sync_endpoint; |
| 388 | 402 | } |
| 389 | 403 | |
| 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) | |
| 391 | 405 | return err; |
| 392 | 406 | |
| 393 | 407 | subs->cur_audiofmt = fmt; |
| @@ -450,7 +464,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, · 56 unmodified lines | ||
| 450 | 464 | struct usb_interface *iface; |
| 451 | 465 | iface = usb_ifnum_to_if(subs->dev, fmt->iface); |
| 452 | 466 | 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); | |
| 454 | 468 | if (ret < 0) |
| 455 | 469 | return ret; |
| 456 | 470 | subs->cur_rate = rate; |
| @@ -460,12 +474,6 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, · 3 unmodified lines | ||
| 460 | 474 | mutex_lock(&subs->stream->chip->shutdown_mutex); |
| 461 | 475 | /* format changed */ |
| 462 | 476 | stop_endpoints(subs, 0, 0, 0); |
| 463 | − deactivate_endpoints(subs); | |
| 464 | − | |
| 465 | − ret = activate_endpoints(subs); | |
| 466 | − if (ret < 0) | |
| 467 | − goto unlock; | |
| 468 | − | |
| 469 | 477 | ret = snd_usb_endpoint_set_params(subs->data_endpoint, hw_params, fmt, |
| 470 | 478 | subs->sync_endpoint); |
| 471 | 479 | if (ret < 0) |
| @@ -500,6 +508,7 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) · 28 unmodified lines | ||
| 500 | 508 | subs->period_bytes = 0; |
| 501 | 509 | mutex_lock(&subs->stream->chip->shutdown_mutex); |
| 502 | 510 | stop_endpoints(subs, 0, 1, 1); |
| 511 | + deactivate_endpoints(subs); | |
| 503 | 512 | mutex_unlock(&subs->stream->chip->shutdown_mutex); |
| 504 | 513 | return snd_pcm_lib_free_vmalloc_buffer(substream); |
| 505 | 514 | } |
| @@ -938,16 +947,20 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) · 432 unmodified lines | ||
| 938 | 947 | |
| 939 | 948 | static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) |
| 940 | 949 | { |
| 941 | − int ret; | |
| 942 | 950 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); |
| 943 | 951 | struct snd_usb_substream *subs = &as->substream[direction]; |
| 944 | 952 | |
| 945 | 953 | 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 | + | |
| 947 | 960 | subs->pcm_substream = NULL; |
| 948 | 961 | snd_usb_autosuspend(subs->stream->chip); |
| 949 | 962 | |
| 950 | − return ret; | |
| 963 | + return 0; | |
| 951 | 964 | } |
| 952 | 965 | |
| 953 | 966 | /* Since a URB can handle only a single linear buffer, we must use double |