libpayload: Reduce verbosity in USB stack
[coreboot.git] / payloads / libpayload / include / usb / usb.h
1 /*
2  * This file is part of the libpayload project.
3  *
4  * Copyright (C) 2008 coresystems GmbH
5  *
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.
16  *
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.
28  */
29
30 #ifndef __USB_H
31 #define __USB_H
32 #include <libpayload.h>
33 #include <pci.h>
34
35 typedef enum { host_to_device = 0, device_to_host = 1 } dev_req_dir;
36 typedef enum { standard_type = 0, class_type = 1, vendor_type =
37                 2, reserved_type = 3
38 } dev_req_type;
39 typedef enum { dev_recp = 0, iface_recp = 1, endp_recp = 2, other_recp = 3
40 } dev_req_recp;
41
42 typedef enum {
43         GET_STATUS = 0,
44         CLEAR_FEATURE = 1,
45         SET_FEATURE = 3,
46         SET_ADDRESS = 5,
47         GET_DESCRIPTOR = 6,
48         SET_DESCRIPTOR = 7,
49         GET_CONFIGURATION = 8,
50         SET_CONFIGURATION = 9,
51         GET_INTERFACE = 10,
52         SET_INTERFACE = 11,
53         SYNCH_FRAME = 12
54 } bRequest_Codes;
55
56 typedef enum {
57         ENDPOINT_HALT = 0,
58         DEVICE_REMOTE_WAKEUP = 1,
59         TEST_MODE = 2
60 } feature_selectors;
61
62 typedef struct {
63         union {
64                 struct {
65                         dev_req_recp req_recp:5;
66                         dev_req_type req_type:2;
67                         dev_req_dir data_dir:1;
68                 } __attribute__ ((packed));
69                 unsigned char bmRequestType;
70         } __attribute__ ((packed));
71         unsigned char bRequest;
72         unsigned short wValue;
73         unsigned short wIndex;
74         unsigned short wLength;
75 } __attribute__ ((packed)) dev_req_t;
76
77 struct usbdev_hc;
78 typedef struct usbdev_hc hci_t;
79
80 struct usbdev;
81 typedef struct usbdev usbdev_t;
82
83 typedef enum { SETUP, IN, OUT } direction_t;
84 typedef enum { CONTROL = 0, ISOCHRONOUS = 1, BULK = 2, INTERRUPT = 3
85 } endpoint_type;
86
87 typedef struct {
88         usbdev_t *dev;
89         int endpoint;
90         direction_t direction;
91         int toggle;
92         int maxpacketsize;
93         endpoint_type type;
94 } endpoint_t;
95
96
97 struct usbdev {
98         hci_t *controller;
99         endpoint_t endpoints[32];
100         int num_endp;
101         int address;            // usb address
102         int hub;                // hub, device is attached to
103         int port;               // port where device is attached
104         int speed;              // 1: lowspeed, 0: fullspeed, 2: highspeed
105         u32 quirks;             // quirks field. got to love usb
106         void *data;
107         u8 *descriptor;
108         u8 *configuration;
109         void (*init) (usbdev_t *dev);
110         void (*destroy) (usbdev_t *dev);
111         void (*poll) (usbdev_t *dev);
112 };
113
114 struct usbdev_hc {
115         struct usbdev_hc *next;
116         pcidev_t bus_address;
117         u32 reg_base;
118         usbdev_t *devices[128]; // dev 0 is root hub, 127 is last addressable
119         void (*start) (hci_t *controller);
120         void (*stop) (hci_t *controller);
121         void (*reset) (hci_t *controller);
122         void (*shutdown) (hci_t *controller);
123         int (*bulk) (endpoint_t *ep, int size, u8 *data, int finalize);
124         int (*control) (usbdev_t *dev, direction_t pid, int dr_length,
125                         void *devreq, int data_length, u8 *data);
126         void* (*create_intr_queue) (endpoint_t *ep, int reqsize, int reqcount, int reqtiming);
127         void (*destroy_intr_queue) (endpoint_t *ep, void *queue);
128         u8* (*poll_intr_queue) (void *queue);
129         void *instance;
130 };
131
132 typedef struct {
133         unsigned char bDescLength;
134         unsigned char bDescriptorType;
135         unsigned char bNbrPorts;
136         union {
137                 struct {
138                         unsigned long logicalPowerSwitchingMode:2;
139                         unsigned long isCompoundDevice:1;
140                         unsigned long overcurrentProtectionMode:2;
141                         unsigned long ttThinkTime:2;
142                         unsigned long arePortIndicatorsSupported:1;
143                         unsigned long:8;
144                 } __attribute__ ((packed));
145                 unsigned short wHubCharacteristics;
146         } __attribute__ ((packed));
147         unsigned char bPowerOn2PwrGood;
148         unsigned char bHubContrCurrent;
149         char DeviceRemovable[];
150 } __attribute__ ((packed)) hub_descriptor_t;
151
152 typedef struct {
153         unsigned char bLength;
154         unsigned char bDescriptorType;
155         unsigned short bcdUSB;
156         unsigned char bDeviceClass;
157         unsigned char bDeviceSubClass;
158         unsigned char bDeviceProtocol;
159         unsigned char bMaxPacketSize0;
160         unsigned short idVendor;
161         unsigned short idProduct;
162         unsigned short bcdDevice;
163         unsigned char iManufacturer;
164         unsigned char iProduct;
165         unsigned char iSerialNumber;
166         unsigned char bNumConfigurations;
167 } __attribute__ ((packed)) device_descriptor_t;
168
169 typedef struct {
170         unsigned char bLength;
171         unsigned char bDescriptorType;
172         unsigned short wTotalLength;
173         unsigned char bNumInterfaces;
174         unsigned char bConfigurationValue;
175         unsigned char iConfiguration;
176         unsigned char bmAttributes;
177         unsigned char bMaxPower;
178 } __attribute__ ((packed)) configuration_descriptor_t;
179
180 typedef struct {
181         unsigned char bLength;
182         unsigned char bDescriptorType;
183         unsigned char bInterfaceNumber;
184         unsigned char bAlternateSetting;
185         unsigned char bNumEndpoints;
186         unsigned char bInterfaceClass;
187         unsigned char bInterfaceSubClass;
188         unsigned char bInterfaceProtocol;
189         unsigned char iInterface;
190 } __attribute__ ((packed)) interface_descriptor_t;
191
192 typedef struct {
193         unsigned char bLength;
194         unsigned char bDescriptorType;
195         unsigned char bEndpointAddress;
196         unsigned char bmAttributes;
197         unsigned short wMaxPacketSize;
198         unsigned char bInterval;
199 } __attribute__ ((packed)) endpoint_descriptor_t;
200
201 typedef struct {
202         unsigned char bLength;
203         unsigned char bDescriptorType;
204         unsigned short bcdHID;
205         unsigned char bCountryCode;
206         unsigned char bNumDescriptors;
207         unsigned char bReportDescriptorType;
208         unsigned short wReportDescriptorLength;
209 } __attribute__ ((packed)) hid_descriptor_t;
210
211 hci_t *new_controller (void);
212 void detach_controller (hci_t *controller);
213 void usb_poll (void);
214 void init_device_entry (hci_t *controller, int num);
215
216 void set_feature (usbdev_t *dev, int endp, int feature, int rtype);
217 void get_status (usbdev_t *dev, int endp, int rtype, int len, void *data);
218 int clear_stall (endpoint_t *ep);
219
220 void usb_nop_init (usbdev_t *dev);
221 void usb_hub_init (usbdev_t *dev);
222 void usb_hid_init (usbdev_t *dev);
223 void usb_msc_init (usbdev_t *dev);
224
225 int set_address (hci_t *controller, int speed);
226
227 u8 *get_descriptor (usbdev_t *dev, unsigned char bmRequestType,
228                     int descType, int descIdx, int langID);
229
230 static inline unsigned char
231 gen_bmRequestType (dev_req_dir dir, dev_req_type type, dev_req_recp recp)
232 {
233         return (dir << 7) | (type << 5) | recp;
234 }
235
236 void usb_detach_device(hci_t *controller, int devno);
237 int usb_attach_device(hci_t *controller, int hubaddress, int port, int speed);
238
239 u32 usb_quirk_check(u16 vendor, u16 device);
240 int usb_interface_check(u16 vendor, u16 device);
241
242 #define USB_QUIRK_MSC_FORCE_PROTO_SCSI          (1 <<  0)
243 #define USB_QUIRK_MSC_FORCE_PROTO_ATAPI         (1 <<  1)
244 #define USB_QUIRK_MSC_FORCE_PROTO_UFI           (1 <<  2)
245 #define USB_QUIRK_MSC_FORCE_PROTO_RBC           (1 <<  3)
246 #define USB_QUIRK_MSC_FORCE_TRANS_BBB           (1 <<  4)
247 #define USB_QUIRK_MSC_FORCE_TRANS_CBI           (1 <<  5)
248 #define USB_QUIRK_MSC_FORCE_TRANS_CBI_I         (1 <<  6)
249 #define USB_QUIRK_MSC_NO_TEST_UNIT_READY        (1 <<  7)
250 #define USB_QUIRK_MSC_SHORT_INQUIRY             (1 <<  8)
251 #define USB_QUIRK_TEST                          (1 << 31)
252 #define USB_QUIRK_NONE                           0
253
254 #ifdef USB_DEBUG
255 # define debug(fmt, ...)        printf(fmt, ##__VA_ARGS__)
256 #else
257 # define debug(fmt, ...)        while (0) { printf(fmt, ##__VA_ARGS__); }
258 #endif
259
260 void usb_fatal(const char *message) __attribute__ ((noreturn));
261 #endif