1 /* $NetBSD: usb.c,v 1.45 2000/06/01 14:29:01 augustss Exp $ */ 2 /* $FreeBSD: src/sys/dev/usb/usb.c,v 1.20 1999/11/17 22:33:46 n_hibma Exp $ */ 3 4 /* 5 * Copyright (c) 1998 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Lennart Augustsson (lennart@augustsson.net) at 10 * Carlstedt Research & Technology. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the NetBSD 23 * Foundation, Inc. and its contributors. 24 * 4. Neither the name of The NetBSD Foundation nor the names of its 25 * contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41 /* 42 * USB specifications and other documentation can be found at 43 * http://www.usb.org/developers/data/ and 44 * http://www.usb.org/developers/index.html . 45 */ 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/kernel.h> 50 #include <sys/malloc.h> 51 #if defined(__NetBSD__) || defined(__OpenBSD__) 52 #include <sys/device.h> 53 #include <sys/kthread.h> 54 #include <sys/proc.h> 55 #elif defined(__FreeBSD__) 56 #include <sys/module.h> 57 #include <sys/bus.h> 58 #include <sys/filio.h> 59 #include <sys/uio.h> 60 #endif 61 #include <sys/conf.h> 62 #include <sys/poll.h> 63 #include <sys/select.h> 64 #include <sys/vnode.h> 65 #include <sys/signalvar.h> 66 67 #include <dev/usb/usb.h> 68 #include <dev/usb/usbdi.h> 69 #include <dev/usb/usbdi_util.h> 70 71 #define USB_DEV_MINOR 255 72 73 #if defined(__FreeBSD__) 74 MALLOC_DEFINE(M_USB, "USB", "USB"); 75 MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device"); 76 MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller"); 77 78 #include "usb_if.h" 79 #endif /* defined(__FreeBSD__) */ 80 81 #include <machine/bus.h> 82 83 #include <dev/usb/usbdivar.h> 84 #include <dev/usb/usb_quirks.h> 85 86 #ifdef USB_DEBUG 87 #define DPRINTF(x) if (usbdebug) logprintf x 88 #define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x 89 int usbdebug = 0; 90 #ifdef UHCI_DEBUG 91 int uhcidebug; 92 #endif 93 #ifdef OHCI_DEBUG 94 int ohcidebug; 95 #endif 96 /* 97 * 0 - do usual exploration 98 * 1 - do not use timeout exploration 99 * >1 - do no exploration 100 */ 101 int usb_noexplore = 0; 102 #else 103 #define DPRINTF(x) 104 #define DPRINTFN(n,x) 105 #endif 106 107 struct usb_softc { 108 USBBASEDEVICE sc_dev; /* base device */ 109 usbd_bus_handle sc_bus; /* USB controller */ 110 struct usbd_port sc_port; /* dummy port for root hub */ 111 112 #if defined(__FreeBSD__) 113 /* This part should be deleted when kthreads is available */ 114 struct selinfo sc_consel; /* waiting for connect change */ 115 #else 116 struct proc *sc_event_thread; 117 #endif 118 119 char sc_dying; 120 }; 121 122 #if defined(__NetBSD__) || defined(__OpenBSD__) 123 cdev_decl(usb); 124 #elif defined(__FreeBSD__) 125 d_open_t usbopen; 126 d_close_t usbclose; 127 d_read_t usbread; 128 d_ioctl_t usbioctl; 129 int usbpoll(dev_t, int, struct proc *); 130 131 struct cdevsw usb_cdevsw = { 132 /* open */ usbopen, 133 /* close */ usbclose, 134 /* read */ noread, 135 /* write */ nowrite, 136 /* ioctl */ usbioctl, 137 /* poll */ usbpoll, 138 /* mmap */ nommap, 139 /* strategy */ nostrategy, 140 /* name */ "usb", 141 /* maj */ USB_CDEV_MAJOR, 142 /* dump */ nodump, 143 /* psize */ nopsize, 144 /* flags */ 0, 145 /* bmaj */ -1 146 }; 147 #endif 148 149 Static usbd_status usb_discover(struct usb_softc *); 150 Static void usb_create_event_thread(void *); 151 Static void usb_event_thread(void *); 152 153 #define USB_MAX_EVENTS 100 154 struct usb_event_q { 155 struct usb_event ue; 156 SIMPLEQ_ENTRY(usb_event_q) next; 157 }; 158 Static SIMPLEQ_HEAD(, usb_event_q) usb_events = 159 SIMPLEQ_HEAD_INITIALIZER(usb_events); 160 Static int usb_nevents = 0; 161 Static struct selinfo usb_selevent; 162 Static struct proc *usb_async_proc; /* process who wants USB SIGIO */ 163 Static int usb_dev_open = 0; 164 Static void usb_add_event(int, struct usb_event *); 165 166 Static int usb_get_next_event(struct usb_event *); 167 168 #if defined(__NetBSD__) || defined(__OpenBSD__) 169 /* Flag to see if we are in the cold boot process. */ 170 extern int cold; 171 #endif 172 173 Static const char *usbrev_str[] = USBREV_STR; 174 175 USB_DECLARE_DRIVER(usb); 176 177 USB_MATCH(usb) 178 { 179 DPRINTF(("usbd_match\n")); 180 return (UMATCH_GENERIC); 181 } 182 183 USB_ATTACH(usb) 184 { 185 #if defined(__NetBSD__) || defined(__OpenBSD__) 186 struct usb_softc *sc = (struct usb_softc *)self; 187 #elif defined(__FreeBSD__) 188 struct usb_softc *sc = device_get_softc(self); 189 void *aux = device_get_ivars(self); 190 #endif 191 usbd_device_handle dev; 192 usbd_status err; 193 int usbrev; 194 struct usb_event ue; 195 196 #if defined(__FreeBSD__) 197 printf("%s", USBDEVNAME(sc->sc_dev)); 198 sc->sc_dev = self; 199 #endif 200 201 DPRINTF(("usbd_attach\n")); 202 203 usbd_init(); 204 sc->sc_bus = aux; 205 sc->sc_bus->usbctl = sc; 206 sc->sc_port.power = USB_MAX_POWER; 207 208 usbrev = sc->sc_bus->usbrev; 209 printf(": USB revision %s", usbrev_str[usbrev]); 210 if (usbrev != USBREV_1_0 && usbrev != USBREV_1_1) { 211 printf(", not supported\n"); 212 USB_ATTACH_ERROR_RETURN; 213 } 214 printf("\n"); 215 216 /* Make sure not to use tsleep() if we are cold booting. */ 217 if (cold) 218 sc->sc_bus->use_polling++; 219 220 ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev); 221 usb_add_event(USB_EVENT_CTRLR_ATTACH, &ue); 222 223 err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, 0, 0, 224 &sc->sc_port); 225 if (!err) { 226 dev = sc->sc_port.device; 227 if (dev->hub == NULL) { 228 sc->sc_dying = 1; 229 printf("%s: root device is not a hub\n", 230 USBDEVNAME(sc->sc_dev)); 231 USB_ATTACH_ERROR_RETURN; 232 } 233 sc->sc_bus->root_hub = dev; 234 #if 1 235 /* 236 * Turning this code off will delay attachment of USB devices 237 * until the USB event thread is running, which means that 238 * the keyboard will not work until after cold boot. 239 */ 240 if (cold && (sc->sc_dev.dv_cfdata->cf_flags & 1)) 241 dev->hub->explore(sc->sc_bus->root_hub); 242 #endif 243 } else { 244 printf("%s: root hub problem, error=%d\n", 245 USBDEVNAME(sc->sc_dev), err); 246 sc->sc_dying = 1; 247 } 248 if (cold) 249 sc->sc_bus->use_polling--; 250 251 config_pending_incr(); 252 usb_kthread_create(usb_create_event_thread, sc); 253 254 #if defined(__FreeBSD__) 255 make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR, 256 0644, "usb%d", device_get_unit(self)); 257 #endif 258 259 USB_ATTACH_SUCCESS_RETURN; 260 } 261 262 #if defined(__NetBSD__) || defined(__OpenBSD__) 263 void 264 usb_create_event_thread(void *arg) 265 { 266 struct usb_softc *sc = arg; 267 268 if (usb_kthread_create1(usb_event_thread, sc, &sc->sc_event_thread, 269 "%s", sc->sc_dev.dv_xname)) { 270 printf("%s: unable to create event thread for\n", 271 sc->sc_dev.dv_xname); 272 panic("usb_create_event_thread"); 273 } 274 } 275 276 void 277 usb_event_thread(void *arg) 278 { 279 struct usb_softc *sc = arg; 280 int first = 1; 281 282 DPRINTF(("usb_event_thread: start\n")); 283 284 /* Make sure first discover does something. */ 285 sc->sc_bus->needs_explore = 1; 286 287 while (!sc->sc_dying) { 288 #ifdef USB_DEBUG 289 if (usb_noexplore < 2) 290 #endif 291 usb_discover(sc); 292 if (first) { 293 config_pending_decr(); 294 first = 0; 295 } 296 (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt", 297 #ifdef USB_DEBUG 298 usb_noexplore ? 0 : 299 #endif 300 hz*60 301 ); 302 DPRINTFN(2,("usb_event_thread: woke up\n")); 303 } 304 sc->sc_event_thread = 0; 305 306 /* In case parent is waiting for us to exit. */ 307 wakeup(sc); 308 309 DPRINTF(("usb_event_thread: exit\n")); 310 kthread_exit(0); 311 } 312 313 int 314 usbctlprint(void *aux, const char *pnp) 315 { 316 /* only "usb"es can attach to host controllers */ 317 if (pnp) 318 printf("usb at %s", pnp); 319 320 return (UNCONF); 321 } 322 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ 323 324 int 325 usbopen(dev_t dev, int flag, int mode, struct proc *p) 326 { 327 int unit = minor(dev); 328 struct usb_softc *sc; 329 330 if (unit == USB_DEV_MINOR) { 331 if (usb_dev_open) 332 return (EBUSY); 333 usb_dev_open = 1; 334 usb_async_proc = 0; 335 return (0); 336 } 337 338 USB_GET_SC_OPEN(usb, unit, sc); 339 340 if (sc->sc_dying) 341 return (EIO); 342 343 return (0); 344 } 345 346 int 347 usbread(dev_t dev, struct uio *uio, int flag) 348 { 349 struct usb_event ue; 350 int s, error, n; 351 352 if (minor(dev) != USB_DEV_MINOR) 353 return (ENXIO); 354 355 if (uio->uio_resid != sizeof(struct usb_event)) 356 return (EINVAL); 357 358 error = 0; 359 s = splusb(); 360 for (;;) { 361 n = usb_get_next_event(&ue); 362 if (n != 0) 363 break; 364 if (flag & IO_NDELAY) { 365 error = EWOULDBLOCK; 366 break; 367 } 368 error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0); 369 if (error) 370 break; 371 } 372 splx(s); 373 if (!error) 374 error = uiomove((void *)&ue, uio->uio_resid, uio); 375 376 return (error); 377 } 378 379 int 380 usbclose(dev_t dev, int flag, int mode, struct proc *p) 381 { 382 int unit = minor(dev); 383 384 if (unit == USB_DEV_MINOR) { 385 usb_async_proc = 0; 386 usb_dev_open = 0; 387 } 388 389 return (0); 390 } 391 392 int 393 usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, struct proc *p) 394 { 395 struct usb_softc *sc; 396 int unit = minor(devt); 397 398 if (unit == USB_DEV_MINOR) { 399 switch (cmd) { 400 case FIONBIO: 401 /* All handled in the upper FS layer. */ 402 return (0); 403 404 case FIOASYNC: 405 if (*(int *)data) 406 usb_async_proc = p; 407 else 408 usb_async_proc = 0; 409 return (0); 410 411 default: 412 return (EINVAL); 413 } 414 } 415 416 USB_GET_SC(usb, unit, sc); 417 418 if (sc->sc_dying) 419 return (EIO); 420 421 switch (cmd) { 422 #if defined(__FreeBSD__) 423 /* This part should be deleted when kthreads is available */ 424 case USB_DISCOVER: 425 usb_discover(sc); 426 break; 427 #endif 428 #ifdef USB_DEBUG 429 case USB_SETDEBUG: 430 usbdebug = ((*(int *)data) & 0x000000ff); 431 #ifdef UHCI_DEBUG 432 uhcidebug = ((*(int *)data) & 0x0000ff00) >> 8; 433 #endif 434 #ifdef OHCI_DEBUG 435 ohcidebug = ((*(int *)data) & 0x00ff0000) >> 16; 436 #endif 437 break; 438 #endif 439 case USB_REQUEST: 440 { 441 struct usb_ctl_request *ur = (void *)data; 442 int len = UGETW(ur->request.wLength); 443 struct iovec iov; 444 struct uio uio; 445 void *ptr = 0; 446 int addr = ur->addr; 447 usbd_status err; 448 int error = 0; 449 450 DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len)); 451 if (len < 0 || len > 32768) 452 return (EINVAL); 453 if (addr < 0 || addr >= USB_MAX_DEVICES || 454 sc->sc_bus->devices[addr] == 0) 455 return (EINVAL); 456 if (len != 0) { 457 iov.iov_base = (caddr_t)ur->data; 458 iov.iov_len = len; 459 uio.uio_iov = &iov; 460 uio.uio_iovcnt = 1; 461 uio.uio_resid = len; 462 uio.uio_offset = 0; 463 uio.uio_segflg = UIO_USERSPACE; 464 uio.uio_rw = 465 ur->request.bmRequestType & UT_READ ? 466 UIO_READ : UIO_WRITE; 467 uio.uio_procp = p; 468 ptr = malloc(len, M_TEMP, M_WAITOK); 469 if (uio.uio_rw == UIO_WRITE) { 470 error = uiomove(ptr, len, &uio); 471 if (error) 472 goto ret; 473 } 474 } 475 err = usbd_do_request_flags(sc->sc_bus->devices[addr], 476 &ur->request, ptr, ur->flags, &ur->actlen); 477 if (err) { 478 error = EIO; 479 goto ret; 480 } 481 if (len != 0) { 482 if (uio.uio_rw == UIO_READ) { 483 error = uiomove(ptr, len, &uio); 484 if (error) 485 goto ret; 486 } 487 } 488 ret: 489 if (ptr) 490 free(ptr, M_TEMP); 491 return (error); 492 } 493 494 case USB_DEVICEINFO: 495 { 496 struct usb_device_info *di = (void *)data; 497 int addr = di->addr; 498 usbd_device_handle dev; 499 500 if (addr < 1 || addr >= USB_MAX_DEVICES) 501 return (EINVAL); 502 dev = sc->sc_bus->devices[addr]; 503 if (dev == NULL) 504 return (ENXIO); 505 usbd_fill_deviceinfo(dev, di); 506 break; 507 } 508 509 case USB_DEVICESTATS: 510 *(struct usb_device_stats *)data = sc->sc_bus->stats; 511 break; 512 513 default: 514 return (EINVAL); 515 } 516 return (0); 517 } 518 519 int 520 usbpoll(dev_t dev, int events, struct proc *p) 521 { 522 int revents, mask, s; 523 524 if (minor(dev) == USB_DEV_MINOR) { 525 revents = 0; 526 mask = POLLIN | POLLRDNORM; 527 528 s = splusb(); 529 if (events & mask && usb_nevents > 0) 530 revents |= events & mask; 531 if (revents == 0 && events & mask) 532 selrecord(p, &usb_selevent); 533 splx(s); 534 535 return (revents); 536 } else { 537 #if defined(__FreeBSD__) 538 /* This part should be deleted when kthreads is available */ 539 struct usb_softc *sc; 540 int unit = minor(dev); 541 542 USB_GET_SC(usb, unit, sc); 543 544 revents = 0; 545 mask = POLLOUT | POLLRDNORM; 546 547 s = splusb(); 548 if (events & mask && sc->sc_bus->needs_explore) 549 revents |= events & mask; 550 if (revents == 0 && events & mask) 551 selrecord(p, &sc->sc_consel); 552 splx(s); 553 554 return (revents); 555 #else 556 return (ENXIO); 557 #endif 558 } 559 } 560 561 /* Explore device tree from the root. */ 562 usbd_status 563 usb_discover(struct usb_softc *sc) 564 { 565 #if defined(__FreeBSD__) 566 /* The splxxx parts should be deleted when kthreads is available */ 567 int s; 568 #endif 569 570 /* 571 * We need mutual exclusion while traversing the device tree, 572 * but this is guaranteed since this function is only called 573 * from the event thread for the controller. 574 */ 575 #if defined(__FreeBSD__) 576 s = splusb(); 577 #endif 578 while (sc->sc_bus->needs_explore && !sc->sc_dying) { 579 sc->sc_bus->needs_explore = 0; 580 #if defined(__FreeBSD__) 581 splx(s); 582 #endif 583 sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub); 584 #if defined(__FreeBSD__) 585 s = splusb(); 586 #endif 587 } 588 #if defined(__FreeBSD__) 589 splx(s); 590 #endif 591 592 return (USBD_NORMAL_COMPLETION); 593 } 594 595 void 596 usb_needs_explore(usbd_bus_handle bus) 597 { 598 bus->needs_explore = 1; 599 #if defined(__FreeBSD__) 600 /* This part should be deleted when kthreads is available */ 601 selwakeup(&bus->usbctl->sc_consel); 602 #endif 603 wakeup(&bus->needs_explore); 604 } 605 606 /* Called at splusb() */ 607 int 608 usb_get_next_event(struct usb_event *ue) 609 { 610 struct usb_event_q *ueq; 611 612 if (usb_nevents <= 0) 613 return (0); 614 ueq = SIMPLEQ_FIRST(&usb_events); 615 *ue = ueq->ue; 616 SIMPLEQ_REMOVE_HEAD(&usb_events, ueq, next); 617 free(ueq, M_USBDEV); 618 usb_nevents--; 619 return (1); 620 } 621 622 void 623 usbd_add_dev_event(int type, usbd_device_handle udev) 624 { 625 struct usb_event ue; 626 627 usbd_fill_deviceinfo(udev, &ue.u.ue_device); 628 usb_add_event(type, &ue); 629 } 630 631 void 632 usbd_add_drv_event(int type, usbd_device_handle udev, device_ptr_t dev) 633 { 634 struct usb_event ue; 635 636 ue.u.ue_driver.ue_cookie = udev->cookie; 637 strncpy(ue.u.ue_driver.ue_devname, USBDEVPTRNAME(dev), 638 sizeof ue.u.ue_driver.ue_devname); 639 usb_add_event(type, &ue); 640 } 641 642 Static void 643 usb_add_event(int type, struct usb_event *uep) 644 { 645 struct usb_event_q *ueq; 646 struct usb_event ue; 647 struct timeval thetime; 648 int s; 649 650 microtime(&thetime); 651 /* Don't want to wait here inside splusb() */ 652 ueq = malloc(sizeof *ueq, M_USBDEV, M_WAITOK); 653 ueq->ue = *uep; 654 ueq->ue.ue_type = type; 655 TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time); 656 657 s = splusb(); 658 if (++usb_nevents >= USB_MAX_EVENTS) { 659 /* Too many queued events, drop an old one. */ 660 DPRINTFN(-1,("usb: event dropped\n")); 661 (void)usb_get_next_event(&ue); 662 } 663 SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next); 664 wakeup(&usb_events); 665 selwakeup(&usb_selevent); 666 if (usb_async_proc != NULL) 667 psignal(usb_async_proc, SIGIO); 668 splx(s); 669 } 670 void 671 usb_schedsoftintr(struct usbd_bus *bus) 672 { 673 bus->methods->soft_intr(bus); 674 } 675 676 #if defined(__NetBSD__) || defined(__OpenBSD__) 677 int 678 usb_activate(device_ptr_t self, enum devact act) 679 { 680 struct usb_softc *sc = (struct usb_softc *)self; 681 usbd_device_handle dev = sc->sc_port.device; 682 int i, rv = 0; 683 684 switch (act) { 685 case DVACT_ACTIVATE: 686 return (EOPNOTSUPP); 687 break; 688 689 case DVACT_DEACTIVATE: 690 sc->sc_dying = 1; 691 if (dev && dev->cdesc && dev->subdevs) { 692 for (i = 0; dev->subdevs[i]; i++) 693 rv |= config_deactivate(dev->subdevs[i]); 694 } 695 break; 696 } 697 return (rv); 698 } 699 700 int 701 usb_detach(device_ptr_t self, int flags) 702 { 703 struct usb_softc *sc = (struct usb_softc *)self; 704 struct usb_event ue; 705 706 DPRINTF(("usb_detach: start\n")); 707 708 sc->sc_dying = 1; 709 710 /* Make all devices disconnect. */ 711 if (sc->sc_port.device) 712 usb_disconnect_port(&sc->sc_port, self); 713 714 /* Kill off event thread. */ 715 if (sc->sc_event_thread) { 716 wakeup(&sc->sc_bus->needs_explore); 717 if (tsleep(sc, PWAIT, "usbdet", hz * 60)) 718 printf("%s: event thread didn't die\n", 719 USBDEVNAME(sc->sc_dev)); 720 DPRINTF(("usb_detach: event thread dead\n")); 721 } 722 723 usbd_finish(); 724 725 ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev); 726 usb_add_event(USB_EVENT_CTRLR_DETACH, &ue); 727 728 return (0); 729 } 730 #elif defined(__FreeBSD__) 731 int 732 usb_detach(device_t self) 733 { 734 DPRINTF(("%s: unload, prevented\n", USBDEVNAME(self))); 735 736 return (EINVAL); 737 } 738 #endif 739 740 741 #if defined(__FreeBSD__) 742 DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0); 743 DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0); 744 #endif 745