aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-10-30 06:08:25 -0400
committerTakashi Iwai <tiwai@suse.de>2012-10-30 06:08:25 -0400
commita5d00dc3a4b65ed38249f3225e453944c633747b (patch)
tree6249ca5a5f13059f42890525a9ea7133778f3891 /sound/usb
parent1a8506d4402b6e96c2ed778dc7ccbb48d1e02fce (diff)
parent0914f7961babbf28aaa2f19b453951fb4841c03f (diff)
Merge branch 'for-linus' into for-next
... for migrating the core changes for USB-audio disconnection fixes
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/card.c12
-rw-r--r--sound/usb/card.h1
-rw-r--r--sound/usb/mixer.c65
-rw-r--r--sound/usb/mixer_quirks.c58
-rw-r--r--sound/usb/pcm.c53
-rw-r--r--sound/usb/proc.c4
-rw-r--r--sound/usb/stream.c1
-rw-r--r--sound/usb/usbaudio.h2
8 files changed, 141 insertions, 55 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 561bb74fd364..282f0fc9fed1 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -339,7 +339,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
339 } 339 }
340 340
341 mutex_init(&chip->mutex); 341 mutex_init(&chip->mutex);
342 mutex_init(&chip->shutdown_mutex); 342 init_rwsem(&chip->shutdown_rwsem);
343 chip->index = idx; 343 chip->index = idx;
344 chip->dev = dev; 344 chip->dev = dev;
345 chip->card = card; 345 chip->card = card;
@@ -560,7 +560,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
560 560
561 card = chip->card; 561 card = chip->card;
562 mutex_lock(&register_mutex); 562 mutex_lock(&register_mutex);
563 mutex_lock(&chip->shutdown_mutex); 563 down_write(&chip->shutdown_rwsem);
564 chip->shutdown = 1; 564 chip->shutdown = 1;
565 chip->num_interfaces--; 565 chip->num_interfaces--;
566 if (chip->num_interfaces <= 0) { 566 if (chip->num_interfaces <= 0) {
@@ -582,11 +582,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
582 snd_usb_mixer_disconnect(p); 582 snd_usb_mixer_disconnect(p);
583 } 583 }
584 usb_chip[chip->index] = NULL; 584 usb_chip[chip->index] = NULL;
585 mutex_unlock(&chip->shutdown_mutex); 585 up_write(&chip->shutdown_rwsem);
586 mutex_unlock(&register_mutex); 586 mutex_unlock(&register_mutex);
587 snd_card_free_when_closed(card); 587 snd_card_free_when_closed(card);
588 } else { 588 } else {
589 mutex_unlock(&chip->shutdown_mutex); 589 up_write(&chip->shutdown_rwsem);
590 mutex_unlock(&register_mutex); 590 mutex_unlock(&register_mutex);
591 } 591 }
592} 592}
@@ -618,16 +618,20 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
618{ 618{
619 int err = -ENODEV; 619 int err = -ENODEV;
620 620
621 down_read(&chip->shutdown_rwsem);
621 if (!chip->shutdown && !chip->probing) 622 if (!chip->shutdown && !chip->probing)
622 err = usb_autopm_get_interface(chip->pm_intf); 623 err = usb_autopm_get_interface(chip->pm_intf);
624 up_read(&chip->shutdown_rwsem);
623 625
624 return err; 626 return err;
625} 627}
626 628
627void snd_usb_autosuspend(struct snd_usb_audio *chip) 629void snd_usb_autosuspend(struct snd_usb_audio *chip)
628{ 630{
631 down_read(&chip->shutdown_rwsem);
629 if (!chip->shutdown && !chip->probing) 632 if (!chip->shutdown && !chip->probing)
630 usb_autopm_put_interface(chip->pm_intf); 633 usb_autopm_put_interface(chip->pm_intf);
634 up_read(&chip->shutdown_rwsem);
631} 635}
632 636
633static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) 637static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
diff --git a/sound/usb/card.h b/sound/usb/card.h
index afa4f9e9b27a..814cb357ff88 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -126,6 +126,7 @@ struct snd_usb_substream {
126 struct snd_usb_endpoint *sync_endpoint; 126 struct snd_usb_endpoint *sync_endpoint;
127 unsigned long flags; 127 unsigned long flags;
128 bool need_setup_ep; /* (re)configure EP at prepare? */ 128 bool need_setup_ep; /* (re)configure EP at prepare? */
129 unsigned int speed; /* USB_SPEED_XXX */
129 130
130 u64 formats; /* format bitmasks (all or'ed) */ 131 u64 formats; /* format bitmasks (all or'ed) */
131 unsigned int num_formats; /* number of supported audio formats (list) */ 132 unsigned int num_formats; /* number of supported audio formats (list) */
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index fe56c9da38e9..298070e8f2d4 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -287,25 +287,32 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
287 unsigned char buf[2]; 287 unsigned char buf[2];
288 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 288 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
289 int timeout = 10; 289 int timeout = 10;
290 int err; 290 int idx = 0, err;
291 291
292 err = snd_usb_autoresume(cval->mixer->chip); 292 err = snd_usb_autoresume(cval->mixer->chip);
293 if (err < 0) 293 if (err < 0)
294 return -EIO; 294 return -EIO;
295 down_read(&chip->shutdown_rwsem);
295 while (timeout-- > 0) { 296 while (timeout-- > 0) {
297 if (chip->shutdown)
298 break;
299 idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
296 if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, 300 if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
297 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 301 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
298 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), 302 validx, idx, buf, val_len) >= val_len) {
299 buf, val_len) >= val_len) {
300 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); 303 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
301 snd_usb_autosuspend(cval->mixer->chip); 304 err = 0;
302 return 0; 305 goto out;
303 } 306 }
304 } 307 }
305 snd_usb_autosuspend(cval->mixer->chip);
306 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", 308 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
307 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); 309 request, validx, idx, cval->val_type);
308 return -EINVAL; 310 err = -EINVAL;
311
312 out:
313 up_read(&chip->shutdown_rwsem);
314 snd_usb_autosuspend(cval->mixer->chip);
315 return err;
309} 316}
310 317
311static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) 318static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
@@ -313,7 +320,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
313 struct snd_usb_audio *chip = cval->mixer->chip; 320 struct snd_usb_audio *chip = cval->mixer->chip;
314 unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ 321 unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
315 unsigned char *val; 322 unsigned char *val;
316 int ret, size; 323 int idx = 0, ret, size;
317 __u8 bRequest; 324 __u8 bRequest;
318 325
319 if (request == UAC_GET_CUR) { 326 if (request == UAC_GET_CUR) {
@@ -330,16 +337,22 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
330 if (ret) 337 if (ret)
331 goto error; 338 goto error;
332 339
333 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, 340 down_read(&chip->shutdown_rwsem);
341 if (chip->shutdown)
342 ret = -ENODEV;
343 else {
344 idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
345 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
334 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 346 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
335 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), 347 validx, idx, buf, size);
336 buf, size); 348 }
349 up_read(&chip->shutdown_rwsem);
337 snd_usb_autosuspend(chip); 350 snd_usb_autosuspend(chip);
338 351
339 if (ret < 0) { 352 if (ret < 0) {
340error: 353error:
341 snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", 354 snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
342 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); 355 request, validx, idx, cval->val_type);
343 return ret; 356 return ret;
344 } 357 }
345 358
@@ -417,7 +430,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
417{ 430{
418 struct snd_usb_audio *chip = cval->mixer->chip; 431 struct snd_usb_audio *chip = cval->mixer->chip;
419 unsigned char buf[2]; 432 unsigned char buf[2];
420 int val_len, err, timeout = 10; 433 int idx = 0, val_len, err, timeout = 10;
421 434
422 if (cval->mixer->protocol == UAC_VERSION_1) { 435 if (cval->mixer->protocol == UAC_VERSION_1) {
423 val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 436 val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
@@ -440,19 +453,27 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
440 err = snd_usb_autoresume(chip); 453 err = snd_usb_autoresume(chip);
441 if (err < 0) 454 if (err < 0)
442 return -EIO; 455 return -EIO;
443 while (timeout-- > 0) 456 down_read(&chip->shutdown_rwsem);
457 while (timeout-- > 0) {
458 if (chip->shutdown)
459 break;
460 idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
444 if (snd_usb_ctl_msg(chip->dev, 461 if (snd_usb_ctl_msg(chip->dev,
445 usb_sndctrlpipe(chip->dev, 0), request, 462 usb_sndctrlpipe(chip->dev, 0), request,
446 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 463 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
447 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), 464 validx, idx, buf, val_len) >= 0) {
448 buf, val_len) >= 0) { 465 err = 0;
449 snd_usb_autosuspend(chip); 466 goto out;
450 return 0;
451 } 467 }
452 snd_usb_autosuspend(chip); 468 }
453 snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", 469 snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
454 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]); 470 request, validx, idx, cval->val_type, buf[0], buf[1]);
455 return -EINVAL; 471 err = -EINVAL;
472
473 out:
474 up_read(&chip->shutdown_rwsem);
475 snd_usb_autosuspend(chip);
476 return err;
456} 477}
457 478
458static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) 479static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 690000db0ec0..ae2b71435220 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -283,6 +283,11 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
283 if (value > 1) 283 if (value > 1)
284 return -EINVAL; 284 return -EINVAL;
285 changed = value != mixer->audigy2nx_leds[index]; 285 changed = value != mixer->audigy2nx_leds[index];
286 down_read(&mixer->chip->shutdown_rwsem);
287 if (mixer->chip->shutdown) {
288 err = -ENODEV;
289 goto out;
290 }
286 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) 291 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
287 err = snd_usb_ctl_msg(mixer->chip->dev, 292 err = snd_usb_ctl_msg(mixer->chip->dev,
288 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 293 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
@@ -299,6 +304,8 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
299 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 304 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
300 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 305 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
301 value, index + 2, NULL, 0); 306 value, index + 2, NULL, 0);
307 out:
308 up_read(&mixer->chip->shutdown_rwsem);
302 if (err < 0) 309 if (err < 0)
303 return err; 310 return err;
304 mixer->audigy2nx_leds[index] = value; 311 mixer->audigy2nx_leds[index] = value;
@@ -392,11 +399,16 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
392 399
393 for (i = 0; jacks[i].name; ++i) { 400 for (i = 0; jacks[i].name; ++i) {
394 snd_iprintf(buffer, "%s: ", jacks[i].name); 401 snd_iprintf(buffer, "%s: ", jacks[i].name);
395 err = snd_usb_ctl_msg(mixer->chip->dev, 402 down_read(&mixer->chip->shutdown_rwsem);
403 if (mixer->chip->shutdown)
404 err = 0;
405 else
406 err = snd_usb_ctl_msg(mixer->chip->dev,
396 usb_rcvctrlpipe(mixer->chip->dev, 0), 407 usb_rcvctrlpipe(mixer->chip->dev, 0),
397 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | 408 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
398 USB_RECIP_INTERFACE, 0, 409 USB_RECIP_INTERFACE, 0,
399 jacks[i].unitid << 8, buf, 3); 410 jacks[i].unitid << 8, buf, 3);
411 up_read(&mixer->chip->shutdown_rwsem);
400 if (err == 3 && (buf[0] == 3 || buf[0] == 6)) 412 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
401 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); 413 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
402 else 414 else
@@ -426,10 +438,15 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
426 else 438 else
427 new_status = old_status & ~0x02; 439 new_status = old_status & ~0x02;
428 changed = new_status != old_status; 440 changed = new_status != old_status;
429 err = snd_usb_ctl_msg(mixer->chip->dev, 441 down_read(&mixer->chip->shutdown_rwsem);
442 if (mixer->chip->shutdown)
443 err = -ENODEV;
444 else
445 err = snd_usb_ctl_msg(mixer->chip->dev,
430 usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, 446 usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
431 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 447 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
432 50, 0, &new_status, 1); 448 50, 0, &new_status, 1);
449 up_read(&mixer->chip->shutdown_rwsem);
433 if (err < 0) 450 if (err < 0)
434 return err; 451 return err;
435 mixer->xonar_u1_status = new_status; 452 mixer->xonar_u1_status = new_status;
@@ -468,11 +485,17 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
468 u8 bRequest = (kcontrol->private_value >> 16) & 0xff; 485 u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
469 u16 wIndex = kcontrol->private_value & 0xffff; 486 u16 wIndex = kcontrol->private_value & 0xffff;
470 u8 tmp; 487 u8 tmp;
488 int ret;
471 489
472 int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, 490 down_read(&mixer->chip->shutdown_rwsem);
491 if (mixer->chip->shutdown)
492 ret = -ENODEV;
493 else
494 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
473 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 495 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
474 0, cpu_to_le16(wIndex), 496 0, cpu_to_le16(wIndex),
475 &tmp, sizeof(tmp), 1000); 497 &tmp, sizeof(tmp), 1000);
498 up_read(&mixer->chip->shutdown_rwsem);
476 499
477 if (ret < 0) { 500 if (ret < 0) {
478 snd_printk(KERN_ERR 501 snd_printk(KERN_ERR
@@ -493,11 +516,17 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
493 u8 bRequest = (kcontrol->private_value >> 16) & 0xff; 516 u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
494 u16 wIndex = kcontrol->private_value & 0xffff; 517 u16 wIndex = kcontrol->private_value & 0xffff;
495 u16 wValue = ucontrol->value.integer.value[0]; 518 u16 wValue = ucontrol->value.integer.value[0];
519 int ret;
496 520
497 int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, 521 down_read(&mixer->chip->shutdown_rwsem);
522 if (mixer->chip->shutdown)
523 ret = -ENODEV;
524 else
525 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
498 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 526 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
499 cpu_to_le16(wValue), cpu_to_le16(wIndex), 527 cpu_to_le16(wValue), cpu_to_le16(wIndex),
500 NULL, 0, 1000); 528 NULL, 0, 1000);
529 up_read(&mixer->chip->shutdown_rwsem);
501 530
502 if (ret < 0) { 531 if (ret < 0) {
503 snd_printk(KERN_ERR 532 snd_printk(KERN_ERR
@@ -656,11 +685,16 @@ static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl,
656 return -EINVAL; 685 return -EINVAL;
657 686
658 687
659 err = snd_usb_ctl_msg(chip->dev, 688 down_read(&mixer->chip->shutdown_rwsem);
689 if (mixer->chip->shutdown)
690 err = -ENODEV;
691 else
692 err = snd_usb_ctl_msg(chip->dev,
660 usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, 693 usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
661 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 694 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
662 validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), 695 validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
663 value, val_len); 696 value, val_len);
697 up_read(&mixer->chip->shutdown_rwsem);
664 if (err < 0) 698 if (err < 0)
665 return err; 699 return err;
666 700
@@ -703,11 +737,16 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
703 737
704 if (!pval->is_cached) { 738 if (!pval->is_cached) {
705 /* Read current value */ 739 /* Read current value */
706 err = snd_usb_ctl_msg(chip->dev, 740 down_read(&mixer->chip->shutdown_rwsem);
741 if (mixer->chip->shutdown)
742 err = -ENODEV;
743 else
744 err = snd_usb_ctl_msg(chip->dev,
707 usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, 745 usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
708 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 746 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
709 validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), 747 validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
710 value, val_len); 748 value, val_len);
749 up_read(&mixer->chip->shutdown_rwsem);
711 if (err < 0) 750 if (err < 0)
712 return err; 751 return err;
713 752
@@ -719,11 +758,16 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
719 if (cur_val != new_val) { 758 if (cur_val != new_val) {
720 value[0] = new_val; 759 value[0] = new_val;
721 value[1] = 0; 760 value[1] = 0;
722 err = snd_usb_ctl_msg(chip->dev, 761 down_read(&mixer->chip->shutdown_rwsem);
762 if (mixer->chip->shutdown)
763 err = -ENODEV;
764 else
765 err = snd_usb_ctl_msg(chip->dev,
723 usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, 766 usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
724 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 767 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
725 validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), 768 validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
726 value, val_len); 769 value, val_len);
770 up_read(&mixer->chip->shutdown_rwsem);
727 if (err < 0) 771 if (err < 0)
728 return err; 772 return err;
729 773
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index f77b87ad0256..8ca6edf29fee 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -71,6 +71,8 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream
71 unsigned int hwptr_done; 71 unsigned int hwptr_done;
72 72
73 subs = (struct snd_usb_substream *)substream->runtime->private_data; 73 subs = (struct snd_usb_substream *)substream->runtime->private_data;
74 if (subs->stream->chip->shutdown)
75 return SNDRV_PCM_POS_XRUN;
74 spin_lock(&subs->lock); 76 spin_lock(&subs->lock);
75 hwptr_done = subs->hwptr_done; 77 hwptr_done = subs->hwptr_done;
76 substream->runtime->delay = snd_usb_pcm_delay(subs, 78 substream->runtime->delay = snd_usb_pcm_delay(subs,
@@ -441,7 +443,6 @@ static int configure_endpoint(struct snd_usb_substream *subs)
441{ 443{
442 int ret; 444 int ret;
443 445
444 mutex_lock(&subs->stream->chip->shutdown_mutex);
445 /* format changed */ 446 /* format changed */
446 stop_endpoints(subs, 0, 0, 0); 447 stop_endpoints(subs, 0, 0, 0);
447 ret = snd_usb_endpoint_set_params(subs->data_endpoint, 448 ret = snd_usb_endpoint_set_params(subs->data_endpoint,
@@ -452,7 +453,7 @@ static int configure_endpoint(struct snd_usb_substream *subs)
452 subs->cur_audiofmt, 453 subs->cur_audiofmt,
453 subs->sync_endpoint); 454 subs->sync_endpoint);
454 if (ret < 0) 455 if (ret < 0)
455 goto unlock; 456 return ret;
456 457
457 if (subs->sync_endpoint) 458 if (subs->sync_endpoint)
458 ret = snd_usb_endpoint_set_params(subs->data_endpoint, 459 ret = snd_usb_endpoint_set_params(subs->data_endpoint,
@@ -462,9 +463,6 @@ static int configure_endpoint(struct snd_usb_substream *subs)
462 subs->cur_rate, 463 subs->cur_rate,
463 subs->cur_audiofmt, 464 subs->cur_audiofmt,
464 NULL); 465 NULL);
465
466unlock:
467 mutex_unlock(&subs->stream->chip->shutdown_mutex);
468 return ret; 466 return ret;
469} 467}
470 468
@@ -502,7 +500,13 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
502 return -EINVAL; 500 return -EINVAL;
503 } 501 }
504 502
505 if ((ret = set_format(subs, fmt)) < 0) 503 down_read(&subs->stream->chip->shutdown_rwsem);
504 if (subs->stream->chip->shutdown)
505 ret = -ENODEV;
506 else
507 ret = set_format(subs, fmt);
508 up_read(&subs->stream->chip->shutdown_rwsem);
509 if (ret < 0)
506 return ret; 510 return ret;
507 511
508 subs->interface = fmt->iface; 512 subs->interface = fmt->iface;
@@ -524,10 +528,12 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
524 subs->cur_audiofmt = NULL; 528 subs->cur_audiofmt = NULL;
525 subs->cur_rate = 0; 529 subs->cur_rate = 0;
526 subs->period_bytes = 0; 530 subs->period_bytes = 0;
527 mutex_lock(&subs->stream->chip->shutdown_mutex); 531 down_read(&subs->stream->chip->shutdown_rwsem);
528 stop_endpoints(subs, 0, 1, 1); 532 if (!subs->stream->chip->shutdown) {
529 deactivate_endpoints(subs); 533 stop_endpoints(subs, 0, 1, 1);
530 mutex_unlock(&subs->stream->chip->shutdown_mutex); 534 deactivate_endpoints(subs);
535 }
536 up_read(&subs->stream->chip->shutdown_rwsem);
531 return snd_pcm_lib_free_vmalloc_buffer(substream); 537 return snd_pcm_lib_free_vmalloc_buffer(substream);
532} 538}
533 539
@@ -549,12 +555,19 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
549 return -ENXIO; 555 return -ENXIO;
550 } 556 }
551 557
552 if (snd_BUG_ON(!subs->data_endpoint)) 558 down_read(&subs->stream->chip->shutdown_rwsem);
553 return -EIO; 559 if (subs->stream->chip->shutdown) {
560 ret = -ENODEV;
561 goto unlock;
562 }
563 if (snd_BUG_ON(!subs->data_endpoint)) {
564 ret = -EIO;
565 goto unlock;
566 }
554 567
555 ret = set_format(subs, subs->cur_audiofmt); 568 ret = set_format(subs, subs->cur_audiofmt);
556 if (ret < 0) 569 if (ret < 0)
557 return ret; 570 goto unlock;
558 571
559 iface = usb_ifnum_to_if(subs->dev, subs->cur_audiofmt->iface); 572 iface = usb_ifnum_to_if(subs->dev, subs->cur_audiofmt->iface);
560 alts = &iface->altsetting[subs->cur_audiofmt->altset_idx]; 573 alts = &iface->altsetting[subs->cur_audiofmt->altset_idx];
@@ -564,12 +577,12 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
564 subs->cur_audiofmt, 577 subs->cur_audiofmt,
565 subs->cur_rate); 578 subs->cur_rate);
566 if (ret < 0) 579 if (ret < 0)
567 return ret; 580 goto unlock;
568 581
569 if (subs->need_setup_ep) { 582 if (subs->need_setup_ep) {
570 ret = configure_endpoint(subs); 583 ret = configure_endpoint(subs);
571 if (ret < 0) 584 if (ret < 0)
572 return ret; 585 goto unlock;
573 subs->need_setup_ep = false; 586 subs->need_setup_ep = false;
574 } 587 }
575 588
@@ -589,9 +602,11 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
589 /* for playback, submit the URBs now; otherwise, the first hwptr_done 602 /* for playback, submit the URBs now; otherwise, the first hwptr_done
590 * updates for all URBs would happen at the same time when starting */ 603 * updates for all URBs would happen at the same time when starting */
591 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) 604 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
592 return start_endpoints(subs, 1); 605 ret = start_endpoints(subs, 1);
593 606
594 return 0; 607 unlock:
608 up_read(&subs->stream->chip->shutdown_rwsem);
609 return ret;
595} 610}
596 611
597static struct snd_pcm_hardware snd_usb_hardware = 612static struct snd_pcm_hardware snd_usb_hardware =
@@ -644,7 +659,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs,
644 return 0; 659 return 0;
645 } 660 }
646 /* check whether the period time is >= the data packet interval */ 661 /* check whether the period time is >= the data packet interval */
647 if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) { 662 if (subs->speed != USB_SPEED_FULL) {
648 ptime = 125 * (1 << fp->datainterval); 663 ptime = 125 * (1 << fp->datainterval);
649 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) { 664 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
650 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max); 665 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
@@ -922,7 +937,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
922 return err; 937 return err;
923 938
924 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; 939 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
925 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) 940 if (subs->speed == USB_SPEED_FULL)
926 /* full speed devices have fixed data packet interval */ 941 /* full speed devices have fixed data packet interval */
927 ptmin = 1000; 942 ptmin = 1000;
928 if (ptmin == 1000) 943 if (ptmin == 1000)
diff --git a/sound/usb/proc.c b/sound/usb/proc.c
index ebc1a5b5b3f1..d218f763501f 100644
--- a/sound/usb/proc.c
+++ b/sound/usb/proc.c
@@ -108,7 +108,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
108 } 108 }
109 snd_iprintf(buffer, "\n"); 109 snd_iprintf(buffer, "\n");
110 } 110 }
111 if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) 111 if (subs->speed != USB_SPEED_FULL)
112 snd_iprintf(buffer, " Data packet interval: %d us\n", 112 snd_iprintf(buffer, " Data packet interval: %d us\n",
113 125 * (1 << fp->datainterval)); 113 125 * (1 << fp->datainterval));
114 // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize); 114 // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
@@ -124,7 +124,7 @@ static void proc_dump_ep_status(struct snd_usb_substream *subs,
124 return; 124 return;
125 snd_iprintf(buffer, " Packet Size = %d\n", ep->curpacksize); 125 snd_iprintf(buffer, " Packet Size = %d\n", ep->curpacksize);
126 snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n", 126 snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n",
127 snd_usb_get_speed(subs->dev) == USB_SPEED_FULL 127 subs->speed == USB_SPEED_FULL
128 ? get_full_speed_hz(ep->freqm) 128 ? get_full_speed_hz(ep->freqm)
129 : get_high_speed_hz(ep->freqm), 129 : get_high_speed_hz(ep->freqm),
130 ep->freqm >> 16, ep->freqm & 0xffff); 130 ep->freqm >> 16, ep->freqm & 0xffff);
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 083ed81160e5..1de0c8c002a8 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -90,6 +90,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
90 subs->direction = stream; 90 subs->direction = stream;
91 subs->dev = as->chip->dev; 91 subs->dev = as->chip->dev;
92 subs->txfr_quirk = as->chip->txfr_quirk; 92 subs->txfr_quirk = as->chip->txfr_quirk;
93 subs->speed = snd_usb_get_speed(subs->dev);
93 94
94 snd_usb_set_pcm_ops(as->pcm, stream); 95 snd_usb_set_pcm_ops(as->pcm, stream);
95 96
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index b8233ebe250f..ef42797f56fb 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -37,7 +37,7 @@ 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 mutex shutdown_mutex; 40 struct rw_semaphore shutdown_rwsem;
41 unsigned int shutdown:1; 41 unsigned int shutdown:1;
42 unsigned int probing:1; 42 unsigned int probing:1;
43 unsigned int autosuspended:1; 43 unsigned int autosuspended:1;