xref: /openbmc/qemu/hw/usb/desc.h (revision 7f709ce7)
1 #ifndef QEMU_HW_USB_DESC_H
2 #define QEMU_HW_USB_DESC_H
3 
4 #include <wchar.h>
5 
6 /* binary representation */
7 typedef struct USBDescriptor {
8     uint8_t                   bLength;
9     uint8_t                   bDescriptorType;
10     union {
11         struct {
12             uint8_t           bcdUSB_lo;
13             uint8_t           bcdUSB_hi;
14             uint8_t           bDeviceClass;
15             uint8_t           bDeviceSubClass;
16             uint8_t           bDeviceProtocol;
17             uint8_t           bMaxPacketSize0;
18             uint8_t           idVendor_lo;
19             uint8_t           idVendor_hi;
20             uint8_t           idProduct_lo;
21             uint8_t           idProduct_hi;
22             uint8_t           bcdDevice_lo;
23             uint8_t           bcdDevice_hi;
24             uint8_t           iManufacturer;
25             uint8_t           iProduct;
26             uint8_t           iSerialNumber;
27             uint8_t           bNumConfigurations;
28         } device;
29         struct {
30             uint8_t           bcdUSB_lo;
31             uint8_t           bcdUSB_hi;
32             uint8_t           bDeviceClass;
33             uint8_t           bDeviceSubClass;
34             uint8_t           bDeviceProtocol;
35             uint8_t           bMaxPacketSize0;
36             uint8_t           bNumConfigurations;
37             uint8_t           bReserved;
38         } device_qualifier;
39         struct {
40             uint8_t           wTotalLength_lo;
41             uint8_t           wTotalLength_hi;
42             uint8_t           bNumInterfaces;
43             uint8_t           bConfigurationValue;
44             uint8_t           iConfiguration;
45             uint8_t           bmAttributes;
46             uint8_t           bMaxPower;
47         } config;
48         struct {
49             uint8_t           bInterfaceNumber;
50             uint8_t           bAlternateSetting;
51             uint8_t           bNumEndpoints;
52             uint8_t           bInterfaceClass;
53             uint8_t           bInterfaceSubClass;
54             uint8_t           bInterfaceProtocol;
55             uint8_t           iInterface;
56         } interface;
57         struct {
58             uint8_t           bEndpointAddress;
59             uint8_t           bmAttributes;
60             uint8_t           wMaxPacketSize_lo;
61             uint8_t           wMaxPacketSize_hi;
62             uint8_t           bInterval;
63             uint8_t           bRefresh;        /* only audio ep */
64             uint8_t           bSynchAddress;   /* only audio ep */
65         } endpoint;
66         struct {
67             uint8_t           bMaxBurst;
68             uint8_t           bmAttributes;
69             uint8_t           wBytesPerInterval_lo;
70             uint8_t           wBytesPerInterval_hi;
71         } super_endpoint;
72         struct {
73             uint8_t           wTotalLength_lo;
74             uint8_t           wTotalLength_hi;
75             uint8_t           bNumDeviceCaps;
76         } bos;
77         struct {
78             uint8_t           bDevCapabilityType;
79             union {
80                 struct {
81                     uint8_t   bmAttributes_1;
82                     uint8_t   bmAttributes_2;
83                     uint8_t   bmAttributes_3;
84                     uint8_t   bmAttributes_4;
85                 } usb2_ext;
86                 struct {
87                     uint8_t   bmAttributes;
88                     uint8_t   wSpeedsSupported_lo;
89                     uint8_t   wSpeedsSupported_hi;
90                     uint8_t   bFunctionalitySupport;
91                     uint8_t   bU1DevExitLat;
92                     uint8_t   wU2DevExitLat_lo;
93                     uint8_t   wU2DevExitLat_hi;
94                 } super;
95             } u;
96         } cap;
97     } u;
98 } QEMU_PACKED USBDescriptor;
99 
100 struct USBDescID {
101     uint16_t                  idVendor;
102     uint16_t                  idProduct;
103     uint16_t                  bcdDevice;
104     uint8_t                   iManufacturer;
105     uint8_t                   iProduct;
106     uint8_t                   iSerialNumber;
107 };
108 
109 struct USBDescDevice {
110     uint16_t                  bcdUSB;
111     uint8_t                   bDeviceClass;
112     uint8_t                   bDeviceSubClass;
113     uint8_t                   bDeviceProtocol;
114     uint8_t                   bMaxPacketSize0;
115     uint8_t                   bNumConfigurations;
116 
117     const USBDescConfig       *confs;
118 };
119 
120 struct USBDescConfig {
121     uint8_t                   bNumInterfaces;
122     uint8_t                   bConfigurationValue;
123     uint8_t                   iConfiguration;
124     uint8_t                   bmAttributes;
125     uint8_t                   bMaxPower;
126 
127     /* grouped interfaces */
128     uint8_t                   nif_groups;
129     const USBDescIfaceAssoc   *if_groups;
130 
131     /* "normal" interfaces */
132     uint8_t                   nif;
133     const USBDescIface        *ifs;
134 };
135 
136 /* conceptually an Interface Association Descriptor, and releated interfaces */
137 struct USBDescIfaceAssoc {
138     uint8_t                   bFirstInterface;
139     uint8_t                   bInterfaceCount;
140     uint8_t                   bFunctionClass;
141     uint8_t                   bFunctionSubClass;
142     uint8_t                   bFunctionProtocol;
143     uint8_t                   iFunction;
144 
145     uint8_t                   nif;
146     const USBDescIface        *ifs;
147 };
148 
149 struct USBDescIface {
150     uint8_t                   bInterfaceNumber;
151     uint8_t                   bAlternateSetting;
152     uint8_t                   bNumEndpoints;
153     uint8_t                   bInterfaceClass;
154     uint8_t                   bInterfaceSubClass;
155     uint8_t                   bInterfaceProtocol;
156     uint8_t                   iInterface;
157 
158     uint8_t                   ndesc;
159     USBDescOther              *descs;
160     USBDescEndpoint           *eps;
161 };
162 
163 struct USBDescEndpoint {
164     uint8_t                   bEndpointAddress;
165     uint8_t                   bmAttributes;
166     uint16_t                  wMaxPacketSize;
167     uint8_t                   bInterval;
168     uint8_t                   bRefresh;
169     uint8_t                   bSynchAddress;
170 
171     uint8_t                   is_audio; /* has bRefresh + bSynchAddress */
172     uint8_t                   *extra;
173 
174     /* superspeed endpoint companion */
175     uint8_t                   bMaxBurst;
176     uint8_t                   bmAttributes_super;
177     uint16_t                  wBytesPerInterval;
178 };
179 
180 struct USBDescOther {
181     uint8_t                   length;
182     const uint8_t             *data;
183 };
184 
185 struct USBDescMSOS {
186     const char                *CompatibleID;
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