Rename __attribute__((packed)) --> __packed
[coreboot.git] / payloads / libpayload / include / usb / usb.h
blobef1892661c20f3028fdbe9a2111ea59168181aac
1 /*
2 * This file is part of the libpayload project.
4 * Copyright (C) 2008 coresystems GmbH
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
30 #ifndef __USB_H
31 #define __USB_H
32 #include <libpayload.h>
33 #include <pci/pci.h>
34 #include <stdint.h>
36 typedef enum { host_to_device = 0, device_to_host = 1 } dev_req_dir;
37 typedef enum { standard_type = 0, class_type = 1, vendor_type =
38 2, reserved_type = 3
39 } dev_req_type;
40 typedef enum { dev_recp = 0, iface_recp = 1, endp_recp = 2, other_recp = 3
41 } dev_req_recp;
43 enum {
44 DT_DEV = 1,
45 DT_CFG = 2,
46 DT_STR = 3,
47 DT_INTF = 4,
48 DT_ENDP = 5,
51 typedef enum {
52 GET_STATUS = 0,
53 CLEAR_FEATURE = 1,
54 SET_FEATURE = 3,
55 SET_ADDRESS = 5,
56 GET_DESCRIPTOR = 6,
57 SET_DESCRIPTOR = 7,
58 GET_CONFIGURATION = 8,
59 SET_CONFIGURATION = 9,
60 GET_INTERFACE = 10,
61 SET_INTERFACE = 11,
62 SYNCH_FRAME = 12
63 } bRequest_Codes;
65 typedef enum {
66 ENDPOINT_HALT = 0,
67 DEVICE_REMOTE_WAKEUP = 1,
68 TEST_MODE = 2
69 } feature_selectors;
71 /* SetAddress() recovery interval (USB 2.0 specification 9.2.6.3 */
72 #define SET_ADDRESS_MDELAY 2
74 typedef struct {
75 unsigned char bDescLength;
76 unsigned char bDescriptorType;
77 unsigned char bNbrPorts;
78 union {
79 struct {
80 unsigned long logicalPowerSwitchingMode:2;
81 unsigned long isCompoundDevice:1;
82 unsigned long overcurrentProtectionMode:2;
83 unsigned long ttThinkTime:2;
84 unsigned long arePortIndicatorsSupported:1;
85 unsigned long:8;
86 } __packed;
87 unsigned short wHubCharacteristics;
88 } __packed;
89 unsigned char bPowerOn2PwrGood;
90 unsigned char bHubContrCurrent;
91 char DeviceRemovable[];
92 } __packed hub_descriptor_t;
94 typedef struct {
95 unsigned char bLength;
96 unsigned char bDescriptorType;
97 unsigned short bcdUSB;
98 unsigned char bDeviceClass;
99 unsigned char bDeviceSubClass;
100 unsigned char bDeviceProtocol;
101 unsigned char bMaxPacketSize0;
102 unsigned short idVendor;
103 unsigned short idProduct;
104 unsigned short bcdDevice;
105 unsigned char iManufacturer;
106 unsigned char iProduct;
107 unsigned char iSerialNumber;
108 unsigned char bNumConfigurations;
109 } __packed device_descriptor_t;
111 typedef struct {
112 unsigned char bLength;
113 unsigned char bDescriptorType;
114 unsigned short wTotalLength;
115 unsigned char bNumInterfaces;
116 unsigned char bConfigurationValue;
117 unsigned char iConfiguration;
118 unsigned char bmAttributes;
119 unsigned char bMaxPower;
120 } __packed configuration_descriptor_t;
122 typedef struct {
123 unsigned char bLength;
124 unsigned char bDescriptorType;
125 unsigned char bInterfaceNumber;
126 unsigned char bAlternateSetting;
127 unsigned char bNumEndpoints;
128 unsigned char bInterfaceClass;
129 unsigned char bInterfaceSubClass;
130 unsigned char bInterfaceProtocol;
131 unsigned char iInterface;
132 } __packed interface_descriptor_t;
134 typedef struct {
135 unsigned char bLength;
136 unsigned char bDescriptorType;
137 unsigned char bEndpointAddress;
138 unsigned char bmAttributes;
139 unsigned short wMaxPacketSize;
140 unsigned char bInterval;
141 } __packed endpoint_descriptor_t;
143 typedef struct {
144 unsigned char bLength;
145 unsigned char bDescriptorType;
146 unsigned short bcdHID;
147 unsigned char bCountryCode;
148 unsigned char bNumDescriptors;
149 unsigned char bReportDescriptorType;
150 unsigned short wReportDescriptorLength;
151 } __packed hid_descriptor_t;
153 typedef struct {
154 union {
155 struct {
156 dev_req_recp req_recp:5;
157 dev_req_type req_type:2;
158 dev_req_dir data_dir:1;
159 } __packed;
160 unsigned char bmRequestType;
161 } __packed;
162 unsigned char bRequest;
163 unsigned short wValue;
164 unsigned short wIndex;
165 unsigned short wLength;
166 } __packed dev_req_t;
168 struct usbdev_hc;
169 typedef struct usbdev_hc hci_t;
171 struct usbdev;
172 typedef struct usbdev usbdev_t;
174 typedef enum { SETUP, IN, OUT } direction_t;
175 typedef enum { CONTROL = 0, ISOCHRONOUS = 1, BULK = 2, INTERRUPT = 3
176 } endpoint_type;
178 typedef struct {
179 usbdev_t *dev;
180 int endpoint;
181 direction_t direction;
182 int toggle;
183 int maxpacketsize;
184 endpoint_type type;
185 int interval; /* expressed as binary logarithm of the number
186 of microframes (i.e. t = 125us * 2^interval) */
187 } endpoint_t;
189 typedef enum {
190 FULL_SPEED = 0, LOW_SPEED = 1, HIGH_SPEED = 2, SUPER_SPEED = 3,
191 } usb_speed;
193 struct usbdev {
194 hci_t *controller;
195 endpoint_t endpoints[32];
196 int num_endp;
197 int address; // usb address
198 int hub; // hub, device is attached to
199 int port; // port where device is attached
200 usb_speed speed;
201 u32 quirks; // quirks field. got to love usb
202 void *data;
203 device_descriptor_t *descriptor;
204 configuration_descriptor_t *configuration;
205 void (*init) (usbdev_t *dev);
206 void (*destroy) (usbdev_t *dev);
207 void (*poll) (usbdev_t *dev);
210 typedef enum { OHCI = 0, UHCI = 1, EHCI = 2, XHCI = 3, DWC2 = 4} hc_type;
212 struct usbdev_hc {
213 hci_t *next;
214 uintptr_t reg_base;
215 pcidev_t pcidev; // 0 if not used (eg on ARM)
216 hc_type type;
217 int latest_address;
218 usbdev_t *devices[128]; // dev 0 is root hub, 127 is last addressable
220 /* start(): Resume operation. */
221 void (*start) (hci_t *controller);
222 /* stop(): Stop operation but keep controller initialized. */
223 void (*stop) (hci_t *controller);
224 /* reset(): Perform a controller reset. The controller needs to
225 be (re)initialized afterwards to work (again). */
226 void (*reset) (hci_t *controller);
227 /* init(): Initialize a (previously reset) controller
228 to a working state. */
229 void (*init) (hci_t *controller);
230 /* shutdown(): Stop operation, detach host controller and shutdown
231 this driver instance. After calling shutdown() any
232 other usage of this hci_t* is invalid. */
233 void (*shutdown) (hci_t *controller);
235 int (*bulk) (endpoint_t *ep, int size, u8 *data, int finalize);
236 int (*control) (usbdev_t *dev, direction_t pid, int dr_length,
237 void *devreq, int data_length, u8 *data);
238 void* (*create_intr_queue) (endpoint_t *ep, int reqsize, int reqcount, int reqtiming);
239 void (*destroy_intr_queue) (endpoint_t *ep, void *queue);
240 u8* (*poll_intr_queue) (void *queue);
241 void *instance;
243 /* set_address(): Tell the usb device its address (xHCI
244 controllers want to do this by
245 themselves). Also, allocate the usbdev
246 structure, initialize enpoint 0
247 (including MPS) and return it. */
248 usbdev_t *(*set_address) (hci_t *controller, usb_speed speed,
249 int hubport, int hubaddr);
250 /* finish_device_config(): Another hook for xHCI,
251 returns 0 on success. */
252 int (*finish_device_config) (usbdev_t *dev);
253 /* destroy_device(): Finally, destroy all structures that
254 were allocated during set_address()
255 and finish_device_config(). */
256 void (*destroy_device) (hci_t *controller, int devaddr);
259 hci_t *usb_add_mmio_hc(hc_type type, void *bar);
260 hci_t *new_controller (void);
261 void detach_controller (hci_t *controller);
262 void usb_poll (void);
263 usbdev_t *init_device_entry (hci_t *controller, int num);
265 int usb_decode_mps0 (usb_speed speed, u8 bMaxPacketSize0);
266 int speed_to_default_mps(usb_speed speed);
267 int set_feature (usbdev_t *dev, int endp, int feature, int rtype);
268 int get_status (usbdev_t *dev, int endp, int rtype, int len, void *data);
269 int get_descriptor (usbdev_t *dev, int rtype, int descType, int descIdx,
270 void *data, size_t len);
271 int set_configuration (usbdev_t *dev);
272 int clear_feature (usbdev_t *dev, int endp, int feature, int rtype);
273 int clear_stall (endpoint_t *ep);
275 void usb_nop_init (usbdev_t *dev);
276 void usb_hub_init (usbdev_t *dev);
277 void usb_hid_init (usbdev_t *dev);
278 void usb_msc_init (usbdev_t *dev);
279 void usb_generic_init (usbdev_t *dev);
281 int closest_usb2_hub(const usbdev_t *dev, int *const addr, int *const port);
283 static inline unsigned char
284 gen_bmRequestType (dev_req_dir dir, dev_req_type type, dev_req_recp recp)
286 return (dir << 7) | (type << 5) | recp;
289 /* default "set address" handler */
290 usbdev_t *generic_set_address (hci_t *controller, usb_speed speed,
291 int hubport, int hubaddr);
293 void usb_detach_device(hci_t *controller, int devno);
294 int usb_attach_device(hci_t *controller, int hubaddress, int port,
295 usb_speed speed);
297 u32 usb_quirk_check(u16 vendor, u16 device);
298 int usb_interface_check(u16 vendor, u16 device);
300 #define USB_QUIRK_MSC_FORCE_PROTO_SCSI (1 << 0)
301 #define USB_QUIRK_MSC_FORCE_PROTO_ATAPI (1 << 1)
302 #define USB_QUIRK_MSC_FORCE_PROTO_UFI (1 << 2)
303 #define USB_QUIRK_MSC_FORCE_PROTO_RBC (1 << 3)
304 #define USB_QUIRK_MSC_FORCE_TRANS_BBB (1 << 4)
305 #define USB_QUIRK_MSC_FORCE_TRANS_CBI (1 << 5)
306 #define USB_QUIRK_MSC_FORCE_TRANS_CBI_I (1 << 6)
307 #define USB_QUIRK_MSC_NO_TEST_UNIT_READY (1 << 7)
308 #define USB_QUIRK_MSC_SHORT_INQUIRY (1 << 8)
309 #define USB_QUIRK_TEST (1 << 31)
310 #define USB_QUIRK_NONE 0
312 static inline void usb_debug(const char *fmt, ...)
314 #ifdef USB_DEBUG
315 va_list ap;
316 va_start(ap, fmt);
317 vprintf(fmt, ap);
318 va_end(ap);
319 #endif
323 * To be implemented by libpayload-client. It's called by the USB stack
324 * when a new USB device is found which isn't claimed by a built in driver,
325 * so the client has the chance to know about it.
327 * @param dev descriptor for the USB device
329 void __attribute__((weak)) usb_generic_create (usbdev_t *dev);
332 * To be implemented by libpayload-client. It's called by the USB stack
333 * when it finds out that a USB device is removed which wasn't claimed by a
334 * built in driver.
336 * @param dev descriptor for the USB device
338 void __attribute__((weak)) usb_generic_remove (usbdev_t *dev);
340 #endif