The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/usb.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: usb.c,v 1.68 2002/02/20 20:30:12 christos Exp $        */
    2 
    3 /* Also already merged from NetBSD:
    4  *      $NetBSD: usb.c,v 1.70 2002/05/09 21:54:32 augustss Exp $
    5  *      $NetBSD: usb.c,v 1.71 2002/06/01 23:51:04 lukem Exp $
    6  *      $NetBSD: usb.c,v 1.73 2002/09/23 05:51:19 simonb Exp $
    7  *      $NetBSD: usb.c,v 1.80 2003/11/07 17:03:25 wiz Exp $
    8  */
    9 
   10 #include <sys/cdefs.h>
   11 __FBSDID("$FreeBSD: releng/7.3/sys/dev/usb/usb.c 170960 2007-06-20 05:11:37Z imp $");
   12 
   13 /*-
   14  * Copyright (c) 1998 The NetBSD Foundation, Inc.
   15  * All rights reserved.
   16  *
   17  * This code is derived from software contributed to The NetBSD Foundation
   18  * by Lennart Augustsson (lennart@augustsson.net) at
   19  * Carlstedt Research & Technology.
   20  *
   21  * Redistribution and use in source and binary forms, with or without
   22  * modification, are permitted provided that the following conditions
   23  * are met:
   24  * 1. Redistributions of source code must retain the above copyright
   25  *    notice, this list of conditions and the following disclaimer.
   26  * 2. Redistributions in binary form must reproduce the above copyright
   27  *    notice, this list of conditions and the following disclaimer in the
   28  *    documentation and/or other materials provided with the distribution.
   29  * 3. All advertising materials mentioning features or use of this software
   30  *    must display the following acknowledgement:
   31  *        This product includes software developed by the NetBSD
   32  *        Foundation, Inc. and its contributors.
   33  * 4. Neither the name of The NetBSD Foundation nor the names of its
   34  *    contributors may be used to endorse or promote products derived
   35  *    from this software without specific prior written permission.
   36  *
   37  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   38  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   39  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   40  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   41  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   42  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   43  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   44  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   45  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   47  * POSSIBILITY OF SUCH DAMAGE.
   48  */
   49 
   50 /*
   51  * USB specifications and other documentation can be found at
   52  * http://www.usb.org/developers/docs/ and
   53  * http://www.usb.org/developers/devclass_docs/
   54  */
   55 
   56 #include <sys/param.h>
   57 #include <sys/systm.h>
   58 #include <sys/kernel.h>
   59 #include <sys/lock.h>
   60 #include <sys/malloc.h>
   61 #include <sys/mutex.h>
   62 #include <sys/unistd.h>
   63 #include <sys/module.h>
   64 #include <sys/bus.h>
   65 #include <sys/fcntl.h>
   66 #include <sys/filio.h>
   67 #include <sys/uio.h>
   68 #include <sys/kthread.h>
   69 #include <sys/proc.h>
   70 #include <sys/conf.h>
   71 #include <sys/poll.h>
   72 #include <sys/selinfo.h>
   73 #include <sys/signalvar.h>
   74 #include <sys/sysctl.h>
   75 #include <sys/uio.h>
   76 
   77 #include <dev/usb/usb.h>
   78 #include <dev/usb/usbdi.h>
   79 #include <dev/usb/usbdi_util.h>
   80 
   81 #define USBUNIT(d)      (minor(d))      /* usb_discover device nodes, kthread */
   82 #define USB_DEV_MINOR   255             /* event queue device */
   83 
   84 MALLOC_DEFINE(M_USB, "USB", "USB");
   85 MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
   86 MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
   87 
   88 #include "usb_if.h"
   89 
   90 #include <machine/bus.h>
   91 
   92 #include <dev/usb/usbdivar.h>
   93 #include <dev/usb/usb_quirks.h>
   94 
   95 /* Define this unconditionally in case a kernel module is loaded that
   96  * has been compiled with debugging options.
   97  */
   98 SYSCTL_NODE(_hw, OID_AUTO, usb, CTLFLAG_RW, 0, "USB debugging");
   99 
  100 #ifdef USB_DEBUG
  101 #define DPRINTF(x)      if (usbdebug) printf x
  102 #define DPRINTFN(n,x)   if (usbdebug>(n)) printf x
  103 int     usbdebug = 0;
  104 SYSCTL_INT(_hw_usb, OID_AUTO, debug, CTLFLAG_RW,
  105            &usbdebug, 0, "usb debug level");
  106 /*
  107  * 0  - do usual exploration
  108  * 1  - do not use timeout exploration
  109  * >1 - do no exploration
  110  */
  111 int     usb_noexplore = 0;
  112 #else
  113 #define DPRINTF(x)
  114 #define DPRINTFN(n,x)
  115 #endif
  116 
  117 struct usb_softc {
  118         device_t        sc_dev;         /* base device */
  119         struct cdev     *sc_usbdev;     /* /dev/usbN device */
  120         TAILQ_ENTRY(usb_softc) sc_coldexplist; /* cold needs-explore list */
  121         usbd_bus_handle sc_bus;         /* USB controller */
  122         struct usbd_port sc_port;       /* dummy port for root hub */
  123 
  124         struct proc     *sc_event_thread;
  125 
  126         char            sc_dying;
  127 };
  128 
  129 struct usb_taskq {
  130         TAILQ_HEAD(, usb_task) tasks;
  131         struct proc *task_thread_proc;
  132         const char *name;
  133         int taskcreated;                /* task thread exists. */
  134 };
  135 
  136 static struct usb_taskq usb_taskq[USB_NUM_TASKQS];
  137 
  138 d_open_t  usbopen;
  139 d_close_t usbclose;
  140 d_read_t usbread;
  141 d_ioctl_t usbioctl;
  142 d_poll_t usbpoll;
  143 
  144 struct cdevsw usb_cdevsw = {
  145         .d_version =    D_VERSION,
  146         .d_flags =      D_NEEDGIANT,
  147         .d_open =       usbopen,
  148         .d_close =      usbclose,
  149         .d_read =       usbread,
  150         .d_ioctl =      usbioctl,
  151         .d_poll =       usbpoll,
  152         .d_name =       "usb",
  153 };
  154 
  155 static void     usb_discover(void *);
  156 static void     usb_create_event_thread(void *);
  157 static void     usb_event_thread(void *);
  158 static void     usb_task_thread(void *);
  159 
  160 static struct cdev *usb_dev;            /* The /dev/usb device. */
  161 static int usb_ndevs;                   /* Number of /dev/usbN devices. */
  162 /* Busses to explore at the end of boot-time device configuration. */
  163 static TAILQ_HEAD(, usb_softc) usb_coldexplist =
  164     TAILQ_HEAD_INITIALIZER(usb_coldexplist);
  165 
  166 #define USB_MAX_EVENTS 100
  167 struct usb_event_q {
  168         struct usb_event ue;
  169         TAILQ_ENTRY(usb_event_q) next;
  170 };
  171 static TAILQ_HEAD(, usb_event_q) usb_events =
  172         TAILQ_HEAD_INITIALIZER(usb_events);
  173 static int usb_nevents = 0;
  174 static struct selinfo usb_selevent;
  175 static struct proc *usb_async_proc;  /* process that wants USB SIGIO */
  176 static int usb_dev_open = 0;
  177 static void usb_add_event(int, struct usb_event *);
  178 
  179 static int usb_get_next_event(struct usb_event *);
  180 
  181 static const char *usbrev_str[] = USBREV_STR;
  182 
  183 static device_probe_t usb_match;
  184 static device_attach_t usb_attach;
  185 static device_detach_t usb_detach;
  186 static bus_child_detached_t usb_child_detached;
  187 
  188 static device_method_t usb_methods[] = {
  189         /* Device interface */
  190         DEVMETHOD(device_probe,         usb_match),
  191         DEVMETHOD(device_attach,        usb_attach),
  192         DEVMETHOD(device_detach,        usb_detach),
  193         DEVMETHOD(device_suspend,       bus_generic_suspend),
  194         DEVMETHOD(device_resume,        bus_generic_resume),
  195         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
  196 
  197         /* Bus interface */
  198         DEVMETHOD(bus_child_detached,   usb_child_detached),
  199 
  200         { 0, 0 }
  201 };
  202 
  203 static driver_t usb_driver = {
  204         "usb",
  205         usb_methods,
  206         sizeof(struct usb_softc)
  207 };
  208 
  209 static devclass_t usb_devclass;
  210 
  211 DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0);
  212 DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0);
  213 DRIVER_MODULE(usb, ehci, usb_driver, usb_devclass, 0, 0);
  214 DRIVER_MODULE(usb, slhci, usb_driver, usb_devclass, 0, 0);
  215 MODULE_VERSION(usb, 1);
  216 
  217 static int
  218 usb_match(device_t self)
  219 {
  220         DPRINTF(("usbd_match\n"));
  221         return (UMATCH_GENERIC);
  222 }
  223 
  224 static int
  225 usb_attach(device_t self)
  226 {
  227         struct usb_softc *sc = device_get_softc(self);
  228         void *aux = device_get_ivars(self);
  229         usbd_device_handle dev;
  230         usbd_status err;
  231         int usbrev;
  232         int speed;
  233         struct usb_event ue;
  234 
  235         sc->sc_dev = self;
  236 
  237         DPRINTF(("usbd_attach\n"));
  238 
  239         usbd_init();
  240         sc->sc_bus = aux;
  241         sc->sc_bus->usbctl = sc;
  242         sc->sc_port.power = USB_MAX_POWER;
  243 
  244         printf("%s", device_get_nameunit(sc->sc_dev));
  245         usbrev = sc->sc_bus->usbrev;
  246         printf(": USB revision %s", usbrev_str[usbrev]);
  247         switch (usbrev) {
  248         case USBREV_1_0:
  249         case USBREV_1_1:
  250                 speed = USB_SPEED_FULL;
  251                 break;
  252         case USBREV_2_0:
  253                 speed = USB_SPEED_HIGH;
  254                 break;
  255         default:
  256                 printf(", not supported\n");
  257                 sc->sc_dying = 1;
  258                 return ENXIO;
  259         }
  260         printf("\n");
  261 
  262         /* Make sure not to use tsleep() if we are cold booting. */
  263         if (cold)
  264                 sc->sc_bus->use_polling++;
  265 
  266         ue.u.ue_ctrlr.ue_bus = device_get_unit(sc->sc_dev);
  267         usb_add_event(USB_EVENT_CTRLR_ATTACH, &ue);
  268 
  269 #ifdef USB_USE_SOFTINTR
  270 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
  271         /* XXX we should have our own level */
  272         sc->sc_bus->soft = softintr_establish(IPL_SOFTNET,
  273             sc->sc_bus->methods->soft_intr, sc->sc_bus);
  274         if (sc->sc_bus->soft == NULL) {
  275                 printf("%s: can't register softintr\n", device_get_nameunit(sc->sc_dev));
  276                 sc->sc_dying = 1;
  277                 return ENXIO;
  278         }
  279 #else
  280         usb_callout_init(sc->sc_bus->softi);
  281 #endif
  282 #endif
  283 
  284         err = usbd_new_device(sc->sc_dev, sc->sc_bus, 0, speed, 0,
  285                   &sc->sc_port);
  286         if (!err) {
  287                 dev = sc->sc_port.device;
  288                 if (dev->hub == NULL) {
  289                         sc->sc_dying = 1;
  290                         printf("%s: root device is not a hub\n",
  291                                device_get_nameunit(sc->sc_dev));
  292                         return ENXIO;
  293                 }
  294                 sc->sc_bus->root_hub = dev;
  295 #if 1
  296                 /*
  297                  * Turning this code off will delay attachment of USB devices
  298                  * until the USB event thread is running, which means that
  299                  * the keyboard will not work until after cold boot.
  300                  */
  301                 if (cold) {
  302                         /* Explore high-speed busses before others. */
  303                         if (speed == USB_SPEED_HIGH)
  304                                 dev->hub->explore(sc->sc_bus->root_hub);
  305                         else
  306                                 TAILQ_INSERT_TAIL(&usb_coldexplist, sc,
  307                                     sc_coldexplist);
  308                 }
  309 #endif
  310         } else {
  311                 printf("%s: root hub problem, error=%d\n",
  312                        device_get_nameunit(sc->sc_dev), err);
  313                 sc->sc_dying = 1;
  314         }
  315         if (cold)
  316                 sc->sc_bus->use_polling--;
  317 
  318         /* XXX really do right config_pending_incr(); */
  319         usb_create_event_thread(sc);
  320         /* The per controller devices (used for usb_discover) */
  321         /* XXX This is redundant now, but old usbd's will want it */
  322         sc->sc_usbdev = make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT,
  323             GID_OPERATOR, 0660, "usb%d", device_get_unit(self));
  324         if (usb_ndevs++ == 0) {
  325                 /* The device spitting out events */
  326                 usb_dev = make_dev(&usb_cdevsw, USB_DEV_MINOR, UID_ROOT,
  327                     GID_OPERATOR, 0660, "usb");
  328         }
  329         return 0;
  330 }
  331 
  332 static const char *taskq_names[] = USB_TASKQ_NAMES;
  333 
  334 void
  335 usb_create_event_thread(void *arg)
  336 {
  337         struct usb_softc *sc = arg;
  338         struct usb_taskq *taskq;
  339         int i;
  340 
  341         if (kthread_create(usb_event_thread, sc, &sc->sc_event_thread,
  342               RFHIGHPID, 0, device_get_nameunit(sc->sc_dev))) {
  343                 printf("%s: unable to create event thread for\n",
  344                        device_get_nameunit(sc->sc_dev));
  345                 panic("usb_create_event_thread");
  346         }
  347         for (i = 0; i < USB_NUM_TASKQS; i++) {
  348                 taskq = &usb_taskq[i];
  349 
  350                 if (taskq->taskcreated == 0) {
  351                         taskq->taskcreated = 1;
  352                         taskq->name = taskq_names[i];
  353                         TAILQ_INIT(&taskq->tasks);
  354                         if (kthread_create(usb_task_thread, taskq,
  355                             &taskq->task_thread_proc, RFHIGHPID, 0,
  356                             taskq->name)) {
  357                                 printf("unable to create task thread\n");
  358                                 panic("usb_create_event_thread task");
  359                         }
  360                 }
  361         }
  362 }
  363 
  364 /*
  365  * Add a task to be performed by the task thread.  This function can be
  366  * called from any context and the task will be executed in a process
  367  * context ASAP.
  368  */
  369 void
  370 usb_add_task(usbd_device_handle dev, struct usb_task *task, int queue)
  371 {
  372         struct usb_taskq *taskq;
  373         int s;
  374 
  375         s = splusb();
  376         taskq = &usb_taskq[queue];
  377         if (task->queue == -1) {
  378                 DPRINTFN(2,("usb_add_task: task=%p\n", task));
  379                 TAILQ_INSERT_TAIL(&taskq->tasks, task, next);
  380                 task->queue = queue;
  381         } else {
  382                 DPRINTFN(3,("usb_add_task: task=%p on q\n", task));
  383         }
  384         wakeup(&taskq->tasks);
  385         splx(s);
  386 }
  387 
  388 void
  389 usb_rem_task(usbd_device_handle dev, struct usb_task *task)
  390 {
  391         struct usb_taskq *taskq;
  392         int s;
  393 
  394         s = splusb();
  395         if (task->queue != -1) {
  396                 taskq = &usb_taskq[task->queue];
  397                 TAILQ_REMOVE(&taskq->tasks, task, next);
  398                 task->queue = -1;
  399         }
  400         splx(s);
  401 }
  402 
  403 void
  404 usb_event_thread(void *arg)
  405 {
  406         static int newthread_wchan;
  407         struct usb_softc *sc = arg;
  408 
  409         mtx_lock(&Giant);
  410 
  411         DPRINTF(("usb_event_thread: start\n"));
  412 
  413         /*
  414          * In case this controller is a companion controller to an
  415          * EHCI controller we need to wait until the EHCI controller
  416          * has grabbed the port. What we do here is wait until no new
  417          * USB threads have been created in a while. XXX we actually
  418          * just want to wait for the PCI slot to be fully scanned.
  419          *
  420          * Note that when you `kldload usb' it actually attaches the
  421          * devices in order that the drivers appear in the kld, not the
  422          * normal PCI order, since the addition of each driver within
  423          * usb.ko (ohci, ehci etc.) causes a separate PCI bus re-scan.
  424          */
  425         wakeup(&newthread_wchan);
  426         for (;;) {
  427                 if (tsleep(&newthread_wchan , PWAIT, "usbets", hz * 4) != 0)
  428                         break;
  429         }
  430 
  431         /* Make sure first discover does something. */
  432         sc->sc_bus->needs_explore = 1;
  433         usb_discover(sc);
  434         /* XXX really do right config_pending_decr(); */
  435 
  436         while (!sc->sc_dying) {
  437 #ifdef USB_DEBUG
  438                 if (usb_noexplore < 2)
  439 #endif
  440                 usb_discover(sc);
  441 #ifdef USB_DEBUG
  442                 (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
  443                     usb_noexplore ? 0 : hz * 60);
  444 #else
  445                 (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
  446                     hz * 60);
  447 #endif
  448                 DPRINTFN(2,("usb_event_thread: woke up\n"));
  449         }
  450         sc->sc_event_thread = NULL;
  451 
  452         /* In case parent is waiting for us to exit. */
  453         wakeup(sc);
  454 
  455         DPRINTF(("usb_event_thread: exit\n"));
  456         kthread_exit(0);
  457 }
  458 
  459 void
  460 usb_task_thread(void *arg)
  461 {
  462         struct usb_task *task;
  463         struct usb_taskq *taskq;
  464         int s;
  465 
  466         mtx_lock(&Giant);
  467 
  468         taskq = arg;
  469         DPRINTF(("usb_task_thread: start taskq %s\n", taskq->name));
  470 
  471         s = splusb();
  472         while (usb_ndevs > 0) {
  473                 task = TAILQ_FIRST(&taskq->tasks);
  474                 if (task == NULL) {
  475                         tsleep(&taskq->tasks, PWAIT, "usbtsk", 0);
  476                         task = TAILQ_FIRST(&taskq->tasks);
  477                 }
  478                 DPRINTFN(2,("usb_task_thread: woke up task=%p\n", task));
  479                 if (task != NULL) {
  480                         TAILQ_REMOVE(&taskq->tasks, task, next);
  481                         task->queue = -1;
  482                         splx(s);
  483                         task->fun(task->arg);
  484                         s = splusb();
  485                 }
  486         }
  487         splx(s);
  488 
  489         taskq->taskcreated = 0;
  490         wakeup(&taskq->taskcreated);
  491 
  492         DPRINTF(("usb_event_thread: exit\n"));
  493         kthread_exit(0);
  494 }
  495 
  496 int
  497 usbopen(struct cdev *dev, int flag, int mode, struct thread *p)
  498 {
  499         int unit = USBUNIT(dev);
  500         struct usb_softc *sc;
  501 
  502         if (unit == USB_DEV_MINOR) {
  503                 if (usb_dev_open)
  504                         return (EBUSY);
  505                 usb_dev_open = 1;
  506                 usb_async_proc = 0;
  507                 return (0);
  508         }
  509         sc = devclass_get_softc(usb_devclass, unit);
  510         if (sc == NULL)
  511                 return (ENXIO);
  512         if (sc->sc_dying)
  513                 return (EIO);
  514 
  515         return (0);
  516 }
  517 
  518 int
  519 usbread(struct cdev *dev, struct uio *uio, int flag)
  520 {
  521         struct usb_event ue;
  522         int unit = USBUNIT(dev);
  523         int s, error, n;
  524 
  525         if (unit != USB_DEV_MINOR)
  526                 return (ENODEV);
  527 
  528         if (uio->uio_resid != sizeof(struct usb_event))
  529                 return (EINVAL);
  530 
  531         error = 0;
  532         s = splusb();
  533         for (;;) {
  534                 n = usb_get_next_event(&ue);
  535                 if (n != 0)
  536                         break;
  537                 if (flag & O_NONBLOCK) {
  538                         error = EWOULDBLOCK;
  539                         break;
  540                 }
  541                 error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0);
  542                 if (error)
  543                         break;
  544         }
  545         splx(s);
  546         if (!error)
  547                 error = uiomove((void *)&ue, uio->uio_resid, uio);
  548 
  549         return (error);
  550 }
  551 
  552 int
  553 usbclose(struct cdev *dev, int flag, int mode, struct thread *p)
  554 {
  555         int unit = USBUNIT(dev);
  556 
  557         if (unit == USB_DEV_MINOR) {
  558                 usb_async_proc = 0;
  559                 usb_dev_open = 0;
  560         }
  561 
  562         return (0);
  563 }
  564 
  565 int
  566 usbioctl(struct cdev *devt, u_long cmd, caddr_t data, int flag, struct thread *p)
  567 {
  568         struct usb_softc *sc;
  569         int unit = USBUNIT(devt);
  570 
  571         if (unit == USB_DEV_MINOR) {
  572                 switch (cmd) {
  573                 case FIONBIO:
  574                         /* All handled in the upper FS layer. */
  575                         return (0);
  576 
  577                 case FIOASYNC:
  578                         if (*(int *)data)
  579                                 usb_async_proc = p->td_proc;
  580                         else
  581                                 usb_async_proc = 0;
  582                         return (0);
  583 
  584                 default:
  585                         return (EINVAL);
  586                 }
  587         }
  588         sc = devclass_get_softc(usb_devclass, unit);
  589         if (sc->sc_dying)
  590                 return (EIO);
  591 
  592         switch (cmd) {
  593         /* This part should be deleted */
  594         case USB_DISCOVER:
  595                 break;
  596         case USB_REQUEST:
  597         {
  598                 struct usb_ctl_request *ur = (void *)data;
  599                 int len = UGETW(ur->ucr_request.wLength);
  600                 struct iovec iov;
  601                 struct uio uio;
  602                 void *ptr = 0;
  603                 int addr = ur->ucr_addr;
  604                 usbd_status err;
  605                 int error = 0;
  606 
  607                 DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len));
  608                 if (len < 0 || len > 32768)
  609                         return (EINVAL);
  610                 if (addr < 0 || addr >= USB_MAX_DEVICES ||
  611                     sc->sc_bus->devices[addr] == 0)
  612                         return (EINVAL);
  613                 if (len != 0) {
  614                         iov.iov_base = (caddr_t)ur->ucr_data;
  615                         iov.iov_len = len;
  616                         uio.uio_iov = &iov;
  617                         uio.uio_iovcnt = 1;
  618                         uio.uio_resid = len;
  619                         uio.uio_offset = 0;
  620                         uio.uio_segflg = UIO_USERSPACE;
  621                         uio.uio_rw =
  622                                 ur->ucr_request.bmRequestType & UT_READ ?
  623                                 UIO_READ : UIO_WRITE;
  624                         uio.uio_td = p;
  625                         ptr = malloc(len, M_TEMP, M_WAITOK);
  626                         if (uio.uio_rw == UIO_WRITE) {
  627                                 error = uiomove(ptr, len, &uio);
  628                                 if (error)
  629                                         goto ret;
  630                         }
  631                 }
  632                 err = usbd_do_request_flags(sc->sc_bus->devices[addr],
  633                           &ur->ucr_request, ptr, ur->ucr_flags, &ur->ucr_actlen,
  634                           USBD_DEFAULT_TIMEOUT);
  635                 if (err) {
  636                         error = EIO;
  637                         goto ret;
  638                 }
  639                 if (len != 0) {
  640                         if (uio.uio_rw == UIO_READ) {
  641                                 error = uiomove(ptr, len, &uio);
  642                                 if (error)
  643                                         goto ret;
  644                         }
  645                 }
  646         ret:
  647                 if (ptr)
  648                         free(ptr, M_TEMP);
  649                 return (error);
  650         }
  651 
  652         case USB_DEVICEINFO:
  653         {
  654                 struct usb_device_info *di = (void *)data;
  655                 int addr = di->udi_addr;
  656                 usbd_device_handle dev;
  657 
  658                 if (addr < 1 || addr >= USB_MAX_DEVICES)
  659                         return (EINVAL);
  660                 dev = sc->sc_bus->devices[addr];
  661                 if (dev == NULL)
  662                         return (ENXIO);
  663                 usbd_fill_deviceinfo(dev, di, 1);
  664                 break;
  665         }
  666 
  667         case USB_DEVICESTATS:
  668                 *(struct usb_device_stats *)data = sc->sc_bus->stats;
  669                 break;
  670 
  671         default:
  672                 return (EINVAL);
  673         }
  674         return (0);
  675 }
  676 
  677 int
  678 usbpoll(struct cdev *dev, int events, struct thread *p)
  679 {
  680         int revents, mask, s;
  681         int unit = USBUNIT(dev);
  682 
  683         if (unit == USB_DEV_MINOR) {
  684                 revents = 0;
  685                 mask = POLLIN | POLLRDNORM;
  686 
  687                 s = splusb();
  688                 if (events & mask && usb_nevents > 0)
  689                         revents |= events & mask;
  690                 if (revents == 0 && events & mask)
  691                         selrecord(p, &usb_selevent);
  692                 splx(s);
  693 
  694                 return (revents);
  695         } else {
  696                 return (0);     /* select/poll never wakes up - back compat */
  697         }
  698 }
  699 
  700 /* Explore device tree from the root. */
  701 static void
  702 usb_discover(void *v)
  703 {
  704         struct usb_softc *sc = v;
  705 
  706         /* splxxx should be changed to mutexes for preemption safety some day */
  707         int s;
  708 
  709         DPRINTFN(2,("usb_discover\n"));
  710 #ifdef USB_DEBUG
  711         if (usb_noexplore > 1)
  712                 return;
  713 #endif
  714 
  715         /*
  716          * We need mutual exclusion while traversing the device tree,
  717          * but this is guaranteed since this function is only called
  718          * from the event thread for the controller.
  719          */
  720         s = splusb();
  721         while (sc->sc_bus->needs_explore && !sc->sc_dying) {
  722                 sc->sc_bus->needs_explore = 0;
  723                 splx(s);
  724                 sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
  725                 s = splusb();
  726         }
  727         splx(s);
  728 }
  729 
  730 void
  731 usb_needs_explore(usbd_device_handle dev)
  732 {
  733         DPRINTFN(2,("usb_needs_explore\n"));
  734         dev->bus->needs_explore = 1;
  735         wakeup(&dev->bus->needs_explore);
  736 }
  737 
  738 /* Called at splusb() */
  739 int
  740 usb_get_next_event(struct usb_event *ue)
  741 {
  742         struct usb_event_q *ueq;
  743 
  744         if (usb_nevents <= 0)
  745                 return (0);
  746         ueq = TAILQ_FIRST(&usb_events);
  747 #ifdef DIAGNOSTIC
  748         if (ueq == NULL) {
  749                 printf("usb: usb_nevents got out of sync! %d\n", usb_nevents);
  750                 usb_nevents = 0;
  751                 return (0);
  752         }
  753 #endif
  754         *ue = ueq->ue;
  755         TAILQ_REMOVE(&usb_events, ueq, next);
  756         free(ueq, M_USBDEV);
  757         usb_nevents--;
  758         return (1);
  759 }
  760 
  761 void
  762 usbd_add_dev_event(int type, usbd_device_handle udev)
  763 {
  764         struct usb_event ue;
  765 
  766         usbd_fill_deviceinfo(udev, &ue.u.ue_device, USB_EVENT_IS_ATTACH(type));
  767         usb_add_event(type, &ue);
  768 }
  769 
  770 void
  771 usbd_add_drv_event(int type, usbd_device_handle udev, device_t dev)
  772 {
  773         struct usb_event ue;
  774 
  775         ue.u.ue_driver.ue_cookie = udev->cookie;
  776         strncpy(ue.u.ue_driver.ue_devname, device_get_nameunit(dev),
  777             sizeof ue.u.ue_driver.ue_devname);
  778         usb_add_event(type, &ue);
  779 }
  780 
  781 void
  782 usb_add_event(int type, struct usb_event *uep)
  783 {
  784         struct usb_event_q *ueq;
  785         struct usb_event ue;
  786         struct timeval thetime;
  787         int s;
  788 
  789         ueq = malloc(sizeof *ueq, M_USBDEV, M_WAITOK);
  790         ueq->ue = *uep;
  791         ueq->ue.ue_type = type;
  792         microtime(&thetime);
  793         TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time);
  794 
  795         s = splusb();
  796         if (USB_EVENT_IS_DETACH(type)) {
  797                 struct usb_event_q *ueqi, *ueqi_next;
  798 
  799                 for (ueqi = TAILQ_FIRST(&usb_events); ueqi; ueqi = ueqi_next) {
  800                         ueqi_next = TAILQ_NEXT(ueqi, next);
  801                         if (ueqi->ue.u.ue_driver.ue_cookie.cookie ==
  802                             uep->u.ue_device.udi_cookie.cookie) {
  803                                 TAILQ_REMOVE(&usb_events, ueqi, next);
  804                                 free(ueqi, M_USBDEV);
  805                                 usb_nevents--;
  806                                 ueqi_next = TAILQ_FIRST(&usb_events);
  807                         }
  808                 }
  809         }
  810         if (usb_nevents >= USB_MAX_EVENTS) {
  811                 /* Too many queued events, drop an old one. */
  812                 DPRINTF(("usb: event dropped\n"));
  813                 (void)usb_get_next_event(&ue);
  814         }
  815         TAILQ_INSERT_TAIL(&usb_events, ueq, next);
  816         usb_nevents++;
  817         wakeup(&usb_events);
  818         selwakeuppri(&usb_selevent, PZERO);
  819         if (usb_async_proc != NULL) {
  820                 PROC_LOCK(usb_async_proc);
  821                 psignal(usb_async_proc, SIGIO);
  822                 PROC_UNLOCK(usb_async_proc);
  823         }
  824         splx(s);
  825 }
  826 
  827 void
  828 usb_schedsoftintr(usbd_bus_handle bus)
  829 {
  830         DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling));
  831 #ifdef USB_USE_SOFTINTR
  832         if (bus->use_polling) {
  833                 bus->methods->soft_intr(bus);
  834         } else {
  835 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
  836                 softintr_schedule(bus->soft);
  837 #else
  838                 if (!callout_pending(&bus->softi))
  839                         callout_reset(&bus->softi, 0, bus->methods->soft_intr,
  840                             bus);
  841 #endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
  842         }
  843 #else
  844        bus->methods->soft_intr(bus);
  845 #endif /* USB_USE_SOFTINTR */
  846 }
  847 
  848 static int
  849 usb_detach(device_t self)
  850 {
  851         struct usb_softc *sc = device_get_softc(self);
  852         struct usb_event ue;
  853         struct usb_taskq *taskq;
  854         int i;
  855 
  856         DPRINTF(("usb_detach: start\n"));
  857 
  858         sc->sc_dying = 1;
  859 
  860         /* Make all devices disconnect. */
  861         if (sc->sc_port.device != NULL)
  862                 usb_disconnect_port(&sc->sc_port, self);
  863 
  864         /* Kill off event thread. */
  865         if (sc->sc_event_thread != NULL) {
  866                 wakeup(&sc->sc_bus->needs_explore);
  867                 if (tsleep(sc, PWAIT, "usbdet", hz * 60))
  868                         printf("%s: event thread didn't die\n",
  869                                device_get_nameunit(sc->sc_dev));
  870                 DPRINTF(("usb_detach: event thread dead\n"));
  871         }
  872 
  873         destroy_dev(sc->sc_usbdev);
  874         if (--usb_ndevs == 0) {
  875                 destroy_dev(usb_dev);
  876                 usb_dev = NULL;
  877                 for (i = 0; i < USB_NUM_TASKQS; i++) {
  878                         taskq = &usb_taskq[i];
  879                         wakeup(&taskq->tasks);
  880                         if (tsleep(&taskq->taskcreated, PWAIT, "usbtdt",
  881                             hz * 60)) {
  882                                 printf("usb task thread %s didn't die\n",
  883                                     taskq->name);
  884                         }
  885                 }
  886         }
  887 
  888         usbd_finish();
  889 
  890 #ifdef USB_USE_SOFTINTR
  891 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
  892         if (sc->sc_bus->soft != NULL) {
  893                 softintr_disestablish(sc->sc_bus->soft);
  894                 sc->sc_bus->soft = NULL;
  895         }
  896 #else
  897         callout_stop(&sc->sc_bus->softi);
  898 #endif
  899 #endif
  900 
  901         ue.u.ue_ctrlr.ue_bus = device_get_unit(sc->sc_dev);
  902         usb_add_event(USB_EVENT_CTRLR_DETACH, &ue);
  903 
  904         return (0);
  905 }
  906 
  907 static void
  908 usb_child_detached(device_t self, device_t child)
  909 {
  910         struct usb_softc *sc = device_get_softc(self);
  911 
  912         /* XXX, should check it is the right device. */
  913         sc->sc_port.device = NULL;
  914 }
  915 
  916 /* Explore USB busses at the end of device configuration. */
  917 static void
  918 usb_cold_explore(void *arg)
  919 {
  920         struct usb_softc *sc;
  921 
  922         KASSERT(cold || TAILQ_EMPTY(&usb_coldexplist),
  923             ("usb_cold_explore: busses to explore when !cold"));
  924         while (!TAILQ_EMPTY(&usb_coldexplist)) {
  925                 sc = TAILQ_FIRST(&usb_coldexplist);
  926                 TAILQ_REMOVE(&usb_coldexplist, sc, sc_coldexplist);
  927 
  928                 sc->sc_bus->use_polling++;
  929                 sc->sc_port.device->hub->explore(sc->sc_bus->root_hub);
  930                 sc->sc_bus->use_polling--;
  931         }
  932 }
  933 
  934 SYSINIT(usb_cold_explore, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE,
  935     usb_cold_explore, NULL);

Cache object: 960ebe485c313d0697952c9b62b60ae2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.