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