xref: /openbmc/qemu/hw/usb/desc.h (revision 623d7e3551a6fc5693c06ea938c60fe281b52e27)
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 related 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_MAX_LEN    8192
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