xref: /openbmc/qemu/hw/usb/desc.h (revision 2077469b)
1f1ae32a1SGerd Hoffmann #ifndef QEMU_HW_USB_DESC_H
2f1ae32a1SGerd Hoffmann #define QEMU_HW_USB_DESC_H
3f1ae32a1SGerd Hoffmann 
4f1ae32a1SGerd Hoffmann #include <inttypes.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;
72*2077469bSGerd Hoffmann         struct {
73*2077469bSGerd Hoffmann             uint8_t           wTotalLength_lo;
74*2077469bSGerd Hoffmann             uint8_t           wTotalLength_hi;
75*2077469bSGerd Hoffmann             uint8_t           bNumDeviceCaps;
76*2077469bSGerd Hoffmann         } bos;
77*2077469bSGerd Hoffmann         struct {
78*2077469bSGerd Hoffmann             uint8_t           bDevCapabilityType;
79*2077469bSGerd Hoffmann             union {
80*2077469bSGerd Hoffmann                 struct {
81*2077469bSGerd Hoffmann                     uint8_t   bmAttributes_1;
82*2077469bSGerd Hoffmann                     uint8_t   bmAttributes_2;
83*2077469bSGerd Hoffmann                     uint8_t   bmAttributes_3;
84*2077469bSGerd Hoffmann                     uint8_t   bmAttributes_4;
85*2077469bSGerd Hoffmann                 } usb2_ext;
86*2077469bSGerd Hoffmann                 struct {
87*2077469bSGerd Hoffmann                     uint8_t   bmAttributes;
88*2077469bSGerd Hoffmann                     uint8_t   wSpeedsSupported_lo;
89*2077469bSGerd Hoffmann                     uint8_t   wSpeedsSupported_hi;
90*2077469bSGerd Hoffmann                     uint8_t   bFunctionalitySupport;
91*2077469bSGerd Hoffmann                     uint8_t   bU1DevExitLat;
92*2077469bSGerd Hoffmann                     uint8_t   wU2DevExitLat_lo;
93*2077469bSGerd Hoffmann                     uint8_t   wU2DevExitLat_hi;
94*2077469bSGerd Hoffmann                 } super;
95*2077469bSGerd Hoffmann             } u;
96*2077469bSGerd 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 
136f1ae32a1SGerd Hoffmann /* conceptually an Interface Association Descriptor, and releated 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 
185f1ae32a1SGerd Hoffmann typedef const char *USBDescStrings[256];
186f1ae32a1SGerd Hoffmann 
187f1ae32a1SGerd Hoffmann struct USBDesc {
188f1ae32a1SGerd Hoffmann     USBDescID                 id;
189f1ae32a1SGerd Hoffmann     const USBDescDevice       *full;
190f1ae32a1SGerd Hoffmann     const USBDescDevice       *high;
1916d51b2bbSGerd Hoffmann     const USBDescDevice       *super;
192f1ae32a1SGerd Hoffmann     const char* const         *str;
193f1ae32a1SGerd Hoffmann };
194f1ae32a1SGerd Hoffmann 
195b43a2851SGerd Hoffmann #define USB_DESC_FLAG_SUPER (1 << 1)
196b43a2851SGerd Hoffmann 
197f1ae32a1SGerd Hoffmann /* generate usb packages from structs */
198f1ae32a1SGerd Hoffmann int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
199f1ae32a1SGerd Hoffmann                     uint8_t *dest, size_t len);
200f1ae32a1SGerd Hoffmann int usb_desc_device_qualifier(const USBDescDevice *dev,
201f1ae32a1SGerd Hoffmann                               uint8_t *dest, size_t len);
202b43a2851SGerd Hoffmann int usb_desc_config(const USBDescConfig *conf, int flags,
203b43a2851SGerd Hoffmann                     uint8_t *dest, size_t len);
204b43a2851SGerd Hoffmann int usb_desc_iface_group(const USBDescIfaceAssoc *iad, int flags,
205b43a2851SGerd Hoffmann                          uint8_t *dest, size_t len);
206b43a2851SGerd Hoffmann int usb_desc_iface(const USBDescIface *iface, int flags,
207b43a2851SGerd Hoffmann                    uint8_t *dest, size_t len);
208b43a2851SGerd Hoffmann int usb_desc_endpoint(const USBDescEndpoint *ep, int flags,
209b43a2851SGerd Hoffmann                       uint8_t *dest, size_t len);
210f1ae32a1SGerd Hoffmann int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
211f1ae32a1SGerd Hoffmann 
212f1ae32a1SGerd Hoffmann /* control message emulation helpers */
213f1ae32a1SGerd Hoffmann void usb_desc_init(USBDevice *dev);
214f1ae32a1SGerd Hoffmann void usb_desc_attach(USBDevice *dev);
215f1ae32a1SGerd Hoffmann void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str);
2169d55d1adSGerd Hoffmann void usb_desc_create_serial(USBDevice *dev);
217f1ae32a1SGerd Hoffmann const char *usb_desc_get_string(USBDevice *dev, uint8_t index);
218f1ae32a1SGerd Hoffmann int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
219f1ae32a1SGerd Hoffmann int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len);
220f1ae32a1SGerd Hoffmann int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
221f1ae32a1SGerd Hoffmann         int request, int value, int index, int length, uint8_t *data);
222f1ae32a1SGerd Hoffmann 
223f1ae32a1SGerd Hoffmann #endif /* QEMU_HW_USB_DESC_H */
224