On Wed, 12 Aug 2020 21:39:15 +0200 Marcus Glocker <mar...@nazgul.ch> wrote:
> jmc was so nice to send me his trouble device over to do some further > investigations. Just some updates on what I've noticed today: > > - The issue isn't specific to xhci(4). I also see the same issue on > some of my ehci(4) machines when attaching this device. > > - It seems like the device gets in to an 'corrupted state' after > running a couple of control transfer against it. Initially they > work fine, with smaller and larger transfer sizes, and at one point > the device hangs up and doesn't recover until re-attaching it. > While on some ehci(4) machines the uhidev(4) attach works fine, after > running lsusb against the device, I see transfer errors coming up > again; On xhci(4) namely XHCI_CODE_TXERR. > > - Attaching an USB 2.0 hub doesn't make any difference, no matter if > attached to an xhci(4) or an ehci(4) controller. > > Not sure what is going wrong with this little beast ... OK, I give up :-) Following my summary report. This device seems to have issues with two control request types: - UR_GET_STATUS, not called for this device from the kernel in the default code path. But e.g. 'lsusb -v' will call it. - UR_SET_IDLE, as called in uhidev_attach(). UR_GET_STATUS will stall the device for good on *all* controller drivers. UR_SET_IDLE works only on ehci(4) - Don't ask me why. On all the other controller drivers the following UR_GET_REPORT request will fail, stalling the device as well. I tried all kind of things to get the UR_SET_IDLE request working on xhci(4), but without any luck. The good news is that when we skip the UR_SET_IDLE request on xhci(4), the following UR_GET_REPORT request works, and isoc transfers also work perfectly fine. You can use the device for audio streaming. Therefore the only thing I can offer is a quirk to skip the UR_SET_IDLE request when attaching this device. On ehci(4) the device continues to work as before with this quirk. Therefore I didn't include any code to only apply the quirk on non-ehci controllers. I know it's not a nice solution, but at least it makes this device usable on xhci(4) while not impacting other things. If anyone is OK with that and has no better idea how to fix it, I'm happy to commit. Cheers, Marcus Index: uhidev.c =================================================================== RCS file: /cvs/src/sys/dev/usb/uhidev.c,v retrieving revision 1.80 diff -u -p -u -p -r1.80 uhidev.c --- uhidev.c 31 Jul 2020 10:49:33 -0000 1.80 +++ uhidev.c 18 Aug 2020 13:36:13 -0000 @@ -151,7 +151,8 @@ uhidev_attach(struct device *parent, str sc->sc_ifaceno = uaa->ifaceno; id = usbd_get_interface_descriptor(sc->sc_iface); - usbd_set_idle(sc->sc_udev, sc->sc_ifaceno, 0, 0); + if (!(usbd_get_quirks(uaa->device)->uq_flags & UQ_NO_SET_IDLE)) + usbd_set_idle(sc->sc_udev, sc->sc_ifaceno, 0, 0); sc->sc_iep_addr = sc->sc_oep_addr = -1; for (i = 0; i < id->bNumEndpoints; i++) { Index: usb_quirks.c =================================================================== RCS file: /cvs/src/sys/dev/usb/usb_quirks.c,v retrieving revision 1.76 diff -u -p -u -p -r1.76 usb_quirks.c --- usb_quirks.c 5 Jan 2020 00:54:13 -0000 1.76 +++ usb_quirks.c 18 Aug 2020 13:36:13 -0000 @@ -52,6 +52,7 @@ const struct usbd_quirk_entry { u_int16_t bcdDevice; struct usbd_quirks quirks; } usb_quirks[] = { + { USB_VENDOR_MICROCHIP, USB_PRODUCT_MICROCHIP_SOUNDKEY, ANY, { UQ_NO_SET_IDLE }}, { USB_VENDOR_KYE, USB_PRODUCT_KYE_NICHE, 0x100, { UQ_NO_SET_PROTO}}, { USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4, 0x094, { UQ_SWAP_UNICODE}}, Index: usb_quirks.h =================================================================== RCS file: /cvs/src/sys/dev/usb/usb_quirks.h,v retrieving revision 1.16 diff -u -p -u -p -r1.16 usb_quirks.h --- usb_quirks.h 19 Jul 2010 05:08:37 -0000 1.16 +++ usb_quirks.h 18 Aug 2020 13:36:13 -0000 @@ -49,6 +49,7 @@ struct usbd_quirks { #define UQ_MS_LEADING_BYTE 0x00010000 /* mouse sends unknown leading byte */ #define UQ_EHCI_NEEDTO_DISOWN 0x00020000 /* must hand device over to USB 1.1 if attached to EHCI */ +#define UQ_NO_SET_IDLE 0x00040000 /* cannot handle set idle request */ }; extern const struct usbd_quirks usbd_no_quirk; Index: usbdevs =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdevs,v retrieving revision 1.720 diff -u -p -u -p -r1.720 usbdevs --- usbdevs 3 Aug 2020 14:25:44 -0000 1.720 +++ usbdevs 18 Aug 2020 13:36:14 -0000 @@ -3009,6 +3009,7 @@ product MGE UPS2 0xffff UPS /* Microchip Technology, Inc. products */ product MICROCHIP USBLCD20X2 0x0002 USB-LCD-20x2 product MICROCHIP USBLCD256X64 0xc002 USB-LCD-256x64 +product MICROCHIP SOUNDKEY 0xf0bf Cyrus soundKey /* Microdia / Sonix Techonology Co., Ltd. products */ product MICRODIA YUREX 0x1010 YUREX