> Date: Thu, 28 Jan 2021 16:45:12 +0100
> From: Marcus Glocker <[email protected]>
> Cc: Alexandre Ratchov <[email protected]>, [email protected], [email protected],
> [email protected], [email protected], [email protected]
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: inline
>
> On Thu, Jan 28, 2021 at 02:38:04PM +0000, Edd Barrett wrote:
>
> > On Thu, Jan 28, 2021 at 09:56:14AM +0000, Edd Barrett wrote:
> > >
> >
> > Here's a revised diff that always searches the array, instead of first
> > trying the expected index. Everyone agreed that this makes for simpler
> > code, and that since this function isn't called much, there's no real
> > performance concern.
> >
> > Cursory testing seems good. All USB devices working so far, including
> > the non-compliant uaudio device.
> >
> > Please give this a spin to check for breakage.
>
> The code looks good to me (cleaner than before), and I also quickly
> tested the diff with some devices.
>
> ok mglocker@
ok kettenis@ as well
> > Index: usbdi.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/usb/usbdi.c,v
> > retrieving revision 1.107
> > diff -u -p -r1.107 usbdi.c
> > --- usbdi.c 27 Jan 2021 17:28:19 -0000 1.107
> > +++ usbdi.c 28 Jan 2021 14:19:28 -0000
> > @@ -638,12 +638,23 @@ usbd_status
> > usbd_device2interface_handle(struct usbd_device *dev, u_int8_t ifaceno,
> > struct usbd_interface **iface)
> > {
> > + u_int8_t idx;
> > +
> > if (dev->cdesc == NULL)
> > return (USBD_NOT_CONFIGURED);
> > - if (ifaceno >= dev->cdesc->bNumInterfaces)
> > - return (USBD_INVAL);
> > - *iface = &dev->ifaces[ifaceno];
> > - return (USBD_NORMAL_COMPLETION);
> > + /*
> > + * The correct interface should be at dev->ifaces[ifaceno], but we've
> > + * seen non-compliant devices in the wild which present non-contiguous
> > + * interface numbers and this skews the indices. For this reason we
> > + * linearly search the interface array.
> > + */
> > + for (idx = 0; idx < dev->cdesc->bNumInterfaces; idx++) {
> > + if (dev->ifaces[idx].idesc->bInterfaceNumber == ifaceno) {
> > + *iface = &dev->ifaces[idx];
> > + return (USBD_NORMAL_COMPLETION);
> > + }
> > + }
> > + return (USBD_INVAL);
> > }
> >
> > /* XXXX use altno */
>