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