xref: /openbmc/qemu/hw/usb/desc.h (revision 52f91c37)
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 char                *CompatibleID;
188     const wchar_t             *Label;
189     bool                      SelectiveSuspendEnabled;
190 };
191 
192 typedef const char *USBDescStrings[256];
193 
194 struct USBDesc {
195     USBDescID                 id;
196     const USBDescDevice       *full;
197     const USBDescDevice       *high;
198     const USBDescDevice       *super;
199     const char* const         *str;
200     const USBDescMSOS         *msos;
201 };
202 
203 #define USB_DESC_FLAG_SUPER (1 << 1)
204 
205 /* little helpers */
206 static inline uint8_t usb_lo(uint16_t val)
207 {
208     return val & 0xff;
209 }
210 
211 static inline uint8_t usb_hi(uint16_t val)
212 {
213     return (val >> 8) & 0xff;
214 }
215 
216 /* generate usb packages from structs */
217 int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
218                     bool msos, uint8_t *dest, size_t len);
219 int usb_desc_device_qualifier(const USBDescDevice *dev,
220                               uint8_t *dest, size_t len);
221 int usb_desc_config(const USBDescConfig *conf, int flags,
222                     uint8_t *dest, size_t len);
223 int usb_desc_iface_group(const USBDescIfaceAssoc *iad, int flags,
224                          uint8_t *dest, size_t len);
225 int usb_desc_iface(const USBDescIface *iface, int flags,
226                    uint8_t *dest, size_t len);
227 int usb_desc_endpoint(const USBDescEndpoint *ep, int flags,
228                       uint8_t *dest, size_t len);
229 int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
230 int usb_desc_msos(const USBDesc *desc, USBPacket *p,
231                   int index, uint8_t *dest, size_t len);
232 
233 /* control message emulation helpers */
234 void usb_desc_init(USBDevice *dev);
235 void usb_desc_attach(USBDevice *dev);
236 void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str);
237 void usb_desc_create_serial(USBDevice *dev);
238 const char *usb_desc_get_string(USBDevice *dev, uint8_t index);
239 int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
240 int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
241         int value, uint8_t *dest, size_t len);
242 int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
243         int request, int value, int index, int length, uint8_t *data);
244 
245 #endif /* QEMU_HW_USB_DESC_H */
246