1 /* $NetBSD: usb.c,v 1.48 2000/12/13 04:05:14 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 that 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 Static const char *usbrev_str[] = USBREV_STR; 169 170 USB_DECLARE_DRIVER(usb); 171 172 USB_MATCH(usb) 173 { 174 DPRINTF(("usbd_match\n")); 175 return (UMATCH_GENERIC); 176 } 177 178 USB_ATTACH(usb) 179 { 180 #if defined(__NetBSD__) || defined(__OpenBSD__) 181 struct usb_softc *sc = (struct usb_softc *)self; 182 #elif defined(__FreeBSD__) 183 struct usb_softc *sc = device_get_softc(self); 184 void *aux = device_get_ivars(self); 185 #endif 186 usbd_device_handle dev; 187 usbd_status err; 188 int usbrev; 189 struct usb_event ue; 190 191 #if defined(__FreeBSD__) 192 printf("%s", USBDEVNAME(sc->sc_dev)); 193 sc->sc_dev = self; 194 #endif 195 196 DPRINTF(("usbd_attach\n")); 197 198 usbd_init(); 199 sc->sc_bus = aux; 200 sc->sc_bus->usbctl = sc; 201 sc->sc_port.power = USB_MAX_POWER; 202 203 usbrev = sc->sc_bus->usbrev; 204 printf(": USB revision %s", usbrev_str[usbrev]); 205 if (usbrev != USBREV_1_0 && usbrev != USBREV_1_1) { 206 printf(", not supported\n"); 207 USB_ATTACH_ERROR_RETURN; 208 } 209 printf("\n"); 210 211 /* Make sure not to use tsleep() if we are cold booting. */ 212 if (cold) 213 sc->sc_bus->use_polling++; 214 215 ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev); 216 usb_add_event(USB_EVENT_CTRLR_ATTACH, &ue); 217 218 err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, 0, 0, 219 &sc->sc_port); 220 if (!err) { 221 dev = sc->sc_port.device; 222 if (dev->hub == NULL) { 223 sc->sc_dying = 1; 224 printf("%s: root device is not a hub\n", 225 USBDEVNAME(sc->sc_dev)); 226 USB_ATTACH_ERROR_RETURN; 227 } 228 sc->sc_bus->root_hub = dev; 229 #if 1 230 /* 231 * Turning this code off will delay attachment of USB devices 232 * until the USB event thread is running, which means that 233 * the keyboard will not work until after cold boot. 234 */ 235 if (cold && (sc->sc_dev.dv_cfdata->cf_flags & 1)) 236 dev->hub->explore(sc->sc_bus->root_hub); 237 #endif 238 } else { 239 printf("%s: root hub problem, error=%d\n", 240 USBDEVNAME(sc->sc_dev), err); 241 sc->sc_dying = 1; 242 } 243 if (cold) 244 sc->sc_bus->use_polling--; 245 246 config_pending_incr(); 247 usb_kthread_create(usb_create_event_thread, sc); 248 249 #if defined(__FreeBSD__) 250 make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR, 251 0644, "usb%d", device_get_unit(self)); 252 #endif 253 254 USB_ATTACH_SUCCESS_RETURN; 255 } 256 257 #if defined(__NetBSD__) || defined(__OpenBSD__) 258 void 259 usb_create_event_thread(void *arg) 260 { 261 struct usb_softc *sc = arg; 262 263 if (usb_kthread_create1(usb_event_thread, sc, &sc->sc_event_thread, 264 "%s", sc->sc_dev.dv_xname)) { 265 printf("%s: unable to create event thread for\n", 266 sc->sc_dev.dv_xname); 267 panic("usb_create_event_thread"); 268 } 269 } 270 271 void 272 usb_event_thread(void *arg) 273 { 274 struct usb_softc *sc = arg; 275 int first = 1; 276 277 DPRINTF(("usb_event_thread: start\n")); 278 279 /* Make sure first discover does something. */ 280 sc->sc_bus->needs_explore = 1; 281 282 while (!sc->sc_dying) { 283 #ifdef USB_DEBUG 284 if (usb_noexplore < 2) 285 #endif 286 usb_discover(sc); 287 if (first) { 288 config_pending_decr(); 289 first = 0; 290 } 291 #ifdef USB_DEBUG 292 (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt", 293 usb_noexplore ? 0 : hz * 60); 294 #else 295 (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt", 296 hz * 60); 297 #endif 298 DPRINTFN(2,("usb_event_thread: woke up\n")); 299 } 300 sc->sc_event_thread = 0; 301 302 /* In case parent is waiting for us to exit. */ 303 wakeup(sc); 304 305 DPRINTF(("usb_event_thread: exit\n")); 306 kthread_exit(0); 307 } 308 309 int 310 usbctlprint(void *aux, const char *pnp) 311 { 312 /* only "usb"es can attach to host controllers */ 313 if (pnp) 314 printf("usb at %s", pnp); 315 316 return (UNCONF); 317 } 318 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ 319 320 int 321 usbopen(dev_t dev, int flag, int mode, struct proc *p) 322 { 323 int unit = minor(dev); 324 struct usb_softc *sc; 325 326 if (unit == USB_DEV_MINOR) { 327 if (usb_dev_open) 328 return (EBUSY); 329 usb_dev_open = 1; 330 usb_async_proc = 0; 331 return (0); 332 } 333 334 USB_GET_SC_OPEN(usb, unit, sc); 335 336 if (sc->sc_dying) 337 return (EIO); 338 339 return (0); 340 } 341 342 int 343 usbread(dev_t dev, struct uio *uio, int flag) 344 { 345 struct usb_event ue; 346 int s, error, n; 347 348 if (minor(dev) != USB_DEV_MINOR) 349 return (ENXIO); 350 351 if (uio->uio_resid != sizeof(struct usb_event)) 352 return (EINVAL); 353 354 error = 0; 355 s = splusb(); 356 for (;;) { 357 n = usb_get_next_event(&ue); 358 if (n != 0) 359 break; 360 if (flag & IO_NDELAY) { 361 error = EWOULDBLOCK; 362 break; 363 } 364 error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0); 365 if (error) 366 break; 367 } 368 splx(s); 369 if (!error) 370 error = uiomove((void *)&ue, uio->uio_resid, uio); 371 372 return (error); 373 } 374 375 int 376 usbclose(dev_t dev, int flag, int mode, struct proc *p) 377 { 378 int unit = minor(dev); 379 380 if (unit == USB_DEV_MINOR) { 381 usb_async_proc = 0; 382 usb_dev_open = 0; 383 } 384 385 return (0); 386 } 387 388 int 389 usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, struct proc *p) 390 { 391 struct usb_softc *sc; 392 int unit = minor(devt); 393 394 if (unit == USB_DEV_MINOR) { 395 switch (cmd) { 396 case FIONBIO: 397 /* All handled in the upper FS layer. */ 398 return (0); 399 400 case FIOASYNC: 401 if (*(int *)data) 402 usb_async_proc = p; 403 else 404 usb_async_proc = 0; 405 return (0); 406 407 default: 408 return (EINVAL); 409 } 410 } 411 412 USB_GET_SC(usb, unit, sc); 413 414 if (sc->sc_dying) 415 return (EIO); 416 417 switch (cmd) { 418 #if defined(__FreeBSD__) 419 /* This part should be deleted when kthreads is available */ 420 case USB_DISCOVER: 421 usb_discover(sc); 422 break; 423 #endif 424 #ifdef USB_DEBUG 425 case USB_SETDEBUG: 426 usbdebug = ((*(int *)data) & 0x000000ff); 427 #ifdef UHCI_DEBUG 428 uhcidebug = ((*(int *)data) & 0x0000ff00) >> 8; 429 #endif 430 #ifdef OHCI_DEBUG 431 ohcidebug = ((*(int *)data) & 0x00ff0000) >> 16; 432 #endif 433 break; 434 #endif 435 case USB_REQUEST: 436 { 437 struct usb_ctl_request *ur = (void *)data; 438 int len = UGETW(ur->request.wLength); 439 struct iovec iov; 440 struct uio uio; 441 void *ptr = 0; 442 int addr = ur->addr; 443 usbd_status err; 444 int error = 0; 445 446 DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len)); 447 if (len < 0 || len > 32768) 448 return (EINVAL); 449 if (addr < 0 || addr >= USB_MAX_DEVICES || 450 sc->sc_bus->devices[addr] == 0) 451 return (EINVAL); 452 if (len != 0) { 453 iov.iov_base = (caddr_t)ur->data; 454 iov.iov_len = len; 455 uio.uio_iov = &iov; 456 uio.uio_iovcnt = 1; 457 uio.uio_resid = len; 458 uio.uio_offset = 0; 459 uio.uio_segflg = UIO_USERSPACE; 460 uio.uio_rw = 461 ur->request.bmRequestType & UT_READ ? 462 UIO_READ : UIO_WRITE; 463 uio.uio_procp = p; 464 ptr = malloc(len, M_TEMP, M_WAITOK); 465 if (uio.uio_rw == UIO_WRITE) { 466 error = uiomove(ptr, len, &uio); 467 if (error) 468 goto ret; 469 } 470 } 471 err = usbd_do_request_flags(sc->sc_bus->devices[addr], 472 &ur->request, ptr, ur->flags, &ur->actlen); 473 if (err) { 474 error = EIO; 475 goto ret; 476 } 477 if (len != 0) { 478 if (uio.uio_rw == UIO_READ) { 479 error = uiomove(ptr, len, &uio); 480 if (error) 481 goto ret; 482 } 483 } 484 ret: 485 if (ptr) 486 free(ptr, M_TEMP); 487 return (error); 488 } 489 490 case USB_DEVICEINFO: 491 { 492 struct usb_device_info *di = (void *)data; 493 int addr = di->addr; 494 usbd_device_handle dev; 495 496 if (addr < 1 || addr >= USB_MAX_DEVICES) 497 return (EINVAL); 498 dev = sc->sc_bus->devices[addr]; 499 if (dev == NULL) 500 return (ENXIO); 501 usbd_fill_deviceinfo(dev, di, 1); 502 break; 503 } 504 505 case USB_DEVICESTATS: 506 *(struct usb_device_stats *)data = sc->sc_bus->stats; 507 break; 508 509 default: 510 return (EINVAL); 511 } 512 return (0); 513 } 514 515 int 516 usbpoll(dev_t dev, int events, struct proc *p) 517 { 518 int revents, mask, s; 519 520 if (minor(dev) == USB_DEV_MINOR) { 521 revents = 0; 522 mask = POLLIN | POLLRDNORM; 523 524 s = splusb(); 525 if (events & mask && usb_nevents > 0) 526 revents |= events & mask; 527 if (revents == 0 && events & mask) 528 selrecord(p, &usb_selevent); 529 splx(s); 530 531 return (revents); 532 } else { 533 #if defined(__FreeBSD__) 534 /* This part should be deleted when kthreads is available */ 535 struct usb_softc *sc; 536 int unit = minor(dev); 537 538 USB_GET_SC(usb, unit, sc); 539 540 revents = 0; 541 mask = POLLOUT | POLLRDNORM; 542 543 s = splusb(); 544 if (events & mask && sc->sc_bus->needs_explore) 545 revents |= events & mask; 546 if (revents == 0 && events & mask) 547 selrecord(p, &sc->sc_consel); 548 splx(s); 549 550 return (revents); 551 #else 552 return (ENXIO); 553 #endif 554 } 555 } 556 557 /* Explore device tree from the root. */ 558 usbd_status 559 usb_discover(struct usb_softc *sc) 560 { 561 #if defined(__FreeBSD__) 562 /* The splxxx parts should be deleted when kthreads is available */ 563 int s; 564 #endif 565 566 /* 567 * We need mutual exclusion while traversing the device tree, 568 * but this is guaranteed since this function is only called 569 * from the event thread for the controller. 570 */ 571 #if defined(__FreeBSD__) 572 s = splusb(); 573 #endif 574 while (sc->sc_bus->needs_explore && !sc->sc_dying) { 575 sc->sc_bus->needs_explore = 0; 576 #if defined(__FreeBSD__) 577 splx(s); 578 #endif 579 sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub); 580 #if defined(__FreeBSD__) 581 s = splusb(); 582 #endif 583 } 584 #if defined(__FreeBSD__) 585 splx(s); 586 #endif 587 588 return (USBD_NORMAL_COMPLETION); 589 } 590 591 void 592 usb_needs_explore(usbd_bus_handle bus) 593 { 594 bus->needs_explore = 1; 595 #if defined(__FreeBSD__) 596 /* This part should be deleted when kthreads is available */ 597 selwakeup(&bus->usbctl->sc_consel); 598 #endif 599 wakeup(&bus->needs_explore); 600 } 601 602 /* Called at splusb() */ 603 int 604 usb_get_next_event(struct usb_event *ue) 605 { 606 struct usb_event_q *ueq; 607 608 if (usb_nevents <= 0) 609 return (0); 610 ueq = SIMPLEQ_FIRST(&usb_events); 611 *ue = ueq->ue; 612 SIMPLEQ_REMOVE_HEAD(&usb_events, ueq, next); 613 free(ueq, M_USBDEV); 614 usb_nevents--; 615 return (1); 616 } 617 618 void 619 usbd_add_dev_event(int type, usbd_device_handle udev) 620 { 621 struct usb_event ue; 622 623 usbd_fill_deviceinfo(udev, &ue.u.ue_device, USB_EVENT_IS_ATTACH(type)); 624 usb_add_event(type, &ue); 625 } 626 627 void 628 usbd_add_drv_event(int type, usbd_device_handle udev, device_ptr_t dev) 629 { 630 struct usb_event ue; 631 632 ue.u.ue_driver.ue_cookie = udev->cookie; 633 strncpy(ue.u.ue_driver.ue_devname, USBDEVPTRNAME(dev), 634 sizeof ue.u.ue_driver.ue_devname); 635 usb_add_event(type, &ue); 636 } 637 638 Static void 639 usb_add_event(int type, struct usb_event *uep) 640 { 641 struct usb_event_q *ueq; 642 struct usb_event ue; 643 struct timeval thetime; 644 int s; 645 646 microtime(&thetime); 647 /* Don't want to wait here inside splusb() */ 648 ueq = malloc(sizeof *ueq, M_USBDEV, M_WAITOK); 649 ueq->ue = *uep; 650 ueq->ue.ue_type = type; 651 TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time); 652 653 s = splusb(); 654 if (++usb_nevents >= USB_MAX_EVENTS) { 655 /* Too many queued events, drop an old one. */ 656 DPRINTFN(-1,("usb: event dropped\n")); 657 (void)usb_get_next_event(&ue); 658 } 659 SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next); 660 wakeup(&usb_events); 661 selwakeup(&usb_selevent); 662 if (usb_async_proc != NULL) 663 psignal(usb_async_proc, SIGIO); 664 splx(s); 665 } 666 void 667 usb_schedsoftintr(struct usbd_bus *bus) 668 { 669 bus->methods->soft_intr(bus); 670 } 671 672 #if defined(__NetBSD__) || defined(__OpenBSD__) 673 int 674 usb_activate(device_ptr_t self, enum devact act) 675 { 676 struct usb_softc *sc = (struct usb_softc *)self; 677 usbd_device_handle dev = sc->sc_port.device; 678 int i, rv = 0; 679 680 switch (act) { 681 case DVACT_ACTIVATE: 682 return (EOPNOTSUPP); 683 break; 684 685 case DVACT_DEACTIVATE: 686 sc->sc_dying = 1; 687 if (dev && dev->cdesc && dev->subdevs) { 688 for (i = 0; dev->subdevs[i]; i++) 689 rv |= config_deactivate(dev->subdevs[i]); 690 } 691 break; 692 } 693 return (rv); 694 } 695 696 int 697 usb_detach(device_ptr_t self, int flags) 698 { 699 struct usb_softc *sc = (struct usb_softc *)self; 700 struct usb_event ue; 701 702 DPRINTF(("usb_detach: start\n")); 703 704 sc->sc_dying = 1; 705 706 /* Make all devices disconnect. */ 707 if (sc->sc_port.device) 708 usb_disconnect_port(&sc->sc_port, self); 709 710 /* Kill off event thread. */ 711 if (sc->sc_event_thread) { 712 wakeup(&sc->sc_bus->needs_explore); 713 if (tsleep(sc, PWAIT, "usbdet", hz * 60)) 714 printf("%s: event thread didn't die\n", 715 USBDEVNAME(sc->sc_dev)); 716 DPRINTF(("usb_detach: event thread dead\n")); 717 } 718 719 usbd_finish(); 720 721 ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev); 722 usb_add_event(USB_EVENT_CTRLR_DETACH, &ue); 723 724 return (0); 725 } 726 #elif defined(__FreeBSD__) 727 int 728 usb_detach(device_t self) 729 { 730 DPRINTF(("%s: unload, prevented\n", USBDEVNAME(self))); 731 732 return (EINVAL); 733 } 734 #endif 735 736 737 #if defined(__FreeBSD__) 738 DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0); 739 DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0); 740 #endif 741