blob: 8e8db03a0caa3b2932b2d2e4a606185d7ca3dc5c [file] [log] [blame]
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +01001#ifndef QEMU_HW_USB_DESC_H
2#define QEMU_HW_USB_DESC_H
3
4#include <inttypes.h>
Gerd Hoffmann5319dc72013-11-20 07:32:31 +01005#include <wchar.h>
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +01006
Gerd Hoffmannd3f904e2012-03-29 12:04:54 +02007/* binary representation */
8typedef 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;
Gerd Hoffmann3cfeee62012-03-29 12:15:01 +020030 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;
Gerd Hoffmann0a263db2012-03-29 12:24:08 +020040 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;
Gerd Hoffmannfeafd792012-03-29 12:30:33 +020049 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;
Gerd Hoffmanne36a20d2012-03-29 16:01:21 +020058 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;
Gerd Hoffmannb43a2852012-08-28 17:28:03 +020067 struct {
68 uint8_t bMaxBurst;
69 uint8_t bmAttributes;
70 uint8_t wBytesPerInterval_lo;
71 uint8_t wBytesPerInterval_hi;
72 } super_endpoint;
Gerd Hoffmann20774692012-08-28 17:46:29 +020073 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;
Gerd Hoffmannd3f904e2012-03-29 12:04:54 +020098 } u;
99} QEMU_PACKED USBDescriptor;
100
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +0100101struct 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
110struct 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
121struct USBDescConfig {
122 uint8_t bNumInterfaces;
123 uint8_t bConfigurationValue;
124 uint8_t iConfiguration;
125 uint8_t bmAttributes;
126 uint8_t bMaxPower;
127
Brad Hards6e625fc2011-04-03 15:33:21 +1000128 /* 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 */
138struct 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
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +0100146 uint8_t nif;
147 const USBDescIface *ifs;
148};
149
150struct 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
164struct USBDescEndpoint {
165 uint8_t bEndpointAddress;
166 uint8_t bmAttributes;
167 uint16_t wMaxPacketSize;
168 uint8_t bInterval;
Gerd Hoffmanncc5f1392011-08-10 14:10:04 +0200169 uint8_t bRefresh;
170 uint8_t bSynchAddress;
171
172 uint8_t is_audio; /* has bRefresh + bSynchAddress */
173 uint8_t *extra;
Gerd Hoffmannb43a2852012-08-28 17:28:03 +0200174
175 /* superspeed endpoint companion */
176 uint8_t bMaxBurst;
177 uint8_t bmAttributes_super;
178 uint16_t wBytesPerInterval;
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +0100179};
180
181struct USBDescOther {
182 uint8_t length;
Gerd Hoffmann97237e02011-08-30 11:49:05 +0200183 const uint8_t *data;
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +0100184};
185
Gerd Hoffmann5319dc72013-11-20 07:32:31 +0100186struct USBDescMSOS {
Gerd Hoffmann409951f2014-03-18 11:01:50 +0100187 const char *CompatibleID;
Gerd Hoffmann5319dc72013-11-20 07:32:31 +0100188 const wchar_t *Label;
189 bool SelectiveSuspendEnabled;
190};
191
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +0100192typedef const char *USBDescStrings[256];
193
194struct USBDesc {
195 USBDescID id;
196 const USBDescDevice *full;
197 const USBDescDevice *high;
Gerd Hoffmann6d51b2b2012-08-28 17:28:50 +0200198 const USBDescDevice *super;
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +0100199 const char* const *str;
Gerd Hoffmann5319dc72013-11-20 07:32:31 +0100200 const USBDescMSOS *msos;
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +0100201};
202
Gerd Hoffmannb43a2852012-08-28 17:28:03 +0200203#define USB_DESC_FLAG_SUPER (1 << 1)
204
Gerd Hoffmann0b1fa342013-11-20 07:33:28 +0100205/* little helpers */
206static inline uint8_t usb_lo(uint16_t val)
207{
208 return val & 0xff;
209}
210
211static inline uint8_t usb_hi(uint16_t val)
212{
213 return (val >> 8) & 0xff;
214}
215
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +0100216/* generate usb packages from structs */
217int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
Gerd Hoffmann5319dc72013-11-20 07:32:31 +0100218 bool msos, uint8_t *dest, size_t len);
Gerd Hoffmann25620cb2010-12-08 17:35:22 +0100219int usb_desc_device_qualifier(const USBDescDevice *dev,
220 uint8_t *dest, size_t len);
Gerd Hoffmannb43a2852012-08-28 17:28:03 +0200221int usb_desc_config(const USBDescConfig *conf, int flags,
222 uint8_t *dest, size_t len);
223int usb_desc_iface_group(const USBDescIfaceAssoc *iad, int flags,
224 uint8_t *dest, size_t len);
225int usb_desc_iface(const USBDescIface *iface, int flags,
226 uint8_t *dest, size_t len);
227int usb_desc_endpoint(const USBDescEndpoint *ep, int flags,
228 uint8_t *dest, size_t len);
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +0100229int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
Gerd Hoffmann5319dc72013-11-20 07:32:31 +0100230int usb_desc_msos(const USBDesc *desc, USBPacket *p,
231 int index, uint8_t *dest, size_t len);
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +0100232
233/* control message emulation helpers */
Gerd Hoffmanna980a062010-11-26 20:20:41 +0100234void usb_desc_init(USBDevice *dev);
Gerd Hoffmann32d41912010-12-03 18:07:20 +0100235void usb_desc_attach(USBDevice *dev);
Gerd Hoffmann132a3f52010-11-26 12:25:32 +0100236void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str);
Gerd Hoffmann9d55d1a2012-04-20 12:33:30 +0200237void usb_desc_create_serial(USBDevice *dev);
Gerd Hoffmann132a3f52010-11-26 12:25:32 +0100238const char *usb_desc_get_string(USBDevice *dev, uint8_t index);
239int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
Hans de Goede9a77a0f2012-11-01 17:15:01 +0100240int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
241 int value, uint8_t *dest, size_t len);
Hans de Goede007fd622011-02-02 16:33:13 +0100242int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
243 int request, int value, int index, int length, uint8_t *data);
Gerd Hoffmann37fb59d2010-11-17 11:03:53 +0100244
245#endif /* QEMU_HW_USB_DESC_H */