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 = 0x2d, IN = 0x69, OUT = 0xe1 } pid_t;
84 typedef enum { CONTROL = 0, ISOCHRONOUS = 1, BULK = 2, INTERRUPT = 3
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 lowspeed; // 1 if lowspeed device
108 void (*init) (usbdev_t *dev);
109 void (*destroy) (usbdev_t *dev);
110 void (*poll) (usbdev_t *dev);
114 struct usbdev_hc *next;
115 pcidev_t bus_address;
117 usbdev_t devices[128]; // dev 0 is root hub, 127 is last addressable
118 void (*start) (hci_t *controller);
119 void (*stop) (hci_t *controller);
120 void (*reset) (hci_t *controller);
121 void (*shutdown) (hci_t *controller);
122 int (*packet) (usbdev_t *dev, int endp, int pid, int toggle,
123 int length, u8 *data);
124 int (*bulk) (endpoint_t *ep, int size, u8 *data, int finalize);
125 int (*control) (usbdev_t *dev, pid_t pid, int dr_length,
126 void *devreq, int data_length, u8 *data);
131 unsigned char bDescLength;
132 unsigned char bDescriptorType;
133 unsigned char bNbrPorts;
136 unsigned long logicalPowerSwitchingMode:2;
137 unsigned long isCompoundDevice:1;
138 unsigned long overcurrentProtectionMode:2;
139 unsigned long ttThinkTime:2;
140 unsigned long arePortIndicatorsSupported:1;
142 } __attribute__ ((packed));
143 unsigned short wHubCharacteristics;
144 } __attribute__ ((packed));
145 unsigned char bPowerOn2PwrGood;
146 unsigned char bHubContrCurrent;
147 char DeviceRemovable[];
148 } __attribute__ ((packed)) hub_descriptor_t;
151 unsigned char bLength;
152 unsigned char bDescriptorType;
153 unsigned short bcdUSB;
154 unsigned char bDeviceClass;
155 unsigned char bDeviceSubClass;
156 unsigned char bDeviceProtocol;
157 unsigned char bMaxPacketSize0;
158 unsigned short idVendor;
159 unsigned short idProduct;
160 unsigned short bcdDevice;
161 unsigned char iManufacturer;
162 unsigned char iProduct;
163 unsigned char iSerialNumber;
164 unsigned char bNumConfigurations;
165 } __attribute__ ((packed)) device_descriptor_t;
168 unsigned char bLength;
169 unsigned char bDescriptorType;
170 unsigned short wTotalLength;
171 unsigned char bNumInterfaces;
172 unsigned char bConfigurationValue;
173 unsigned char iConfiguration;
174 unsigned char bmAttributes;
175 unsigned char bMaxPower;
176 } __attribute__ ((packed)) configuration_descriptor_t;
179 unsigned char bLength;
180 unsigned char bDescriptorType;
181 unsigned char bInterfaceNumber;
182 unsigned char bAlternateSetting;
183 unsigned char bNumEndpoints;
184 unsigned char bInterfaceClass;
185 unsigned char bInterfaceSubClass;
186 unsigned char bInterfaceProtocol;
187 unsigned char iInterface;
188 } __attribute__ ((packed)) interface_descriptor_t;
191 unsigned char bLength;
192 unsigned char bDescriptorType;
193 unsigned char bEndpointAddress;
194 unsigned char bmAttributes;
195 unsigned short wMaxPacketSize;
196 unsigned char bInterval;
197 } __attribute__ ((packed)) endpoint_descriptor_t;
199 hci_t *new_controller (void);
200 void detach_controller (hci_t *controller);
201 void usb_poll (void);
202 void init_device_entry (hci_t *controller, int num);
204 void set_feature (usbdev_t *dev, int endp, int feature, int rtype);
205 void get_status (usbdev_t *dev, int endp, int rtype, int len, void *data);
206 int clear_stall (endpoint_t *ep);
208 void usb_nop_init (usbdev_t *dev);
209 void usb_hub_init (usbdev_t *dev);
210 void usb_hid_init (usbdev_t *dev);
211 void usb_msc_init (usbdev_t *dev);
213 int set_address (hci_t *controller, int lowspeed);
215 u8 *get_descriptor (usbdev_t *dev, unsigned char bmRequestType,
216 int descType, int descIdx, int langID);
218 static inline unsigned char
219 gen_bmRequestType (dev_req_dir dir, dev_req_type type, dev_req_recp recp)
221 return (dir << 7) | (type << 5) | recp;