1f1ae32a1SGerd Hoffmann #ifndef QEMU_HW_USB_DESC_H 2f1ae32a1SGerd Hoffmann #define QEMU_HW_USB_DESC_H 3f1ae32a1SGerd Hoffmann 4f1ae32a1SGerd Hoffmann #include <inttypes.h> 5f1ae32a1SGerd Hoffmann 6d3f904eaSGerd Hoffmann /* binary representation */ 7d3f904eaSGerd Hoffmann typedef struct USBDescriptor { 8d3f904eaSGerd Hoffmann uint8_t bLength; 9d3f904eaSGerd Hoffmann uint8_t bDescriptorType; 10d3f904eaSGerd Hoffmann union { 11d3f904eaSGerd Hoffmann struct { 12d3f904eaSGerd Hoffmann uint8_t bcdUSB_lo; 13d3f904eaSGerd Hoffmann uint8_t bcdUSB_hi; 14d3f904eaSGerd Hoffmann uint8_t bDeviceClass; 15d3f904eaSGerd Hoffmann uint8_t bDeviceSubClass; 16d3f904eaSGerd Hoffmann uint8_t bDeviceProtocol; 17d3f904eaSGerd Hoffmann uint8_t bMaxPacketSize0; 18d3f904eaSGerd Hoffmann uint8_t idVendor_lo; 19d3f904eaSGerd Hoffmann uint8_t idVendor_hi; 20d3f904eaSGerd Hoffmann uint8_t idProduct_lo; 21d3f904eaSGerd Hoffmann uint8_t idProduct_hi; 22d3f904eaSGerd Hoffmann uint8_t bcdDevice_lo; 23d3f904eaSGerd Hoffmann uint8_t bcdDevice_hi; 24d3f904eaSGerd Hoffmann uint8_t iManufacturer; 25d3f904eaSGerd Hoffmann uint8_t iProduct; 26d3f904eaSGerd Hoffmann uint8_t iSerialNumber; 27d3f904eaSGerd Hoffmann uint8_t bNumConfigurations; 28d3f904eaSGerd Hoffmann } device; 293cfeee61SGerd Hoffmann struct { 303cfeee61SGerd Hoffmann uint8_t bcdUSB_lo; 313cfeee61SGerd Hoffmann uint8_t bcdUSB_hi; 323cfeee61SGerd Hoffmann uint8_t bDeviceClass; 333cfeee61SGerd Hoffmann uint8_t bDeviceSubClass; 343cfeee61SGerd Hoffmann uint8_t bDeviceProtocol; 353cfeee61SGerd Hoffmann uint8_t bMaxPacketSize0; 363cfeee61SGerd Hoffmann uint8_t bNumConfigurations; 373cfeee61SGerd Hoffmann uint8_t bReserved; 383cfeee61SGerd Hoffmann } device_qualifier; 390a263db1SGerd Hoffmann struct { 400a263db1SGerd Hoffmann uint8_t wTotalLength_lo; 410a263db1SGerd Hoffmann uint8_t wTotalLength_hi; 420a263db1SGerd Hoffmann uint8_t bNumInterfaces; 430a263db1SGerd Hoffmann uint8_t bConfigurationValue; 440a263db1SGerd Hoffmann uint8_t iConfiguration; 450a263db1SGerd Hoffmann uint8_t bmAttributes; 460a263db1SGerd Hoffmann uint8_t bMaxPower; 470a263db1SGerd Hoffmann } config; 48feafd797SGerd Hoffmann struct { 49feafd797SGerd Hoffmann uint8_t bInterfaceNumber; 50feafd797SGerd Hoffmann uint8_t bAlternateSetting; 51feafd797SGerd Hoffmann uint8_t bNumEndpoints; 52feafd797SGerd Hoffmann uint8_t bInterfaceClass; 53feafd797SGerd Hoffmann uint8_t bInterfaceSubClass; 54feafd797SGerd Hoffmann uint8_t bInterfaceProtocol; 55feafd797SGerd Hoffmann uint8_t iInterface; 56feafd797SGerd Hoffmann } interface; 57e36a20d3SGerd Hoffmann struct { 58e36a20d3SGerd Hoffmann uint8_t bEndpointAddress; 59e36a20d3SGerd Hoffmann uint8_t bmAttributes; 60e36a20d3SGerd Hoffmann uint8_t wMaxPacketSize_lo; 61e36a20d3SGerd Hoffmann uint8_t wMaxPacketSize_hi; 62e36a20d3SGerd Hoffmann uint8_t bInterval; 63e36a20d3SGerd Hoffmann uint8_t bRefresh; /* only audio ep */ 64e36a20d3SGerd Hoffmann uint8_t bSynchAddress; /* only audio ep */ 65e36a20d3SGerd Hoffmann } endpoint; 66b43a2851SGerd Hoffmann struct { 67b43a2851SGerd Hoffmann uint8_t bMaxBurst; 68b43a2851SGerd Hoffmann uint8_t bmAttributes; 69b43a2851SGerd Hoffmann uint8_t wBytesPerInterval_lo; 70b43a2851SGerd Hoffmann uint8_t wBytesPerInterval_hi; 71b43a2851SGerd Hoffmann } super_endpoint; 72*2077469bSGerd Hoffmann struct { 73*2077469bSGerd Hoffmann uint8_t wTotalLength_lo; 74*2077469bSGerd Hoffmann uint8_t wTotalLength_hi; 75*2077469bSGerd Hoffmann uint8_t bNumDeviceCaps; 76*2077469bSGerd Hoffmann } bos; 77*2077469bSGerd Hoffmann struct { 78*2077469bSGerd Hoffmann uint8_t bDevCapabilityType; 79*2077469bSGerd Hoffmann union { 80*2077469bSGerd Hoffmann struct { 81*2077469bSGerd Hoffmann uint8_t bmAttributes_1; 82*2077469bSGerd Hoffmann uint8_t bmAttributes_2; 83*2077469bSGerd Hoffmann uint8_t bmAttributes_3; 84*2077469bSGerd Hoffmann uint8_t bmAttributes_4; 85*2077469bSGerd Hoffmann } usb2_ext; 86*2077469bSGerd Hoffmann struct { 87*2077469bSGerd Hoffmann uint8_t bmAttributes; 88*2077469bSGerd Hoffmann uint8_t wSpeedsSupported_lo; 89*2077469bSGerd Hoffmann uint8_t wSpeedsSupported_hi; 90*2077469bSGerd Hoffmann uint8_t bFunctionalitySupport; 91*2077469bSGerd Hoffmann uint8_t bU1DevExitLat; 92*2077469bSGerd Hoffmann uint8_t wU2DevExitLat_lo; 93*2077469bSGerd Hoffmann uint8_t wU2DevExitLat_hi; 94*2077469bSGerd Hoffmann } super; 95*2077469bSGerd Hoffmann } u; 96*2077469bSGerd Hoffmann } cap; 97d3f904eaSGerd Hoffmann } u; 98d3f904eaSGerd Hoffmann } QEMU_PACKED USBDescriptor; 99d3f904eaSGerd Hoffmann 100f1ae32a1SGerd Hoffmann struct USBDescID { 101f1ae32a1SGerd Hoffmann uint16_t idVendor; 102f1ae32a1SGerd Hoffmann uint16_t idProduct; 103f1ae32a1SGerd Hoffmann uint16_t bcdDevice; 104f1ae32a1SGerd Hoffmann uint8_t iManufacturer; 105f1ae32a1SGerd Hoffmann uint8_t iProduct; 106f1ae32a1SGerd Hoffmann uint8_t iSerialNumber; 107f1ae32a1SGerd Hoffmann }; 108f1ae32a1SGerd Hoffmann 109f1ae32a1SGerd Hoffmann struct USBDescDevice { 110f1ae32a1SGerd Hoffmann uint16_t bcdUSB; 111f1ae32a1SGerd Hoffmann uint8_t bDeviceClass; 112f1ae32a1SGerd Hoffmann uint8_t bDeviceSubClass; 113f1ae32a1SGerd Hoffmann uint8_t bDeviceProtocol; 114f1ae32a1SGerd Hoffmann uint8_t bMaxPacketSize0; 115f1ae32a1SGerd Hoffmann uint8_t bNumConfigurations; 116f1ae32a1SGerd Hoffmann 117f1ae32a1SGerd Hoffmann const USBDescConfig *confs; 118f1ae32a1SGerd Hoffmann }; 119f1ae32a1SGerd Hoffmann 120f1ae32a1SGerd Hoffmann struct USBDescConfig { 121f1ae32a1SGerd Hoffmann uint8_t bNumInterfaces; 122f1ae32a1SGerd Hoffmann uint8_t bConfigurationValue; 123f1ae32a1SGerd Hoffmann uint8_t iConfiguration; 124f1ae32a1SGerd Hoffmann uint8_t bmAttributes; 125f1ae32a1SGerd Hoffmann uint8_t bMaxPower; 126f1ae32a1SGerd Hoffmann 127f1ae32a1SGerd Hoffmann /* grouped interfaces */ 128f1ae32a1SGerd Hoffmann uint8_t nif_groups; 129f1ae32a1SGerd Hoffmann const USBDescIfaceAssoc *if_groups; 130f1ae32a1SGerd Hoffmann 131f1ae32a1SGerd Hoffmann /* "normal" interfaces */ 132f1ae32a1SGerd Hoffmann uint8_t nif; 133f1ae32a1SGerd Hoffmann const USBDescIface *ifs; 134f1ae32a1SGerd Hoffmann }; 135f1ae32a1SGerd Hoffmann 136f1ae32a1SGerd Hoffmann /* conceptually an Interface Association Descriptor, and releated interfaces */ 137f1ae32a1SGerd Hoffmann struct USBDescIfaceAssoc { 138f1ae32a1SGerd Hoffmann uint8_t bFirstInterface; 139f1ae32a1SGerd Hoffmann uint8_t bInterfaceCount; 140f1ae32a1SGerd Hoffmann uint8_t bFunctionClass; 141f1ae32a1SGerd Hoffmann uint8_t bFunctionSubClass; 142f1ae32a1SGerd Hoffmann uint8_t bFunctionProtocol; 143f1ae32a1SGerd Hoffmann uint8_t iFunction; 144f1ae32a1SGerd Hoffmann 145f1ae32a1SGerd Hoffmann uint8_t nif; 146f1ae32a1SGerd Hoffmann const USBDescIface *ifs; 147f1ae32a1SGerd Hoffmann }; 148f1ae32a1SGerd Hoffmann 149f1ae32a1SGerd Hoffmann struct USBDescIface { 150f1ae32a1SGerd Hoffmann uint8_t bInterfaceNumber; 151f1ae32a1SGerd Hoffmann uint8_t bAlternateSetting; 152f1ae32a1SGerd Hoffmann uint8_t bNumEndpoints; 153f1ae32a1SGerd Hoffmann uint8_t bInterfaceClass; 154f1ae32a1SGerd Hoffmann uint8_t bInterfaceSubClass; 155f1ae32a1SGerd Hoffmann uint8_t bInterfaceProtocol; 156f1ae32a1SGerd Hoffmann uint8_t iInterface; 157f1ae32a1SGerd Hoffmann 158f1ae32a1SGerd Hoffmann uint8_t ndesc; 159f1ae32a1SGerd Hoffmann USBDescOther *descs; 160f1ae32a1SGerd Hoffmann USBDescEndpoint *eps; 161f1ae32a1SGerd Hoffmann }; 162f1ae32a1SGerd Hoffmann 163f1ae32a1SGerd Hoffmann struct USBDescEndpoint { 164f1ae32a1SGerd Hoffmann uint8_t bEndpointAddress; 165f1ae32a1SGerd Hoffmann uint8_t bmAttributes; 166f1ae32a1SGerd Hoffmann uint16_t wMaxPacketSize; 167f1ae32a1SGerd Hoffmann uint8_t bInterval; 168f1ae32a1SGerd Hoffmann uint8_t bRefresh; 169f1ae32a1SGerd Hoffmann uint8_t bSynchAddress; 170f1ae32a1SGerd Hoffmann 171f1ae32a1SGerd Hoffmann uint8_t is_audio; /* has bRefresh + bSynchAddress */ 172f1ae32a1SGerd Hoffmann uint8_t *extra; 173b43a2851SGerd Hoffmann 174b43a2851SGerd Hoffmann /* superspeed endpoint companion */ 175b43a2851SGerd Hoffmann uint8_t bMaxBurst; 176b43a2851SGerd Hoffmann uint8_t bmAttributes_super; 177b43a2851SGerd Hoffmann uint16_t wBytesPerInterval; 178f1ae32a1SGerd Hoffmann }; 179f1ae32a1SGerd Hoffmann 180f1ae32a1SGerd Hoffmann struct USBDescOther { 181f1ae32a1SGerd Hoffmann uint8_t length; 182f1ae32a1SGerd Hoffmann const uint8_t *data; 183f1ae32a1SGerd Hoffmann }; 184f1ae32a1SGerd Hoffmann 185f1ae32a1SGerd Hoffmann typedef const char *USBDescStrings[256]; 186f1ae32a1SGerd Hoffmann 187f1ae32a1SGerd Hoffmann struct USBDesc { 188f1ae32a1SGerd Hoffmann USBDescID id; 189f1ae32a1SGerd Hoffmann const USBDescDevice *full; 190f1ae32a1SGerd Hoffmann const USBDescDevice *high; 1916d51b2bbSGerd Hoffmann const USBDescDevice *super; 192f1ae32a1SGerd Hoffmann const char* const *str; 193f1ae32a1SGerd Hoffmann }; 194f1ae32a1SGerd Hoffmann 195b43a2851SGerd Hoffmann #define USB_DESC_FLAG_SUPER (1 << 1) 196b43a2851SGerd Hoffmann 197f1ae32a1SGerd Hoffmann /* generate usb packages from structs */ 198f1ae32a1SGerd Hoffmann int usb_desc_device(const USBDescID *id, const USBDescDevice *dev, 199f1ae32a1SGerd Hoffmann uint8_t *dest, size_t len); 200f1ae32a1SGerd Hoffmann int usb_desc_device_qualifier(const USBDescDevice *dev, 201f1ae32a1SGerd Hoffmann uint8_t *dest, size_t len); 202b43a2851SGerd Hoffmann int usb_desc_config(const USBDescConfig *conf, int flags, 203b43a2851SGerd Hoffmann uint8_t *dest, size_t len); 204b43a2851SGerd Hoffmann int usb_desc_iface_group(const USBDescIfaceAssoc *iad, int flags, 205b43a2851SGerd Hoffmann uint8_t *dest, size_t len); 206b43a2851SGerd Hoffmann int usb_desc_iface(const USBDescIface *iface, int flags, 207b43a2851SGerd Hoffmann uint8_t *dest, size_t len); 208b43a2851SGerd Hoffmann int usb_desc_endpoint(const USBDescEndpoint *ep, int flags, 209b43a2851SGerd Hoffmann uint8_t *dest, size_t len); 210f1ae32a1SGerd Hoffmann int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len); 211f1ae32a1SGerd Hoffmann 212f1ae32a1SGerd Hoffmann /* control message emulation helpers */ 213f1ae32a1SGerd Hoffmann void usb_desc_init(USBDevice *dev); 214f1ae32a1SGerd Hoffmann void usb_desc_attach(USBDevice *dev); 215f1ae32a1SGerd Hoffmann void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str); 2169d55d1adSGerd Hoffmann void usb_desc_create_serial(USBDevice *dev); 217f1ae32a1SGerd Hoffmann const char *usb_desc_get_string(USBDevice *dev, uint8_t index); 218f1ae32a1SGerd Hoffmann int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len); 219f1ae32a1SGerd Hoffmann int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len); 220f1ae32a1SGerd Hoffmann int usb_desc_handle_control(USBDevice *dev, USBPacket *p, 221f1ae32a1SGerd Hoffmann int request, int value, int index, int length, uint8_t *data); 222f1ae32a1SGerd Hoffmann 223f1ae32a1SGerd Hoffmann #endif /* QEMU_HW_USB_DESC_H */ 224