|
USB Configuration DescriptorsA configuration of USB device consists of a series of interfaces. Each interface consists of one or more alternate settings, and each alternate setting is made up of a set of endpoints. An interface, or any of its alternate settings, specifies a class code, subclass, and protocol. Each endpoint of an interface describes a single stream of input or output for the device. A device that supports the input or output of several different kinds of data has multiple interfaces. A device that supports several streams of the same kind of data, supports multiple endpoints on a single interface. To obtain all this information from the device, drivers request the device's configuration descriptor. With the device returns the configuration descriptor, it also returns an interface descriptor for each interface or alternate setting, and an endpoint descriptor for each endpoint. The driver can collect this information in two steps. The driver can issue the request to get the configuration descriptor, and pass a buffer big enough to hold the configuration descriptor alone. From the configuration descriptor, the driver can determine what size buffer is needed to hold all of the configuration information. The driver then issues the same request with the bigger buffer. The UsbBuildGetDescriptorRequest routine builds the necessary request. The bus driver returns the configuration descriptor in a USB_CONFIGURATION_DESCRIPTOR structure. This structure specifies the total length of configuration information in its wTotalLength member. A device may support multiple configurations, numbered starting at zero. It reports the number of configurations it supports in its device descriptor. See USB Device Descriptors for details. The following code demonstrates how to request the configuration information for the i-th configuration: USB_CONFIGURATION_DESCRIPTOR UCD, *pFullUCD; UsbBuildGetDescriptorRequest( pURB, // points to the URB to be filled in sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_CONFIGURATION_DESCRIPTOR_TYPE, i, // number of configuration descriptor 0, // this parameter not used for configuration descriptors &UCD, // points to a USB_CONFIGURATION_DESCRIPTOR NULL, sizeof(USB_DEVICE_DESCRIPTOR), NULL ); pFullUCD = ExAllocatePool(NonPagedPool, UCD.wTotalLength); UsbBuildGetDescriptorRequest( pURB, // points to the URB to be filled in sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_CONFIGURATION_DESCRIPTOR_TYPE, i, // number of configuration descriptor 0, // this parameter not used for configuration descriptors pFullUCD, // points to a USB_CONFIGURATION_DESCRIPTOR NULL, UCD.wTotalLength, NULL ); Each interface descriptor is stored in a USB_INTERFACE_DESCRIPTOR structure. The driver returns one interface descriptor for each interface or alternate setting. The zero-based bInterfaceNumber member of USB_INTERFACE_DESCRIPTOR distinguishes interfaces within a configuration. For a given interface the zero-based bAlternateSetting member distinguishes between alternate settings of the interface. Each endpoint descriptor is stored in a USB_ENDPOINT_DESCRIPTOR structure. When a device reports a configuration, each interface descriptor is followed in memory by all of the endpoint descriptors for the interface and alternate setting. The device returns interface descriptors in order of bInterfaceNumber values and then in order of bAlternateSetting values. For example, consider a device that supports a configuration with two interfaces, and the first interface supports two alternate settings. The configuration information is laid out in memory as follows: Example of Configuration Descriptor Layout The operating system provides a helper function, USBD_ParseConfigurationDescriptorEx, to search for a given interface descriptor within the configuration. The driver provides a starting position within the configuration, and optionally an interface number, an alternate setting, a class, a subclass, or a protocol. The routine returns a pointer to the next matching interface descriptor. To examine a configuration descriptor for an endpoint or string descriptor, use the USBD_ParseDescriptors routine. The caller provides a starting position within the configuration and a descriptor type, such as USB_STRING_DESCRIPTOR_TYPE or USB_ENDPOINT_DESCRIPTOR_TYPE. The routine returns a pointer to the next matching descriptor. |
Contact Us | E-mail this Page | MSDN Flash Newsletter |
© 2001 Microsoft Corporation. All rights reserved. Terms of Use Privacy Statement Accessibility |