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>
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 */
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
34 * More details can be found in chapter 9 of the usb1.1 spec
37 struct device_descriptor
39 struct desc_header hdr;
54 struct device_qualifier
65 struct config_descriptor
67 struct desc_header hdr;
68 uint16_t total_length;
76 struct interface_descriptor
78 struct desc_header hdr;
81 uint8_t num_endpoints;
83 uint8_t iface_subclass;
88 struct endpoint_descriptor
90 struct desc_header hdr;
91 /* end point address */
92 uint8_t endpoint_num:4;
109 #define USB_CLASS_HUB 0x09
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 */
121 struct usb_class *dev; /* class driver */
122 struct list usb_ifaces; /* usb devices on class */
123 struct list_elem peers;
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 */
131 #define usb_lock() lock_acquire(&usb_sys_lock)
132 #define usb_unlock() lock_release(&usb_sys_lock)
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);
145 extern void uhci_init (void);
146 extern void ehci_init (void);
151 list_init (&host_list);
152 list_init (&class_list);
153 list_init (&usb_dev_list);
154 lock_init (&usb_sys_lock);
159 printf ("Initializing EHCI\n");
161 printf ("Initializing UHCI\n");
165 /* add host controller device to usb layer */
167 usb_register_host (struct usb_host *uh, host_info info)
171 h = malloc (sizeof (struct host));
174 h->usb_dev_addrs = bitmap_create (ADDRS_PER_HOST);
175 list_init (&h->host_usb_devs);
178 list_push_back (&host_list, &h->peers);
181 usb_scan_devices (h);
185 usb_register_class (struct usb_class *uc)
191 /* check to make sure class is not in list */
192 if (usb_get_class_by_id (uc->class_id) != NULL)
199 /* add class to class list */
200 c = malloc (sizeof (struct class));
202 list_init (&c->usb_ifaces);
203 list_push_back (&class_list, &c->peers);
205 usb_apply_class_to_interfaces (c);
213 usb_scan_devices (struct host *h)
215 /* scan until there all devices using default pipe are configured */
217 printf ("USB: scanning devices...\n");
222 dev = usb_configure_default (h);
226 if (dev->ignore_device == false)
227 printf ("USB Device %d: %s (%s)\n",
228 dev->addr, dev->product, dev->manufacturer);
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);
237 static struct usb_dev *
238 usb_configure_default (struct host *h)
241 struct usb_setup_pkt sp;
242 struct device_descriptor dd;
244 host_eop_info cfg_eop;
245 bool ignore_device = false;
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);
253 /* determine device descriptor */
254 sp.recipient = USB_SETUP_RECIP_DEV;
255 sp.type = USB_SETUP_TYPE_STD;
257 sp.request = REQ_STD_GET_DESC;
258 sp.value = SETUP_DESC_DEVICE << 8;
263 err = h->dev->dev_control (cfg_eop, &sp, &dd, &size);
266 /* FIXME: free memory. */
267 printf ("err=%d: no more devices\n", err);
271 if (dd.usb_spec == USB_VERSION_1_0)
273 /* USB 1.0 devices have strict schedule requirements not yet supported */
274 printf ("USB 1.0 device detected - skipping\n");
276 if (dd.num_configs == 0)
277 ignore_device = true;
279 h->dev->remove_eop (cfg_eop);
280 cfg_eop = h->dev->create_eop (hi, 0, dd.max_pktsz);
282 sp.length = sizeof dd;
284 err = h->dev->dev_control (cfg_eop, &sp, &dd, &size);
287 /* FIXME: free memory. */
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);
296 dev->ignore_device = ignore_device;
298 dev->h_cfg_eop = cfg_eop;
300 dev->cfg_eop.h_eop = cfg_eop;
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;
311 dev->cfg_eop.iface = &dev->default_iface;
312 dev->cfg_eop.max_pkt = dd.max_pktsz;
313 dev->cfg_eop.eop = 0;
317 dev->vendor_id = dd.vendor_id;
318 dev->product_id = dd.product_id;
319 dev->device_id = dd.device_id;
321 if (ignore_device == false)
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);
329 /* read in configuration data if there are configurations available */
330 /* (which there should be...) */
331 if (dd.num_configs > 0 && ignore_device == false)
333 config_val = usb_load_config (dev, 0);
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);
343 usb_setup_dev_addr (dev);
345 usb_config_dev (dev, (config_val < 0) ? 1 : config_val);
351 * Load in data for 'idx' configuration into device structure
352 * XXX support multiple configurations
355 usb_load_config (struct usb_dev *dev, int idx)
357 struct usb_setup_pkt sp;
358 struct config_descriptor *cd;
368 cfg = dev->h_cfg_eop;
370 sp.recipient = USB_SETUP_RECIP_DEV;
371 sp.type = USB_SETUP_TYPE_STD;
373 sp.request = REQ_STD_GET_DESC;
374 sp.value = SETUP_DESC_CONFIG << 8 | idx;
376 sp.length = sizeof data;
377 cd = (struct config_descriptor *) data;
380 err = h->dev->dev_control (cfg, &sp, data, &size);
381 if (err != USB_HOST_ERR_NONE)
383 printf ("USB: Could not setup GET descriptor\n");
387 if (size < sizeof *cd || cd->hdr.type != SETUP_DESC_CONFIG)
389 printf ("USB: Invalid descriptor\n");
393 if (size < cd->total_length)
395 printf ("USB: configuration data too long\n");
399 dev->pwr = cd->max_power;
401 /* interface information comes right after config data */
402 /* scan interfaces */
403 ptr = data + sizeof (struct config_descriptor);
405 for (i = 0; i < cd->num_ifaces; i++)
407 struct interface_descriptor *iface;
408 struct usb_iface *ui;
412 if (iface->hdr.type != SETUP_DESC_IFACE)
414 hex_dump (0, iface, 64, false);
415 PANIC ("Expected %d, found %d\n", SETUP_DESC_IFACE,
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;
427 list_init (&ui->endpoints);
429 /* endpoint data comes after interfaces */
431 ptr += sizeof (struct interface_descriptor);
432 for (j = 0; j < iface->num_endpoints;
433 j++, ptr += sizeof (struct endpoint_descriptor))
435 struct usb_endpoint *ue;
436 struct endpoint_descriptor *ed;
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;
447 ue->h_eop = h->dev->create_eop (dev->h_dev, ue->eop, ue->max_pkt);
449 list_push_back (&ui->endpoints, &ue->peers);
452 list_push_back (&dev->interfaces, &ui->peers);
455 config_val = cd->config_val;
461 * Set USB device configuration to desired configuration value
464 usb_config_dev (struct usb_dev *dev, int config_val)
466 struct usb_setup_pkt sp;
472 cfg = dev->h_cfg_eop;
474 sp.recipient = USB_SETUP_RECIP_DEV;
475 sp.type = USB_SETUP_TYPE_STD;
477 sp.request = REQ_STD_SET_CONFIG;
478 sp.value = config_val;
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);
487 * Set a device address to something other than the default pipe
490 usb_setup_dev_addr (struct usb_dev *dev)
492 struct usb_setup_pkt sp;
497 ASSERT (dev->addr == 0);
500 cfg = dev->h_cfg_eop;
502 dev->addr = bitmap_scan_and_flip (h->usb_dev_addrs, 1, 1, false);
504 sp.recipient = USB_SETUP_RECIP_DEV;
505 sp.type = USB_SETUP_TYPE_STD;
507 sp.request = REQ_STD_SET_ADDRESS;
508 sp.value = dev->addr;
511 err = h->dev->dev_control (cfg, &sp, 0, NULL);
512 if (err != USB_HOST_ERR_NONE)
514 PANIC ("USB: Error on setting device address (err = %d)\n", err);
517 h->dev->modify_dev_channel (dev->h_dev, dev->addr, dev->usb_version);
520 #define MAX_USB_STR 128
521 /* read string by string descriptor index from usb device */
523 usb_get_string (struct usb_dev *udev, int ndx)
525 struct usb_setup_pkt sp;
526 char str[MAX_USB_STR + 1];
531 sp.recipient = USB_SETUP_RECIP_DEV;
532 sp.type = USB_SETUP_TYPE_STD;
534 sp.request = REQ_STD_GET_DESC;
535 sp.value = (SETUP_DESC_STRING << 8) | ndx;
537 size = sp.length = MAX_USB_STR;
538 err = udev->host->dev->dev_control (udev->h_cfg_eop, &sp, str, &size);
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 */
546 /* usb uses wchars for strings, convert to ASCII */
547 wchar_to_ascii (str, str + 2);
548 ret = malloc (strlen (str) + 1);
550 strlcpy (ret, str, MAX_USB_STR);
554 static struct class *
555 usb_get_class_by_id (int id)
557 struct list_elem *li;
559 li = list_begin (&class_list);
560 while (li != list_end (&class_list))
563 c = list_entry (li, struct class, peers);
564 if (c->dev->class_id == id)
573 * Asssociate interfaces on a device with their respective device classes
576 usb_attach_interfaces (struct usb_dev *dev)
579 struct list_elem *li;
580 li = list_begin (&dev->interfaces);
581 while (li != list_end (&dev->interfaces))
584 struct usb_iface *ui;
586 ui = list_entry (li, struct usb_iface, peers);
588 cl = usb_get_class_by_id (ui->class_id);
590 /* no matching class? try next interface */
594 ui->c_info = cl->dev->attached (ui);
595 /* did class driver initialize it OK? */
596 if (ui->c_info != NULL)
598 /* yes, add to list of usable interfaces */
599 list_push_back (&cl->usb_ifaces, &ui->class_peers);
606 * Scan all interfaces for interfaces that match class's class id
607 * Attach interfaces that match
610 usb_apply_class_to_interfaces (struct class *c)
612 struct list_elem *li;
614 li = list_begin (&usb_dev_list);
615 while (li != list_end (&usb_dev_list))
618 struct list_elem *lii;
620 ud = list_entry (li, struct usb_dev, sys_peers);
622 lii = list_begin (&ud->interfaces);
623 while (lii != list_end (&ud->interfaces))
625 struct usb_iface *ui;
627 ui = list_entry (lii, struct usb_iface, peers);
629 lii = list_next (lii);
630 if (ui->class_id != c->dev->class_id)
633 ui->c_info = c->dev->attached (ui);
634 if (ui->c_info == NULL)
637 list_push_back (&c->usb_ifaces, &ui->class_peers);
646 usb_dev_control (struct usb_endpoint *eop, struct usb_setup_pkt *setup,
647 void *data, size_t *size)
652 h = eop->iface->dev->host;
653 err = h->dev->dev_control (eop->h_eop, setup, data, size);
658 usb_dev_bulk (struct usb_endpoint *eop, void *buf, int sz, int *tx)
664 h = eop->iface->dev->host;
667 err = h->dev->dev_bulk (eop->h_eop, eop->direction == 0, buf, &size);
669 printf ("usb_dev_bulk=%d\n", err);
673 /** convert a wchar string to ascii in place */
675 wchar_to_ascii (char *dst, const char *src)
678 for (sz = 0; src[sz * 2] != '\0'; sz++)
680 dst[sz] = src[sz * 2];
682 while (sz > 0 && isspace (dst[sz - 1]))