xref: /openbmc/qemu/hw/usb/desc.h (revision 6d51b2bb)
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         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     } u;
67 } QEMU_PACKED USBDescriptor;
68 
69 struct USBDescID {
70     uint16_t                  idVendor;
71     uint16_t                  idProduct;
72     uint16_t                  bcdDevice;
73     uint8_t                   iManufacturer;
74     uint8_t                   iProduct;
75     uint8_t                   iSerialNumber;
76 };
77 
78 struct USBDescDevice {
79     uint16_t                  bcdUSB;
80     uint8_t                   bDeviceClass;
81     uint8_t                   bDeviceSubClass;
82     uint8_t                   bDeviceProtocol;
83     uint8_t                   bMaxPacketSize0;
84     uint8_t                   bNumConfigurations;
85 
86     const USBDescConfig       *confs;
87 };
88 
89 struct USBDescConfig {
90     uint8_t                   bNumInterfaces;
91     uint8_t                   bConfigurationValue;
92     uint8_t                   iConfiguration;
93     uint8_t                   bmAttributes;
94     uint8_t                   bMaxPower;
95 
96     /* grouped interfaces */
97     uint8_t                   nif_groups;
98     const USBDescIfaceAssoc   *if_groups;
99 
100     /* "normal" interfaces */
101     uint8_t                   nif;
102     const USBDescIface        *ifs;
103 };
104 
105 /* conceptually an Interface Association Descriptor, and releated interfaces */
106 struct USBDescIfaceAssoc {
107     uint8_t                   bFirstInterface;
108     uint8_t                   bInterfaceCount;
109     uint8_t                   bFunctionClass;
110     uint8_t                   bFunctionSubClass;
111     uint8_t                   bFunctionProtocol;
112     uint8_t                   iFunction;
113 
114     uint8_t                   nif;
115     const USBDescIface        *ifs;
116 };
117 
118 struct USBDescIface {
119     uint8_t                   bInterfaceNumber;
120     uint8_t                   bAlternateSetting;
121     uint8_t                   bNumEndpoints;
122     uint8_t                   bInterfaceClass;
123     uint8_t                   bInterfaceSubClass;
124     uint8_t                   bInterfaceProtocol;
125     uint8_t                   iInterface;
126 
127     uint8_t                   ndesc;
128     USBDescOther              *descs;
129     USBDescEndpoint           *eps;
130 };
131 
132 struct USBDescEndpoint {
133     uint8_t                   bEndpointAddress;
134     uint8_t                   bmAttributes;
135     uint16_t                  wMaxPacketSize;
136     uint8_t                   bInterval;
137     uint8_t                   bRefresh;
138     uint8_t                   bSynchAddress;
139 
140     uint8_t                   is_audio; /* has bRefresh + bSynchAddress */
141     uint8_t                   *extra;
142 };
143 
144 struct USBDescOther {
145     uint8_t                   length;
146     const uint8_t             *data;
147 };
148 
149 typedef const char *USBDescStrings[256];
150 
151 struct USBDesc {
152     USBDescID                 id;
153     const USBDescDevice       *full;
154     const USBDescDevice       *high;
155     const USBDescDevice       *super;
156     const char* const         *str;
157 };
158 
159 /* generate usb packages from structs */
160 int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
161                     uint8_t *dest, size_t len);
162 int usb_desc_device_qualifier(const USBDescDevice *dev,
163                               uint8_t *dest, size_t len);
164 int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len);
165 int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest,
166                          size_t len);
167 int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len);
168 int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len);
169 int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
170 
171 /* control message emulation helpers */
172 void usb_desc_init(USBDevice *dev);
173 void usb_desc_attach(USBDevice *dev);
174 void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str);
175 void usb_desc_create_serial(USBDevice *dev);
176 const char *usb_desc_get_string(USBDevice *dev, uint8_t index);
177 int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
178 int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len);
179 int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
180         int request, int value, int index, int length, uint8_t *data);
181 
182 #endif /* QEMU_HW_USB_DESC_H */
183