|  | #ifndef QEMU_HW_USB_DESC_H | 
|  | #define QEMU_HW_USB_DESC_H | 
|  |  | 
|  | #include <wchar.h> | 
|  |  | 
|  | /* binary representation */ | 
|  | typedef struct USBDescriptor { | 
|  | uint8_t                   bLength; | 
|  | uint8_t                   bDescriptorType; | 
|  | union { | 
|  | struct { | 
|  | uint8_t           bcdUSB_lo; | 
|  | uint8_t           bcdUSB_hi; | 
|  | uint8_t           bDeviceClass; | 
|  | uint8_t           bDeviceSubClass; | 
|  | uint8_t           bDeviceProtocol; | 
|  | uint8_t           bMaxPacketSize0; | 
|  | uint8_t           idVendor_lo; | 
|  | uint8_t           idVendor_hi; | 
|  | uint8_t           idProduct_lo; | 
|  | uint8_t           idProduct_hi; | 
|  | uint8_t           bcdDevice_lo; | 
|  | uint8_t           bcdDevice_hi; | 
|  | uint8_t           iManufacturer; | 
|  | uint8_t           iProduct; | 
|  | uint8_t           iSerialNumber; | 
|  | uint8_t           bNumConfigurations; | 
|  | } device; | 
|  | struct { | 
|  | uint8_t           bcdUSB_lo; | 
|  | uint8_t           bcdUSB_hi; | 
|  | uint8_t           bDeviceClass; | 
|  | uint8_t           bDeviceSubClass; | 
|  | uint8_t           bDeviceProtocol; | 
|  | uint8_t           bMaxPacketSize0; | 
|  | uint8_t           bNumConfigurations; | 
|  | uint8_t           bReserved; | 
|  | } device_qualifier; | 
|  | struct { | 
|  | uint8_t           wTotalLength_lo; | 
|  | uint8_t           wTotalLength_hi; | 
|  | uint8_t           bNumInterfaces; | 
|  | uint8_t           bConfigurationValue; | 
|  | uint8_t           iConfiguration; | 
|  | uint8_t           bmAttributes; | 
|  | uint8_t           bMaxPower; | 
|  | } config; | 
|  | struct { | 
|  | uint8_t           bInterfaceNumber; | 
|  | uint8_t           bAlternateSetting; | 
|  | uint8_t           bNumEndpoints; | 
|  | uint8_t           bInterfaceClass; | 
|  | uint8_t           bInterfaceSubClass; | 
|  | uint8_t           bInterfaceProtocol; | 
|  | uint8_t           iInterface; | 
|  | } interface; | 
|  | struct { | 
|  | uint8_t           bEndpointAddress; | 
|  | uint8_t           bmAttributes; | 
|  | uint8_t           wMaxPacketSize_lo; | 
|  | uint8_t           wMaxPacketSize_hi; | 
|  | uint8_t           bInterval; | 
|  | uint8_t           bRefresh;        /* only audio ep */ | 
|  | uint8_t           bSynchAddress;   /* only audio ep */ | 
|  | } endpoint; | 
|  | struct { | 
|  | uint8_t           bMaxBurst; | 
|  | uint8_t           bmAttributes; | 
|  | uint8_t           wBytesPerInterval_lo; | 
|  | uint8_t           wBytesPerInterval_hi; | 
|  | } super_endpoint; | 
|  | struct { | 
|  | uint8_t           wTotalLength_lo; | 
|  | uint8_t           wTotalLength_hi; | 
|  | uint8_t           bNumDeviceCaps; | 
|  | } bos; | 
|  | struct { | 
|  | uint8_t           bDevCapabilityType; | 
|  | union { | 
|  | struct { | 
|  | uint8_t   bmAttributes_1; | 
|  | uint8_t   bmAttributes_2; | 
|  | uint8_t   bmAttributes_3; | 
|  | uint8_t   bmAttributes_4; | 
|  | } usb2_ext; | 
|  | struct { | 
|  | uint8_t   bmAttributes; | 
|  | uint8_t   wSpeedsSupported_lo; | 
|  | uint8_t   wSpeedsSupported_hi; | 
|  | uint8_t   bFunctionalitySupport; | 
|  | uint8_t   bU1DevExitLat; | 
|  | uint8_t   wU2DevExitLat_lo; | 
|  | uint8_t   wU2DevExitLat_hi; | 
|  | } super; | 
|  | } u; | 
|  | } cap; | 
|  | } u; | 
|  | } QEMU_PACKED USBDescriptor; | 
|  |  | 
|  | struct USBDescID { | 
|  | uint16_t                  idVendor; | 
|  | uint16_t                  idProduct; | 
|  | uint16_t                  bcdDevice; | 
|  | uint8_t                   iManufacturer; | 
|  | uint8_t                   iProduct; | 
|  | uint8_t                   iSerialNumber; | 
|  | }; | 
|  |  | 
|  | struct USBDescDevice { | 
|  | uint16_t                  bcdUSB; | 
|  | uint8_t                   bDeviceClass; | 
|  | uint8_t                   bDeviceSubClass; | 
|  | uint8_t                   bDeviceProtocol; | 
|  | uint8_t                   bMaxPacketSize0; | 
|  | uint8_t                   bNumConfigurations; | 
|  |  | 
|  | const USBDescConfig       *confs; | 
|  | }; | 
|  |  | 
|  | struct USBDescConfig { | 
|  | uint8_t                   bNumInterfaces; | 
|  | uint8_t                   bConfigurationValue; | 
|  | uint8_t                   iConfiguration; | 
|  | uint8_t                   bmAttributes; | 
|  | uint8_t                   bMaxPower; | 
|  |  | 
|  | /* grouped interfaces */ | 
|  | uint8_t                   nif_groups; | 
|  | const USBDescIfaceAssoc   *if_groups; | 
|  |  | 
|  | /* "normal" interfaces */ | 
|  | uint8_t                   nif; | 
|  | const USBDescIface        *ifs; | 
|  | }; | 
|  |  | 
|  | /* conceptually an Interface Association Descriptor, and related interfaces */ | 
|  | struct USBDescIfaceAssoc { | 
|  | uint8_t                   bFirstInterface; | 
|  | uint8_t                   bInterfaceCount; | 
|  | uint8_t                   bFunctionClass; | 
|  | uint8_t                   bFunctionSubClass; | 
|  | uint8_t                   bFunctionProtocol; | 
|  | uint8_t                   iFunction; | 
|  |  | 
|  | uint8_t                   nif; | 
|  | const USBDescIface        *ifs; | 
|  | }; | 
|  |  | 
|  | struct USBDescIface { | 
|  | uint8_t                   bInterfaceNumber; | 
|  | uint8_t                   bAlternateSetting; | 
|  | uint8_t                   bNumEndpoints; | 
|  | uint8_t                   bInterfaceClass; | 
|  | uint8_t                   bInterfaceSubClass; | 
|  | uint8_t                   bInterfaceProtocol; | 
|  | uint8_t                   iInterface; | 
|  |  | 
|  | uint8_t                   ndesc; | 
|  | USBDescOther              *descs; | 
|  | USBDescEndpoint           *eps; | 
|  | }; | 
|  |  | 
|  | struct USBDescEndpoint { | 
|  | uint8_t                   bEndpointAddress; | 
|  | uint8_t                   bmAttributes; | 
|  | uint16_t                  wMaxPacketSize; | 
|  | uint8_t                   bInterval; | 
|  | uint8_t                   bRefresh; | 
|  | uint8_t                   bSynchAddress; | 
|  |  | 
|  | uint8_t                   is_audio; /* has bRefresh + bSynchAddress */ | 
|  | uint8_t                   *extra; | 
|  |  | 
|  | /* superspeed endpoint companion */ | 
|  | uint8_t                   bMaxBurst; | 
|  | uint8_t                   bmAttributes_super; | 
|  | uint16_t                  wBytesPerInterval; | 
|  | }; | 
|  |  | 
|  | struct USBDescOther { | 
|  | uint8_t                   length; | 
|  | const uint8_t             *data; | 
|  | }; | 
|  |  | 
|  | struct USBDescMSOS { | 
|  | const char                *CompatibleID; | 
|  | const wchar_t             *Label; | 
|  | bool                      SelectiveSuspendEnabled; | 
|  | }; | 
|  |  | 
|  | typedef const char *USBDescStrings[256]; | 
|  |  | 
|  | struct USBDesc { | 
|  | USBDescID                 id; | 
|  | const USBDescDevice       *full; | 
|  | const USBDescDevice       *high; | 
|  | const USBDescDevice       *super; | 
|  | const char* const         *str; | 
|  | const USBDescMSOS         *msos; | 
|  | }; | 
|  |  | 
|  | #define USB_DESC_MAX_LEN    8192 | 
|  | #define USB_DESC_FLAG_SUPER (1 << 1) | 
|  |  | 
|  | /* little helpers */ | 
|  | static inline uint8_t usb_lo(uint16_t val) | 
|  | { | 
|  | return val & 0xff; | 
|  | } | 
|  |  | 
|  | static inline uint8_t usb_hi(uint16_t val) | 
|  | { | 
|  | return (val >> 8) & 0xff; | 
|  | } | 
|  |  | 
|  | /* generate usb packages from structs */ | 
|  | int usb_desc_device(const USBDescID *id, const USBDescDevice *dev, | 
|  | bool msos, uint8_t *dest, size_t len); | 
|  | int usb_desc_device_qualifier(const USBDescDevice *dev, | 
|  | uint8_t *dest, size_t len); | 
|  | int usb_desc_config(const USBDescConfig *conf, int flags, | 
|  | uint8_t *dest, size_t len); | 
|  | int usb_desc_iface_group(const USBDescIfaceAssoc *iad, int flags, | 
|  | uint8_t *dest, size_t len); | 
|  | int usb_desc_iface(const USBDescIface *iface, int flags, | 
|  | uint8_t *dest, size_t len); | 
|  | int usb_desc_endpoint(const USBDescEndpoint *ep, int flags, | 
|  | uint8_t *dest, size_t len); | 
|  | int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len); | 
|  | int usb_desc_msos(const USBDesc *desc, USBPacket *p, | 
|  | int index, uint8_t *dest, size_t len); | 
|  |  | 
|  | /* control message emulation helpers */ | 
|  | void usb_desc_init(USBDevice *dev); | 
|  | void usb_desc_attach(USBDevice *dev); | 
|  | void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str); | 
|  | void usb_desc_create_serial(USBDevice *dev); | 
|  | const char *usb_desc_get_string(USBDevice *dev, uint8_t index); | 
|  | int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len); | 
|  | int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p, | 
|  | int value, uint8_t *dest, size_t len); | 
|  | int usb_desc_handle_control(USBDevice *dev, USBPacket *p, | 
|  | int request, int value, int index, int length, uint8_t *data); | 
|  |  | 
|  | #endif /* QEMU_HW_USB_DESC_H */ |