1 /* $OpenBSD: usb.c,v 1.7 1999/11/11 15:57:40 ho Exp $ */ 2 /* $NetBSD: usb.c,v 1.28 1999/10/13 08:10:57 augustss 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 #elif defined(__FreeBSD__) 55 #include <sys/module.h> 56 #include <sys/bus.h> 57 #include <sys/ioccom.h> 58 #include <sys/uio.h> 59 #endif 60 #include <sys/conf.h> 61 #include <sys/poll.h> 62 #include <sys/proc.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 int uhcidebug; 91 int ohcidebug; 92 int usb_noexplore = 0; 93 #else 94 #define DPRINTF(x) 95 #define DPRINTFN(n,x) 96 #endif 97 98 struct usb_softc { 99 USBBASEDEVICE sc_dev; /* base device */ 100 usbd_bus_handle sc_bus; /* USB controller */ 101 struct usbd_port sc_port; /* dummy port for root hub */ 102 103 struct selinfo sc_consel; /* waiting for connect change */ 104 struct proc *sc_event_thread; 105 106 char sc_dying; 107 }; 108 109 #if defined(__NetBSD__) || defined(__OpenBSD__) 110 cdev_decl(usb); 111 #elif defined(__FreeBSD__) 112 d_open_t usbopen; 113 d_close_t usbclose; 114 d_ioctl_t usbioctl; 115 int usbpoll __P((dev_t, int, struct proc *)); 116 117 struct cdevsw usb_cdevsw = { 118 /* open */ usbopen, 119 /* close */ usbclose, 120 /* read */ noread, 121 /* write */ nowrite, 122 /* ioctl */ usbioctl, 123 /* poll */ usbpoll, 124 /* mmap */ nommap, 125 /* strategy */ nostrategy, 126 /* name */ "usb", 127 /* maj */ USB_CDEV_MAJOR, 128 /* dump */ nodump, 129 /* psize */ nopsize, 130 /* flags */ 0, 131 /* bmaj */ -1 132 }; 133 #endif 134 135 usbd_status usb_discover __P((struct usb_softc *)); 136 void usb_create_event_thread __P((void *)); 137 void usb_event_thread __P((void *)); 138 139 #define USB_MAX_EVENTS 50 140 struct usb_event_q { 141 struct usb_event ue; 142 SIMPLEQ_ENTRY(usb_event_q) next; 143 }; 144 SIMPLEQ_HEAD(, usb_event_q) usb_events = SIMPLEQ_HEAD_INITIALIZER(usb_events); 145 int usb_nevents = 0; 146 struct selinfo usb_selevent; 147 struct proc *usb_async_proc; /* process who wants USB SIGIO */ 148 int usb_dev_open = 0; 149 150 int usb_get_next_event __P((struct usb_event *)); 151 152 /* Flag to see if we are in the cold boot process. */ 153 extern int cold; 154 155 USB_DECLARE_DRIVER(usb); 156 157 USB_MATCH(usb) 158 { 159 DPRINTF(("usbd_match\n")); 160 return (UMATCH_GENERIC); 161 } 162 163 USB_ATTACH(usb) 164 { 165 #if defined(__NetBSD__) || defined(__OpenBSD__) 166 struct usb_softc *sc = (struct usb_softc *)self; 167 #elif defined(__FreeBSD__) 168 struct usb_softc *sc = device_get_softc(self); 169 void *aux = device_get_ivars(self); 170 #endif 171 usbd_device_handle dev; 172 usbd_status r; 173 174 #if defined(__NetBSD__) || defined(__OpenBSD__) 175 printf("\n"); 176 #elif defined(__FreeBSD__) 177 sc->sc_dev = self; 178 #endif 179 180 DPRINTF(("usbd_attach\n")); 181 usbd_init(); 182 sc->sc_bus = aux; 183 sc->sc_bus->usbctl = sc; 184 sc->sc_port.power = USB_MAX_POWER; 185 r = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, 0, 0, 186 &sc->sc_port); 187 188 if (r == USBD_NORMAL_COMPLETION) { 189 dev = sc->sc_port.device; 190 if (!dev->hub) { 191 sc->sc_dying = 1; 192 printf("%s: root device is not a hub\n", 193 USBDEVNAME(sc->sc_dev)); 194 USB_ATTACH_ERROR_RETURN; 195 } 196 sc->sc_bus->root_hub = dev; 197 #if 0 198 /* 199 * Turning this code off will delay attachment of USB devices 200 * until the USB event thread is running, which means that 201 * the keyboard will not work until after cold boot. 202 */ 203 if (cold) { 204 sc->sc_bus->use_polling++; 205 dev->hub->explore(sc->sc_bus->root_hub); 206 sc->sc_bus->use_polling--; 207 } 208 #endif 209 } else { 210 printf("%s: root hub problem, error=%d\n", 211 USBDEVNAME(sc->sc_dev), r); 212 sc->sc_dying = 1; 213 } 214 215 #if defined(__NetBSD__) 216 kthread_create(usb_create_event_thread, sc); 217 #elif defined(__OpenBSD__) 218 kthread_create_deferred(usb_create_event_thread, sc); 219 #endif 220 221 #if defined(__FreeBSD__) 222 make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR, 223 0644, "usb%d", device_get_unit(self)); 224 #endif 225 226 USB_ATTACH_SUCCESS_RETURN; 227 } 228 229 #if defined(__NetBSD__) || defined(__OpenBSD__) 230 void 231 usb_create_event_thread(arg) 232 void *arg; 233 { 234 struct usb_softc *sc = arg; 235 236 #if defined(__NetBSD__) 237 if (kthread_create1(usb_event_thread, sc, &sc->sc_event_thread, 238 #else 239 if (kthread_create(usb_event_thread, sc, &sc->sc_event_thread, 240 #endif 241 "%s", sc->sc_dev.dv_xname)) { 242 printf("%s: unable to create event thread for\n", 243 sc->sc_dev.dv_xname); 244 panic("usb_create_event_thread"); 245 } 246 } 247 248 void 249 usb_event_thread(arg) 250 void *arg; 251 { 252 struct usb_softc *sc = arg; 253 254 DPRINTF(("usb_event_thread: start\n")); 255 256 while (!sc->sc_dying) { 257 #ifdef USB_DEBUG 258 if (!usb_noexplore) 259 #endif 260 usb_discover(sc); 261 (void)tsleep(&sc->sc_bus->needs_explore, 262 PWAIT, "usbevt", hz*60); 263 DPRINTFN(2,("usb_event_thread: woke up\n")); 264 } 265 sc->sc_event_thread = 0; 266 267 /* In case parent is waiting for us to exit. */ 268 wakeup(sc); 269 270 DPRINTF(("usb_event_thread: exit\n")); 271 kthread_exit(0); 272 } 273 274 int 275 usbctlprint(aux, pnp) 276 void *aux; 277 const char *pnp; 278 { 279 /* only "usb"es can attach to host controllers */ 280 if (pnp) 281 printf("usb at %s", pnp); 282 283 return (UNCONF); 284 } 285 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ 286 287 int 288 usbopen(dev, flag, mode, p) 289 dev_t dev; 290 int flag, mode; 291 struct proc *p; 292 { 293 int unit = minor(dev); 294 struct usb_softc *sc; 295 296 if (unit == USB_DEV_MINOR) { 297 if (usb_dev_open) 298 return (EBUSY); 299 usb_dev_open = 1; 300 usb_async_proc = 0; 301 return (0); 302 } 303 304 USB_GET_SC_OPEN(usb, unit, sc); 305 306 if (sc->sc_dying) 307 return (EIO); 308 309 return (0); 310 } 311 312 int 313 usbread(dev, uio, flag) 314 dev_t dev; 315 struct uio *uio; 316 int flag; 317 { 318 struct usb_event ue; 319 int s, error, n; 320 321 if (minor(dev) != USB_DEV_MINOR) 322 return (ENXIO); 323 324 if (uio->uio_resid != sizeof(struct usb_event)) 325 return (EINVAL); 326 327 error = 0; 328 s = splusb(); 329 for (;;) { 330 n = usb_get_next_event(&ue); 331 if (n != 0) 332 break; 333 if (flag & IO_NDELAY) { 334 error = EWOULDBLOCK; 335 break; 336 } 337 error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0); 338 if (error) 339 break; 340 } 341 splx(s); 342 if (!error) 343 error = uiomove((caddr_t)&ue, uio->uio_resid, uio); 344 345 return (error); 346 } 347 348 int 349 usbclose(dev, flag, mode, p) 350 dev_t dev; 351 int flag, mode; 352 struct proc *p; 353 { 354 int unit = minor(dev); 355 356 if (unit == USB_DEV_MINOR) { 357 usb_async_proc = 0; 358 usb_dev_open = 0; 359 } 360 361 return (0); 362 } 363 364 int 365 usbioctl(devt, cmd, data, flag, p) 366 dev_t devt; 367 u_long cmd; 368 caddr_t data; 369 int flag; 370 struct proc *p; 371 { 372 struct usb_softc *sc; 373 int unit = minor(devt); 374 375 if (unit == USB_DEV_MINOR) { 376 switch (cmd) { 377 case FIONBIO: 378 /* All handled in the upper FS layer. */ 379 return (0); 380 381 case FIOASYNC: 382 if (*(int *)data) 383 usb_async_proc = p; 384 else 385 usb_async_proc = 0; 386 return (0); 387 388 default: 389 return (EINVAL); 390 } 391 } 392 393 USB_GET_SC(usb, unit, sc); 394 395 if (sc->sc_dying) 396 return (EIO); 397 398 switch (cmd) { 399 #if defined(__FreeBSD__) 400 case USB_DISCOVER: 401 usb_discover(sc); 402 break; 403 #endif 404 #ifdef USB_DEBUG 405 case USB_SETDEBUG: 406 usbdebug = uhcidebug = ohcidebug = *(int *)data; 407 break; 408 #endif 409 case USB_REQUEST: 410 { 411 struct usb_ctl_request *ur = (void *)data; 412 int len = UGETW(ur->request.wLength); 413 struct iovec iov; 414 struct uio uio; 415 void *ptr = 0; 416 int addr = ur->addr; 417 usbd_status r; 418 int error = 0; 419 420 DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len)); 421 if (len < 0 || len > 32768) 422 return (EINVAL); 423 if (addr < 0 || addr >= USB_MAX_DEVICES || 424 sc->sc_bus->devices[addr] == 0) 425 return (EINVAL); 426 if (len != 0) { 427 iov.iov_base = (caddr_t)ur->data; 428 iov.iov_len = len; 429 uio.uio_iov = &iov; 430 uio.uio_iovcnt = 1; 431 uio.uio_resid = len; 432 uio.uio_offset = 0; 433 uio.uio_segflg = UIO_USERSPACE; 434 uio.uio_rw = 435 ur->request.bmRequestType & UT_READ ? 436 UIO_READ : UIO_WRITE; 437 uio.uio_procp = p; 438 ptr = malloc(len, M_TEMP, M_WAITOK); 439 if (uio.uio_rw == UIO_WRITE) { 440 error = uiomove(ptr, len, &uio); 441 if (error) 442 goto ret; 443 } 444 } 445 r = usbd_do_request_flags(sc->sc_bus->devices[addr], 446 &ur->request, ptr, 447 ur->flags, &ur->actlen); 448 if (r != USBD_NORMAL_COMPLETION) { 449 error = EIO; 450 goto ret; 451 } 452 if (len != 0) { 453 if (uio.uio_rw == UIO_READ) { 454 error = uiomove(ptr, len, &uio); 455 if (error) 456 goto ret; 457 } 458 } 459 ret: 460 if (ptr) 461 free(ptr, M_TEMP); 462 return (error); 463 } 464 465 case USB_DEVICEINFO: 466 { 467 struct usb_device_info *di = (void *)data; 468 int addr = di->addr; 469 usbd_device_handle devh; 470 471 if (addr < 1 || addr >= USB_MAX_DEVICES) 472 return (EINVAL); 473 devh = sc->sc_bus->devices[addr]; 474 if (devh == 0) 475 return (ENXIO); 476 usbd_fill_deviceinfo(devh, di); 477 break; 478 } 479 480 case USB_DEVICESTATS: 481 *(struct usb_device_stats *)data = sc->sc_bus->stats; 482 break; 483 484 default: 485 return (EINVAL); 486 } 487 return (0); 488 } 489 490 int 491 usbpoll(dev, events, p) 492 dev_t dev; 493 int events; 494 struct proc *p; 495 { 496 int revents, mask, s; 497 498 if (minor(dev) != USB_DEV_MINOR) 499 return (ENXIO); 500 501 revents = 0; 502 s = splusb(); 503 mask = POLLIN | POLLRDNORM; 504 if (events & mask) 505 if (usb_nevents > 0) 506 revents |= events & mask; 507 508 DPRINTFN(2, ("usbpoll: revents=0x%x\n", revents)); 509 if (revents == 0) { 510 if (events & mask) { 511 DPRINTFN(2, ("usbpoll: selrecord\n")); 512 selrecord(p, &usb_selevent); 513 } 514 } 515 splx(s); 516 return (revents); 517 } 518 519 /* Explore device tree from the root. */ 520 usbd_status 521 usb_discover(sc) 522 struct usb_softc *sc; 523 { 524 /* 525 * We need mutual exclusion while traversing the device tree, 526 * but this is guaranteed since this function is only called 527 * from the event thread for the controller. 528 */ 529 do { 530 sc->sc_bus->needs_explore = 0; 531 sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub); 532 } while (sc->sc_bus->needs_explore && !sc->sc_dying); 533 return (USBD_NORMAL_COMPLETION); 534 } 535 536 void 537 usb_needs_explore(bus) 538 usbd_bus_handle bus; 539 { 540 bus->needs_explore = 1; 541 wakeup(&bus->needs_explore); 542 } 543 544 /* Called at splusb() */ 545 int 546 usb_get_next_event(ue) 547 struct usb_event *ue; 548 { 549 struct usb_event_q *ueq; 550 551 if (usb_nevents <= 0) 552 return (0); 553 ueq = SIMPLEQ_FIRST(&usb_events); 554 *ue = ueq->ue; 555 SIMPLEQ_REMOVE_HEAD(&usb_events, ueq, next); 556 free(ueq, M_USBDEV); 557 usb_nevents--; 558 return (1); 559 } 560 561 void 562 usbd_add_event(type, devh) 563 int type; 564 usbd_device_handle devh; 565 { 566 struct usb_event_q *ueq; 567 struct usb_event ue; 568 struct timeval thetime; 569 int s; 570 571 s = splusb(); 572 if (++usb_nevents >= USB_MAX_EVENTS) { 573 /* Too many queued events, drop an old one. */ 574 DPRINTFN(-1,("usb: event dropped\n")); 575 (void)usb_get_next_event(&ue); 576 } 577 /* Don't want to wait here inside splusb() */ 578 ueq = malloc(sizeof *ueq, M_USBDEV, M_NOWAIT); 579 if (ueq == 0) { 580 printf("usb: no memory, event dropped\n"); 581 splx(s); 582 return; 583 } 584 ueq->ue.ue_type = type; 585 ueq->ue.ue_cookie = devh->cookie; 586 usbd_fill_deviceinfo(devh, &ueq->ue.ue_device); 587 microtime(&thetime); 588 TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time); 589 SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next); 590 wakeup(&usb_events); 591 selwakeup(&usb_selevent); 592 if (usb_async_proc) 593 psignal(usb_async_proc, SIGIO); 594 splx(s); 595 } 596 597 #if defined(__NetBSD__) || defined(__OpenBSD__) 598 int 599 usb_activate(self, act) 600 device_ptr_t self; 601 enum devact act; 602 { 603 struct usb_softc *sc = (struct usb_softc *)self; 604 usbd_device_handle dev = sc->sc_port.device; 605 int i, rv = 0; 606 607 switch (act) { 608 case DVACT_ACTIVATE: 609 return (EOPNOTSUPP); 610 break; 611 612 case DVACT_DEACTIVATE: 613 sc->sc_dying = 1; 614 if (dev && dev->cdesc && dev->subdevs) { 615 for (i = 0; dev->subdevs[i]; i++) 616 rv |= config_deactivate(dev->subdevs[i]); 617 } 618 break; 619 } 620 return (rv); 621 } 622 623 int 624 usb_detach(self, flags) 625 device_ptr_t self; 626 int flags; 627 { 628 struct usb_softc *sc = (struct usb_softc *)self; 629 630 DPRINTF(("usb_detach: start\n")); 631 632 sc->sc_dying = 1; 633 634 /* Make all devices disconnect. */ 635 if (sc->sc_port.device) 636 usb_disconnect_port(&sc->sc_port, self); 637 638 /* Kill off event thread. */ 639 if (sc->sc_event_thread) { 640 wakeup(&sc->sc_bus->needs_explore); 641 if (tsleep(sc, PWAIT, "usbdet", hz * 60)) 642 printf("%s: event thread didn't die\n", 643 USBDEVNAME(sc->sc_dev)); 644 DPRINTF(("usb_detach: event thread dead\n")); 645 } 646 647 usbd_finish(); 648 return (0); 649 } 650 #elif defined(__FreeBSD__) 651 int 652 usb_detach(device_t self) 653 { 654 DPRINTF(("%s: unload, prevented\n", USBDEVNAME(self))); 655 656 return (EINVAL); 657 } 658 #endif 659 660 661 #if defined(__FreeBSD__) 662 DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0); 663 DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0); 664 #endif 665