aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-08-25 10:09:00 -0400
committerTakashi Iwai <tiwai@suse.de>2015-08-26 09:38:25 -0400
commit47ab154593827b1a8f0713a2b9dd445753d551d8 (patch)
tree17d18cafdf9d13b169f50ada290553db8b62fbe7
parentb25cf30a013195a69c167209d13c19b90a7450f2 (diff)
ALSA: usb-audio: Avoid nested autoresume calls
After the recent fix of runtime PM for USB-audio driver, we got a lockdep warning like: ============================================= [ INFO: possible recursive locking detected ] 4.2.0-rc8+ #61 Not tainted --------------------------------------------- pulseaudio/980 is trying to acquire lock: (&chip->shutdown_rwsem){.+.+.+}, at: [<ffffffffa0355dac>] snd_usb_autoresume+0x1d/0x52 [snd_usb_audio] but task is already holding lock: (&chip->shutdown_rwsem){.+.+.+}, at: [<ffffffffa0355dac>] snd_usb_autoresume+0x1d/0x52 [snd_usb_audio] This comes from snd_usb_autoresume() invoking down_read() and it's used in a nested way. Although it's basically safe, per se (as these are read locks), it's better to reduce such spurious warnings. The read lock is needed to guarantee the execution of "shutdown" (cleanup at disconnection) task after all concurrent tasks are finished. This can be implemented in another better way. Also, the current check of chip->in_pm isn't good enough for protecting the racy execution of multiple auto-resumes. This patch rewrites the logic of snd_usb_autoresume() & co; namely, - The recursive call of autopm is avoided by the new refcount, chip->active. The chip->in_pm flag is removed accordingly. - Instead of rwsem, another refcount, chip->usage_count, is introduced for tracking the period to delay the shutdown procedure. At the last clear of this refcount, wake_up() to the shutdown waiter is called. - The shutdown flag is replaced with shutdown atomic count; this is for reducing the lock. - Two new helpers are introduced to simplify the management of these refcounts; snd_usb_lock_shutdown() increases the usage_count, checks the shutdown state, and does autoresume. snd_usb_unlock_shutdown() does the opposite. Most of mixer and other codes just need this, and simply returns an error if it receives an error from lock. Fixes: 9003ebb13f61 ('ALSA: usb-audio: Fix runtime PM unbalance') Reported-and-tested-by: Alexnader Kuleshov <kuleshovmail@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/usb/card.c74
-rw-r--r--sound/usb/endpoint.c10
-rw-r--r--sound/usb/mixer.c32
-rw-r--r--sound/usb/mixer_quirks.c126
-rw-r--r--sound/usb/pcm.c32
-rw-r--r--sound/usb/proc.c4
-rw-r--r--sound/usb/usbaudio.h10
7 files changed, 145 insertions, 143 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 0450593980fd..b6621bcba2dc 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -365,13 +365,15 @@ static int snd_usb_audio_create(struct usb_interface *intf,
365 } 365 }
366 366
367 mutex_init(&chip->mutex); 367 mutex_init(&chip->mutex);
368 init_rwsem(&chip->shutdown_rwsem); 368 init_waitqueue_head(&chip->shutdown_wait);
369 chip->index = idx; 369 chip->index = idx;
370 chip->dev = dev; 370 chip->dev = dev;
371 chip->card = card; 371 chip->card = card;
372 chip->setup = device_setup[idx]; 372 chip->setup = device_setup[idx];
373 chip->autoclock = autoclock; 373 chip->autoclock = autoclock;
374 chip->probing = 1; 374 chip->probing = 1;
375 atomic_set(&chip->usage_count, 0);
376 atomic_set(&chip->shutdown, 0);
375 377
376 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), 378 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
377 le16_to_cpu(dev->descriptor.idProduct)); 379 le16_to_cpu(dev->descriptor.idProduct));
@@ -495,7 +497,7 @@ static int usb_audio_probe(struct usb_interface *intf,
495 mutex_lock(&register_mutex); 497 mutex_lock(&register_mutex);
496 for (i = 0; i < SNDRV_CARDS; i++) { 498 for (i = 0; i < SNDRV_CARDS; i++) {
497 if (usb_chip[i] && usb_chip[i]->dev == dev) { 499 if (usb_chip[i] && usb_chip[i]->dev == dev) {
498 if (usb_chip[i]->shutdown) { 500 if (atomic_read(&usb_chip[i]->shutdown)) {
499 dev_err(&dev->dev, "USB device is in the shutdown state, cannot create a card instance\n"); 501 dev_err(&dev->dev, "USB device is in the shutdown state, cannot create a card instance\n");
500 err = -EIO; 502 err = -EIO;
501 goto __error; 503 goto __error;
@@ -585,23 +587,23 @@ static void usb_audio_disconnect(struct usb_interface *intf)
585 struct snd_usb_audio *chip = usb_get_intfdata(intf); 587 struct snd_usb_audio *chip = usb_get_intfdata(intf);
586 struct snd_card *card; 588 struct snd_card *card;
587 struct list_head *p; 589 struct list_head *p;
588 bool was_shutdown;
589 590
590 if (chip == (void *)-1L) 591 if (chip == (void *)-1L)
591 return; 592 return;
592 593
593 card = chip->card; 594 card = chip->card;
594 down_write(&chip->shutdown_rwsem);
595 was_shutdown = chip->shutdown;
596 chip->shutdown = 1;
597 up_write(&chip->shutdown_rwsem);
598 595
599 mutex_lock(&register_mutex); 596 mutex_lock(&register_mutex);
600 if (!was_shutdown) { 597 if (atomic_inc_return(&chip->shutdown) == 1) {
601 struct snd_usb_stream *as; 598 struct snd_usb_stream *as;
602 struct snd_usb_endpoint *ep; 599 struct snd_usb_endpoint *ep;
603 struct usb_mixer_interface *mixer; 600 struct usb_mixer_interface *mixer;
604 601
602 /* wait until all pending tasks done;
603 * they are protected by snd_usb_lock_shutdown()
604 */
605 wait_event(chip->shutdown_wait,
606 !atomic_read(&chip->usage_count));
605 snd_card_disconnect(card); 607 snd_card_disconnect(card);
606 /* release the pcm resources */ 608 /* release the pcm resources */
607 list_for_each_entry(as, &chip->pcm_list, list) { 609 list_for_each_entry(as, &chip->pcm_list, list) {
@@ -631,28 +633,54 @@ static void usb_audio_disconnect(struct usb_interface *intf)
631 } 633 }
632} 634}
633 635
634#ifdef CONFIG_PM 636/* lock the shutdown (disconnect) task and autoresume */
635 637int snd_usb_lock_shutdown(struct snd_usb_audio *chip)
636int snd_usb_autoresume(struct snd_usb_audio *chip)
637{ 638{
638 int err = -ENODEV; 639 int err;
639 640
640 down_read(&chip->shutdown_rwsem); 641 atomic_inc(&chip->usage_count);
641 if (chip->probing || chip->in_pm) 642 if (atomic_read(&chip->shutdown)) {
642 err = 0; 643 err = -EIO;
643 else if (!chip->shutdown) 644 goto error;
644 err = usb_autopm_get_interface(chip->pm_intf); 645 }
645 up_read(&chip->shutdown_rwsem); 646 err = snd_usb_autoresume(chip);
647 if (err < 0)
648 goto error;
649 return 0;
646 650
651 error:
652 if (atomic_dec_and_test(&chip->usage_count))
653 wake_up(&chip->shutdown_wait);
647 return err; 654 return err;
648} 655}
649 656
657/* autosuspend and unlock the shutdown */
658void snd_usb_unlock_shutdown(struct snd_usb_audio *chip)
659{
660 snd_usb_autosuspend(chip);
661 if (atomic_dec_and_test(&chip->usage_count))
662 wake_up(&chip->shutdown_wait);
663}
664
665#ifdef CONFIG_PM
666
667int snd_usb_autoresume(struct snd_usb_audio *chip)
668{
669 if (atomic_read(&chip->shutdown))
670 return -EIO;
671 if (chip->probing)
672 return 0;
673 if (atomic_inc_return(&chip->active) == 1)
674 return usb_autopm_get_interface(chip->pm_intf);
675 return 0;
676}
677
650void snd_usb_autosuspend(struct snd_usb_audio *chip) 678void snd_usb_autosuspend(struct snd_usb_audio *chip)
651{ 679{
652 down_read(&chip->shutdown_rwsem); 680 if (chip->probing)
653 if (!chip->shutdown && !chip->probing && !chip->in_pm) 681 return;
682 if (atomic_dec_and_test(&chip->active))
654 usb_autopm_put_interface(chip->pm_intf); 683 usb_autopm_put_interface(chip->pm_intf);
655 up_read(&chip->shutdown_rwsem);
656} 684}
657 685
658static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) 686static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
@@ -705,7 +733,7 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
705 if (--chip->num_suspended_intf) 733 if (--chip->num_suspended_intf)
706 return 0; 734 return 0;
707 735
708 chip->in_pm = 1; 736 atomic_inc(&chip->active); /* avoid autopm */
709 /* 737 /*
710 * ALSA leaves material resumption to user space 738 * ALSA leaves material resumption to user space
711 * we just notify and restart the mixers 739 * we just notify and restart the mixers
@@ -725,7 +753,7 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
725 chip->autosuspended = 0; 753 chip->autosuspended = 0;
726 754
727err_out: 755err_out:
728 chip->in_pm = 0; 756 atomic_dec(&chip->active); /* allow autopm after this point */
729 return err; 757 return err;
730} 758}
731 759
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 03b074419964..e6f71894ecdc 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -355,8 +355,10 @@ static void snd_complete_urb(struct urb *urb)
355 if (unlikely(urb->status == -ENOENT || /* unlinked */ 355 if (unlikely(urb->status == -ENOENT || /* unlinked */
356 urb->status == -ENODEV || /* device removed */ 356 urb->status == -ENODEV || /* device removed */
357 urb->status == -ECONNRESET || /* unlinked */ 357 urb->status == -ECONNRESET || /* unlinked */
358 urb->status == -ESHUTDOWN || /* device disabled */ 358 urb->status == -ESHUTDOWN)) /* device disabled */
359 ep->chip->shutdown)) /* device disconnected */ 359 goto exit_clear;
360 /* device disconnected */
361 if (unlikely(atomic_read(&ep->chip->shutdown)))
360 goto exit_clear; 362 goto exit_clear;
361 363
362 if (usb_pipeout(ep->pipe)) { 364 if (usb_pipeout(ep->pipe)) {
@@ -529,7 +531,7 @@ static int deactivate_urbs(struct snd_usb_endpoint *ep, bool force)
529{ 531{
530 unsigned int i; 532 unsigned int i;
531 533
532 if (!force && ep->chip->shutdown) /* to be sure... */ 534 if (!force && atomic_read(&ep->chip->shutdown)) /* to be sure... */
533 return -EBADFD; 535 return -EBADFD;
534 536
535 clear_bit(EP_FLAG_RUNNING, &ep->flags); 537 clear_bit(EP_FLAG_RUNNING, &ep->flags);
@@ -868,7 +870,7 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep)
868 int err; 870 int err;
869 unsigned int i; 871 unsigned int i;
870 872
871 if (ep->chip->shutdown) 873 if (atomic_read(&ep->chip->shutdown))
872 return -EBADFD; 874 return -EBADFD;
873 875
874 /* already running? */ 876 /* already running? */
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index c50790cb3f4d..fd5c49e94867 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -311,14 +311,11 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
311 int timeout = 10; 311 int timeout = 10;
312 int idx = 0, err; 312 int idx = 0, err;
313 313
314 err = snd_usb_autoresume(chip); 314 err = snd_usb_lock_shutdown(chip);
315 if (err < 0) 315 if (err < 0)
316 return -EIO; 316 return -EIO;
317 317
318 down_read(&chip->shutdown_rwsem);
319 while (timeout-- > 0) { 318 while (timeout-- > 0) {
320 if (chip->shutdown)
321 break;
322 idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); 319 idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
323 if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, 320 if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
324 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 321 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
@@ -334,8 +331,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
334 err = -EINVAL; 331 err = -EINVAL;
335 332
336 out: 333 out:
337 up_read(&chip->shutdown_rwsem); 334 snd_usb_unlock_shutdown(chip);
338 snd_usb_autosuspend(chip);
339 return err; 335 return err;
340} 336}
341 337
@@ -358,21 +354,15 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
358 354
359 memset(buf, 0, sizeof(buf)); 355 memset(buf, 0, sizeof(buf));
360 356
361 ret = snd_usb_autoresume(chip) ? -EIO : 0; 357 ret = snd_usb_lock_shutdown(chip) ? -EIO : 0;
362 if (ret) 358 if (ret)
363 goto error; 359 goto error;
364 360
365 down_read(&chip->shutdown_rwsem); 361 idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
366 if (chip->shutdown) { 362 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
367 ret = -ENODEV;
368 } else {
369 idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
370 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
371 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 363 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
372 validx, idx, buf, size); 364 validx, idx, buf, size);
373 } 365 snd_usb_unlock_shutdown(chip);
374 up_read(&chip->shutdown_rwsem);
375 snd_usb_autosuspend(chip);
376 366
377 if (ret < 0) { 367 if (ret < 0) {
378error: 368error:
@@ -485,13 +475,12 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
485 buf[1] = (value_set >> 8) & 0xff; 475 buf[1] = (value_set >> 8) & 0xff;
486 buf[2] = (value_set >> 16) & 0xff; 476 buf[2] = (value_set >> 16) & 0xff;
487 buf[3] = (value_set >> 24) & 0xff; 477 buf[3] = (value_set >> 24) & 0xff;
488 err = snd_usb_autoresume(chip); 478
479 err = snd_usb_lock_shutdown(chip);
489 if (err < 0) 480 if (err < 0)
490 return -EIO; 481 return -EIO;
491 down_read(&chip->shutdown_rwsem); 482
492 while (timeout-- > 0) { 483 while (timeout-- > 0) {
493 if (chip->shutdown)
494 break;
495 idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); 484 idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
496 if (snd_usb_ctl_msg(chip->dev, 485 if (snd_usb_ctl_msg(chip->dev,
497 usb_sndctrlpipe(chip->dev, 0), request, 486 usb_sndctrlpipe(chip->dev, 0), request,
@@ -506,8 +495,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
506 err = -EINVAL; 495 err = -EINVAL;
507 496
508 out: 497 out:
509 up_read(&chip->shutdown_rwsem); 498 snd_usb_unlock_shutdown(chip);
510 snd_usb_autosuspend(chip);
511 return err; 499 return err;
512} 500}
513 501
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 337c317ead6f..d3608c0a29f3 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -308,11 +308,10 @@ static int snd_audigy2nx_led_update(struct usb_mixer_interface *mixer,
308 struct snd_usb_audio *chip = mixer->chip; 308 struct snd_usb_audio *chip = mixer->chip;
309 int err; 309 int err;
310 310
311 down_read(&chip->shutdown_rwsem); 311 err = snd_usb_lock_shutdown(chip);
312 if (chip->shutdown) { 312 if (err < 0)
313 err = -ENODEV; 313 return err;
314 goto out; 314
315 }
316 if (chip->usb_id == USB_ID(0x041e, 0x3042)) 315 if (chip->usb_id == USB_ID(0x041e, 0x3042))
317 err = snd_usb_ctl_msg(chip->dev, 316 err = snd_usb_ctl_msg(chip->dev,
318 usb_sndctrlpipe(chip->dev, 0), 0x24, 317 usb_sndctrlpipe(chip->dev, 0), 0x24,
@@ -329,8 +328,7 @@ static int snd_audigy2nx_led_update(struct usb_mixer_interface *mixer,
329 usb_sndctrlpipe(chip->dev, 0), 0x24, 328 usb_sndctrlpipe(chip->dev, 0), 0x24,
330 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 329 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
331 value, index + 2, NULL, 0); 330 value, index + 2, NULL, 0);
332 out: 331 snd_usb_unlock_shutdown(chip);
333 up_read(&chip->shutdown_rwsem);
334 return err; 332 return err;
335} 333}
336 334
@@ -441,16 +439,15 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
441 439
442 for (i = 0; jacks[i].name; ++i) { 440 for (i = 0; jacks[i].name; ++i) {
443 snd_iprintf(buffer, "%s: ", jacks[i].name); 441 snd_iprintf(buffer, "%s: ", jacks[i].name);
444 down_read(&mixer->chip->shutdown_rwsem); 442 err = snd_usb_lock_shutdown(mixer->chip);
445 if (mixer->chip->shutdown) 443 if (err < 0)
446 err = 0; 444 return;
447 else 445 err = snd_usb_ctl_msg(mixer->chip->dev,
448 err = snd_usb_ctl_msg(mixer->chip->dev,
449 usb_rcvctrlpipe(mixer->chip->dev, 0), 446 usb_rcvctrlpipe(mixer->chip->dev, 0),
450 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | 447 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
451 USB_RECIP_INTERFACE, 0, 448 USB_RECIP_INTERFACE, 0,
452 jacks[i].unitid << 8, buf, 3); 449 jacks[i].unitid << 8, buf, 3);
453 up_read(&mixer->chip->shutdown_rwsem); 450 snd_usb_unlock_shutdown(mixer->chip);
454 if (err == 3 && (buf[0] == 3 || buf[0] == 6)) 451 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
455 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); 452 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
456 else 453 else
@@ -481,11 +478,9 @@ static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer,
481 int err; 478 int err;
482 unsigned char buf[2]; 479 unsigned char buf[2];
483 480
484 down_read(&chip->shutdown_rwsem); 481 err = snd_usb_lock_shutdown(chip);
485 if (mixer->chip->shutdown) { 482 if (err < 0)
486 err = -ENODEV; 483 return err;
487 goto out;
488 }
489 484
490 buf[0] = 0x01; 485 buf[0] = 0x01;
491 buf[1] = value ? 0x02 : 0x01; 486 buf[1] = value ? 0x02 : 0x01;
@@ -493,8 +488,7 @@ static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer,
493 usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, 488 usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
494 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 489 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
495 0x0400, 0x0e00, buf, 2); 490 0x0400, 0x0e00, buf, 2);
496 out: 491 snd_usb_unlock_shutdown(chip);
497 up_read(&chip->shutdown_rwsem);
498 return err; 492 return err;
499} 493}
500 494
@@ -554,15 +548,14 @@ static int snd_xonar_u1_switch_update(struct usb_mixer_interface *mixer,
554 struct snd_usb_audio *chip = mixer->chip; 548 struct snd_usb_audio *chip = mixer->chip;
555 int err; 549 int err;
556 550
557 down_read(&chip->shutdown_rwsem); 551 err = snd_usb_lock_shutdown(chip);
558 if (chip->shutdown) 552 if (err < 0)
559 err = -ENODEV; 553 return err;
560 else 554 err = snd_usb_ctl_msg(chip->dev,
561 err = snd_usb_ctl_msg(chip->dev,
562 usb_sndctrlpipe(chip->dev, 0), 0x08, 555 usb_sndctrlpipe(chip->dev, 0), 0x08,
563 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 556 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
564 50, 0, &status, 1); 557 50, 0, &status, 1);
565 up_read(&chip->shutdown_rwsem); 558 snd_usb_unlock_shutdown(chip);
566 return err; 559 return err;
567} 560}
568 561
@@ -623,11 +616,9 @@ static int snd_mbox1_switch_update(struct usb_mixer_interface *mixer, int val)
623 int err; 616 int err;
624 unsigned char buff[3]; 617 unsigned char buff[3];
625 618
626 down_read(&chip->shutdown_rwsem); 619 err = snd_usb_lock_shutdown(chip);
627 if (chip->shutdown) { 620 if (err < 0)
628 err = -ENODEV; 621 return err;
629 goto err;
630 }
631 622
632 /* Prepare for magic command to toggle clock source */ 623 /* Prepare for magic command to toggle clock source */
633 err = snd_usb_ctl_msg(chip->dev, 624 err = snd_usb_ctl_msg(chip->dev,
@@ -683,7 +674,7 @@ static int snd_mbox1_switch_update(struct usb_mixer_interface *mixer, int val)
683 goto err; 674 goto err;
684 675
685err: 676err:
686 up_read(&chip->shutdown_rwsem); 677 snd_usb_unlock_shutdown(chip);
687 return err; 678 return err;
688} 679}
689 680
@@ -778,15 +769,14 @@ static int snd_ni_update_cur_val(struct usb_mixer_elem_list *list)
778 unsigned int pval = list->kctl->private_value; 769 unsigned int pval = list->kctl->private_value;
779 int err; 770 int err;
780 771
781 down_read(&chip->shutdown_rwsem); 772 err = snd_usb_lock_shutdown(chip);
782 if (chip->shutdown) 773 if (err < 0)
783 err = -ENODEV; 774 return err;
784 else 775 err = usb_control_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
785 err = usb_control_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), 776 (pval >> 16) & 0xff,
786 (pval >> 16) & 0xff, 777 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
787 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 778 pval >> 24, pval & 0xffff, NULL, 0, 1000);
788 pval >> 24, pval & 0xffff, NULL, 0, 1000); 779 snd_usb_unlock_shutdown(chip);
789 up_read(&chip->shutdown_rwsem);
790 return err; 780 return err;
791} 781}
792 782
@@ -944,18 +934,17 @@ static int snd_ftu_eff_switch_update(struct usb_mixer_elem_list *list)
944 value[0] = pval >> 24; 934 value[0] = pval >> 24;
945 value[1] = 0; 935 value[1] = 0;
946 936
947 down_read(&chip->shutdown_rwsem); 937 err = snd_usb_lock_shutdown(chip);
948 if (chip->shutdown) 938 if (err < 0)
949 err = -ENODEV; 939 return err;
950 else 940 err = snd_usb_ctl_msg(chip->dev,
951 err = snd_usb_ctl_msg(chip->dev, 941 usb_sndctrlpipe(chip->dev, 0),
952 usb_sndctrlpipe(chip->dev, 0), 942 UAC_SET_CUR,
953 UAC_SET_CUR, 943 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
954 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 944 pval & 0xff00,
955 pval & 0xff00, 945 snd_usb_ctrl_intf(chip) | ((pval & 0xff) << 8),
956 snd_usb_ctrl_intf(chip) | ((pval & 0xff) << 8), 946 value, 2);
957 value, 2); 947 snd_usb_unlock_shutdown(chip);
958 up_read(&chip->shutdown_rwsem);
959 return err; 948 return err;
960} 949}
961 950
@@ -1519,11 +1508,9 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
1519 unsigned char data[3]; 1508 unsigned char data[3];
1520 int rate; 1509 int rate;
1521 1510
1522 down_read(&chip->shutdown_rwsem); 1511 err = snd_usb_lock_shutdown(chip);
1523 if (chip->shutdown) { 1512 if (err < 0)
1524 err = -ENODEV; 1513 return err;
1525 goto end;
1526 }
1527 1514
1528 ucontrol->value.iec958.status[0] = kcontrol->private_value & 0xff; 1515 ucontrol->value.iec958.status[0] = kcontrol->private_value & 0xff;
1529 ucontrol->value.iec958.status[1] = (kcontrol->private_value >> 8) & 0xff; 1516 ucontrol->value.iec958.status[1] = (kcontrol->private_value >> 8) & 0xff;
@@ -1551,7 +1538,7 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
1551 1538
1552 err = 0; 1539 err = 0;
1553 end: 1540 end:
1554 up_read(&chip->shutdown_rwsem); 1541 snd_usb_unlock_shutdown(chip);
1555 return err; 1542 return err;
1556} 1543}
1557 1544
@@ -1562,11 +1549,9 @@ static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list)
1562 u8 reg; 1549 u8 reg;
1563 int err; 1550 int err;
1564 1551
1565 down_read(&chip->shutdown_rwsem); 1552 err = snd_usb_lock_shutdown(chip);
1566 if (chip->shutdown) { 1553 if (err < 0)
1567 err = -ENODEV; 1554 return err;
1568 goto end;
1569 }
1570 1555
1571 reg = ((pval >> 4) & 0xf0) | (pval & 0x0f); 1556 reg = ((pval >> 4) & 0xf0) | (pval & 0x0f);
1572 err = snd_usb_ctl_msg(chip->dev, 1557 err = snd_usb_ctl_msg(chip->dev,
@@ -1594,7 +1579,7 @@ static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list)
1594 goto end; 1579 goto end;
1595 1580
1596 end: 1581 end:
1597 up_read(&chip->shutdown_rwsem); 1582 snd_usb_unlock_shutdown(chip);
1598 return err; 1583 return err;
1599} 1584}
1600 1585
@@ -1650,11 +1635,9 @@ static int snd_microii_spdif_switch_update(struct usb_mixer_elem_list *list)
1650 u8 reg = list->kctl->private_value; 1635 u8 reg = list->kctl->private_value;
1651 int err; 1636 int err;
1652 1637
1653 down_read(&chip->shutdown_rwsem); 1638 err = snd_usb_lock_shutdown(chip);
1654 if (chip->shutdown) { 1639 if (err < 0)
1655 err = -ENODEV; 1640 return err;
1656 goto end;
1657 }
1658 1641
1659 err = snd_usb_ctl_msg(chip->dev, 1642 err = snd_usb_ctl_msg(chip->dev,
1660 usb_sndctrlpipe(chip->dev, 0), 1643 usb_sndctrlpipe(chip->dev, 0),
@@ -1665,8 +1648,7 @@ static int snd_microii_spdif_switch_update(struct usb_mixer_elem_list *list)
1665 NULL, 1648 NULL,
1666 0); 1649 0);
1667 1650
1668 end: 1651 snd_usb_unlock_shutdown(chip);
1669 up_read(&chip->shutdown_rwsem);
1670 return err; 1652 return err;
1671} 1653}
1672 1654
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 30797269d5aa..cdac5179db3f 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -80,7 +80,7 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream
80 unsigned int hwptr_done; 80 unsigned int hwptr_done;
81 81
82 subs = (struct snd_usb_substream *)substream->runtime->private_data; 82 subs = (struct snd_usb_substream *)substream->runtime->private_data;
83 if (subs->stream->chip->shutdown) 83 if (atomic_read(&subs->stream->chip->shutdown))
84 return SNDRV_PCM_POS_XRUN; 84 return SNDRV_PCM_POS_XRUN;
85 spin_lock(&subs->lock); 85 spin_lock(&subs->lock);
86 hwptr_done = subs->hwptr_done; 86 hwptr_done = subs->hwptr_done;
@@ -735,12 +735,11 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
735 return -EINVAL; 735 return -EINVAL;
736 } 736 }
737 737
738 down_read(&subs->stream->chip->shutdown_rwsem); 738 ret = snd_usb_lock_shutdown(subs->stream->chip);
739 if (subs->stream->chip->shutdown) 739 if (ret < 0)
740 ret = -ENODEV; 740 return ret;
741 else 741 ret = set_format(subs, fmt);
742 ret = set_format(subs, fmt); 742 snd_usb_unlock_shutdown(subs->stream->chip);
743 up_read(&subs->stream->chip->shutdown_rwsem);
744 if (ret < 0) 743 if (ret < 0)
745 return ret; 744 return ret;
746 745
@@ -763,13 +762,12 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
763 subs->cur_audiofmt = NULL; 762 subs->cur_audiofmt = NULL;
764 subs->cur_rate = 0; 763 subs->cur_rate = 0;
765 subs->period_bytes = 0; 764 subs->period_bytes = 0;
766 down_read(&subs->stream->chip->shutdown_rwsem); 765 if (!snd_usb_lock_shutdown(subs->stream->chip)) {
767 if (!subs->stream->chip->shutdown) {
768 stop_endpoints(subs, true); 766 stop_endpoints(subs, true);
769 snd_usb_endpoint_deactivate(subs->sync_endpoint); 767 snd_usb_endpoint_deactivate(subs->sync_endpoint);
770 snd_usb_endpoint_deactivate(subs->data_endpoint); 768 snd_usb_endpoint_deactivate(subs->data_endpoint);
769 snd_usb_unlock_shutdown(subs->stream->chip);
771 } 770 }
772 up_read(&subs->stream->chip->shutdown_rwsem);
773 return snd_pcm_lib_free_vmalloc_buffer(substream); 771 return snd_pcm_lib_free_vmalloc_buffer(substream);
774} 772}
775 773
@@ -791,11 +789,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
791 return -ENXIO; 789 return -ENXIO;
792 } 790 }
793 791
794 down_read(&subs->stream->chip->shutdown_rwsem); 792 ret = snd_usb_lock_shutdown(subs->stream->chip);
795 if (subs->stream->chip->shutdown) { 793 if (ret < 0)
796 ret = -ENODEV; 794 return ret;
797 goto unlock;
798 }
799 if (snd_BUG_ON(!subs->data_endpoint)) { 795 if (snd_BUG_ON(!subs->data_endpoint)) {
800 ret = -EIO; 796 ret = -EIO;
801 goto unlock; 797 goto unlock;
@@ -844,7 +840,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
844 ret = start_endpoints(subs, true); 840 ret = start_endpoints(subs, true);
845 841
846 unlock: 842 unlock:
847 up_read(&subs->stream->chip->shutdown_rwsem); 843 snd_usb_unlock_shutdown(subs->stream->chip);
848 return ret; 844 return ret;
849} 845}
850 846
@@ -1246,9 +1242,11 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
1246 1242
1247 stop_endpoints(subs, true); 1243 stop_endpoints(subs, true);
1248 1244
1249 if (!as->chip->shutdown && subs->interface >= 0) { 1245 if (subs->interface >= 0 &&
1246 !snd_usb_lock_shutdown(subs->stream->chip)) {
1250 usb_set_interface(subs->dev, subs->interface, 0); 1247 usb_set_interface(subs->dev, subs->interface, 0);
1251 subs->interface = -1; 1248 subs->interface = -1;
1249 snd_usb_unlock_shutdown(subs->stream->chip);
1252 } 1250 }
1253 1251
1254 subs->pcm_substream = NULL; 1252 subs->pcm_substream = NULL;
diff --git a/sound/usb/proc.c b/sound/usb/proc.c
index 5f761ab34c01..0ac89e294d31 100644
--- a/sound/usb/proc.c
+++ b/sound/usb/proc.c
@@ -46,14 +46,14 @@ static inline unsigned get_high_speed_hz(unsigned int usb_rate)
46static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 46static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
47{ 47{
48 struct snd_usb_audio *chip = entry->private_data; 48 struct snd_usb_audio *chip = entry->private_data;
49 if (!chip->shutdown) 49 if (!atomic_read(&chip->shutdown))
50 snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum); 50 snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
51} 51}
52 52
53static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 53static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
54{ 54{
55 struct snd_usb_audio *chip = entry->private_data; 55 struct snd_usb_audio *chip = entry->private_data;
56 if (!chip->shutdown) 56 if (!atomic_read(&chip->shutdown))
57 snd_iprintf(buffer, "%04x:%04x\n", 57 snd_iprintf(buffer, "%04x:%04x\n",
58 USB_ID_VENDOR(chip->usb_id), 58 USB_ID_VENDOR(chip->usb_id),
59 USB_ID_PRODUCT(chip->usb_id)); 59 USB_ID_PRODUCT(chip->usb_id));
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 91d0380431b4..eb1ea7182cdd 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -37,11 +37,12 @@ struct snd_usb_audio {
37 struct usb_interface *pm_intf; 37 struct usb_interface *pm_intf;
38 u32 usb_id; 38 u32 usb_id;
39 struct mutex mutex; 39 struct mutex mutex;
40 struct rw_semaphore shutdown_rwsem;
41 unsigned int shutdown:1;
42 unsigned int probing:1; 40 unsigned int probing:1;
43 unsigned int in_pm:1;
44 unsigned int autosuspended:1; 41 unsigned int autosuspended:1;
42 atomic_t active;
43 atomic_t shutdown;
44 atomic_t usage_count;
45 wait_queue_head_t shutdown_wait;
45 unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ 46 unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
46 47
47 int num_interfaces; 48 int num_interfaces;
@@ -115,4 +116,7 @@ struct snd_usb_audio_quirk {
115#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16)) 116#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16))
116#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24)) 117#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24))
117 118
119int snd_usb_lock_shutdown(struct snd_usb_audio *chip);
120void snd_usb_unlock_shutdown(struct snd_usb_audio *chip);
121
118#endif /* __USBAUDIO_H */ 122#endif /* __USBAUDIO_H */