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