On 24/06/18(Sun) 14:15, Landry Breuil wrote:
> Hi,
>
> the logitech c310 is supported by uvideo, but its uaudio fails to
> attach properly and fallbacks to ugen.
>
> uaudio0 at uhub0 port 1 configuration 1 interface 2 "Logitech Webcam C310"
> rev 2.00/0.12 addr 2
> uaudio_identify_ac: AC interface is 2
> uaudio_identify_ac: found AC header, vers=100, len=38
> uaudio0: audio descriptors make no sense, error=4
> ugen0 at uhub0 port 1 configuration 1 "Logitech Webcam C310" rev 2.00/0.12
> addr 2
>
> after a bit of poking, and looking at lsusb -v output i figured out that
> the audio descriptor was lying on its size, saying it was 38:
>
> AudioControl Interface Descriptor:
> bLength 9
> bDescriptorSubtype 1 (HEADER)
> bcdADC 1.00
> wTotalLength 38
>
> but the sum of the sub-descriptor lengths is in fact 9+12+9+9=39..
>
> AudioControl Interface Descriptor:
> bLength 9
> bDescriptorSubtype 1 (HEADER)
> AudioControl Interface Descriptor:
> bLength 12
> bDescriptorSubtype 2 (INPUT_TERMINAL)
> wTerminalType 0x0201 Microphone
> AudioControl Interface Descriptor:
> bLength 9
> bDescriptorSubtype 3 (OUTPUT_TERMINAL)
> wTerminalType 0x0101 USB Streaming
> AudioControl Interface Descriptor:
> bLength 9
> bDescriptorSubtype 6 (FEATURE_UNIT)
>
> if i 'fix' aclen to be 39 in sys/dev/usb/uaudio.c, line 1806 then the
> device attaches and works fine:
> uaudio0 at uhub1 port 2 configuration 1 interface 2 "Logitech Webcam C310"
> rev 2.00/0.12 addr 5
>
> from that point, i dunno if my analysis is wrong or right, nor how to
> properly handle it, so here's my take:
> - add a UAUDIO_FLAG_BAD_ADC_LEN quirk
> - set it for the c310 vendor/product
> - if the device matches this quirk, aclen++
>
> feedback or better ideas welcome :)
Did you look at how other OSes deal with that problem? Maybe you'll
find a more generic hack.
If you don't find any better solution, I'd suggest using a device ID
check rather than adding a quirk. Because such quirk cannot be generic.
In that case you have an off-by-one, but another device might have a
different problem.
> Index: uaudio.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/uaudio.c,v
> retrieving revision 1.128
> diff -u -r1.128 uaudio.c
> --- uaudio.c 30 Dec 2017 23:08:29 -0000 1.128
> +++ uaudio.c 24 Jun 2018 11:10:53 -0000
> @@ -62,10 +62,11 @@
> #include <dev/usb/uaudioreg.h>
>
> /* #define UAUDIO_DEBUG */
> +#define UAUDIO_DEBUG
> #ifdef UAUDIO_DEBUG
> #define DPRINTF(x) do { if (uaudiodebug) printf x; } while (0)
> #define DPRINTFN(n,x) do { if (uaudiodebug>(n)) printf x; } while (0)
> -int uaudiodebug = 0;
> +int uaudiodebug = 5;
> #else
> #define DPRINTF(x)
> #define DPRINTFN(n,x)
> @@ -172,6 +173,7 @@
> #define UAUDIO_FLAG_VENDOR_CLASS 0x0010 /* claims vendor class but
> works */
> #define UAUDIO_FLAG_DEPENDENT 0x0020 /* play and record params must
> equal */
> #define UAUDIO_FLAG_EMU0202 0x0040
> +#define UAUDIO_FLAG_BAD_ADC_LEN 0x0080 /* bad audio control descriptor
> size */
>
> struct uaudio_devs {
> struct usb_devno uv_dev;
> @@ -222,6 +224,8 @@
> UAUDIO_FLAG_BAD_AUDIO },
> { { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMZOOM },
> UAUDIO_FLAG_BAD_AUDIO },
> + { { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC310 },
> + UAUDIO_FLAG_BAD_ADC_LEN },
> { { USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1 },
> UAUDIO_FLAG_NO_FRAC }
> };
> @@ -1806,6 +1810,9 @@
> aclen = UGETW(acdp->wTotalLength);
> if (offs + aclen > size)
> return (USBD_INVAL);
> +
> + if (sc->sc_quirks & UAUDIO_FLAG_BAD_ADC_LEN)
> + aclen++;
>
> if (!(sc->sc_quirks & UAUDIO_FLAG_BAD_ADC) &&
> UGETW(acdp->bcdADC) != UAUDIO_VERSION)