questions about multi-interface usb device
Posted: 05-31-2006, 07:37 PM
I hope this is the appropriate place to pose these questions...
I'm developing a device driver for a hearing aid programming device.
It is based on the bulkusb driver from the Windows XP DDK with some
modifications to support the device firmware upgrade class. During
normal enumeration, the device presents the standard programming
functionality as interface0 (the 1st usb interface descriptor). The
DFU functionality is presented as interface1. The app can send a
specific command to the DFU interface re-enumerate the device, after
which the device enumerates as a purely DFU-class device (single
interface). Once firmware upgrade is complete, the device again
re-enumerates with the two original interfaces.
With that said, I have some specific questions. When the device is
detected, the usb descriptors get read and eventually there is a call
made to USBD_CreateConfigurationRequestEx to select the configuration.
The return from this call is a urb which gets passed to the
host-controller driver. I am confused about how a 2nd interface is
handled here. It seems clear from the ddk documentation that an
interface list is passed as the 2nd argument to
USBD_CreateConfigurationRequestEx. But the return urb is what gets
sent to the HCD. The urb has this structure:
typedef struct _URB {
union {
struct _URB_HEADER UrbHeader;
struct _URB_SELECT_INTERFACE UrbSelectInterface;
struct _URB_SELECT_CONFIGURATION UrbSelectConfiguration;
struct _URB_PIPE_REQUEST UrbPipeRequest;
struct _URB_FRAME_LENGTH_CONTROL UrbFrameLengthControl;
struct _URB_GET_FRAME_LENGTH UrbGetFrameLength;
struct _URB_SET_FRAME_LENGTH UrbSetFrameLength;
struct _URB_GET_CURRENT_FRAME_NUMBER UrbGetCurrentFrameNumber;
struct _URB_CONTROL_TRANSFER UrbControlTransfer;
struct _URB_BULK_OR_INTERRUPT_TRANSFER UrbBulkOrInterruptTransfer;
struct _URB_ISOCH_TRANSFER UrbIsochronousTransfer;
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest;
struct _URB_CONTROL_GET_STATUS_REQUEST UrbControlGetStatusRequest;
struct _URB_CONTROL_FEATURE_REQUEST UrbControlFeatureRequest;
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
UrbControlVendorClassRequest;
struct _URB_CONTROL_GET_INTERFACE_REQUEST
UrbControlGetInterfaceRequest;
struct _URB_CONTROL_GET_CONFIGURATION_REQUEST
UrbControlGetConfigurationRequest;
}
} URB, *PURB ;
and we are using the UrbSelectConfiguration field, which looks like
this:
struct _USB_SELECT_CONFIGURATION {
struct _URB_HEADER Hdr;
PUSB_CONFIGRUATION_DESCRIPTOR ConfigurationDescriptor ;
USB_CONFIGURATION_HANDLE ConfigurationHandle ;
USBD_INTERFACE_INFORMATION Interface ;
} ;
and the Interface field is not a list, it's just this:
typedef struct _USBD_INTERFACE_INFORMATION {
USHORT Length ;
UCHAR InterfaceNumber ;
UCHAR AlternateSetting ;
UCHAR Class ;
UCHAR SubClass ;
UCHAR Protocol ;



Linear Mode

