1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#include <libpayload-config.h>
33#include <usb/usb.h>
34
35hci_t *usb_hcs = 0;
36
37hci_t *
38new_controller (void)
39{
40 hci_t *controller = malloc (sizeof (hci_t));
41
42 if (controller) {
43
44 controller->next = usb_hcs;
45 usb_hcs = controller;
46
47 }
48
49 return controller;
50}
51
52void
53detach_controller (hci_t *controller)
54{
55 if (controller == NULL)
56 return;
57 if (usb_hcs == controller) {
58 usb_hcs = controller->next;
59 } else {
60 hci_t *it = usb_hcs;
61 while (it != NULL) {
62 if (it->next == controller) {
63 it->next = controller->next;
64 return;
65 }
66 }
67 }
68}
69
70
71
72
73void
74usb_poll (void)
75{
76 if (usb_hcs == 0)
77 return;
78 hci_t *controller = usb_hcs;
79 while (controller != 0) {
80 int i;
81 for (i = 0; i < 128; i++) {
82 if (controller->devices[i] != 0) {
83 controller->devices[i]->poll (controller->devices[i]);
84 }
85 }
86 controller = controller->next;
87 }
88}
89
90void
91init_device_entry (hci_t *controller, int i)
92{
93 if (controller->devices[i] != 0)
94 printf("warning: device %d reassigned?\n", i);
95 controller->devices[i] = malloc(sizeof(usbdev_t));
96 controller->devices[i]->controller = controller;
97 controller->devices[i]->address = -1;
98 controller->devices[i]->hub = -1;
99 controller->devices[i]->port = -1;
100 controller->devices[i]->init = usb_nop_init;
101 controller->devices[i]->init (controller->devices[i]);
102}
103
104void
105set_feature (usbdev_t *dev, int endp, int feature, int rtype)
106{
107 dev_req_t dr;
108
109 dr.bmRequestType = rtype;
110 dr.data_dir = host_to_device;
111 dr.bRequest = SET_FEATURE;
112 dr.wValue = feature;
113 dr.wIndex = endp;
114 dr.wLength = 0;
115 dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0);
116}
117
118void
119get_status (usbdev_t *dev, int intf, int rtype, int len, void *data)
120{
121 dev_req_t dr;
122
123 dr.bmRequestType = rtype;
124 dr.data_dir = device_to_host;
125 dr.bRequest = GET_STATUS;
126 dr.wValue = 0;
127 dr.wIndex = intf;
128 dr.wLength = len;
129 dev->controller->control (dev, IN, sizeof (dr), &dr, len, data);
130}
131
132u8 *
133get_descriptor (usbdev_t *dev, unsigned char bmRequestType, int descType,
134 int descIdx, int langID)
135{
136 u8 buf[8];
137 u8 *result;
138 dev_req_t dr;
139 int size;
140
141 dr.bmRequestType = bmRequestType;
142 dr.data_dir = device_to_host;
143 dr.bRequest = GET_DESCRIPTOR;
144 dr.wValue = (descType << 8) | descIdx;
145 dr.wIndex = langID;
146 dr.wLength = 8;
147 if (dev->controller->control (dev, IN, sizeof (dr), &dr, 8, buf)) {
148 printf ("getting descriptor size (type %x) failed\n",
149 descType);
150 }
151
152 if (descType == 1) {
153 device_descriptor_t *dd = (device_descriptor_t *) buf;
154 debug ("maxPacketSize0: %x\n", dd->bMaxPacketSize0);
155 if (dd->bMaxPacketSize0 != 0)
156 dev->endpoints[0].maxpacketsize = dd->bMaxPacketSize0;
157 }
158
159
160
161
162 size = buf[0];
163 if (buf[1] == 2) {
164 int realsize = ((unsigned short *) (buf + 2))[0];
165 size = realsize;
166 }
167 result = malloc (size);
168 memset (result, 0, size);
169 dr.wLength = size;
170 if (dev->controller->
171 control (dev, IN, sizeof (dr), &dr, size, result)) {
172 printf ("getting descriptor (type %x, size %x) failed\n",
173 descType, size);
174 }
175
176 return result;
177}
178
179void
180set_configuration (usbdev_t *dev)
181{
182 dev_req_t dr;
183
184 dr.bmRequestType = 0;
185 dr.bRequest = SET_CONFIGURATION;
186 dr.wValue = dev->configuration[5];
187 dr.wIndex = 0;
188 dr.wLength = 0;
189 dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0);
190}
191
192int
193clear_stall (endpoint_t *ep)
194{
195 usbdev_t *dev = ep->dev;
196 int endp = ep->endpoint;
197 dev_req_t dr;
198
199 dr.bmRequestType = 0;
200 if (endp != 0) {
201 dr.req_recp = endp_recp;
202 }
203 dr.bRequest = CLEAR_FEATURE;
204 dr.wValue = ENDPOINT_HALT;
205 dr.wIndex = endp;
206 dr.wLength = 0;
207 dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0);
208 ep->toggle = 0;
209 return 0;
210}
211
212
213static int
214get_free_address (hci_t *controller)
215{
216 int i;
217 for (i = 1; i < 128; i++) {
218 if (controller->devices[i] == 0)
219 return i;
220 }
221 printf ("no free address found\n");
222 return -1;
223}
224
225int
226set_address (hci_t *controller, int speed)
227{
228 int adr = get_free_address (controller);
229 dev_req_t dr;
230 configuration_descriptor_t *cd;
231 device_descriptor_t *dd;
232
233 memset (&dr, 0, sizeof (dr));
234 dr.data_dir = host_to_device;
235 dr.req_type = standard_type;
236 dr.req_recp = dev_recp;
237 dr.bRequest = SET_ADDRESS;
238 dr.wValue = adr;
239 dr.wIndex = 0;
240 dr.wLength = 0;
241
242 init_device_entry(controller, adr);
243 usbdev_t *dev = controller->devices[adr];
244
245 dev->address = 0;
246 dev->speed = speed;
247 dev->endpoints[0].dev = dev;
248 dev->endpoints[0].endpoint = 0;
249 dev->endpoints[0].maxpacketsize = 8;
250 dev->endpoints[0].toggle = 0;
251 dev->endpoints[0].direction = SETUP;
252 mdelay (50);
253 if (dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0)) {
254 printf ("set_address failed\n");
255 return -1;
256 }
257 mdelay (50);
258 dev->address = adr;
259 dev->descriptor = get_descriptor (dev, gen_bmRequestType
260 (device_to_host, standard_type, dev_recp), 1, 0, 0);
261 dd = (device_descriptor_t *) dev->descriptor;
262
263 printf ("device 0x%04x:0x%04x is USB %x.%x ",
264 dd->idVendor, dd->idProduct,
265 dd->bcdUSB >> 8, dd->bcdUSB & 0xff);
266 dev->quirks = usb_quirk_check(dd->idVendor, dd->idProduct);
267
268 debug ("\ndevice has %x configurations\n", dd->bNumConfigurations);
269 if (dd->bNumConfigurations == 0) {
270
271 printf ("... no usable configuration!\n");
272 dev->address = 0;
273 return -1;
274 }
275
276 dev->configuration = get_descriptor (dev, gen_bmRequestType
277 (device_to_host, standard_type, dev_recp), 2, 0, 0);
278 cd = (configuration_descriptor_t *) dev->configuration;
279 set_configuration (dev);
280 interface_descriptor_t *interface =
281 (interface_descriptor_t *) (((char *) cd) + cd->bLength);
282 {
283 int i;
284 int num = cd->bNumInterfaces;
285 interface_descriptor_t *current = interface;
286 debug ("device has %x interfaces\n", num);
287 if (num > 1) {
288 int interfaces = usb_interface_check(dd->idVendor, dd->idProduct);
289 if (interfaces) {
290
291 num = interfaces;
292 } else {
293
294 printf ("\nNOTICE: This driver defaults to using the first interface.\n"
295 "This might be the wrong choice and lead to limited functionality\n"
296 "of the device. Please report such a case to coreboot@coreboot.org\n"
297 "as you might be the first.\n");
298
299
300
301
302
303 num = (num > 1) ? 1 : num;
304 }
305 }
306 for (i = 0; i < num; i++) {
307 int j;
308 debug (" #%x has %x endpoints, interface %x:%x, protocol %x\n",
309 current->bInterfaceNumber, current->bNumEndpoints, current->bInterfaceClass, current->bInterfaceSubClass, current->bInterfaceProtocol);
310 endpoint_descriptor_t *endp =
311 (endpoint_descriptor_t *) (((char *) current)
312 + current->bLength);
313 if (interface->bInterfaceClass == 0x3)
314 endp = (endpoint_descriptor_t *) (((char *) endp) + ((char *) endp)[0]);
315 memset (dev->endpoints, 0, sizeof (dev->endpoints));
316 dev->num_endp = 1;
317 dev->endpoints[0].dev = dev;
318 dev->endpoints[0].maxpacketsize = dd->bMaxPacketSize0;
319 dev->endpoints[0].direction = SETUP;
320 dev->endpoints[0].type = CONTROL;
321 for (j = 1; j <= current->bNumEndpoints; j++) {
322#ifdef USB_DEBUG
323 static const char *transfertypes[4] = {
324 "control", "isochronous", "bulk", "interrupt"
325 };
326 debug (" #%x: Endpoint %x (%s), max packet size %x, type %s\n", j, endp->bEndpointAddress & 0x7f, ((endp->bEndpointAddress & 0x80) != 0) ? "in" : "out", endp->wMaxPacketSize, transfertypes[endp->bmAttributes]);
327#endif
328 endpoint_t *ep =
329 &dev->endpoints[dev->num_endp++];
330 ep->dev = dev;
331 ep->endpoint = endp->bEndpointAddress;
332 ep->toggle = 0;
333 ep->maxpacketsize = endp->wMaxPacketSize;
334 ep->direction =
335 ((endp->bEndpointAddress & 0x80) ==
336 0) ? OUT : IN;
337 ep->type = endp->bmAttributes;
338 endp = (endpoint_descriptor_t
339 *) (((char *) endp) + endp->bLength);
340 }
341 current = (interface_descriptor_t *) endp;
342 }
343 }
344
345 int class = dd->bDeviceClass;
346 if (class == 0)
347 class = interface->bInterfaceClass;
348
349 enum {
350 audio_device = 0x01,
351 comm_device = 0x02,
352 hid_device = 0x03,
353 physical_device = 0x05,
354 imaging_device = 0x06,
355 printer_device = 0x07,
356 msc_device = 0x08,
357 hub_device = 0x09,
358 cdc_device = 0x0a,
359 ccid_device = 0x0b,
360 security_device = 0x0d,
361 video_device = 0x0e,
362 healthcare_device = 0x0f,
363 diagnostic_device = 0xdc,
364 wireless_device = 0xe0,
365 misc_device = 0xef,
366 };
367
368 switch (class) {
369 case audio_device:
370 printf("(Audio)\n");
371 break;
372 case comm_device:
373 printf("(Communication)\n");
374 break;
375 case hid_device:
376 printf ("(HID)\n");
377#ifdef CONFIG_USB_HID
378 controller->devices[adr]->init = usb_hid_init;
379#else
380 printf ("NOTICE: USB HID support not compiled in\n");
381#endif
382 break;
383 case physical_device:
384 printf("(Physical)\n");
385 break;
386 case imaging_device:
387 printf("(Camera)\n");
388 break;
389 case printer_device:
390 printf("(Printer)\n");
391 break;
392 case msc_device:
393 printf ("(MSC)\n");
394#ifdef CONFIG_USB_MSC
395 controller->devices[adr]->init = usb_msc_init;
396#else
397 printf ("NOTICE: USB MSC support not compiled in\n");
398#endif
399 break;
400 case hub_device:
401 printf ("(Hub)\n");
402#ifdef CONFIG_USB_HUB
403 controller->devices[adr]->init = usb_hub_init;
404#else
405 printf ("NOTICE: USB hub support not compiled in.\n");
406#endif
407 break;
408 case cdc_device:
409 printf("(CDC)\n");
410 break;
411 case ccid_device:
412 printf ("(Smart Card / CCID)\n");
413 break;
414 case security_device:
415 printf("(Content Security)\n");
416 break;
417 case video_device:
418 printf("(Video)\n");
419 break;
420 case healthcare_device:
421 printf("(Healthcare)\n");
422 break;
423 case diagnostic_device:
424 printf("(Diagnostic)\n");
425 break;
426 case wireless_device:
427 printf("(Wireless)\n");
428 break;
429 default:
430 printf ("(unsupported class %x)\n", class);
431 break;
432 }
433 return adr;
434}
435
436void
437usb_detach_device(hci_t *controller, int devno)
438{
439 controller->devices[devno]->destroy (controller->devices[devno]);
440 free(controller->devices[devno]);
441 controller->devices[devno] = 0;
442}
443
444int
445usb_attach_device(hci_t *controller, int hubaddress, int port, int speed)
446{
447 static const char* speeds[] = { "full", "low", "high" };
448 printf ("%sspeed device\n", (speed <= 2) ? speeds[speed] : "invalid value - no");
449 int newdev = set_address (controller, speed);
450 if (newdev == -1)
451 return -1;
452 usbdev_t *newdev_t = controller->devices[newdev];
453
454 newdev_t->address = newdev;
455 newdev_t->hub = hubaddress;
456 newdev_t->port = port;
457
458 newdev_t->init (newdev_t);
459 return newdev;
460}
461
462void
463usb_fatal (const char *message)
464{
465 printf(message);
466 for (;;) ;
467}
468