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