when a USB device is inserted, usbd_probe_and_attach() first tries to
find a driver that claims to support the device by matching the
vendor/product IDs. if no such driver is found, usbd_probe_and_attach()
loops through each interface of each of the devices configurations,
trying to match "interface" (aka class) drivers to an interface. if
the device has more than one interface *in a single configuration*
that matches drivers, then drivers are allowed to attach to each
interface. for example:
uvideo0 at uhub5 port 1 configuration 1 interface 0 "Logitech product 0x09a2" rev 2.00/0.08 addr 4
video0 at uvideo0
uaudio0 at uhub5 port 1 configuration 1 interface 2 "Logitech product 0x09a2" rev 2.00/0.08 addr 4
uaudio0: audio rev 1.00, 2 mixer controls
audio1 at uaudio0
note how they are both attached "at uhub5 port 1 configuration 1".
and:
uhidev0 at uhub1 port 2 configuration 1 interface 0 "Logitech USB Receiver" rev 2.00/16.00 addr 2
uhidev0: iclass 3/1
ums0 at uhidev0: 16 buttons, Z dir
wsmouse1 at ums0 mux 0
uhidev1 at uhub1 port 2 configuration 1 interface 1 "Logitech USB Receiver" rev 2.00/16.00 addr 2
uhidev1: iclass 3/0, 17 report ids
uhid0 at uhidev1 reportid 3: input=4, output=0, feature=0
uhid1 at uhidev1 reportid 16: input=6, output=6, feature=0
uhid2 at uhidev1 reportid 17: input=19, output=19, feature=0
note how both uhidev(4)s are attached "at uhub1 port 2 configuration 1".
currently, usbd_probe_and_attach() makes a copy of the array of pointers
to the interface descriptors and passes these to the match/attach functions
in struct usb_attach_args (uaa). when an interface is matched, the pointer
to the interface descriptor in uaa is set to NULL. and, if a driver uses
other interfaces, the driver sets the pointer to those interface
descriptors in the uaa to NULL. this way, what interfaces are available
is known, but this only really works at attach time.
currently, ugen(4) assumes it can use any interface in any configuration.
for this reason, ugen(4) ...