> Date: Thu, 28 Jan 2021 16:45:12 +0100 > From: Marcus Glocker <mar...@nazgul.ch> > Cc: Alexandre Ratchov <a...@caoua.org>, tech@openbsd.org, ratc...@openbsd.org, > st...@openbsd.org, kette...@openbsd.org, m...@openbsd.org > 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 */ >