usb-bug-fixes.patch (applied cleanly)
[pintos-anon] / src / devices / usb.c
1 #include "devices/usb.h"
2 #include "devices/usb_hub.h"
3 #include "threads/synch.h"
4 #include "threads/malloc.h"
5 #include "devices/timer.h"
6 #include <kernel/bitmap.h>
7 #include <ctype.h>
8 #include <string.h>
9 #include <stdio.h>
10
11 #define ADDRS_PER_HOST          127     /* number of configurable addresses */
12 #define ADDR_DEFAULT            0       /* default configuration address */
13 #define ADDR_FIRST              1       /* first configurable address */
14
15 /** sometimes used for ''value' */
16 /* used in desc_header */
17 #define SETUP_DESC_DEVICE       1
18 #define SETUP_DESC_CONFIG       2
19 #define SETUP_DESC_STRING       3
20 #define SETUP_DESC_IFACE        4
21 #define SETUP_DESC_ENDPOINT     5
22 #define SETUP_DESC_DEVQUAL      6
23 #define SETUP_DESC_SPDCONFIG    7
24 #define SETUP_DESC_IFACEPWR     8
25
26 #pragma pack(1)
27 struct desc_header
28 {
29   uint8_t length;
30   uint8_t type;
31 };
32
33 /**
34  * More details can be found in chapter 9 of the usb1.1 spec
35  */
36
37 struct device_descriptor
38 {
39   struct desc_header hdr;
40   uint16_t usb_spec;
41   uint8_t dev_class;
42   uint8_t dev_subclass;
43   uint8_t dev_proto;
44   uint8_t max_pktsz;
45   uint16_t vendor_id;
46   uint16_t product_id;
47   uint16_t device_id;
48   uint8_t manufacturer;
49   uint8_t product;
50   uint8_t serial;
51   uint8_t num_configs;
52 };
53
54 struct device_qualifier
55 {
56   uint16_t usb_spec;
57   uint8_t dev_class;
58   uint8_t dev_subclass;
59   uint8_t dev_proto;
60   uint8_t max_pktsz;
61   uint8_t num_configs;
62   uint8_t resv;
63 };
64
65 struct config_descriptor
66 {
67   struct desc_header hdr;
68   uint16_t total_length;
69   uint8_t num_ifaces;
70   uint8_t config_val;
71   uint8_t config_desc;
72   uint8_t attributes;
73   uint8_t max_power;
74 };
75
76 struct interface_descriptor
77 {
78   struct desc_header hdr;
79   uint8_t iface_num;
80   uint8_t alt_setting;
81   uint8_t num_endpoints;
82   uint8_t iface_class;
83   uint8_t iface_subclass;
84   uint8_t iface_proto;
85   uint8_t iface_desc;
86 };
87
88 struct endpoint_descriptor
89 {
90   struct desc_header hdr;
91   /* end point address */
92   uint8_t endpoint_num:4;
93   uint8_t resv1:3;
94   uint8_t direction:1;
95
96   /* attributes */
97   uint8_t transfer:2;
98   uint8_t synch:2;
99   uint8_t usage:2;
100   uint8_t resv2:2;
101
102   uint16_t max_pktsz;
103   uint8_t interval;
104
105 };
106
107 #pragma pack()
108
109 #define USB_CLASS_HUB           0x09
110 struct host
111 {
112   struct usb_host *dev;         /* host driver */
113   host_info info;               /* private to host */
114   struct bitmap *usb_dev_addrs; /* addrs used on device */
115   struct list host_usb_devs;    /* usb devices on host */
116   struct list_elem peers;       /* other hosts on system */
117 };
118
119 struct class
120 {
121   struct usb_class *dev;        /* class driver */
122   struct list usb_ifaces;       /* usb devices on class */
123   struct list_elem peers;
124 };
125
126 static struct list usb_dev_list;        /* list of all usb devices */
127 static struct list class_list;  /* list of all classes */
128 static struct list host_list;   /* list of all hosts on system */
129 static struct lock usb_sys_lock;        /* big usb lock */
130
131 #define usb_lock()              lock_acquire(&usb_sys_lock)
132 #define usb_unlock()            lock_release(&usb_sys_lock)
133
134 static void usb_scan_devices (struct host *h);
135 static struct usb_dev *usb_configure_default (struct host *h);
136 static char *usb_get_string (struct usb_dev *d, int ndx);
137 static struct class *usb_get_class_by_id (int id);
138 static void usb_setup_dev_addr (struct usb_dev *dev);
139 static void usb_config_dev (struct usb_dev *dev, int config_val);
140 static int usb_load_config (struct usb_dev *dev, int idx);
141 static void usb_attach_interfaces (struct usb_dev *dev);
142 static void usb_apply_class_to_interfaces (struct class *c);
143 static size_t wchar_to_ascii (char *dst, const char *src);
144
145 extern void uhci_init (void);
146 extern void ehci_init (void);
147
148 void
149 usb_init (void)
150 {
151   list_init (&host_list);
152   list_init (&class_list);
153   list_init (&usb_dev_list);
154   lock_init (&usb_sys_lock);
155
156   usb_hub_init ();
157
158   /* add usb hosts */
159   printf ("Initializing EHCI\n");
160   ehci_init ();
161   printf ("Initializing UHCI\n");
162   uhci_init ();
163 }
164
165 /* add host controller device to usb layer */
166 void
167 usb_register_host (struct usb_host *uh, host_info info)
168 {
169   struct host *h;
170
171   h = malloc (sizeof (struct host));
172   h->dev = uh;
173   h->info = info;
174   h->usb_dev_addrs = bitmap_create (ADDRS_PER_HOST);
175   list_init (&h->host_usb_devs);
176
177   usb_lock ();
178   list_push_back (&host_list, &h->peers);
179   usb_unlock ();
180
181   usb_scan_devices (h);
182 }
183
184 int
185 usb_register_class (struct usb_class *uc)
186 {
187   struct class *c;
188
189   usb_lock ();
190
191   /* check to make sure class is not in list */
192   if (usb_get_class_by_id (uc->class_id) != NULL)
193     {
194       usb_unlock ();
195       return -1;
196     }
197
198
199   /* add class to class list */
200   c = malloc (sizeof (struct class));
201   c->dev = uc;
202   list_init (&c->usb_ifaces);
203   list_push_back (&class_list, &c->peers);
204
205   usb_apply_class_to_interfaces (c);
206
207   usb_unlock ();
208
209   return 0;
210 }
211
212 static void
213 usb_scan_devices (struct host *h)
214 {
215   /* scan until there all devices using default pipe are configured */
216
217   printf ("USB: scanning devices...\n");
218   while (1)
219     {
220       struct usb_dev *dev;
221
222       dev = usb_configure_default (h);
223       if (dev == NULL)
224         break;
225
226       if (dev->ignore_device == false)
227         printf ("USB Device %d: %s (%s)\n",
228                 dev->addr, dev->product, dev->manufacturer);
229
230       list_push_back (&h->host_usb_devs, &dev->host_peers);
231       list_push_back (&usb_dev_list, &dev->sys_peers);
232       usb_attach_interfaces (dev);
233     }
234 }
235
236
237 static struct usb_dev *
238 usb_configure_default (struct host *h)
239 {
240   struct usb_dev *dev;
241   struct usb_setup_pkt sp;
242   struct device_descriptor dd;
243   host_dev_info hi;
244   host_eop_info cfg_eop;
245   bool ignore_device = false;
246   int err;
247   int config_val;
248   size_t size;
249
250   hi = h->dev->create_dev_channel (h->info, ADDR_DEFAULT, USB_VERSION_1_1);
251   cfg_eop = h->dev->create_eop (hi, 0, 8);
252
253   /* determine device descriptor */
254   sp.recipient = USB_SETUP_RECIP_DEV;
255   sp.type = USB_SETUP_TYPE_STD;
256   sp.direction = 1;
257   sp.request = REQ_STD_GET_DESC;
258   sp.value = SETUP_DESC_DEVICE << 8;
259   sp.index = 0;
260   sp.length = 8;
261
262   size = sp.length;
263   err = h->dev->dev_control (cfg_eop, &sp, &dd, &size); 
264   if (err)
265     {
266       /* FIXME: free memory. */
267       printf ("err=%d: no more devices\n", err);
268       return NULL;
269     }
270
271   if (dd.usb_spec == USB_VERSION_1_0)
272     {
273       /* USB 1.0 devices have strict schedule requirements not yet supported */
274       printf ("USB 1.0 device detected - skipping\n");
275     }
276   if (dd.num_configs == 0)
277     ignore_device = true;
278
279   h->dev->remove_eop (cfg_eop);
280   cfg_eop = h->dev->create_eop (hi, 0, dd.max_pktsz);
281
282   sp.length = sizeof dd;
283   size = sp.length;
284   err = h->dev->dev_control (cfg_eop, &sp, &dd, &size);
285   if (err)
286     {
287       /* FIXME: free memory. */
288       return NULL;
289     }
290
291   /* device exists - create device structure */
292   dev = malloc (sizeof (struct usb_dev));
293   memset (dev, 0, sizeof (struct usb_dev));
294   list_init (&dev->interfaces);
295
296   dev->ignore_device = ignore_device;
297   dev->h_dev = hi;
298   dev->h_cfg_eop = cfg_eop;
299
300   dev->cfg_eop.h_eop = cfg_eop;
301
302   dev->usb_version = dd.usb_spec;
303   dev->default_iface.class_id = dd.dev_class;
304   dev->default_iface.subclass_id = dd.dev_subclass;
305   dev->default_iface.iface_num = 0;
306   dev->default_iface.proto = dd.dev_proto;
307   dev->default_iface.class = NULL;
308   dev->default_iface.c_info = NULL;
309   dev->default_iface.dev = dev;
310
311   dev->cfg_eop.iface = &dev->default_iface;
312   dev->cfg_eop.max_pkt = dd.max_pktsz;
313   dev->cfg_eop.eop = 0;
314
315   dev->host = h;
316
317   dev->vendor_id = dd.vendor_id;
318   dev->product_id = dd.product_id;
319   dev->device_id = dd.device_id;
320
321   if (ignore_device == false)
322     {
323       dev->product = usb_get_string (dev, dd.product);
324       dev->manufacturer = usb_get_string (dev, dd.manufacturer);
325       printf ("product=%s manufacturer=%s\n", dev->product, dev->manufacturer);
326     }
327
328   config_val = -123;
329   /* read in configuration data if there are configurations available */
330   /* (which there should be...) */
331   if (dd.num_configs > 0 && ignore_device == false)
332     {
333       config_val = usb_load_config (dev, 0);
334       if (config_val < 0)
335         {
336           printf
337             ("USB: Invalid configuration value %d on '%s (%s)' (%x,%x,%x)\n",
338              config_val, dev->product, dev->manufacturer, dev->vendor_id,
339              dev->product_id, dev->device_id);
340         }
341     }
342
343   usb_setup_dev_addr (dev);
344
345   usb_config_dev (dev, (config_val < 0) ? 1 : config_val);
346
347   return dev;
348 }
349
350 /**
351  * Load in data for 'idx' configuration into device structure
352  * XXX support multiple configurations
353  */
354 static int
355 usb_load_config (struct usb_dev *dev, int idx)
356 {
357   struct usb_setup_pkt sp;
358   struct config_descriptor *cd;
359   struct host *h;
360   host_eop_info cfg;
361   void *ptr;
362   int config_val, err;
363   size_t size;
364   uint8_t data[256];
365   int i;
366
367   h = dev->host;
368   cfg = dev->h_cfg_eop;
369
370   sp.recipient = USB_SETUP_RECIP_DEV;
371   sp.type = USB_SETUP_TYPE_STD;
372   sp.direction = 1;
373   sp.request = REQ_STD_GET_DESC;
374   sp.value = SETUP_DESC_CONFIG << 8 | idx;
375   sp.index = 0;
376   sp.length = sizeof data;
377   cd = (struct config_descriptor *) data;
378
379   size = sp.length;
380   err = h->dev->dev_control (cfg, &sp, data, &size);
381   if (err != USB_HOST_ERR_NONE)
382     {
383       printf ("USB: Could not setup GET descriptor\n");
384       return -err;
385     }
386
387   if (size < sizeof *cd || cd->hdr.type != SETUP_DESC_CONFIG)
388     {
389       printf ("USB: Invalid descriptor\n");
390       return -1;
391     }
392
393   if (size < cd->total_length) 
394     {
395       printf ("USB: configuration data too long\n");
396       return -1;
397     }
398
399   dev->pwr = cd->max_power;
400
401   /* interface information comes right after config data */
402   /* scan interfaces */
403   ptr = data + sizeof (struct config_descriptor);
404
405   for (i = 0; i < cd->num_ifaces; i++)
406     {
407       struct interface_descriptor *iface;
408       struct usb_iface *ui;
409       int j;
410
411       iface = ptr;
412       if (iface->hdr.type != SETUP_DESC_IFACE)
413         {
414           hex_dump (0, iface, 64, false);
415           PANIC ("Expected %d, found %d\n", SETUP_DESC_IFACE,
416                  iface->hdr.type);
417         }
418
419       ui = malloc (sizeof (struct usb_iface));
420       ui->class_id = iface->iface_class;
421       ui->subclass_id = iface->iface_subclass;
422       ui->iface_num = iface->iface_num;
423       ui->proto = iface->iface_proto;
424       ui->class = NULL;
425       ui->c_info = NULL;
426       ui->dev = dev;
427       list_init (&ui->endpoints);
428
429       /* endpoint data comes after interfaces */
430       /* scan endpoints */
431       ptr += sizeof (struct interface_descriptor);
432       for (j = 0; j < iface->num_endpoints;
433            j++, ptr += sizeof (struct endpoint_descriptor))
434         {
435           struct usb_endpoint *ue;
436           struct endpoint_descriptor *ed;
437
438           ed = ptr;
439
440           ue = malloc (sizeof (struct usb_endpoint));
441           ue->eop = ed->endpoint_num;
442           ue->direction = ed->direction;
443           ue->attr = ed->transfer;
444           ue->max_pkt = ed->max_pktsz;
445           ue->interval = ed->interval;
446           ue->iface = ui;
447           ue->h_eop = h->dev->create_eop (dev->h_dev, ue->eop, ue->max_pkt);
448
449           list_push_back (&ui->endpoints, &ue->peers);
450         }
451
452       list_push_back (&dev->interfaces, &ui->peers);
453     }
454
455   config_val = cd->config_val;
456
457   return config_val;
458 }
459
460 /**
461  * Set USB device configuration to desired configuration value
462  */
463 static void
464 usb_config_dev (struct usb_dev *dev, int config_val)
465 {
466   struct usb_setup_pkt sp;
467   struct host *h;
468   host_eop_info cfg;
469   int err;
470
471   h = dev->host;
472   cfg = dev->h_cfg_eop;
473
474   sp.recipient = USB_SETUP_RECIP_DEV;
475   sp.type = USB_SETUP_TYPE_STD;
476   sp.direction = 0;
477   sp.request = REQ_STD_SET_CONFIG;
478   sp.value = config_val;
479   sp.index = 0;
480   sp.length = 0;
481   err = h->dev->dev_control (cfg, &sp, 0, NULL);
482   if (err != USB_HOST_ERR_NONE)
483     PANIC ("USB: Could not configure device (err=%d)", err);
484 }
485
486 /**
487  * Set a device address to something other than the default pipe 
488  */
489 static void
490 usb_setup_dev_addr (struct usb_dev *dev)
491 {
492   struct usb_setup_pkt sp;
493   struct host *h;
494   host_eop_info cfg;
495   int err;
496
497   ASSERT (dev->addr == 0);
498
499   h = dev->host;
500   cfg = dev->h_cfg_eop;
501
502   dev->addr = bitmap_scan_and_flip (h->usb_dev_addrs, 1, 1, false);
503
504   sp.recipient = USB_SETUP_RECIP_DEV;
505   sp.type = USB_SETUP_TYPE_STD;
506   sp.direction = 0;
507   sp.request = REQ_STD_SET_ADDRESS;
508   sp.value = dev->addr;
509   sp.index = 0;
510   sp.length = 0;
511   err = h->dev->dev_control (cfg, &sp, 0, NULL);
512   if (err != USB_HOST_ERR_NONE)
513     {
514       PANIC ("USB: Error on setting device address (err = %d)\n", err);
515     }
516
517   h->dev->modify_dev_channel (dev->h_dev, dev->addr, dev->usb_version);
518 }
519
520 #define MAX_USB_STR     128
521 /* read string by string descriptor index from usb device */
522 static char *
523 usb_get_string (struct usb_dev *udev, int ndx)
524 {
525   struct usb_setup_pkt sp;
526   char str[MAX_USB_STR + 1];
527   char *ret;
528   size_t size;
529   int err;
530
531   sp.recipient = USB_SETUP_RECIP_DEV;
532   sp.type = USB_SETUP_TYPE_STD;
533   sp.direction = 1;
534   sp.request = REQ_STD_GET_DESC;
535   sp.value = (SETUP_DESC_STRING << 8) | ndx;
536   sp.index = 0;
537   size = sp.length = MAX_USB_STR;
538   err = udev->host->dev->dev_control (udev->h_cfg_eop, &sp, str, &size);
539   if (err)
540     return NULL;
541
542   /* some devices don't respect the string descriptor length value (str[0]) 
543    * and just send any old value they want, so we can't use it */
544   str[size] = '\0';
545
546   /* usb uses wchars for strings, convert to ASCII */
547   wchar_to_ascii (str, str + 2);
548   ret = malloc (strlen (str) + 1);
549   if (ret != NULL)
550     strlcpy (ret, str, MAX_USB_STR);
551   return ret;
552 }
553
554 static struct class *
555 usb_get_class_by_id (int id)
556 {
557   struct list_elem *li;
558
559   li = list_begin (&class_list);
560   while (li != list_end (&class_list))
561     {
562       struct class *c;
563       c = list_entry (li, struct class, peers);
564       if (c->dev->class_id == id)
565         return c;
566       li = list_next (li);
567     }
568
569   return NULL;
570 }
571
572 /**
573  * Asssociate interfaces on a device with their respective device classes
574  */
575 static void
576 usb_attach_interfaces (struct usb_dev *dev)
577 {
578
579   struct list_elem *li;
580   li = list_begin (&dev->interfaces);
581   while (li != list_end (&dev->interfaces))
582     {
583       struct class *cl;
584       struct usb_iface *ui;
585
586       ui = list_entry (li, struct usb_iface, peers);
587       li = list_next (li);
588       cl = usb_get_class_by_id (ui->class_id);
589
590       /* no matching class? try next interface */
591       if (cl == NULL)
592         continue;
593
594       ui->c_info = cl->dev->attached (ui);
595       /* did class driver initialize it OK? */
596       if (ui->c_info != NULL)
597         {
598           /* yes, add to list of usable interfaces */
599           list_push_back (&cl->usb_ifaces, &ui->class_peers);
600           ui->class = cl;
601         }
602     }
603 }
604
605 /**
606  * Scan all interfaces for interfaces that match class's class id
607  * Attach interfaces that match
608  */
609 static void
610 usb_apply_class_to_interfaces (struct class *c)
611 {
612   struct list_elem *li;
613
614   li = list_begin (&usb_dev_list);
615   while (li != list_end (&usb_dev_list))
616     {
617       struct usb_dev *ud;
618       struct list_elem *lii;
619
620       ud = list_entry (li, struct usb_dev, sys_peers);
621
622       lii = list_begin (&ud->interfaces);
623       while (lii != list_end (&ud->interfaces))
624         {
625           struct usb_iface *ui;
626
627           ui = list_entry (lii, struct usb_iface, peers);
628
629           lii = list_next (lii);
630           if (ui->class_id != c->dev->class_id)
631             continue;
632
633           ui->c_info = c->dev->attached (ui);
634           if (ui->c_info == NULL)
635             continue;
636
637           list_push_back (&c->usb_ifaces, &ui->class_peers);
638           ui->class = c;
639         }
640
641       li = list_next (li);
642     }
643 }
644
645 int
646 usb_dev_control (struct usb_endpoint *eop, struct usb_setup_pkt *setup,
647                  void *data, size_t *size) 
648 {
649   struct host *h;
650   int err;
651
652   h = eop->iface->dev->host;
653   err = h->dev->dev_control (eop->h_eop, setup, data, size);
654   return err;
655 }
656
657 int
658 usb_dev_bulk (struct usb_endpoint *eop, void *buf, int sz, int *tx)
659 {
660   struct host *h;
661   size_t size;
662   int err;
663
664   h = eop->iface->dev->host;
665
666   size = sz;
667   err = h->dev->dev_bulk (eop->h_eop, eop->direction == 0, buf, &size);
668   *tx = size;
669   printf ("usb_dev_bulk=%d\n", err);
670   return err;
671 }
672
673 /** convert a wchar string to ascii in place */
674 static size_t
675 wchar_to_ascii (char *dst, const char *src)
676 {
677   size_t sz = 0;
678   for (sz = 0; src[sz * 2] != '\0'; sz++)
679     {
680       dst[sz] = src[sz * 2];
681     }
682   while (sz > 0 && isspace (dst[sz - 1]))
683     sz--;
684   dst[sz] = '\0';
685   return sz;
686 }