Skip to content

USB: Enumeration

hasu@tmk edited this page Aug 19, 2021 · 5 revisions

UHS2 Enumeration

Usb.cpp

Task()

Manage device state transition depeding on bus state

Configuring()

AttemptConfig()

usbhost.h

busprobe()

Update bus state

Linux USB Enumeration

drivers/usb/core/hub.c

Old and New Scheme

/*
 * As of 2.6.10 we introduce a new USB device initialization scheme which
 * closely resembles the way Windows works.  Hopefully it will be compatible
 * with a wider range of devices than the old scheme.  However some previously
 * working devices may start giving rise to "device not accepting address"
 * errors; if that happens the user can try the old scheme by adjusting the
 * following module parameters.
 *
 * For maximum flexibility there are two boolean parameters to control the
 * hub driver's behavior.  On the first initialization attempt, if the
 * "old_scheme_first" parameter is set then the old scheme will be used,
 * otherwise the new scheme is used.  If that fails and "use_both_schemes"
 * is set, then the driver will make another attempt, using the other scheme.
 */

hub_port_init()

https://elixir.bootlin.com/linux/latest/source/drivers/usb/core/hub.c#L4780

/* Reset device, (re)assign address, get device descriptor.
 * Device connection must be stable, no more debouncing needed.
 * Returns device in USB_STATE_ADDRESS, except on error.

Retry Constants:

#define PORT_RESET_TRIES        5
#define SET_ADDRESS_TRIES       2
#define GET_DESCRIPTOR_TRIES    2
#define GET_MAXPACKET0_TRIES    3
#define PORT_INIT_TRIES         4

https://elixir.bootlin.com/linux/latest/source/drivers/usb/core/hub.c#L4766

            /* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
             * Because device hardware and firmware is sometimes buggy in
             * this area, and this is how Linux has done it for ages.
             * Change it cautiously.
             *
             * NOTE:  If use_new_scheme() is true we will start by issuing
             * a 64-byte GET_DESCRIPTOR request.  This is what Windows does,
             * so it may help with some non-standards-compliant devices.
             * Otherwise we start with SET_ADDRESS and then try to read the
             * first 8 bytes of the device descriptor to get the ep0 maxpacket
             * value.
             */

Windows USB Enumeration

How does USB stack enumerate a device?

https://techcommunity.microsoft.com/t5/microsoft-usb-blog/how-does-usb-stack-enumerate-a-device/ba-p/270685#

USB 2.1, 2.0, 1.1 device enumeration changes in Windows 8

https://techcommunity.microsoft.com/t5/microsoft-usb-blog/usb-2-1-2-0-1-1-device-enumeration-changes-in-windows-8/ba-p/270775

Bus Analyzer Capture

https://www.cypress.com/file/134171/download Appendix B

bcdDevice

Should be incremented for Windows when descriptors are updated?

https://github.com/tmk/tmk_keyboard/wiki/USB:-Descriptor#bcddevice