diff options
| -rw-r--r-- | sound/usb/card.h | 1 | ||||
| -rw-r--r-- | sound/usb/mixer.c | 65 | ||||
| -rw-r--r-- | sound/usb/pcm.c | 49 | ||||
| -rw-r--r-- | sound/usb/proc.c | 4 | ||||
| -rw-r--r-- | sound/usb/stream.c | 1 |
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 | ||
| 311 | static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) | 318 | static 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) { |
| 340 | error: | 353 | error: |
| 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 | ||
| 458 | static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) | 479 | static 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 | |||
| 469 | unlock: | ||
| 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 | ||
| 600 | static struct snd_pcm_hardware snd_usb_hardware = | 615 | static 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 | ||
