aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2010-02-22 17:49:09 -0500
committerTakashi Iwai <tiwai@suse.de>2010-02-23 02:40:12 -0500
commit28e1b773083d349d5223f586a39fa30f5d0f1c36 (patch)
tree4793eb1d87a094cf3642600ac3b201f81bab7e54 /sound
parent40717382e0c1f572553e4fdefb489db4b95a5e7e (diff)
ALSA: usbaudio: parse USB descriptors with structs
In preparation of support for v2.0 audio class, use the structs from linux/usb/audio.h and add some new ones to describe the fields that are actually parsed by the descriptor decoders. Also, factor out code from usb_create_streams(). This makes it easier to adopt the new iteration logic needed for v2.0. Signed-off-by: Daniel Mack <daniel@caiaq.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/usb/usbaudio.c198
-rw-r--r--sound/usb/usbmixer.c37
2 files changed, 140 insertions, 95 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index c6b9c8cac59..f833dea6018 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -46,6 +46,8 @@
46#include <linux/usb.h> 46#include <linux/usb.h>
47#include <linux/moduleparam.h> 47#include <linux/moduleparam.h>
48#include <linux/mutex.h> 48#include <linux/mutex.h>
49#include <linux/usb/audio.h>
50
49#include <sound/core.h> 51#include <sound/core.h>
50#include <sound/info.h> 52#include <sound/info.h>
51#include <sound/pcm.h> 53#include <sound/pcm.h>
@@ -2421,15 +2423,17 @@ static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *
2421 * @fmt: the format type descriptor 2423 * @fmt: the format type descriptor
2422 */ 2424 */
2423static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audioformat *fp, 2425static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audioformat *fp,
2424 int format, unsigned char *fmt) 2426 int format, void *fmt_raw)
2425{ 2427{
2426 int pcm_format; 2428 int pcm_format;
2427 int sample_width, sample_bytes; 2429 int sample_width, sample_bytes;
2430 struct uac_format_type_i_discrete_descriptor *fmt = fmt_raw;
2428 2431
2429 /* FIXME: correct endianess and sign? */ 2432 /* FIXME: correct endianess and sign? */
2430 pcm_format = -1; 2433 pcm_format = -1;
2431 sample_width = fmt[6]; 2434 sample_width = fmt->bBitResolution;
2432 sample_bytes = fmt[5]; 2435 sample_bytes = fmt->bSubframeSize;
2436
2433 switch (format) { 2437 switch (format) {
2434 case 0: /* some devices don't define this correctly... */ 2438 case 0: /* some devices don't define this correctly... */
2435 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n", 2439 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
@@ -2442,7 +2446,7 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor
2442 sample_width, sample_bytes); 2446 sample_width, sample_bytes);
2443 } 2447 }
2444 /* check the format byte size */ 2448 /* check the format byte size */
2445 switch (fmt[5]) { 2449 switch (sample_bytes) {
2446 case 1: 2450 case 1:
2447 pcm_format = SNDRV_PCM_FORMAT_S8; 2451 pcm_format = SNDRV_PCM_FORMAT_S8;
2448 break; 2452 break;
@@ -2463,8 +2467,8 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor
2463 break; 2467 break;
2464 default: 2468 default:
2465 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n", 2469 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n",
2466 chip->dev->devnum, fp->iface, 2470 chip->dev->devnum, fp->iface, fp->altsetting,
2467 fp->altsetting, sample_width, sample_bytes); 2471 sample_width, sample_bytes);
2468 break; 2472 break;
2469 } 2473 }
2470 break; 2474 break;
@@ -2564,11 +2568,12 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2564 * parse the format type I and III descriptors 2568 * parse the format type I and III descriptors
2565 */ 2569 */
2566static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat *fp, 2570static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat *fp,
2567 int format, unsigned char *fmt) 2571 int format, void *fmt_raw)
2568{ 2572{
2569 int pcm_format; 2573 int pcm_format;
2574 struct uac_format_type_i_discrete_descriptor *fmt = fmt_raw;
2570 2575
2571 if (fmt[3] == USB_FORMAT_TYPE_III) { 2576 if (fmt->bFormatType == USB_FORMAT_TYPE_III) {
2572 /* FIXME: the format type is really IECxxx 2577 /* FIXME: the format type is really IECxxx
2573 * but we give normal PCM format to get the existing 2578 * but we give normal PCM format to get the existing
2574 * apps working... 2579 * apps working...
@@ -2590,23 +2595,27 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat *
2590 if (pcm_format < 0) 2595 if (pcm_format < 0)
2591 return -1; 2596 return -1;
2592 } 2597 }
2598
2593 fp->format = pcm_format; 2599 fp->format = pcm_format;
2594 fp->channels = fmt[4]; 2600 fp->channels = fmt->bNrChannels;
2601
2595 if (fp->channels < 1) { 2602 if (fp->channels < 1) {
2596 snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n", 2603 snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
2597 chip->dev->devnum, fp->iface, fp->altsetting, fp->channels); 2604 chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
2598 return -1; 2605 return -1;
2599 } 2606 }
2600 return parse_audio_format_rates(chip, fp, fmt, 7); 2607 return parse_audio_format_rates(chip, fp, fmt_raw, 7);
2601} 2608}
2602 2609
2603/* 2610/*
2604 * prase the format type II descriptor 2611 * parse the format type II descriptor
2605 */ 2612 */
2606static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat *fp, 2613static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat *fp,
2607 int format, unsigned char *fmt) 2614 int format, void *fmt_raw)
2608{ 2615{
2609 int brate, framesize; 2616 int brate, framesize;
2617 struct uac_format_type_ii_discrete_descriptor *fmt = fmt_raw;
2618
2610 switch (format) { 2619 switch (format) {
2611 case USB_AUDIO_FORMAT_AC3: 2620 case USB_AUDIO_FORMAT_AC3:
2612 /* FIXME: there is no AC3 format defined yet */ 2621 /* FIXME: there is no AC3 format defined yet */
@@ -2622,20 +2631,25 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat
2622 fp->format = SNDRV_PCM_FORMAT_MPEG; 2631 fp->format = SNDRV_PCM_FORMAT_MPEG;
2623 break; 2632 break;
2624 } 2633 }
2634
2625 fp->channels = 1; 2635 fp->channels = 1;
2626 brate = combine_word(&fmt[4]); /* fmt[4,5] : wMaxBitRate (in kbps) */ 2636
2627 framesize = combine_word(&fmt[6]); /* fmt[6,7]: wSamplesPerFrame */ 2637 brate = le16_to_cpu(fmt->wMaxBitRate);
2638 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
2628 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); 2639 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
2629 fp->frame_size = framesize; 2640 fp->frame_size = framesize;
2630 return parse_audio_format_rates(chip, fp, fmt, 8); /* fmt[8..] sample rates */ 2641 return parse_audio_format_rates(chip, fp, fmt_raw, 8); /* fmt[8..] sample rates */
2631} 2642}
2632 2643
2633static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, 2644static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
2634 int format, unsigned char *fmt, int stream) 2645 int format, void *fmt_raw, int stream)
2635{ 2646{
2636 int err; 2647 int err;
2648 /* we only parse the common header of all format types here,
2649 * so it is safe to take a type_i struct */
2650 struct uac_format_type_i_discrete_descriptor *fmt = fmt_raw;
2637 2651
2638 switch (fmt[3]) { 2652 switch (fmt->bFormatType) {
2639 case USB_FORMAT_TYPE_I: 2653 case USB_FORMAT_TYPE_I:
2640 case USB_FORMAT_TYPE_III: 2654 case USB_FORMAT_TYPE_III:
2641 err = parse_audio_format_i(chip, fp, format, fmt); 2655 err = parse_audio_format_i(chip, fp, format, fmt);
@@ -2645,10 +2659,10 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp
2645 break; 2659 break;
2646 default: 2660 default:
2647 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", 2661 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
2648 chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]); 2662 chip->dev->devnum, fp->iface, fp->altsetting, fmt->bFormatType);
2649 return -1; 2663 return -1;
2650 } 2664 }
2651 fp->fmt_type = fmt[3]; 2665 fp->fmt_type = fmt->bFormatType;
2652 if (err < 0) 2666 if (err < 0)
2653 return err; 2667 return err;
2654#if 1 2668#if 1
@@ -2659,7 +2673,7 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp
2659 if (chip->usb_id == USB_ID(0x041e, 0x3000) || 2673 if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
2660 chip->usb_id == USB_ID(0x041e, 0x3020) || 2674 chip->usb_id == USB_ID(0x041e, 0x3020) ||
2661 chip->usb_id == USB_ID(0x041e, 0x3061)) { 2675 chip->usb_id == USB_ID(0x041e, 0x3061)) {
2662 if (fmt[3] == USB_FORMAT_TYPE_I && 2676 if (fmt->bFormatType == USB_FORMAT_TYPE_I &&
2663 fp->rates != SNDRV_PCM_RATE_48000 && 2677 fp->rates != SNDRV_PCM_RATE_48000 &&
2664 fp->rates != SNDRV_PCM_RATE_96000) 2678 fp->rates != SNDRV_PCM_RATE_96000)
2665 return -1; 2679 return -1;
@@ -2708,6 +2722,8 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2708 num = 4; 2722 num = 4;
2709 2723
2710 for (i = 0; i < num; i++) { 2724 for (i = 0; i < num; i++) {
2725 struct uac_as_header_descriptor_v1 *as;
2726
2711 alts = &iface->altsetting[i]; 2727 alts = &iface->altsetting[i];
2712 altsd = get_iface_desc(alts); 2728 altsd = get_iface_desc(alts);
2713 /* skip invalid one */ 2729 /* skip invalid one */
@@ -2726,7 +2742,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2726 stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? 2742 stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
2727 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; 2743 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
2728 altno = altsd->bAlternateSetting; 2744 altno = altsd->bAlternateSetting;
2729 2745
2730 /* audiophile usb: skip altsets incompatible with device_setup 2746 /* audiophile usb: skip altsets incompatible with device_setup
2731 */ 2747 */
2732 if (chip->usb_id == USB_ID(0x0763, 0x2003) && 2748 if (chip->usb_id == USB_ID(0x0763, 0x2003) &&
@@ -2734,20 +2750,21 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2734 continue; 2750 continue;
2735 2751
2736 /* get audio formats */ 2752 /* get audio formats */
2737 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); 2753 as = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL);
2738 if (!fmt) { 2754
2755 if (!as) {
2739 snd_printk(KERN_ERR "%d:%u:%d : AS_GENERAL descriptor not found\n", 2756 snd_printk(KERN_ERR "%d:%u:%d : AS_GENERAL descriptor not found\n",
2740 dev->devnum, iface_no, altno); 2757 dev->devnum, iface_no, altno);
2741 continue; 2758 continue;
2742 } 2759 }
2743 2760
2744 if (fmt[0] < 7) { 2761 if (as->bLength < sizeof(*as)) {
2745 snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n", 2762 snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n",
2746 dev->devnum, iface_no, altno); 2763 dev->devnum, iface_no, altno);
2747 continue; 2764 continue;
2748 } 2765 }
2749 2766
2750 format = (fmt[6] << 8) | fmt[5]; /* remember the format value */ 2767 format = le16_to_cpu(as->wFormatTag); /* remember the format value */
2751 2768
2752 /* get format type */ 2769 /* get format type */
2753 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, FORMAT_TYPE); 2770 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, FORMAT_TYPE);
@@ -2875,6 +2892,65 @@ static void snd_usb_stream_disconnect(struct list_head *head)
2875 } 2892 }
2876} 2893}
2877 2894
2895static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface)
2896{
2897 struct usb_device *dev = chip->dev;
2898 struct usb_host_interface *alts;
2899 struct usb_interface_descriptor *altsd;
2900 struct usb_interface *iface = usb_ifnum_to_if(dev, interface);
2901
2902 if (!iface) {
2903 snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
2904 dev->devnum, ctrlif, interface);
2905 return -EINVAL;
2906 }
2907
2908 if (usb_interface_claimed(iface)) {
2909 snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n",
2910 dev->devnum, ctrlif, interface);
2911 return -EINVAL;
2912 }
2913
2914 alts = &iface->altsetting[0];
2915 altsd = get_iface_desc(alts);
2916 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
2917 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
2918 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) {
2919 int err = snd_usbmidi_create(chip->card, iface,
2920 &chip->midi_list, NULL);
2921 if (err < 0) {
2922 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n",
2923 dev->devnum, ctrlif, interface);
2924 return -EINVAL;
2925 }
2926 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
2927
2928 return 0;
2929 }
2930
2931 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
2932 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
2933 altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) {
2934 snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n",
2935 dev->devnum, ctrlif, interface, altsd->bInterfaceClass);
2936 /* skip non-supported classes */
2937 return -EINVAL;
2938 }
2939
2940 if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
2941 snd_printk(KERN_ERR "low speed audio streaming not supported\n");
2942 return -EINVAL;
2943 }
2944
2945 if (! parse_audio_endpoints(chip, interface)) {
2946 usb_set_interface(dev, interface, 0); /* reset the current interface */
2947 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
2948 return -EINVAL;
2949 }
2950
2951 return 0;
2952}
2953
2878/* 2954/*
2879 * parse audio control descriptor and create pcm/midi streams 2955 * parse audio control descriptor and create pcm/midi streams
2880 */ 2956 */
@@ -2882,69 +2958,36 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
2882{ 2958{
2883 struct usb_device *dev = chip->dev; 2959 struct usb_device *dev = chip->dev;
2884 struct usb_host_interface *host_iface; 2960 struct usb_host_interface *host_iface;
2885 struct usb_interface *iface; 2961 struct uac_ac_header_descriptor_v1 *h1;
2886 unsigned char *p1; 2962 void *control_header;
2887 int i, j; 2963 int i;
2888 2964
2889 /* find audiocontrol interface */ 2965 /* find audiocontrol interface */
2890 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; 2966 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
2891 if (!(p1 = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen, NULL, HEADER))) { 2967 control_header = snd_usb_find_csint_desc(host_iface->extra,
2968 host_iface->extralen,
2969 NULL, HEADER);
2970
2971 if (!control_header) {
2892 snd_printk(KERN_ERR "cannot find HEADER\n"); 2972 snd_printk(KERN_ERR "cannot find HEADER\n");
2893 return -EINVAL; 2973 return -EINVAL;
2894 } 2974 }
2895 if (! p1[7] || p1[0] < 8 + p1[7]) { 2975
2896 snd_printk(KERN_ERR "invalid HEADER\n"); 2976 h1 = control_header;
2977
2978 if (!h1->bInCollection) {
2979 snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
2897 return -EINVAL; 2980 return -EINVAL;
2898 } 2981 }
2899 2982
2900 /* 2983 if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
2901 * parse all USB audio streaming interfaces 2984 snd_printk(KERN_ERR "invalid HEADER (v1)\n");
2902 */ 2985 return -EINVAL;
2903 for (i = 0; i < p1[7]; i++) {
2904 struct usb_host_interface *alts;
2905 struct usb_interface_descriptor *altsd;
2906 j = p1[8 + i];
2907 iface = usb_ifnum_to_if(dev, j);
2908 if (!iface) {
2909 snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
2910 dev->devnum, ctrlif, j);
2911 continue;
2912 }
2913 if (usb_interface_claimed(iface)) {
2914 snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", dev->devnum, ctrlif, j);
2915 continue;
2916 }
2917 alts = &iface->altsetting[0];
2918 altsd = get_iface_desc(alts);
2919 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
2920 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
2921 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) {
2922 int err = snd_usbmidi_create(chip->card, iface,
2923 &chip->midi_list, NULL);
2924 if (err < 0) {
2925 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j);
2926 continue;
2927 }
2928 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
2929 continue;
2930 }
2931 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
2932 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
2933 altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) {
2934 snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", dev->devnum, ctrlif, j, altsd->bInterfaceClass);
2935 /* skip non-supported classes */
2936 continue;
2937 }
2938 if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
2939 snd_printk(KERN_ERR "low speed audio streaming not supported\n");
2940 continue;
2941 }
2942 if (! parse_audio_endpoints(chip, j)) {
2943 usb_set_interface(dev, j, 0); /* reset the current interface */
2944 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
2945 }
2946 } 2986 }
2947 2987
2988 for (i = 0; i < h1->bInCollection; i++)
2989 snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]);
2990
2948 return 0; 2991 return 0;
2949} 2992}
2950 2993
@@ -3607,7 +3650,6 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
3607 ifnum = get_iface_desc(alts)->bInterfaceNumber; 3650 ifnum = get_iface_desc(alts)->bInterfaceNumber;
3608 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), 3651 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
3609 le16_to_cpu(dev->descriptor.idProduct)); 3652 le16_to_cpu(dev->descriptor.idProduct));
3610
3611 if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum) 3653 if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
3612 goto __err_val; 3654 goto __err_val;
3613 3655
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 35b4830fb0c..11636a6112d 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -32,6 +32,8 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/usb.h> 34#include <linux/usb.h>
35#include <linux/usb/audio.h>
36
35#include <sound/core.h> 37#include <sound/core.h>
36#include <sound/control.h> 38#include <sound/control.h>
37#include <sound/hwdep.h> 39#include <sound/hwdep.h>
@@ -1086,29 +1088,30 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
1086 * 1088 *
1087 * most of controlls are defined here. 1089 * most of controlls are defined here.
1088 */ 1090 */
1089static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsigned char *ftr) 1091static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr)
1090{ 1092{
1091 int channels, i, j; 1093 int channels, i, j;
1092 struct usb_audio_term iterm; 1094 struct usb_audio_term iterm;
1093 unsigned int master_bits, first_ch_bits; 1095 unsigned int master_bits, first_ch_bits;
1094 int err, csize; 1096 int err, csize;
1097 struct uac_feature_unit_descriptor *ftr = _ftr;
1095 1098
1096 if (ftr[0] < 7 || ! (csize = ftr[5]) || ftr[0] < 7 + csize) { 1099 if (ftr->bLength < 7 || ! (csize = ftr->bControlSize) || ftr->bLength < 7 + csize) {
1097 snd_printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid); 1100 snd_printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid);
1098 return -EINVAL; 1101 return -EINVAL;
1099 } 1102 }
1100 1103
1101 /* parse the source unit */ 1104 /* parse the source unit */
1102 if ((err = parse_audio_unit(state, ftr[4])) < 0) 1105 if ((err = parse_audio_unit(state, ftr->bSourceID)) < 0)
1103 return err; 1106 return err;
1104 1107
1105 /* determine the input source type and name */ 1108 /* determine the input source type and name */
1106 if (check_input_term(state, ftr[4], &iterm) < 0) 1109 if (check_input_term(state, ftr->bSourceID, &iterm) < 0)
1107 return -EINVAL; 1110 return -EINVAL;
1108 1111
1109 channels = (ftr[0] - 7) / csize - 1; 1112 channels = (ftr->bLength - 7) / csize - 1;
1110 1113
1111 master_bits = snd_usb_combine_bytes(ftr + 6, csize); 1114 master_bits = snd_usb_combine_bytes(ftr->controls, csize);
1112 /* master configuration quirks */ 1115 /* master configuration quirks */
1113 switch (state->chip->usb_id) { 1116 switch (state->chip->usb_id) {
1114 case USB_ID(0x08bb, 0x2702): 1117 case USB_ID(0x08bb, 0x2702):
@@ -1119,21 +1122,21 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsig
1119 break; 1122 break;
1120 } 1123 }
1121 if (channels > 0) 1124 if (channels > 0)
1122 first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize); 1125 first_ch_bits = snd_usb_combine_bytes(ftr->controls + csize, csize);
1123 else 1126 else
1124 first_ch_bits = 0; 1127 first_ch_bits = 0;
1125 /* check all control types */ 1128 /* check all control types */
1126 for (i = 0; i < 10; i++) { 1129 for (i = 0; i < 10; i++) {
1127 unsigned int ch_bits = 0; 1130 unsigned int ch_bits = 0;
1128 for (j = 0; j < channels; j++) { 1131 for (j = 0; j < channels; j++) {
1129 unsigned int mask = snd_usb_combine_bytes(ftr + 6 + csize * (j+1), csize); 1132 unsigned int mask = snd_usb_combine_bytes(ftr->controls + csize * (j+1), csize);
1130 if (mask & (1 << i)) 1133 if (mask & (1 << i))
1131 ch_bits |= (1 << j); 1134 ch_bits |= (1 << j);
1132 } 1135 }
1133 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */ 1136 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1134 build_feature_ctl(state, ftr, ch_bits, i, &iterm, unitid); 1137 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid);
1135 if (master_bits & (1 << i)) 1138 if (master_bits & (1 << i))
1136 build_feature_ctl(state, ftr, 0, i, &iterm, unitid); 1139 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid);
1137 } 1140 }
1138 1141
1139 return 0; 1142 return 0;
@@ -1780,7 +1783,7 @@ static int snd_usb_mixer_dev_free(struct snd_device *device)
1780 */ 1783 */
1781static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) 1784static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1782{ 1785{
1783 unsigned char *desc; 1786 struct uac_output_terminal_descriptor_v1 *desc;
1784 struct mixer_build state; 1787 struct mixer_build state;
1785 int err; 1788 int err;
1786 const struct usbmix_ctl_map *map; 1789 const struct usbmix_ctl_map *map;
@@ -1805,13 +1808,13 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1805 1808
1806 desc = NULL; 1809 desc = NULL;
1807 while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, OUTPUT_TERMINAL)) != NULL) { 1810 while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, OUTPUT_TERMINAL)) != NULL) {
1808 if (desc[0] < 9) 1811 if (desc->bLength < 9)
1809 continue; /* invalid descriptor? */ 1812 continue; /* invalid descriptor? */
1810 set_bit(desc[3], state.unitbitmap); /* mark terminal ID as visited */ 1813 set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
1811 state.oterm.id = desc[3]; 1814 state.oterm.id = desc->bTerminalID;
1812 state.oterm.type = combine_word(&desc[4]); 1815 state.oterm.type = le16_to_cpu(desc->wTerminalType);
1813 state.oterm.name = desc[8]; 1816 state.oterm.name = desc->iTerminal;
1814 err = parse_audio_unit(&state, desc[7]); 1817 err = parse_audio_unit(&state, desc->bSourceID);
1815 if (err < 0) 1818 if (err < 0)
1816 return err; 1819 return err;
1817 } 1820 }