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
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
32 #include <libpayload.h>
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 =
39 typedef enum { dev_recp = 0, iface_recp = 1, endp_recp = 2, other_recp = 3
49 GET_CONFIGURATION = 8,
50 SET_CONFIGURATION = 9,
58 DEVICE_REMOTE_WAKEUP = 1,
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;
78 typedef struct usbdev_hc hci_t;
81 typedef struct usbdev usbdev_t;
83 typedef enum { SETUP, IN, OUT } direction_t;
84 typedef enum { CONTROL = 0, ISOCHRONOUS = 1, BULK = 2, INTERRUPT = 3
90 direction_t direction;
99 endpoint_t endpoints[32];
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
109 void (*init) (usbdev_t *dev);
110 void (*destroy) (usbdev_t *dev);
111 void (*poll) (usbdev_t *dev);
115 struct usbdev_hc *next;
116 pcidev_t bus_address;
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);
133 unsigned char bDescLength;
134 unsigned char bDescriptorType;
135 unsigned char bNbrPorts;
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;
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;
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;
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;
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;
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;
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;
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);
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);
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);
225 int set_address (hci_t *controller, int speed);
227 u8 *get_descriptor (usbdev_t *dev, unsigned char bmRequestType,
228 int descType, int descIdx, int langID);
230 static inline unsigned char
231 gen_bmRequestType (dev_req_dir dir, dev_req_type type, dev_req_recp recp)
233 return (dir << 7) | (type << 5) | recp;
236 void usb_detach_device(hci_t *controller, int devno);
237 int usb_attach_device(hci_t *controller, int hubaddress, int port, int speed);
239 u32 usb_quirk_check(u16 vendor, u16 device);
240 int usb_interface_check(u16 vendor, u16 device);
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
255 # define debug(fmt, ...) printf(fmt, ##__VA_ARGS__)
257 # define debug(fmt, ...) while (0) { printf(fmt, ##__VA_ARGS__); }
260 void usb_fatal(const char *message) __attribute__ ((noreturn));