xref: /openbmc/qemu/hw/usb/desc.h (revision 3cfeee6177bb7c86db8e1fa01cd6f5d438e4c463)
1 #ifndef QEMU_HW_USB_DESC_H
2 #define QEMU_HW_USB_DESC_H
3 
4 #include <inttypes.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     } u;
40 } QEMU_PACKED USBDescriptor;
41 
42 struct USBDescID {
43     uint16_t                  idVendor;
44     uint16_t                  idProduct;
45     uint16_t                  bcdDevice;
46     uint8_t                   iManufacturer;
47     uint8_t                   iProduct;
48     uint8_t                   iSerialNumber;
49 };
50 
51 struct USBDescDevice {
52     uint16_t                  bcdUSB;
53     uint8_t                   bDeviceClass;
54     uint8_t                   bDeviceSubClass;
55     uint8_t                   bDeviceProtocol;
56     uint8_t                   bMaxPacketSize0;
57     uint8_t                   bNumConfigurations;
58 
59     const USBDescConfig       *confs;
60 };
61 
62 struct USBDescConfig {
63     uint8_t                   bNumInterfaces;
64     uint8_t                   bConfigurationValue;
65     uint8_t                   iConfiguration;
66     uint8_t                   bmAttributes;
67     uint8_t                   bMaxPower;
68 
69     /* grouped interfaces */
70     uint8_t                   nif_groups;
71     const USBDescIfaceAssoc   *if_groups;
72 
73     /* "normal" interfaces */
74     uint8_t                   nif;
75     const USBDescIface        *ifs;
76 };
77 
78 /* conceptually an Interface Association Descriptor, and releated interfaces */
79 struct USBDescIfaceAssoc {
80     uint8_t                   bFirstInterface;
81     uint8_t                   bInterfaceCount;
82     uint8_t                   bFunctionClass;
83     uint8_t                   bFunctionSubClass;
84     uint8_t                   bFunctionProtocol;
85     uint8_t                   iFunction;
86 
87     uint8_t                   nif;
88     const USBDescIface        *ifs;
89 };
90 
91 struct USBDescIface {
92     uint8_t                   bInterfaceNumber;
93     uint8_t                   bAlternateSetting;
94     uint8_t                   bNumEndpoints;
95     uint8_t                   bInterfaceClass;
96     uint8_t                   bInterfaceSubClass;
97     uint8_t                   bInterfaceProtocol;
98     uint8_t                   iInterface;
99 
100     uint8_t                   ndesc;
101     USBDescOther              *descs;
102     USBDescEndpoint           *eps;
103 };
104 
105 struct USBDescEndpoint {
106     uint8_t                   bEndpointAddress;
107     uint8_t                   bmAttributes;
108     uint16_t                  wMaxPacketSize;
109     uint8_t                   bInterval;
110     uint8_t                   bRefresh;
111     uint8_t                   bSynchAddress;
112 
113     uint8_t                   is_audio; /* has bRefresh + bSynchAddress */
114     uint8_t                   *extra;
115 };
116 
117 struct USBDescOther {
118     uint8_t                   length;
119     const uint8_t             *data;
120 };
121 
122 typedef const char *USBDescStrings[256];
123 
124 struct USBDesc {
125     USBDescID                 id;
126     const USBDescDevice       *full;
127     const USBDescDevice       *high;
128     const char* const         *str;
129 };
130 
131 /* generate usb packages from structs */
132 int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
133                     uint8_t *dest, size_t len);
134 int usb_desc_device_qualifier(const USBDescDevice *dev,
135                               uint8_t *dest, size_t len);
136 int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len);
137 int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest,
138                          size_t len);
139 int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len);
140 int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len);
141 int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
142 
143 /* control message emulation helpers */
144 void usb_desc_init(USBDevice *dev);
145 void usb_desc_attach(USBDevice *dev);
146 void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str);
147 const char *usb_desc_get_string(USBDevice *dev, uint8_t index);
148 int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
149 int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len);
150 int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
151         int request, int value, int index, int length, uint8_t *data);
152 
153 #endif /* QEMU_HW_USB_DESC_H */
154