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