1f1ae32a1SGerd Hoffmann #ifndef QEMU_HW_USB_DESC_H
2f1ae32a1SGerd Hoffmann #define QEMU_HW_USB_DESC_H
3f1ae32a1SGerd Hoffmann
45319dc7bSGerd Hoffmann #include <wchar.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;
722077469bSGerd Hoffmann struct {
732077469bSGerd Hoffmann uint8_t wTotalLength_lo;
742077469bSGerd Hoffmann uint8_t wTotalLength_hi;
752077469bSGerd Hoffmann uint8_t bNumDeviceCaps;
762077469bSGerd Hoffmann } bos;
772077469bSGerd Hoffmann struct {
782077469bSGerd Hoffmann uint8_t bDevCapabilityType;
792077469bSGerd Hoffmann union {
802077469bSGerd Hoffmann struct {
812077469bSGerd Hoffmann uint8_t bmAttributes_1;
822077469bSGerd Hoffmann uint8_t bmAttributes_2;
832077469bSGerd Hoffmann uint8_t bmAttributes_3;
842077469bSGerd Hoffmann uint8_t bmAttributes_4;
852077469bSGerd Hoffmann } usb2_ext;
862077469bSGerd Hoffmann struct {
872077469bSGerd Hoffmann uint8_t bmAttributes;
882077469bSGerd Hoffmann uint8_t wSpeedsSupported_lo;
892077469bSGerd Hoffmann uint8_t wSpeedsSupported_hi;
902077469bSGerd Hoffmann uint8_t bFunctionalitySupport;
912077469bSGerd Hoffmann uint8_t bU1DevExitLat;
922077469bSGerd Hoffmann uint8_t wU2DevExitLat_lo;
932077469bSGerd Hoffmann uint8_t wU2DevExitLat_hi;
942077469bSGerd Hoffmann } super;
952077469bSGerd Hoffmann } u;
962077469bSGerd 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
136ae420c95SCai Huoqing /* conceptually an Interface Association Descriptor, and related 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
1855319dc7bSGerd Hoffmann struct USBDescMSOS {
186409951f5SGerd Hoffmann const char *CompatibleID;
1875319dc7bSGerd Hoffmann const wchar_t *Label;
1885319dc7bSGerd Hoffmann bool SelectiveSuspendEnabled;
1895319dc7bSGerd Hoffmann };
1905319dc7bSGerd Hoffmann
191f1ae32a1SGerd Hoffmann typedef const char *USBDescStrings[256];
192f1ae32a1SGerd Hoffmann
193f1ae32a1SGerd Hoffmann struct USBDesc {
194f1ae32a1SGerd Hoffmann USBDescID id;
195f1ae32a1SGerd Hoffmann const USBDescDevice *full;
196f1ae32a1SGerd Hoffmann const USBDescDevice *high;
1976d51b2bbSGerd Hoffmann const USBDescDevice *super;
198f1ae32a1SGerd Hoffmann const char* const *str;
1995319dc7bSGerd Hoffmann const USBDescMSOS *msos;
200f1ae32a1SGerd Hoffmann };
201f1ae32a1SGerd Hoffmann
202*7cd2cfa2Szhenwei pi #define USB_DESC_MAX_LEN 8192
203b43a2851SGerd Hoffmann #define USB_DESC_FLAG_SUPER (1 << 1)
204b43a2851SGerd Hoffmann
2050b1fa34eSGerd Hoffmann /* little helpers */
usb_lo(uint16_t val)2060b1fa34eSGerd Hoffmann static inline uint8_t usb_lo(uint16_t val)
2070b1fa34eSGerd Hoffmann {
2080b1fa34eSGerd Hoffmann return val & 0xff;
2090b1fa34eSGerd Hoffmann }
2100b1fa34eSGerd Hoffmann
usb_hi(uint16_t val)2110b1fa34eSGerd Hoffmann static inline uint8_t usb_hi(uint16_t val)
2120b1fa34eSGerd Hoffmann {
2130b1fa34eSGerd Hoffmann return (val >> 8) & 0xff;
2140b1fa34eSGerd Hoffmann }
2150b1fa34eSGerd Hoffmann
216f1ae32a1SGerd Hoffmann /* generate usb packages from structs */
217f1ae32a1SGerd Hoffmann int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
2185319dc7bSGerd Hoffmann bool msos, uint8_t *dest, size_t len);
219f1ae32a1SGerd Hoffmann int usb_desc_device_qualifier(const USBDescDevice *dev,
220f1ae32a1SGerd Hoffmann uint8_t *dest, size_t len);
221b43a2851SGerd Hoffmann int usb_desc_config(const USBDescConfig *conf, int flags,
222b43a2851SGerd Hoffmann uint8_t *dest, size_t len);
223b43a2851SGerd Hoffmann int usb_desc_iface_group(const USBDescIfaceAssoc *iad, int flags,
224b43a2851SGerd Hoffmann uint8_t *dest, size_t len);
225b43a2851SGerd Hoffmann int usb_desc_iface(const USBDescIface *iface, int flags,
226b43a2851SGerd Hoffmann uint8_t *dest, size_t len);
227b43a2851SGerd Hoffmann int usb_desc_endpoint(const USBDescEndpoint *ep, int flags,
228b43a2851SGerd Hoffmann uint8_t *dest, size_t len);
229f1ae32a1SGerd Hoffmann int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
2305319dc7bSGerd Hoffmann int usb_desc_msos(const USBDesc *desc, USBPacket *p,
2315319dc7bSGerd Hoffmann int index, uint8_t *dest, size_t len);
232f1ae32a1SGerd Hoffmann
233f1ae32a1SGerd Hoffmann /* control message emulation helpers */
234f1ae32a1SGerd Hoffmann void usb_desc_init(USBDevice *dev);
235f1ae32a1SGerd Hoffmann void usb_desc_attach(USBDevice *dev);
236f1ae32a1SGerd Hoffmann void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str);
2379d55d1adSGerd Hoffmann void usb_desc_create_serial(USBDevice *dev);
238f1ae32a1SGerd Hoffmann const char *usb_desc_get_string(USBDevice *dev, uint8_t index);
239f1ae32a1SGerd Hoffmann int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
2409a77a0f5SHans de Goede int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
2419a77a0f5SHans de Goede int value, uint8_t *dest, size_t len);
242f1ae32a1SGerd Hoffmann int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
243f1ae32a1SGerd Hoffmann int request, int value, int index, int length, uint8_t *data);
244f1ae32a1SGerd Hoffmann
245f1ae32a1SGerd Hoffmann #endif /* QEMU_HW_USB_DESC_H */
246