|
|
1.1 root 1: // Main code for handling USB controllers and devices.
2: //
3: // Copyright (C) 2009 Kevin O'Connor <[email protected]>
4: //
5: // This file may be distributed under the terms of the GNU LGPLv3 license.
6:
7: #include "util.h" // dprintf
8: #include "pci.h" // foreachpci
9: #include "config.h" // CONFIG_*
10: #include "pci_regs.h" // PCI_CLASS_REVISION
11: #include "pci_ids.h" // PCI_CLASS_SERIAL_USB_UHCI
12: #include "usb-uhci.h" // uhci_init
13: #include "usb-ohci.h" // ohci_init
1.1.1.3 root 14: #include "usb-ehci.h" // ehci_init
1.1 root 15: #include "usb-hid.h" // usb_keyboard_setup
1.1.1.3 root 16: #include "usb-hub.h" // usb_hub_init
17: #include "usb-msc.h" // usb_msc_init
1.1 root 18: #include "usb.h" // struct usb_s
19: #include "biosvar.h" // GET_GLOBAL
20:
21:
1.1.1.3 root 22: /****************************************************************
23: * Controller function wrappers
24: ****************************************************************/
25:
1.1.1.6 ! root 26: // Allocate an async pipe (control or bulk).
! 27: struct usb_pipe *
! 28: usb_alloc_pipe(struct usbdevice_s *usbdev
! 29: , struct usb_endpoint_descriptor *epdesc)
1.1.1.3 root 30: {
1.1.1.6 ! root 31: switch (usbdev->hub->cntl->type) {
1.1.1.3 root 32: default:
33: case USB_TYPE_UHCI:
1.1.1.6 ! root 34: return uhci_alloc_pipe(usbdev, epdesc);
1.1.1.3 root 35: case USB_TYPE_OHCI:
1.1.1.6 ! root 36: return ohci_alloc_pipe(usbdev, epdesc);
1.1.1.3 root 37: case USB_TYPE_EHCI:
1.1.1.6 ! root 38: return ehci_alloc_pipe(usbdev, epdesc);
1.1.1.3 root 39: }
40: }
41:
42: // Send a message on a control pipe using the default control descriptor.
1.1 root 43: static int
1.1.1.3 root 44: send_control(struct usb_pipe *pipe, int dir, const void *cmd, int cmdsize
1.1 root 45: , void *data, int datasize)
46: {
1.1.1.3 root 47: ASSERT32FLAT();
48: switch (pipe->type) {
1.1 root 49: default:
50: case USB_TYPE_UHCI:
1.1.1.3 root 51: return uhci_control(pipe, dir, cmd, cmdsize, data, datasize);
1.1 root 52: case USB_TYPE_OHCI:
1.1.1.3 root 53: return ohci_control(pipe, dir, cmd, cmdsize, data, datasize);
54: case USB_TYPE_EHCI:
55: return ehci_control(pipe, dir, cmd, cmdsize, data, datasize);
1.1 root 56: }
57: }
58:
59: int
1.1.1.3 root 60: usb_send_bulk(struct usb_pipe *pipe_fl, int dir, void *data, int datasize)
61: {
62: switch (GET_FLATPTR(pipe_fl->type)) {
63: default:
64: case USB_TYPE_UHCI:
65: return uhci_send_bulk(pipe_fl, dir, data, datasize);
66: case USB_TYPE_OHCI:
1.1.1.4 root 67: return ohci_send_bulk(pipe_fl, dir, data, datasize);
1.1.1.3 root 68: case USB_TYPE_EHCI:
69: return ehci_send_bulk(pipe_fl, dir, data, datasize);
70: }
71: }
72:
73: int noinline
74: usb_poll_intr(struct usb_pipe *pipe_fl, void *data)
75: {
76: switch (GET_FLATPTR(pipe_fl->type)) {
77: default:
78: case USB_TYPE_UHCI:
79: return uhci_poll_intr(pipe_fl, data);
80: case USB_TYPE_OHCI:
81: return ohci_poll_intr(pipe_fl, data);
82: case USB_TYPE_EHCI:
83: return ehci_poll_intr(pipe_fl, data);
84: }
85: }
86:
87:
88: /****************************************************************
89: * Helper functions
90: ****************************************************************/
91:
1.1.1.6 ! root 92: // Send a message to the default control pipe of a device.
! 93: int
! 94: send_default_control(struct usb_pipe *pipe, const struct usb_ctrlrequest *req
! 95: , void *data)
! 96: {
! 97: return send_control(pipe, req->bRequestType & USB_DIR_IN
! 98: , req, sizeof(*req), data, req->wLength);
! 99: }
! 100:
! 101: // Free an allocated control or bulk pipe.
! 102: void
! 103: free_pipe(struct usb_pipe *pipe)
! 104: {
! 105: ASSERT32FLAT();
! 106: if (!pipe)
! 107: return;
! 108: // Add to controller's free list.
! 109: struct usb_s *cntl = pipe->cntl;
! 110: pipe->freenext = cntl->freelist;
! 111: cntl->freelist = pipe;
! 112: }
! 113:
! 114: // Check for an available pipe on the freelist.
! 115: struct usb_pipe *
! 116: usb_getFreePipe(struct usb_s *cntl, u8 eptype)
! 117: {
! 118: struct usb_pipe **pfree = &cntl->freelist;
! 119: for (;;) {
! 120: struct usb_pipe *pipe = *pfree;
! 121: if (!pipe)
! 122: return NULL;
! 123: if (pipe->eptype == eptype) {
! 124: *pfree = pipe->freenext;
! 125: return pipe;
! 126: }
! 127: pfree = &pipe->freenext;
! 128: }
! 129: }
! 130:
! 131: // Fill "pipe" endpoint info from an endpoint descriptor.
! 132: void
! 133: usb_desc2pipe(struct usb_pipe *pipe, struct usbdevice_s *usbdev
! 134: , struct usb_endpoint_descriptor *epdesc)
! 135: {
! 136: pipe->cntl = usbdev->hub->cntl;
! 137: pipe->type = usbdev->hub->cntl->type;
! 138: pipe->ep = epdesc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
! 139: pipe->devaddr = usbdev->devaddr;
! 140: pipe->speed = usbdev->speed;
! 141: pipe->maxpacket = epdesc->wMaxPacketSize;
! 142: pipe->eptype = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
! 143: }
! 144:
! 145: // Find the exponential period of the requested interrupt end point.
! 146: int
! 147: usb_getFrameExp(struct usbdevice_s *usbdev
! 148: , struct usb_endpoint_descriptor *epdesc)
! 149: {
! 150: int period = epdesc->bInterval;
! 151: if (usbdev->speed != USB_HIGHSPEED)
! 152: return (period <= 0) ? 0 : __fls(period);
! 153: return (period <= 4) ? 0 : period - 4;
! 154: }
! 155:
1.1.1.3 root 156: // Find the first endpoing of a given type in an interface description.
157: struct usb_endpoint_descriptor *
1.1.1.6 ! root 158: findEndPointDesc(struct usbdevice_s *usbdev, int type, int dir)
1.1.1.3 root 159: {
1.1.1.6 ! root 160: struct usb_endpoint_descriptor *epdesc = (void*)&usbdev->iface[1];
1.1.1.3 root 161: for (;;) {
1.1.1.6 ! root 162: if ((void*)epdesc >= (void*)usbdev->iface + usbdev->imax
1.1.1.3 root 163: || epdesc->bDescriptorType == USB_DT_INTERFACE) {
164: return NULL;
165: }
166: if (epdesc->bDescriptorType == USB_DT_ENDPOINT
167: && (epdesc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == dir
168: && (epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == type)
169: return epdesc;
170: epdesc = (void*)epdesc + epdesc->bLength;
171: }
172: }
173:
1.1 root 174: // Get the first 8 bytes of the device descriptor.
175: static int
1.1.1.3 root 176: get_device_info8(struct usb_pipe *pipe, struct usb_device_descriptor *dinfo)
1.1 root 177: {
178: struct usb_ctrlrequest req;
179: req.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
180: req.bRequest = USB_REQ_GET_DESCRIPTOR;
181: req.wValue = USB_DT_DEVICE<<8;
182: req.wIndex = 0;
183: req.wLength = 8;
1.1.1.3 root 184: return send_default_control(pipe, &req, dinfo);
1.1 root 185: }
186:
187: static struct usb_config_descriptor *
1.1.1.3 root 188: get_device_config(struct usb_pipe *pipe)
1.1 root 189: {
190: struct usb_config_descriptor cfg;
191:
192: struct usb_ctrlrequest req;
193: req.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
194: req.bRequest = USB_REQ_GET_DESCRIPTOR;
195: req.wValue = USB_DT_CONFIG<<8;
196: req.wIndex = 0;
197: req.wLength = sizeof(cfg);
1.1.1.3 root 198: int ret = send_default_control(pipe, &req, &cfg);
1.1 root 199: if (ret)
200: return NULL;
201:
202: void *config = malloc_tmphigh(cfg.wTotalLength);
203: if (!config)
204: return NULL;
205: req.wLength = cfg.wTotalLength;
1.1.1.3 root 206: ret = send_default_control(pipe, &req, config);
1.1 root 207: if (ret)
208: return NULL;
209: //hexdump(config, cfg.wTotalLength);
210: return config;
211: }
212:
1.1.1.3 root 213: static int
214: set_configuration(struct usb_pipe *pipe, u16 val)
1.1 root 215: {
216: struct usb_ctrlrequest req;
217: req.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
1.1.1.3 root 218: req.bRequest = USB_REQ_SET_CONFIGURATION;
219: req.wValue = val;
1.1 root 220: req.wIndex = 0;
221: req.wLength = 0;
1.1.1.3 root 222: return send_default_control(pipe, &req, NULL);
1.1 root 223: }
224:
1.1.1.3 root 225:
226: /****************************************************************
227: * Initialization and enumeration
228: ****************************************************************/
229:
230: // Assign an address to a device in the default state on the given
231: // controller.
1.1.1.6 ! root 232: static int
! 233: usb_set_address(struct usbdevice_s *usbdev)
1.1 root 234: {
1.1.1.3 root 235: ASSERT32FLAT();
1.1.1.6 ! root 236: struct usb_s *cntl = usbdev->hub->cntl;
1.1.1.3 root 237: dprintf(3, "set_address %p\n", cntl);
238: if (cntl->maxaddr >= USB_MAXADDR)
1.1.1.6 ! root 239: return -1;
1.1.1.3 root 240:
1.1.1.6 ! root 241: // Create a pipe for the default address.
! 242: struct usb_endpoint_descriptor epdesc = {
! 243: .wMaxPacketSize = 8,
! 244: .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
! 245: };
! 246: usbdev->defpipe = usb_alloc_pipe(usbdev, &epdesc);
! 247: if (!usbdev->defpipe)
! 248: return -1;
1.1.1.3 root 249:
250: msleep(USB_TIME_RSTRCY);
251:
1.1.1.6 ! root 252: // Send set_address command.
1.1 root 253: struct usb_ctrlrequest req;
254: req.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
1.1.1.3 root 255: req.bRequest = USB_REQ_SET_ADDRESS;
256: req.wValue = cntl->maxaddr + 1;
1.1 root 257: req.wIndex = 0;
258: req.wLength = 0;
1.1.1.6 ! root 259: int ret = send_default_control(usbdev->defpipe, &req, NULL);
! 260: free_pipe(usbdev->defpipe);
1.1.1.3 root 261: if (ret)
1.1.1.6 ! root 262: return -1;
1.1.1.3 root 263:
264: msleep(USB_TIME_SETADDR_RECOVERY);
265:
266: cntl->maxaddr++;
1.1.1.6 ! root 267: usbdev->devaddr = cntl->maxaddr;
! 268: usbdev->defpipe = usb_alloc_pipe(usbdev, &epdesc);
! 269: if (!usbdev->defpipe)
! 270: return -1;
! 271: return 0;
1.1 root 272: }
273:
274: // Called for every found device - see if a driver is available for
275: // this device and do setup if so.
1.1.1.3 root 276: static int
1.1.1.6 ! root 277: configure_usb_device(struct usbdevice_s *usbdev)
1.1 root 278: {
1.1.1.3 root 279: ASSERT32FLAT();
1.1.1.6 ! root 280: dprintf(3, "config_usb: %p\n", usbdev->defpipe);
1.1 root 281:
1.1.1.3 root 282: // Set the max packet size for endpoint 0 of this device.
1.1 root 283: struct usb_device_descriptor dinfo;
1.1.1.6 ! root 284: int ret = get_device_info8(usbdev->defpipe, &dinfo);
1.1 root 285: if (ret)
286: return 0;
287: dprintf(3, "device rev=%04x cls=%02x sub=%02x proto=%02x size=%02x\n"
288: , dinfo.bcdUSB, dinfo.bDeviceClass, dinfo.bDeviceSubClass
289: , dinfo.bDeviceProtocol, dinfo.bMaxPacketSize0);
290: if (dinfo.bMaxPacketSize0 < 8 || dinfo.bMaxPacketSize0 > 64)
291: return 0;
1.1.1.6 ! root 292: free_pipe(usbdev->defpipe);
! 293: struct usb_endpoint_descriptor epdesc = {
! 294: .wMaxPacketSize = dinfo.bMaxPacketSize0,
! 295: .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
! 296: };
! 297: usbdev->defpipe = usb_alloc_pipe(usbdev, &epdesc);
! 298: if (!usbdev->defpipe)
! 299: return -1;
1.1 root 300:
301: // Get configuration
1.1.1.6 ! root 302: struct usb_config_descriptor *config = get_device_config(usbdev->defpipe);
1.1 root 303: if (!config)
304: return 0;
305:
306: // Determine if a driver exists for this device - only look at the
307: // first interface of the first configuration.
308: struct usb_interface_descriptor *iface = (void*)(&config[1]);
309: if (iface->bInterfaceClass != USB_CLASS_HID
1.1.1.3 root 310: && iface->bInterfaceClass != USB_CLASS_MASS_STORAGE
311: && iface->bInterfaceClass != USB_CLASS_HUB)
312: // Not a supported device.
1.1 root 313: goto fail;
314:
1.1.1.3 root 315: // Set the configuration.
1.1.1.6 ! root 316: ret = set_configuration(usbdev->defpipe, config->bConfigurationValue);
1.1 root 317: if (ret)
318: goto fail;
319:
320: // Configure driver.
1.1.1.6 ! root 321: usbdev->config = config;
! 322: usbdev->iface = iface;
! 323: usbdev->imax = (void*)config + config->wTotalLength - (void*)iface;
1.1.1.3 root 324: if (iface->bInterfaceClass == USB_CLASS_HUB)
1.1.1.6 ! root 325: ret = usb_hub_init(usbdev);
1.1.1.3 root 326: else if (iface->bInterfaceClass == USB_CLASS_MASS_STORAGE)
1.1.1.6 ! root 327: ret = usb_msc_init(usbdev);
1.1.1.3 root 328: else
1.1.1.6 ! root 329: ret = usb_hid_init(usbdev);
1.1 root 330: if (ret)
331: goto fail;
332:
333: free(config);
334: return 1;
335: fail:
336: free(config);
337: return 0;
338: }
339:
1.1.1.3 root 340: static void
341: usb_init_hub_port(void *data)
342: {
1.1.1.6 ! root 343: struct usbdevice_s *usbdev = data;
! 344: struct usbhub_s *hub = usbdev->hub;
! 345: u32 port = usbdev->port;
1.1.1.3 root 346:
347: // Detect if device present (and possibly start reset)
348: int ret = hub->op->detect(hub, port);
349: if (ret)
350: // No device present
351: goto done;
352:
353: // Reset port and determine device speed
354: mutex_lock(&hub->cntl->resetlock);
355: ret = hub->op->reset(hub, port);
356: if (ret < 0)
357: // Reset failed
358: goto resetfail;
1.1.1.6 ! root 359: usbdev->speed = ret;
1.1.1.3 root 360:
361: // Set address of port
1.1.1.6 ! root 362: ret = usb_set_address(usbdev);
! 363: if (ret) {
1.1.1.3 root 364: hub->op->disconnect(hub, port);
365: goto resetfail;
366: }
367: mutex_unlock(&hub->cntl->resetlock);
368:
369: // Configure the device
1.1.1.6 ! root 370: int count = configure_usb_device(usbdev);
! 371: free_pipe(usbdev->defpipe);
1.1.1.3 root 372: if (!count)
373: hub->op->disconnect(hub, port);
374: hub->devcount += count;
375: done:
376: hub->threads--;
1.1.1.6 ! root 377: free(usbdev);
1.1.1.3 root 378: return;
379:
380: resetfail:
381: mutex_unlock(&hub->cntl->resetlock);
382: goto done;
383: }
384:
385: void
386: usb_enumerate(struct usbhub_s *hub)
387: {
388: u32 portcount = hub->portcount;
389: hub->threads = portcount;
390:
391: // Launch a thread for every port.
392: int i;
393: for (i=0; i<portcount; i++) {
1.1.1.6 ! root 394: struct usbdevice_s *usbdev = malloc_tmphigh(sizeof(*usbdev));
! 395: if (!usbdev) {
! 396: warn_noalloc();
! 397: continue;
! 398: }
! 399: memset(usbdev, 0, sizeof(*usbdev));
! 400: usbdev->hub = hub;
! 401: usbdev->port = i;
! 402: run_thread(usb_init_hub_port, usbdev);
1.1.1.3 root 403: }
404:
405: // Wait for threads to complete.
406: while (hub->threads)
407: yield();
408: }
409:
1.1 root 410: void
1.1.1.2 root 411: usb_setup(void)
1.1 root 412: {
1.1.1.3 root 413: ASSERT32FLAT();
1.1 root 414: if (! CONFIG_USB)
415: return;
416:
417: dprintf(3, "init usb\n");
418:
419: // Look for USB controllers
420: int count = 0;
1.1.1.5 root 421: struct pci_device *ehcipci = PCIDevices;
422: struct pci_device *pci;
423: foreachpci(pci) {
424: if (pci->class != PCI_CLASS_SERIAL_USB)
1.1 root 425: continue;
426:
1.1.1.5 root 427: if (pci->bdf >= ehcipci->bdf) {
1.1.1.3 root 428: // Check to see if this device has an ehci controller
429: int found = 0;
1.1.1.5 root 430: ehcipci = pci;
1.1.1.3 root 431: for (;;) {
1.1.1.5 root 432: if (pci_classprog(ehcipci) == PCI_CLASS_SERIAL_USB_EHCI) {
1.1.1.3 root 433: // Found an ehci controller.
1.1.1.5 root 434: int ret = ehci_init(ehcipci, count++, pci);
1.1.1.3 root 435: if (ret)
436: // Error
437: break;
438: count += found;
1.1.1.5 root 439: pci = ehcipci;
1.1.1.3 root 440: break;
441: }
1.1.1.5 root 442: if (ehcipci->class == PCI_CLASS_SERIAL_USB)
1.1.1.3 root 443: found++;
1.1.1.5 root 444: ehcipci = ehcipci->next;
445: if (!ehcipci || (pci_bdf_to_busdev(ehcipci->bdf)
446: != pci_bdf_to_busdev(pci->bdf)))
1.1.1.3 root 447: // No ehci controller found.
448: break;
449: }
450: }
1.1 root 451:
1.1.1.5 root 452: if (pci_classprog(pci) == PCI_CLASS_SERIAL_USB_UHCI)
453: uhci_init(pci, count++);
454: else if (pci_classprog(pci) == PCI_CLASS_SERIAL_USB_OHCI)
455: ohci_init(pci, count++);
1.1 root 456: }
457: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.