1 /* $OpenBSD: usb.c,v 1.58 2008/12/09 03:08:07 yuo Exp $ */ 2 /* $NetBSD: usb.c,v 1.77 2003/01/01 00:10:26 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 1998, 2002 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 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * USB specifications and other documentation can be found at 36 * http://www.usb.org/developers/docs/ and 37 * http://www.usb.org/developers/devclass_docs/ 38 */ 39 40 #include "ohci.h" 41 #include "uhci.h" 42 #include "ehci.h" 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/kernel.h> 47 #include <sys/malloc.h> 48 #include <sys/device.h> 49 #include <sys/kthread.h> 50 #include <sys/proc.h> 51 #include <sys/conf.h> 52 #include <sys/fcntl.h> 53 #include <sys/poll.h> 54 #include <sys/selinfo.h> 55 #include <sys/vnode.h> 56 #include <sys/signalvar.h> 57 58 #include <dev/usb/usb.h> 59 #include <dev/usb/usbdi.h> 60 #include <dev/usb/usbdi_util.h> 61 62 #define USB_DEV_MINOR 255 63 64 #include <machine/bus.h> 65 66 #include <dev/usb/usbdivar.h> 67 #include <dev/usb/usb_quirks.h> 68 69 #ifdef USB_DEBUG 70 #define DPRINTF(x) do { if (usbdebug) printf x; } while (0) 71 #define DPRINTFN(n,x) do { if (usbdebug>(n)) printf x; } while (0) 72 int usbdebug = 0; 73 #if defined(UHCI_DEBUG) && NUHCI > 0 74 extern int uhcidebug; 75 #endif 76 #if defined(OHCI_DEBUG) && NOHCI > 0 77 extern int ohcidebug; 78 #endif 79 #if defined(EHCI_DEBUG) && NEHCI > 0 80 extern int ehcidebug; 81 #endif 82 /* 83 * 0 - do usual exploration 84 * 1 - do not use timeout exploration 85 * >1 - do no exploration 86 */ 87 int usb_noexplore = 0; 88 #else 89 #define DPRINTF(x) 90 #define DPRINTFN(n,x) 91 #endif 92 93 struct usb_softc { 94 struct device sc_dev; /* base device */ 95 usbd_bus_handle sc_bus; /* USB controller */ 96 struct usbd_port sc_port; /* dummy port for root hub */ 97 98 struct proc *sc_event_thread; 99 100 char sc_dying; 101 }; 102 103 TAILQ_HEAD(, usb_task) usb_all_tasks; 104 105 volatile int threads_pending = 0; 106 107 void usb_discover(void *); 108 void usb_create_event_thread(void *); 109 void usb_event_thread(void *); 110 void usb_task_thread(void *); 111 struct proc *usb_task_thread_proc = NULL; 112 113 #define USB_MAX_EVENTS 100 114 struct usb_event_q { 115 struct usb_event ue; 116 SIMPLEQ_ENTRY(usb_event_q) next; 117 }; 118 SIMPLEQ_HEAD(, usb_event_q) usb_events = 119 SIMPLEQ_HEAD_INITIALIZER(usb_events); 120 int usb_nevents = 0; 121 struct selinfo usb_selevent; 122 struct proc *usb_async_proc; /* process that wants USB SIGIO */ 123 int usb_dev_open = 0; 124 void usb_add_event(int, struct usb_event *); 125 126 int usb_get_next_event(struct usb_event *); 127 128 const char *usbrev_str[] = USBREV_STR; 129 130 int usb_match(struct device *, void *, void *); 131 void usb_attach(struct device *, struct device *, void *); 132 int usb_detach(struct device *, int); 133 int usb_activate(struct device *, enum devact); 134 135 struct cfdriver usb_cd = { 136 NULL, "usb", DV_DULL 137 }; 138 139 const struct cfattach usb_ca = { 140 sizeof(struct usb_softc), 141 usb_match, 142 usb_attach, 143 usb_detach, 144 usb_activate, 145 }; 146 147 int 148 usb_match(struct device *parent, void *match, void *aux) 149 { 150 DPRINTF(("usbd_match\n")); 151 return (UMATCH_GENERIC); 152 } 153 154 void 155 usb_attach(struct device *parent, struct device *self, void *aux) 156 { 157 struct usb_softc *sc = (struct usb_softc *)self; 158 usbd_device_handle dev; 159 usbd_status err; 160 int usbrev; 161 int speed; 162 struct usb_event ue; 163 164 DPRINTF(("usbd_attach\n")); 165 166 usbd_init(); 167 sc->sc_bus = aux; 168 sc->sc_bus->usbctl = sc; 169 sc->sc_port.power = USB_MAX_POWER; 170 171 usbrev = sc->sc_bus->usbrev; 172 printf(": USB revision %s", usbrev_str[usbrev]); 173 switch (usbrev) { 174 case USBREV_1_0: 175 case USBREV_1_1: 176 speed = USB_SPEED_FULL; 177 break; 178 case USBREV_2_0: 179 speed = USB_SPEED_HIGH; 180 break; 181 default: 182 printf(", not supported\n"); 183 sc->sc_dying = 1; 184 return; 185 } 186 printf("\n"); 187 188 /* Make sure not to use tsleep() if we are cold booting. */ 189 if (cold) 190 sc->sc_bus->use_polling++; 191 192 ue.u.ue_ctrlr.ue_bus = sc->sc_dev.dv_unit; 193 usb_add_event(USB_EVENT_CTRLR_ATTACH, &ue); 194 195 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS 196 /* XXX we should have our own level */ 197 sc->sc_bus->soft = softintr_establish(IPL_SOFTNET, 198 sc->sc_bus->methods->soft_intr, sc->sc_bus); 199 if (sc->sc_bus->soft == NULL) { 200 printf("%s: can't register softintr\n", sc->sc_dev.dv_xname); 201 sc->sc_dying = 1; 202 return; 203 } 204 #endif 205 206 err = usbd_new_device(&sc->sc_dev, sc->sc_bus, 0, speed, 0, 207 &sc->sc_port); 208 if (!err) { 209 dev = sc->sc_port.device; 210 if (dev->hub == NULL) { 211 sc->sc_dying = 1; 212 printf("%s: root device is not a hub\n", 213 sc->sc_dev.dv_xname); 214 return; 215 } 216 sc->sc_bus->root_hub = dev; 217 #if 1 218 /* 219 * Turning this code off will delay attachment of USB devices 220 * until the USB event thread is running, which means that 221 * the keyboard will not work until after cold boot. 222 */ 223 if (cold && (sc->sc_dev.dv_cfdata->cf_flags & 1)) 224 dev->hub->explore(sc->sc_bus->root_hub); 225 #endif 226 } else { 227 printf("%s: root hub problem, error=%d\n", 228 sc->sc_dev.dv_xname, err); 229 sc->sc_dying = 1; 230 } 231 if (cold) 232 sc->sc_bus->use_polling--; 233 234 config_pending_incr(); 235 kthread_create_deferred(usb_create_event_thread, sc); 236 } 237 238 void 239 usb_create_event_thread(void *arg) 240 { 241 struct usb_softc *sc = arg; 242 static int created = 0; 243 244 if (sc->sc_bus->usbrev == USBREV_2_0) 245 threads_pending++; 246 247 if (kthread_create(usb_event_thread, sc, &sc->sc_event_thread, 248 "%s", sc->sc_dev.dv_xname)) 249 panic("unable to create event thread for %s", 250 sc->sc_dev.dv_xname); 251 252 if (!created) { 253 created = 1; 254 TAILQ_INIT(&usb_all_tasks); 255 if (kthread_create(usb_task_thread, NULL, 256 &usb_task_thread_proc, "usbtask")) 257 panic("unable to create usb task thread"); 258 } 259 } 260 261 /* 262 * Add a task to be performed by the task thread. This function can be 263 * called from any context and the task will be executed in a process 264 * context ASAP. 265 */ 266 void 267 usb_add_task(usbd_device_handle dev, struct usb_task *task) 268 { 269 int s; 270 271 s = splusb(); 272 if (!task->onqueue) { 273 DPRINTFN(2,("usb_add_task: task=%p\n", task)); 274 TAILQ_INSERT_TAIL(&usb_all_tasks, task, next); 275 task->onqueue = 1; 276 } else { 277 DPRINTFN(3,("usb_add_task: task=%p on q\n", task)); 278 } 279 wakeup(&usb_all_tasks); 280 splx(s); 281 } 282 283 void 284 usb_rem_task(usbd_device_handle dev, struct usb_task *task) 285 { 286 int s; 287 288 s = splusb(); 289 if (task->onqueue) { 290 TAILQ_REMOVE(&usb_all_tasks, task, next); 291 task->onqueue = 0; 292 } 293 splx(s); 294 } 295 296 void 297 usb_event_thread(void *arg) 298 { 299 struct usb_softc *sc = arg; 300 int pwrdly; 301 302 DPRINTF(("usb_event_thread: start\n")); 303 304 /* Wait for power to come good. */ 305 pwrdly = sc->sc_bus->root_hub->hub->hubdesc.bPwrOn2PwrGood * 306 UHD_PWRON_FACTOR + USB_EXTRA_POWER_UP_TIME; 307 usb_delay_ms(sc->sc_bus, pwrdly); 308 309 /* USB1 threads wait for USB2 threads to finish their first probe. */ 310 while (sc->sc_bus->usbrev != USBREV_2_0 && threads_pending) 311 (void)tsleep((void *)&threads_pending, PWAIT, "config", 0); 312 313 /* Make sure first discover does something. */ 314 sc->sc_bus->needs_explore = 1; 315 usb_discover(sc); 316 config_pending_decr(); 317 318 /* Wake up any companions waiting for handover before their probes. */ 319 if (sc->sc_bus->usbrev == USBREV_2_0) { 320 threads_pending--; 321 wakeup((void *)&threads_pending); 322 } 323 324 while (!sc->sc_dying) { 325 #ifdef USB_DEBUG 326 if (usb_noexplore < 2) 327 #endif 328 usb_discover(sc); 329 #ifdef USB_DEBUG 330 (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt", 331 usb_noexplore ? 0 : hz * 60); 332 #else 333 (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt", 334 hz * 60); 335 #endif 336 DPRINTFN(2,("usb_event_thread: woke up\n")); 337 } 338 sc->sc_event_thread = NULL; 339 340 /* In case parent is waiting for us to exit. */ 341 wakeup(sc); 342 343 DPRINTF(("usb_event_thread: exit\n")); 344 kthread_exit(0); 345 } 346 347 void 348 usb_task_thread(void *arg) 349 { 350 struct usb_task *task; 351 int s; 352 353 DPRINTF(("usb_task_thread: start\n")); 354 355 s = splusb(); 356 for (;;) { 357 task = TAILQ_FIRST(&usb_all_tasks); 358 if (task == NULL) { 359 tsleep(&usb_all_tasks, PWAIT, "usbtsk", 0); 360 task = TAILQ_FIRST(&usb_all_tasks); 361 } 362 DPRINTFN(2,("usb_task_thread: woke up task=%p\n", task)); 363 if (task != NULL) { 364 TAILQ_REMOVE(&usb_all_tasks, task, next); 365 task->onqueue = 0; 366 splx(s); 367 task->fun(task->arg); 368 s = splusb(); 369 } 370 } 371 } 372 373 int 374 usbctlprint(void *aux, const char *pnp) 375 { 376 /* only "usb"es can attach to host controllers */ 377 if (pnp) 378 printf("usb at %s", pnp); 379 380 return (UNCONF); 381 } 382 383 int 384 usbopen(dev_t dev, int flag, int mode, struct proc *p) 385 { 386 int unit = minor(dev); 387 struct usb_softc *sc; 388 389 if (unit == USB_DEV_MINOR) { 390 if (usb_dev_open) 391 return (EBUSY); 392 usb_dev_open = 1; 393 usb_async_proc = 0; 394 return (0); 395 } 396 397 if (unit >= usb_cd.cd_ndevs) 398 return (ENXIO); 399 sc = usb_cd.cd_devs[unit]; 400 if (sc == NULL) 401 return (ENXIO); 402 403 if (sc->sc_dying) 404 return (EIO); 405 406 return (0); 407 } 408 409 int 410 usbread(dev_t dev, struct uio *uio, int flag) 411 { 412 struct usb_event ue; 413 int s, error, n; 414 415 if (minor(dev) != USB_DEV_MINOR) 416 return (ENXIO); 417 418 if (uio->uio_resid != sizeof(struct usb_event)) 419 return (EINVAL); 420 421 error = 0; 422 s = splusb(); 423 for (;;) { 424 n = usb_get_next_event(&ue); 425 if (n != 0) 426 break; 427 if (flag & IO_NDELAY) { 428 error = EWOULDBLOCK; 429 break; 430 } 431 error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0); 432 if (error) 433 break; 434 } 435 splx(s); 436 if (!error) 437 error = uiomove((void *)&ue, uio->uio_resid, uio); 438 439 return (error); 440 } 441 442 int 443 usbclose(dev_t dev, int flag, int mode, struct proc *p) 444 { 445 int unit = minor(dev); 446 447 if (unit == USB_DEV_MINOR) { 448 usb_async_proc = 0; 449 usb_dev_open = 0; 450 } 451 452 return (0); 453 } 454 455 int 456 usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, struct proc *p) 457 { 458 struct usb_softc *sc; 459 int unit = minor(devt); 460 int error; 461 462 if (unit == USB_DEV_MINOR) { 463 switch (cmd) { 464 case FIONBIO: 465 /* All handled in the upper FS layer. */ 466 return (0); 467 468 case FIOASYNC: 469 if (*(int *)data) 470 usb_async_proc = p; 471 else 472 usb_async_proc = 0; 473 return (0); 474 475 default: 476 return (EINVAL); 477 } 478 } 479 480 sc = usb_cd.cd_devs[unit]; 481 482 if (sc->sc_dying) 483 return (EIO); 484 485 error = 0; 486 switch (cmd) { 487 #ifdef USB_DEBUG 488 case USB_SETDEBUG: 489 /* only root can access to these debug flags */ 490 if ((error = suser(curproc, 0)) != 0) 491 return (error); 492 if (!(flag & FWRITE)) 493 return (EBADF); 494 usbdebug = ((*(unsigned int *)data) & 0x000000ff); 495 #if defined(UHCI_DEBUG) && NUHCI > 0 496 uhcidebug = ((*(unsigned int *)data) & 0x0000ff00) >> 8; 497 #endif 498 #if defined(OHCI_DEBUG) && NOHCI > 0 499 ohcidebug = ((*(unsigned int *)data) & 0x00ff0000) >> 16; 500 #endif 501 #if defined(EHCI_DEBUG) && NEHCI > 0 502 ehcidebug = ((*(unsigned int *)data) & 0xff000000) >> 24; 503 #endif 504 break; 505 #endif /* USB_DEBUG */ 506 case USB_REQUEST: 507 { 508 struct usb_ctl_request *ur = (void *)data; 509 int len = UGETW(ur->ucr_request.wLength); 510 struct iovec iov; 511 struct uio uio; 512 void *ptr = 0; 513 int addr = ur->ucr_addr; 514 usbd_status err; 515 int error = 0; 516 517 if (!(flag & FWRITE)) 518 return (EBADF); 519 520 DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len)); 521 if (len < 0 || len > 32768) 522 return (EINVAL); 523 if (addr < 0 || addr >= USB_MAX_DEVICES || 524 sc->sc_bus->devices[addr] == 0) 525 return (EINVAL); 526 if (len != 0) { 527 iov.iov_base = (caddr_t)ur->ucr_data; 528 iov.iov_len = len; 529 uio.uio_iov = &iov; 530 uio.uio_iovcnt = 1; 531 uio.uio_resid = len; 532 uio.uio_offset = 0; 533 uio.uio_segflg = UIO_USERSPACE; 534 uio.uio_rw = 535 ur->ucr_request.bmRequestType & UT_READ ? 536 UIO_READ : UIO_WRITE; 537 uio.uio_procp = p; 538 ptr = malloc(len, M_TEMP, M_WAITOK); 539 if (uio.uio_rw == UIO_WRITE) { 540 error = uiomove(ptr, len, &uio); 541 if (error) 542 goto ret; 543 } 544 } 545 err = usbd_do_request_flags(sc->sc_bus->devices[addr], 546 &ur->ucr_request, ptr, ur->ucr_flags, 547 &ur->ucr_actlen, USBD_DEFAULT_TIMEOUT); 548 if (err) { 549 error = EIO; 550 goto ret; 551 } 552 if (len != 0) { 553 if (uio.uio_rw == UIO_READ) { 554 error = uiomove(ptr, len, &uio); 555 if (error) 556 goto ret; 557 } 558 } 559 ret: 560 if (ptr) 561 free(ptr, M_TEMP); 562 return (error); 563 } 564 565 case USB_DEVICEINFO: 566 { 567 struct usb_device_info *di = (void *)data; 568 int addr = di->udi_addr; 569 usbd_device_handle dev; 570 571 if (addr < 1 || addr >= USB_MAX_DEVICES) 572 return (EINVAL); 573 dev = sc->sc_bus->devices[addr]; 574 if (dev == NULL) 575 return (ENXIO); 576 usbd_fill_deviceinfo(dev, di, 1); 577 break; 578 } 579 580 case USB_DEVICESTATS: 581 *(struct usb_device_stats *)data = sc->sc_bus->stats; 582 break; 583 584 default: 585 return (EINVAL); 586 } 587 return (0); 588 } 589 590 int 591 usbpoll(dev_t dev, int events, struct proc *p) 592 { 593 int revents, mask, s; 594 595 if (minor(dev) == USB_DEV_MINOR) { 596 revents = 0; 597 mask = POLLIN | POLLRDNORM; 598 599 s = splusb(); 600 if (events & mask && usb_nevents > 0) 601 revents |= events & mask; 602 if (revents == 0 && events & mask) 603 selrecord(p, &usb_selevent); 604 splx(s); 605 606 return (revents); 607 } else { 608 return (POLLERR); 609 } 610 } 611 612 void filt_usbrdetach(struct knote *); 613 int filt_usbread(struct knote *, long); 614 int usbkqfilter(dev_t, struct knote *); 615 616 void 617 filt_usbrdetach(struct knote *kn) 618 { 619 int s; 620 621 s = splusb(); 622 SLIST_REMOVE(&usb_selevent.si_note, kn, knote, kn_selnext); 623 splx(s); 624 } 625 626 int 627 filt_usbread(struct knote *kn, long hint) 628 { 629 630 if (usb_nevents == 0) 631 return (0); 632 633 kn->kn_data = sizeof(struct usb_event); 634 return (1); 635 } 636 637 struct filterops usbread_filtops = 638 { 1, NULL, filt_usbrdetach, filt_usbread }; 639 640 int 641 usbkqfilter(dev_t dev, struct knote *kn) 642 { 643 struct klist *klist; 644 int s; 645 646 switch (kn->kn_filter) { 647 case EVFILT_READ: 648 if (minor(dev) != USB_DEV_MINOR) 649 return (1); 650 klist = &usb_selevent.si_note; 651 kn->kn_fop = &usbread_filtops; 652 break; 653 654 default: 655 return (1); 656 } 657 658 kn->kn_hook = NULL; 659 660 s = splusb(); 661 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 662 splx(s); 663 664 return (0); 665 } 666 667 /* Explore device tree from the root. */ 668 void 669 usb_discover(void *v) 670 { 671 struct usb_softc *sc = v; 672 673 DPRINTFN(2,("usb_discover\n")); 674 #ifdef USB_DEBUG 675 if (usb_noexplore > 1) 676 return; 677 #endif 678 /* 679 * We need mutual exclusion while traversing the device tree, 680 * but this is guaranteed since this function is only called 681 * from the event thread for the controller. 682 */ 683 while (sc->sc_bus->needs_explore && !sc->sc_dying) { 684 sc->sc_bus->needs_explore = 0; 685 sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub); 686 } 687 } 688 689 void 690 usb_needs_explore(usbd_device_handle dev) 691 { 692 DPRINTFN(2,("usb_needs_explore\n")); 693 dev->bus->needs_explore = 1; 694 wakeup(&dev->bus->needs_explore); 695 } 696 697 void 698 usb_needs_reattach(usbd_device_handle dev) 699 { 700 DPRINTFN(2,("usb_needs_reattach\n")); 701 dev->powersrc->reattach = 1; 702 dev->bus->needs_explore = 1; 703 wakeup(&dev->bus->needs_explore); 704 } 705 706 /* Called at splusb() */ 707 int 708 usb_get_next_event(struct usb_event *ue) 709 { 710 struct usb_event_q *ueq; 711 712 if (usb_nevents <= 0) 713 return (0); 714 ueq = SIMPLEQ_FIRST(&usb_events); 715 #ifdef DIAGNOSTIC 716 if (ueq == NULL) { 717 printf("usb: usb_nevents got out of sync! %d\n", usb_nevents); 718 usb_nevents = 0; 719 return (0); 720 } 721 #endif 722 *ue = ueq->ue; 723 SIMPLEQ_REMOVE_HEAD(&usb_events, next); 724 free(ueq, M_USBDEV); 725 usb_nevents--; 726 return (1); 727 } 728 729 void 730 usbd_add_dev_event(int type, usbd_device_handle udev) 731 { 732 struct usb_event ue; 733 734 usbd_fill_deviceinfo(udev, &ue.u.ue_device, USB_EVENT_IS_ATTACH(type)); 735 usb_add_event(type, &ue); 736 } 737 738 void 739 usbd_add_drv_event(int type, usbd_device_handle udev, struct device *dev) 740 { 741 struct usb_event ue; 742 743 ue.u.ue_driver.ue_cookie = udev->cookie; 744 strncpy(ue.u.ue_driver.ue_devname, dev->dv_xname, 745 sizeof ue.u.ue_driver.ue_devname); 746 usb_add_event(type, &ue); 747 } 748 749 void 750 usb_add_event(int type, struct usb_event *uep) 751 { 752 struct usb_event_q *ueq; 753 struct usb_event ue; 754 struct timespec thetime; 755 int s; 756 757 nanotime(&thetime); 758 /* Don't want to wait here inside splusb() */ 759 ueq = malloc(sizeof *ueq, M_USBDEV, M_WAITOK); 760 ueq->ue = *uep; 761 ueq->ue.ue_type = type; 762 ueq->ue.ue_time = thetime; 763 764 s = splusb(); 765 if (++usb_nevents >= USB_MAX_EVENTS) { 766 /* Too many queued events, drop an old one. */ 767 DPRINTFN(-1,("usb: event dropped\n")); 768 (void)usb_get_next_event(&ue); 769 } 770 SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next); 771 wakeup(&usb_events); 772 selwakeup(&usb_selevent); 773 if (usb_async_proc != NULL) 774 psignal(usb_async_proc, SIGIO); 775 splx(s); 776 } 777 778 void 779 usb_schedsoftintr(usbd_bus_handle bus) 780 { 781 DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling)); 782 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS 783 if (bus->use_polling) { 784 bus->methods->soft_intr(bus); 785 } else { 786 softintr_schedule(bus->soft); 787 } 788 #else 789 bus->methods->soft_intr(bus); 790 #endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */ 791 } 792 793 int 794 usb_activate(struct device *self, enum devact act) 795 { 796 struct usb_softc *sc = (struct usb_softc *)self; 797 usbd_device_handle dev = sc->sc_port.device; 798 int i, rv = 0; 799 800 switch (act) { 801 case DVACT_ACTIVATE: 802 break; 803 804 case DVACT_DEACTIVATE: 805 sc->sc_dying = 1; 806 if (dev != NULL && dev->cdesc != NULL && 807 dev->subdevs != NULL) { 808 for (i = 0; dev->subdevs[i]; i++) 809 rv |= config_deactivate(dev->subdevs[i]); 810 } 811 break; 812 } 813 return (rv); 814 } 815 816 int 817 usb_detach(struct device *self, int flags) 818 { 819 struct usb_softc *sc = (struct usb_softc *)self; 820 struct usb_event ue; 821 822 DPRINTF(("usb_detach: start\n")); 823 824 sc->sc_dying = 1; 825 826 /* Make all devices disconnect. */ 827 if (sc->sc_port.device != NULL) 828 usb_disconnect_port(&sc->sc_port, self); 829 830 /* Kill off event thread. */ 831 if (sc->sc_event_thread != NULL) { 832 wakeup(&sc->sc_bus->needs_explore); 833 if (tsleep(sc, PWAIT, "usbdet", hz * 60)) 834 printf("%s: event thread didn't die\n", 835 sc->sc_dev.dv_xname); 836 DPRINTF(("usb_detach: event thread dead\n")); 837 } 838 839 usbd_finish(); 840 841 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS 842 if (sc->sc_bus->soft != NULL) { 843 softintr_disestablish(sc->sc_bus->soft); 844 sc->sc_bus->soft = NULL; 845 } 846 #endif 847 848 ue.u.ue_ctrlr.ue_bus = sc->sc_dev.dv_unit; 849 usb_add_event(USB_EVENT_CTRLR_DETACH, &ue); 850 851 return (0); 852 } 853