aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/card.h1
-rw-r--r--sound/usb/mixer.c65
-rw-r--r--sound/usb/pcm.c49
-rw-r--r--sound/usb/proc.c4
-rw-r--r--sound/usb/stream.c1
5 files changed, 79 insertions, 41 deletions
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..c2ef11ccd66a 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 mutex_lock(&chip->shutdown_mutex);
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 mutex_unlock(&chip->shutdown_mutex);
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 mutex_lock(&chip->shutdown_mutex);
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 mutex_unlock(&chip->shutdown_mutex);
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 mutex_lock(&chip->shutdown_mutex);
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 mutex_unlock(&chip->shutdown_mutex);
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/pcm.c b/sound/usb/pcm.c
index 55e19e1b80ec..55e741c5f231 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,
@@ -444,7 +446,6 @@ static int configure_endpoint(struct snd_usb_substream *subs)
444{ 446{
445 int ret; 447 int ret;
446 448
447 mutex_lock(&subs->stream->chip->shutdown_mutex);
448 /* format changed */ 449 /* format changed */
449 stop_endpoints(subs, 0, 0, 0); 450 stop_endpoints(subs, 0, 0, 0);
450 ret = snd_usb_endpoint_set_params(subs->data_endpoint, 451 ret = snd_usb_endpoint_set_params(subs->data_endpoint,
@@ -455,7 +456,7 @@ static int configure_endpoint(struct snd_usb_substream *subs)
455 subs->cur_audiofmt, 456 subs->cur_audiofmt,
456 subs->sync_endpoint); 457 subs->sync_endpoint);
457 if (ret < 0) 458 if (ret < 0)
458 goto unlock; 459 return ret;
459 460
460 if (subs->sync_endpoint) 461 if (subs->sync_endpoint)
461 ret = snd_usb_endpoint_set_params(subs->data_endpoint, 462 ret = snd_usb_endpoint_set_params(subs->data_endpoint,
@@ -465,9 +466,6 @@ static int configure_endpoint(struct snd_usb_substream *subs)
465 subs->cur_rate, 466 subs->cur_rate,
466 subs->cur_audiofmt, 467 subs->cur_audiofmt,
467 NULL); 468 NULL);
468
469unlock:
470 mutex_unlock(&subs->stream->chip->shutdown_mutex);
471 return ret; 469 return ret;
472} 470}
473 471
@@ -505,7 +503,13 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
505 return -EINVAL; 503 return -EINVAL;
506 } 504 }
507 505
508 if ((ret = set_format(subs, fmt)) < 0) 506 mutex_lock(&subs->stream->chip->shutdown_mutex);
507 if (subs->stream->chip->shutdown)
508 ret = -ENODEV;
509 else
510 ret = set_format(subs, fmt);
511 mutex_unlock(&subs->stream->chip->shutdown_mutex);
512 if (ret < 0)
509 return ret; 513 return ret;
510 514
511 subs->interface = fmt->iface; 515 subs->interface = fmt->iface;
@@ -528,8 +532,10 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
528 subs->cur_rate = 0; 532 subs->cur_rate = 0;
529 subs->period_bytes = 0; 533 subs->period_bytes = 0;
530 mutex_lock(&subs->stream->chip->shutdown_mutex); 534 mutex_lock(&subs->stream->chip->shutdown_mutex);
531 stop_endpoints(subs, 0, 1, 1); 535 if (!subs->stream->chip->shutdown) {
532 deactivate_endpoints(subs); 536 stop_endpoints(subs, 0, 1, 1);
537 deactivate_endpoints(subs);
538 }
533 mutex_unlock(&subs->stream->chip->shutdown_mutex); 539 mutex_unlock(&subs->stream->chip->shutdown_mutex);
534 return snd_pcm_lib_free_vmalloc_buffer(substream); 540 return snd_pcm_lib_free_vmalloc_buffer(substream);
535} 541}
@@ -552,12 +558,19 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
552 return -ENXIO; 558 return -ENXIO;
553 } 559 }
554 560
555 if (snd_BUG_ON(!subs->data_endpoint)) 561 mutex_lock(&subs->stream->chip->shutdown_mutex);
556 return -EIO; 562 if (subs->stream->chip->shutdown) {
563 ret = -ENODEV;
564 goto unlock;
565 }
566 if (snd_BUG_ON(!subs->data_endpoint)) {
567 ret = -EIO;
568 goto unlock;
569 }
557 570
558 ret = set_format(subs, subs->cur_audiofmt); 571 ret = set_format(subs, subs->cur_audiofmt);
559 if (ret < 0) 572 if (ret < 0)
560 return ret; 573 goto unlock;
561 574
562 iface = usb_ifnum_to_if(subs->dev, subs->cur_audiofmt->iface); 575 iface = usb_ifnum_to_if(subs->dev, subs->cur_audiofmt->iface);
563 alts = &iface->altsetting[subs->cur_audiofmt->altset_idx]; 576 alts = &iface->altsetting[subs->cur_audiofmt->altset_idx];
@@ -567,12 +580,12 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
567 subs->cur_audiofmt, 580 subs->cur_audiofmt,
568 subs->cur_rate); 581 subs->cur_rate);
569 if (ret < 0) 582 if (ret < 0)
570 return ret; 583 goto unlock;
571 584
572 if (subs->need_setup_ep) { 585 if (subs->need_setup_ep) {
573 ret = configure_endpoint(subs); 586 ret = configure_endpoint(subs);
574 if (ret < 0) 587 if (ret < 0)
575 return ret; 588 goto unlock;
576 subs->need_setup_ep = false; 589 subs->need_setup_ep = false;
577 } 590 }
578 591
@@ -592,9 +605,11 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
592 /* for playback, submit the URBs now; otherwise, the first hwptr_done 605 /* for playback, submit the URBs now; otherwise, the first hwptr_done
593 * updates for all URBs would happen at the same time when starting */ 606 * updates for all URBs would happen at the same time when starting */
594 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) 607 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
595 return start_endpoints(subs, 1); 608 ret = start_endpoints(subs, 1);
596 609
597 return 0; 610 unlock:
611 mutex_unlock(&subs->stream->chip->shutdown_mutex);
612 return ret;
598} 613}
599 614
600static struct snd_pcm_hardware snd_usb_hardware = 615static struct snd_pcm_hardware snd_usb_hardware =
@@ -647,7 +662,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs,
647 return 0; 662 return 0;
648 } 663 }
649 /* check whether the period time is >= the data packet interval */ 664 /* check whether the period time is >= the data packet interval */
650 if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) { 665 if (subs->speed != USB_SPEED_FULL) {
651 ptime = 125 * (1 << fp->datainterval); 666 ptime = 125 * (1 << fp->datainterval);
652 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) { 667 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
653 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max); 668 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
@@ -925,7 +940,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
925 return err; 940 return err;
926 941
927 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; 942 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
928 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) 943 if (subs->speed == USB_SPEED_FULL)
929 /* full speed devices have fixed data packet interval */ 944 /* full speed devices have fixed data packet interval */
930 ptmin = 1000; 945 ptmin = 1000;
931 if (ptmin == 1000) 946 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