1 /* $NetBSD: usb.c,v 1.101 2007/10/19 12:01:22 ad Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson (lennart@augustsson.net) at 9 * Carlstedt Research & Technology. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * USB specifications and other documentation can be found at 42 * http://www.usb.org/developers/docs/ and 43 * http://www.usb.org/developers/devclass_docs/ 44 */ 45 46 #include <sys/cdefs.h> 47 __KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.101 2007/10/19 12:01:22 ad Exp $"); 48 49 #include "opt_compat_netbsd.h" 50 51 #include "ohci.h" 52 #include "uhci.h" 53 54 #include <sys/param.h> 55 #include <sys/systm.h> 56 #include <sys/kernel.h> 57 #include <sys/malloc.h> 58 #include <sys/device.h> 59 #include <sys/kthread.h> 60 #include <sys/proc.h> 61 #include <sys/conf.h> 62 #include <sys/fcntl.h> 63 #include <sys/poll.h> 64 #include <sys/select.h> 65 #include <sys/vnode.h> 66 #include <sys/signalvar.h> 67 #include <sys/intr.h> 68 69 #include <dev/usb/usb.h> 70 #include <dev/usb/usbdi.h> 71 #include <dev/usb/usbdi_util.h> 72 73 #define USB_DEV_MINOR 255 74 75 #include <sys/bus.h> 76 77 #include <dev/usb/usbdivar.h> 78 #include <dev/usb/usb_quirks.h> 79 80 #ifdef USB_DEBUG 81 #define DPRINTF(x) if (usbdebug) logprintf x 82 #define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x 83 int usbdebug = 0; 84 #if defined(UHCI_DEBUG) && NUHCI > 0 85 extern int uhcidebug; 86 #endif 87 #if defined(OHCI_DEBUG) && NOHCI > 0 88 extern int ohcidebug; 89 #endif 90 /* 91 * 0 - do usual exploration 92 * 1 - do not use timeout exploration 93 * >1 - do no exploration 94 */ 95 int usb_noexplore = 0; 96 #else 97 #define DPRINTF(x) 98 #define DPRINTFN(n,x) 99 #endif 100 101 struct usb_softc { 102 USBBASEDEVICE sc_dev; /* base device */ 103 usbd_bus_handle sc_bus; /* USB controller */ 104 struct usbd_port sc_port; /* dummy port for root hub */ 105 106 struct lwp *sc_event_thread; 107 108 char sc_dying; 109 }; 110 111 struct usb_taskq { 112 TAILQ_HEAD(, usb_task) tasks; 113 struct lwp *task_thread_lwp; 114 const char *name; 115 int taskcreated; /* task thread exists. */ 116 }; 117 118 static struct usb_taskq usb_taskq[USB_NUM_TASKQS]; 119 120 dev_type_open(usbopen); 121 dev_type_close(usbclose); 122 dev_type_read(usbread); 123 dev_type_ioctl(usbioctl); 124 dev_type_poll(usbpoll); 125 dev_type_kqfilter(usbkqfilter); 126 127 const struct cdevsw usb_cdevsw = { 128 usbopen, usbclose, usbread, nowrite, usbioctl, 129 nostop, notty, usbpoll, nommap, usbkqfilter, D_OTHER, 130 }; 131 132 Static void usb_discover(void *); 133 Static void usb_create_event_thread(void *); 134 Static void usb_event_thread(void *); 135 Static void usb_task_thread(void *); 136 137 #define USB_MAX_EVENTS 100 138 struct usb_event_q { 139 struct usb_event ue; 140 SIMPLEQ_ENTRY(usb_event_q) next; 141 }; 142 Static SIMPLEQ_HEAD(, usb_event_q) usb_events = 143 SIMPLEQ_HEAD_INITIALIZER(usb_events); 144 Static int usb_nevents = 0; 145 Static struct selinfo usb_selevent; 146 Static usb_proc_ptr usb_async_proc; /* process that wants USB SIGIO */ 147 Static int usb_dev_open = 0; 148 Static struct usb_event *usb_alloc_event(void); 149 Static void usb_free_event(struct usb_event *); 150 Static void usb_add_event(int, struct usb_event *); 151 152 Static int usb_get_next_event(struct usb_event *); 153 154 #ifdef COMPAT_30 155 Static void usb_copy_old_devinfo(struct usb_device_info_old *, const struct usb_device_info *); 156 #endif 157 158 Static const char *usbrev_str[] = USBREV_STR; 159 160 USB_DECLARE_DRIVER(usb); 161 162 USB_MATCH(usb) 163 { 164 DPRINTF(("usbd_match\n")); 165 return (UMATCH_GENERIC); 166 } 167 168 USB_ATTACH(usb) 169 { 170 struct usb_softc *sc = (struct usb_softc *)self; 171 usbd_device_handle dev; 172 usbd_status err; 173 int usbrev; 174 int speed; 175 struct usb_event *ue; 176 177 DPRINTF(("usbd_attach\n")); 178 179 sc->sc_bus = aux; 180 sc->sc_bus->usbctl = sc; 181 sc->sc_port.power = USB_MAX_POWER; 182 183 usbrev = sc->sc_bus->usbrev; 184 printf(": USB revision %s", usbrev_str[usbrev]); 185 switch (usbrev) { 186 case USBREV_1_0: 187 case USBREV_1_1: 188 speed = USB_SPEED_FULL; 189 break; 190 case USBREV_2_0: 191 speed = USB_SPEED_HIGH; 192 break; 193 default: 194 printf(", not supported\n"); 195 sc->sc_dying = 1; 196 USB_ATTACH_ERROR_RETURN; 197 } 198 printf("\n"); 199 200 /* Make sure not to use tsleep() if we are cold booting. */ 201 if (cold) 202 sc->sc_bus->use_polling++; 203 204 ue = usb_alloc_event(); 205 ue->u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev); 206 usb_add_event(USB_EVENT_CTRLR_ATTACH, ue); 207 208 #ifdef USB_USE_SOFTINTR 209 /* XXX we should have our own level */ 210 sc->sc_bus->soft = softint_establish(SOFTINT_NET, 211 sc->sc_bus->methods->soft_intr, sc->sc_bus); 212 if (sc->sc_bus->soft == NULL) { 213 printf("%s: can't register softintr\n", USBDEVNAME(sc->sc_dev)); 214 sc->sc_dying = 1; 215 USB_ATTACH_ERROR_RETURN; 216 } 217 #endif 218 219 err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, speed, 0, 220 &sc->sc_port); 221 if (!err) { 222 dev = sc->sc_port.device; 223 if (dev->hub == NULL) { 224 sc->sc_dying = 1; 225 printf("%s: root device is not a hub\n", 226 USBDEVNAME(sc->sc_dev)); 227 USB_ATTACH_ERROR_RETURN; 228 } 229 sc->sc_bus->root_hub = dev; 230 #if 1 231 /* 232 * Turning this code off will delay attachment of USB devices 233 * until the USB event thread is running, which means that 234 * the keyboard will not work until after cold boot. 235 */ 236 if (cold && (device_cfdata(&sc->sc_dev)->cf_flags & 1)) 237 dev->hub->explore(sc->sc_bus->root_hub); 238 #endif 239 } else { 240 printf("%s: root hub problem, error=%d\n", 241 USBDEVNAME(sc->sc_dev), err); 242 sc->sc_dying = 1; 243 } 244 if (cold) 245 sc->sc_bus->use_polling--; 246 247 config_pending_incr(); 248 usb_kthread_create(usb_create_event_thread, sc); 249 250 USB_ATTACH_SUCCESS_RETURN; 251 } 252 253 static const char *taskq_names[] = USB_TASKQ_NAMES; 254 255 #if defined(__NetBSD__) || defined(__OpenBSD__) 256 void 257 usb_create_event_thread(void *arg) 258 { 259 struct usb_softc *sc = arg; 260 struct usb_taskq *taskq; 261 int i; 262 263 if (usb_kthread_create1(PRI_NONE, 0, NULL, usb_event_thread, sc, 264 &sc->sc_event_thread, "%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 for (i = 0; i < USB_NUM_TASKQS; i++) { 270 taskq = &usb_taskq[i]; 271 272 if (taskq->taskcreated) 273 continue; 274 275 TAILQ_INIT(&taskq->tasks); 276 taskq->taskcreated = 1; 277 taskq->name = taskq_names[i]; 278 if (usb_kthread_create1(PRI_NONE, 0, NULL, usb_task_thread, 279 taskq, &taskq->task_thread_lwp, taskq->name)) { 280 printf("unable to create task thread: %s\n", taskq->name); 281 panic("usb_create_event_thread task"); 282 } 283 } 284 } 285 286 /* 287 * Add a task to be performed by the task thread. This function can be 288 * called from any context and the task will be executed in a process 289 * context ASAP. 290 */ 291 void 292 usb_add_task(usbd_device_handle dev, struct usb_task *task, int queue) 293 { 294 struct usb_taskq *taskq; 295 int s; 296 297 taskq = &usb_taskq[queue]; 298 s = splusb(); 299 if (task->queue == -1) { 300 DPRINTFN(2,("usb_add_task: task=%p\n", task)); 301 TAILQ_INSERT_TAIL(&taskq->tasks, task, next); 302 task->queue = queue; 303 } else { 304 DPRINTFN(3,("usb_add_task: task=%p on q\n", task)); 305 } 306 wakeup(&taskq->tasks); 307 splx(s); 308 } 309 310 void 311 usb_rem_task(usbd_device_handle dev, struct usb_task *task) 312 { 313 struct usb_taskq *taskq; 314 int s; 315 316 taskq = &usb_taskq[task->queue]; 317 s = splusb(); 318 if (task->queue != -1) { 319 TAILQ_REMOVE(&taskq->tasks, task, next); 320 task->queue = -1; 321 } 322 splx(s); 323 } 324 325 void 326 usb_event_thread(void *arg) 327 { 328 struct usb_softc *sc = arg; 329 330 DPRINTF(("usb_event_thread: start\n")); 331 332 /* 333 * In case this controller is a companion controller to an 334 * EHCI controller we need to wait until the EHCI controller 335 * has grabbed the port. 336 * XXX It would be nicer to do this with a tsleep(), but I don't 337 * know how to synchronize the creation of the threads so it 338 * will work. 339 */ 340 usb_delay_ms(sc->sc_bus, 500); 341 342 /* Make sure first discover does something. */ 343 sc->sc_bus->needs_explore = 1; 344 usb_discover(sc); 345 config_pending_decr(); 346 347 while (!sc->sc_dying) { 348 #ifdef USB_DEBUG 349 if (usb_noexplore < 2) 350 #endif 351 usb_discover(sc); 352 #ifdef USB_DEBUG 353 (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt", 354 usb_noexplore ? 0 : hz * 60); 355 #else 356 (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt", 357 hz * 60); 358 #endif 359 DPRINTFN(2,("usb_event_thread: woke up\n")); 360 } 361 sc->sc_event_thread = NULL; 362 363 /* In case parent is waiting for us to exit. */ 364 wakeup(sc); 365 366 DPRINTF(("usb_event_thread: exit\n")); 367 kthread_exit(0); 368 } 369 370 void 371 usb_task_thread(void *arg) 372 { 373 struct usb_task *task; 374 struct usb_taskq *taskq; 375 int s; 376 377 taskq = arg; 378 DPRINTF(("usb_task_thread: start taskq %s\n", taskq->name)); 379 380 s = splusb(); 381 for (;;) { 382 task = TAILQ_FIRST(&taskq->tasks); 383 if (task == NULL) { 384 tsleep(&taskq->tasks, PWAIT, "usbtsk", 0); 385 task = TAILQ_FIRST(&taskq->tasks); 386 } 387 DPRINTFN(2,("usb_task_thread: woke up task=%p\n", task)); 388 if (task != NULL) { 389 TAILQ_REMOVE(&taskq->tasks, task, next); 390 task->queue = -1; 391 splx(s); 392 task->fun(task->arg); 393 s = splusb(); 394 } 395 } 396 } 397 398 int 399 usbctlprint(void *aux, const char *pnp) 400 { 401 /* only "usb"es can attach to host controllers */ 402 if (pnp) 403 aprint_normal("usb at %s", pnp); 404 405 return (UNCONF); 406 } 407 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ 408 409 int 410 usbopen(dev_t dev, int flag, int mode, struct lwp *l) 411 { 412 int unit = minor(dev); 413 struct usb_softc *sc; 414 415 if (unit == USB_DEV_MINOR) { 416 if (usb_dev_open) 417 return (EBUSY); 418 usb_dev_open = 1; 419 usb_async_proc = 0; 420 return (0); 421 } 422 423 USB_GET_SC_OPEN(usb, unit, sc); 424 425 if (sc->sc_dying) 426 return (EIO); 427 428 return (0); 429 } 430 431 int 432 usbread(dev_t dev, struct uio *uio, int flag) 433 { 434 struct usb_event *ue; 435 #ifdef COMPAT_30 436 struct usb_event_old *ueo = NULL; /* XXXGCC */ 437 #endif 438 int s, error, n, useold; 439 440 if (minor(dev) != USB_DEV_MINOR) 441 return (ENXIO); 442 443 useold = 0; 444 switch (uio->uio_resid) { 445 #ifdef COMPAT_30 446 case sizeof(struct usb_event_old): 447 ueo = malloc(sizeof(struct usb_event_old), M_USBDEV, 448 M_WAITOK|M_ZERO); 449 useold = 1; 450 /* FALLTHRU */ 451 #endif 452 case sizeof(struct usb_event): 453 ue = usb_alloc_event(); 454 break; 455 default: 456 return (EINVAL); 457 } 458 459 error = 0; 460 s = splusb(); 461 for (;;) { 462 n = usb_get_next_event(ue); 463 if (n != 0) 464 break; 465 if (flag & IO_NDELAY) { 466 error = EWOULDBLOCK; 467 break; 468 } 469 error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0); 470 if (error) 471 break; 472 } 473 splx(s); 474 if (!error) { 475 #ifdef COMPAT_30 476 if (useold) { /* copy fields to old struct */ 477 ueo->ue_type = ue->ue_type; 478 memcpy(&ueo->ue_time, &ue->ue_time, 479 sizeof(struct timespec)); 480 switch (ue->ue_type) { 481 case USB_EVENT_DEVICE_ATTACH: 482 case USB_EVENT_DEVICE_DETACH: 483 usb_copy_old_devinfo(&ueo->u.ue_device, &ue->u.ue_device); 484 break; 485 486 case USB_EVENT_CTRLR_ATTACH: 487 case USB_EVENT_CTRLR_DETACH: 488 ueo->u.ue_ctrlr.ue_bus=ue->u.ue_ctrlr.ue_bus; 489 break; 490 491 case USB_EVENT_DRIVER_ATTACH: 492 case USB_EVENT_DRIVER_DETACH: 493 ueo->u.ue_driver.ue_cookie=ue->u.ue_driver.ue_cookie; 494 memcpy(ueo->u.ue_driver.ue_devname, 495 ue->u.ue_driver.ue_devname, 496 sizeof(ue->u.ue_driver.ue_devname)); 497 break; 498 default: 499 ; 500 } 501 502 error = uiomove((void *)ueo, uio->uio_resid, uio); 503 } else 504 #endif 505 error = uiomove((void *)ue, uio->uio_resid, uio); 506 } 507 usb_free_event(ue); 508 #ifdef COMPAT_30 509 if (useold) 510 free(ueo, M_USBDEV); 511 #endif 512 513 return (error); 514 } 515 516 int 517 usbclose(dev_t dev, int flag, int mode, 518 struct lwp *l) 519 { 520 int unit = minor(dev); 521 522 if (unit == USB_DEV_MINOR) { 523 usb_async_proc = 0; 524 usb_dev_open = 0; 525 } 526 527 return (0); 528 } 529 530 int 531 usbioctl(dev_t devt, u_long cmd, void *data, int flag, struct lwp *l) 532 { 533 struct usb_softc *sc; 534 int unit = minor(devt); 535 536 if (unit == USB_DEV_MINOR) { 537 switch (cmd) { 538 case FIONBIO: 539 /* All handled in the upper FS layer. */ 540 return (0); 541 542 case FIOASYNC: 543 if (*(int *)data) 544 usb_async_proc = l->l_proc; 545 else 546 usb_async_proc = 0; 547 return (0); 548 549 default: 550 return (EINVAL); 551 } 552 } 553 554 USB_GET_SC(usb, unit, sc); 555 556 if (sc->sc_dying) 557 return (EIO); 558 559 switch (cmd) { 560 #ifdef USB_DEBUG 561 case USB_SETDEBUG: 562 if (!(flag & FWRITE)) 563 return (EBADF); 564 usbdebug = ((*(int *)data) & 0x000000ff); 565 #if defined(UHCI_DEBUG) && NUHCI > 0 566 uhcidebug = ((*(int *)data) & 0x0000ff00) >> 8; 567 #endif 568 #if defined(OHCI_DEBUG) && NOHCI > 0 569 ohcidebug = ((*(int *)data) & 0x00ff0000) >> 16; 570 #endif 571 break; 572 #endif /* USB_DEBUG */ 573 case USB_REQUEST: 574 { 575 struct usb_ctl_request *ur = (void *)data; 576 int len = UGETW(ur->ucr_request.wLength); 577 struct iovec iov; 578 struct uio uio; 579 void *ptr = 0; 580 int addr = ur->ucr_addr; 581 usbd_status err; 582 int error = 0; 583 584 if (!(flag & FWRITE)) 585 return (EBADF); 586 587 DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len)); 588 if (len < 0 || len > 32768) 589 return (EINVAL); 590 if (addr < 0 || addr >= USB_MAX_DEVICES || 591 sc->sc_bus->devices[addr] == 0) 592 return (EINVAL); 593 if (len != 0) { 594 iov.iov_base = (void *)ur->ucr_data; 595 iov.iov_len = len; 596 uio.uio_iov = &iov; 597 uio.uio_iovcnt = 1; 598 uio.uio_resid = len; 599 uio.uio_offset = 0; 600 uio.uio_rw = 601 ur->ucr_request.bmRequestType & UT_READ ? 602 UIO_READ : UIO_WRITE; 603 uio.uio_vmspace = l->l_proc->p_vmspace; 604 ptr = malloc(len, M_TEMP, M_WAITOK); 605 if (uio.uio_rw == UIO_WRITE) { 606 error = uiomove(ptr, len, &uio); 607 if (error) 608 goto ret; 609 } 610 } 611 err = usbd_do_request_flags(sc->sc_bus->devices[addr], 612 &ur->ucr_request, ptr, ur->ucr_flags, &ur->ucr_actlen, 613 USBD_DEFAULT_TIMEOUT); 614 if (err) { 615 error = EIO; 616 goto ret; 617 } 618 if (len != 0) { 619 if (uio.uio_rw == UIO_READ) { 620 error = uiomove(ptr, len, &uio); 621 if (error) 622 goto ret; 623 } 624 } 625 ret: 626 if (ptr) 627 free(ptr, M_TEMP); 628 return (error); 629 } 630 631 case USB_DEVICEINFO: 632 { 633 usbd_device_handle dev; 634 struct usb_device_info *di = (void *)data; 635 int addr = di->udi_addr; 636 637 if (addr < 1 || addr >= USB_MAX_DEVICES) 638 return EINVAL; 639 if ((dev = sc->sc_bus->devices[addr]) == NULL) 640 return ENXIO; 641 usbd_fill_deviceinfo(dev, di, 1); 642 break; 643 } 644 645 #ifdef COMPAT_30 646 case USB_DEVICEINFO_OLD: 647 { 648 usbd_device_handle dev; 649 struct usb_device_info_old *di = (void *)data; 650 int addr = di->udi_addr; 651 652 if (addr < 1 || addr >= USB_MAX_DEVICES) 653 return EINVAL; 654 if ((dev = sc->sc_bus->devices[addr]) == NULL) 655 return ENXIO; 656 usbd_fill_deviceinfo_old(dev, di, 1); 657 break; 658 } 659 #endif 660 661 case USB_DEVICESTATS: 662 *(struct usb_device_stats *)data = sc->sc_bus->stats; 663 break; 664 665 default: 666 return (EINVAL); 667 } 668 return (0); 669 } 670 671 int 672 usbpoll(dev_t dev, int events, struct lwp *l) 673 { 674 int revents, mask, s; 675 676 if (minor(dev) == USB_DEV_MINOR) { 677 revents = 0; 678 mask = POLLIN | POLLRDNORM; 679 680 s = splusb(); 681 if (events & mask && usb_nevents > 0) 682 revents |= events & mask; 683 if (revents == 0 && events & mask) 684 selrecord(l, &usb_selevent); 685 splx(s); 686 687 return (revents); 688 } else { 689 return (0); 690 } 691 } 692 693 static void 694 filt_usbrdetach(struct knote *kn) 695 { 696 int s; 697 698 s = splusb(); 699 SLIST_REMOVE(&usb_selevent.sel_klist, kn, knote, kn_selnext); 700 splx(s); 701 } 702 703 static int 704 filt_usbread(struct knote *kn, long hint) 705 { 706 707 if (usb_nevents == 0) 708 return (0); 709 710 kn->kn_data = sizeof(struct usb_event); 711 return (1); 712 } 713 714 static const struct filterops usbread_filtops = 715 { 1, NULL, filt_usbrdetach, filt_usbread }; 716 717 int 718 usbkqfilter(dev_t dev, struct knote *kn) 719 { 720 struct klist *klist; 721 int s; 722 723 switch (kn->kn_filter) { 724 case EVFILT_READ: 725 if (minor(dev) != USB_DEV_MINOR) 726 return (1); 727 klist = &usb_selevent.sel_klist; 728 kn->kn_fop = &usbread_filtops; 729 break; 730 731 default: 732 return (1); 733 } 734 735 kn->kn_hook = NULL; 736 737 s = splusb(); 738 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 739 splx(s); 740 741 return (0); 742 } 743 744 /* Explore device tree from the root. */ 745 Static void 746 usb_discover(void *v) 747 { 748 struct usb_softc *sc = v; 749 750 DPRINTFN(2,("usb_discover\n")); 751 #ifdef USB_DEBUG 752 if (usb_noexplore > 1) 753 return; 754 #endif 755 /* 756 * We need mutual exclusion while traversing the device tree, 757 * but this is guaranteed since this function is only called 758 * from the event thread for the controller. 759 */ 760 while (sc->sc_bus->needs_explore && !sc->sc_dying) { 761 sc->sc_bus->needs_explore = 0; 762 sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub); 763 } 764 } 765 766 void 767 usb_needs_explore(usbd_device_handle dev) 768 { 769 DPRINTFN(2,("usb_needs_explore\n")); 770 dev->bus->needs_explore = 1; 771 wakeup(&dev->bus->needs_explore); 772 } 773 774 void 775 usb_needs_reattach(usbd_device_handle dev) 776 { 777 DPRINTFN(2,("usb_needs_reattach\n")); 778 dev->powersrc->reattach = 1; 779 dev->bus->needs_explore = 1; 780 wakeup(&dev->bus->needs_explore); 781 } 782 783 /* Called at splusb() */ 784 int 785 usb_get_next_event(struct usb_event *ue) 786 { 787 struct usb_event_q *ueq; 788 789 if (usb_nevents <= 0) 790 return (0); 791 ueq = SIMPLEQ_FIRST(&usb_events); 792 #ifdef DIAGNOSTIC 793 if (ueq == NULL) { 794 printf("usb: usb_nevents got out of sync! %d\n", usb_nevents); 795 usb_nevents = 0; 796 return (0); 797 } 798 #endif 799 if (ue) 800 *ue = ueq->ue; 801 SIMPLEQ_REMOVE_HEAD(&usb_events, next); 802 usb_free_event((struct usb_event *)(void *)ueq); 803 usb_nevents--; 804 return (1); 805 } 806 807 void 808 usbd_add_dev_event(int type, usbd_device_handle udev) 809 { 810 struct usb_event *ue = usb_alloc_event(); 811 812 usbd_fill_deviceinfo(udev, &ue->u.ue_device, USB_EVENT_IS_ATTACH(type)); 813 usb_add_event(type, ue); 814 } 815 816 void 817 usbd_add_drv_event(int type, usbd_device_handle udev, device_ptr_t dev) 818 { 819 struct usb_event *ue = usb_alloc_event(); 820 821 ue->u.ue_driver.ue_cookie = udev->cookie; 822 strncpy(ue->u.ue_driver.ue_devname, USBDEVPTRNAME(dev), 823 sizeof ue->u.ue_driver.ue_devname); 824 usb_add_event(type, ue); 825 } 826 827 Static struct usb_event * 828 usb_alloc_event(void) 829 { 830 /* Yes, this is right; we allocate enough so that we can use it later */ 831 return malloc(sizeof(struct usb_event_q), M_USBDEV, M_WAITOK|M_ZERO); 832 } 833 834 Static void 835 usb_free_event(struct usb_event *uep) 836 { 837 free(uep, M_USBDEV); 838 } 839 840 Static void 841 usb_add_event(int type, struct usb_event *uep) 842 { 843 struct usb_event_q *ueq; 844 struct timeval thetime; 845 int s; 846 847 microtime(&thetime); 848 /* Don't want to wait here inside splusb() */ 849 ueq = (struct usb_event_q *)(void *)uep; 850 ueq->ue = *uep; 851 ueq->ue.ue_type = type; 852 TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time); 853 854 s = splusb(); 855 if (++usb_nevents >= USB_MAX_EVENTS) { 856 /* Too many queued events, drop an old one. */ 857 DPRINTFN(-1,("usb: event dropped\n")); 858 (void)usb_get_next_event(0); 859 } 860 SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next); 861 wakeup(&usb_events); 862 selnotify(&usb_selevent, 0); 863 if (usb_async_proc != NULL) { 864 mutex_enter(&proclist_mutex); 865 psignal(usb_async_proc, SIGIO); 866 mutex_exit(&proclist_mutex); 867 } 868 splx(s); 869 } 870 871 void 872 usb_schedsoftintr(usbd_bus_handle bus) 873 { 874 DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling)); 875 #ifdef USB_USE_SOFTINTR 876 if (bus->use_polling) { 877 bus->methods->soft_intr(bus); 878 } else { 879 softint_schedule(bus->soft); 880 } 881 #else 882 bus->methods->soft_intr(bus); 883 #endif /* USB_USE_SOFTINTR */ 884 } 885 886 int 887 usb_activate(device_ptr_t self, enum devact act) 888 { 889 struct usb_softc *sc = (struct usb_softc *)self; 890 usbd_device_handle dev = sc->sc_port.device; 891 int i, rv = 0; 892 893 switch (act) { 894 case DVACT_ACTIVATE: 895 return (EOPNOTSUPP); 896 897 case DVACT_DEACTIVATE: 898 sc->sc_dying = 1; 899 if (dev != NULL && dev->cdesc != NULL && dev->subdevs != NULL) { 900 for (i = 0; dev->subdevs[i]; i++) 901 rv |= config_deactivate(dev->subdevs[i]); 902 } 903 break; 904 } 905 return (rv); 906 } 907 908 int 909 usb_detach(device_ptr_t self, int flags) 910 { 911 struct usb_softc *sc = (struct usb_softc *)self; 912 struct usb_event *ue; 913 914 DPRINTF(("usb_detach: start\n")); 915 916 /* Kill off event thread. */ 917 while (sc->sc_event_thread != NULL) { 918 wakeup(&sc->sc_bus->needs_explore); 919 tsleep(sc, PWAIT, "usbdet", hz * 60); 920 } 921 DPRINTF(("usb_detach: event thread dead\n")); 922 923 /* Make all devices disconnect. */ 924 if (sc->sc_port.device != NULL) 925 usb_disconnect_port(&sc->sc_port, self); 926 927 #ifdef USB_USE_SOFTINTR 928 if (sc->sc_bus->soft != NULL) { 929 softint_disestablish(sc->sc_bus->soft); 930 sc->sc_bus->soft = NULL; 931 } 932 #endif 933 934 ue = usb_alloc_event(); 935 ue->u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev); 936 usb_add_event(USB_EVENT_CTRLR_DETACH, ue); 937 938 return (0); 939 } 940 941 #ifdef COMPAT_30 942 Static void 943 usb_copy_old_devinfo(struct usb_device_info_old *uo, 944 const struct usb_device_info *ue) 945 { 946 const unsigned char *p; 947 unsigned char *q; 948 int i, n; 949 950 uo->udi_bus = ue->udi_bus; 951 uo->udi_addr = ue->udi_addr; 952 uo->udi_cookie = ue->udi_cookie; 953 for (i = 0, p = (const unsigned char *)ue->udi_product, 954 q = (unsigned char *)uo->udi_product; 955 *p && i < USB_MAX_STRING_LEN - 1; p++) { 956 if (*p < 0x80) 957 q[i++] = *p; 958 else { 959 q[i++] = '?'; 960 if ((*p & 0xe0) == 0xe0) 961 p++; 962 p++; 963 } 964 } 965 q[i] = 0; 966 967 for (i = 0, p = ue->udi_vendor, q = uo->udi_vendor; 968 *p && i < USB_MAX_STRING_LEN - 1; p++) { 969 if (* p < 0x80) 970 q[i++] = *p; 971 else { 972 q[i++] = '?'; 973 p++; 974 if ((*p & 0xe0) == 0xe0) 975 p++; 976 } 977 } 978 q[i] = 0; 979 980 memcpy(uo->udi_release, ue->udi_release, sizeof(uo->udi_release)); 981 982 uo->udi_productNo = ue->udi_productNo; 983 uo->udi_vendorNo = ue->udi_vendorNo; 984 uo->udi_releaseNo = ue->udi_releaseNo; 985 uo->udi_class = ue->udi_class; 986 uo->udi_subclass = ue->udi_subclass; 987 uo->udi_protocol = ue->udi_protocol; 988 uo->udi_config = ue->udi_config; 989 uo->udi_speed = ue->udi_speed; 990 uo->udi_power = ue->udi_power; 991 uo->udi_nports = ue->udi_nports; 992 993 for (n=0; n<USB_MAX_DEVNAMES; n++) 994 memcpy(uo->udi_devnames[n], 995 ue->udi_devnames[n], USB_MAX_DEVNAMELEN); 996 memcpy(uo->udi_ports, ue->udi_ports, sizeof(uo->udi_ports)); 997 } 998 #endif 999