Don't rely on USB interfaces being at compliant indices.
authoredd <edd@openbsd.org>
Fri, 29 Jan 2021 11:44:06 +0000 (11:44 +0000)
committeredd <edd@openbsd.org>
Fri, 29 Jan 2021 11:44:06 +0000 (11:44 +0000)
commit3882cb129944bae6f8b229f8862dcf37c6bc2873
tree18a09a1a72590fa3ae576c2bff282445032ed6db
parentc67d5b9a6f94fa69d8e6e5a602c13ae764bf75b9
Don't rely on USB interfaces being at compliant indices.

When obtaining an interface handle, we currently rely on the device being
properly USB compliant, and thus the interface being at the correct index in
the interfaces array.

However, some devices present their indices incorrectly. For example, the
following audio device exposes interfaces 0, 1 and 3, in that order (skipping
interface 2 entirely):

uaudio2 at uhub4 port 4 configuration 1 interface 3 "E+ Corp. DAC Audio" rev 1.10/0.01 addr 2
uaudio2: class v1, full-speed, async, channels: 2 play, 0 rec, 3 ctls

This means that that the audio stream interface (number 3) is not found at the
expected index of 2, and this causes looking up the handle to fail.

This change makes usbd_device2interface_handle() search for the right
interface, instead of assuming it will be at the right index. Although this is
a little slower, note that this routine not very frequently called and there
are typically not hundreds of interfaces on a typical USB device.

This fixes the above E+ Corp device, and one other uaudio device reported
broken by a user.

With input from, tested by, and OK ratchov@, mglocker@ and kettenis@.

Many thanks!
sys/dev/usb/usbdi.c