LCOV - code coverage report
Current view: top level - dev/usb - usb.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 518 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 25 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: usb.c,v 1.120 2018/08/31 16:32:31 miko 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/timeout.h>
      50             : #include <sys/kthread.h>
      51             : #include <sys/conf.h>
      52             : #include <sys/fcntl.h>
      53             : #include <sys/poll.h>
      54             : #include <sys/selinfo.h>
      55             : #include <sys/signalvar.h>
      56             : #include <sys/time.h>
      57             : #include <sys/rwlock.h>
      58             : 
      59             : #include <dev/usb/usb.h>
      60             : #include <dev/usb/usbdi.h>
      61             : #include <dev/usb/usbdi_util.h>
      62             : 
      63             : #include <machine/bus.h>
      64             : 
      65             : #include <dev/usb/usbdivar.h>
      66             : #include <dev/usb/usb_mem.h>
      67             : #include <dev/usb/usbpcap.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             :  * !0 - do no exploration
      85             :  */
      86             : int     usb_noexplore = 0;
      87             : #else
      88             : #define DPRINTF(x)
      89             : #define DPRINTFN(n,x)
      90             : #endif
      91             : 
      92             : struct usb_softc {
      93             :         struct device    sc_dev;        /* base device */
      94             :         struct usbd_bus  *sc_bus;       /* USB controller */
      95             :         struct usbd_port sc_port;       /* dummy port for root hub */
      96             :         int              sc_speed;
      97             : 
      98             :         struct usb_task  sc_explore_task;
      99             : 
     100             :         struct timeval   sc_ptime;
     101             : };
     102             : 
     103             : struct rwlock usbpalock;
     104             : 
     105             : TAILQ_HEAD(, usb_task) usb_abort_tasks;
     106             : TAILQ_HEAD(, usb_task) usb_explore_tasks;
     107             : TAILQ_HEAD(, usb_task) usb_generic_tasks;
     108             : 
     109             : static int usb_nbuses = 0;
     110             : static int usb_run_tasks, usb_run_abort_tasks;
     111             : int explore_pending;
     112             : const char *usbrev_str[] = USBREV_STR;
     113             : 
     114             : void             usb_explore(void *);
     115             : void             usb_create_task_threads(void *);
     116             : void             usb_task_thread(void *);
     117             : struct proc     *usb_task_thread_proc = NULL;
     118             : void             usb_abort_task_thread(void *);
     119             : struct proc     *usb_abort_task_thread_proc = NULL;
     120             : 
     121             : void             usb_fill_di_task(void *);
     122             : void             usb_fill_udc_task(void *);
     123             : void             usb_fill_udf_task(void *);
     124             : 
     125             : int              usb_match(struct device *, void *, void *);
     126             : void             usb_attach(struct device *, struct device *, void *);
     127             : int              usb_detach(struct device *, int);
     128             : int              usb_activate(struct device *, int);
     129             : 
     130             : int              usb_attach_roothub(struct usb_softc *);
     131             : void             usb_detach_roothub(struct usb_softc *);
     132             : 
     133             : struct cfdriver usb_cd = {
     134             :         NULL, "usb", DV_DULL
     135             : };
     136             : 
     137             : const struct cfattach usb_ca = {
     138             :         sizeof(struct usb_softc), usb_match, usb_attach, usb_detach,
     139             :         usb_activate,
     140             : };
     141             : 
     142             : int
     143           0 : usb_match(struct device *parent, void *match, void *aux)
     144             : {
     145           0 :         return (1);
     146             : }
     147             : 
     148             : void
     149           0 : usb_attach(struct device *parent, struct device *self, void *aux)
     150             : {
     151           0 :         struct usb_softc *sc = (struct usb_softc *)self;
     152             :         int usbrev;
     153             : 
     154           0 :         if (usb_nbuses == 0) {
     155           0 :                 rw_init(&usbpalock, "usbpalock");
     156           0 :                 TAILQ_INIT(&usb_abort_tasks);
     157           0 :                 TAILQ_INIT(&usb_explore_tasks);
     158           0 :                 TAILQ_INIT(&usb_generic_tasks);
     159           0 :                 usb_run_tasks = usb_run_abort_tasks = 1;
     160           0 :                 kthread_create_deferred(usb_create_task_threads, NULL);
     161           0 :         }
     162           0 :         usb_nbuses++;
     163             : 
     164           0 :         sc->sc_bus = aux;
     165           0 :         sc->sc_bus->usbctl = self;
     166           0 :         sc->sc_port.power = USB_MAX_POWER;
     167             : 
     168           0 :         usbrev = sc->sc_bus->usbrev;
     169           0 :         printf(": USB revision %s", usbrev_str[usbrev]);
     170           0 :         switch (usbrev) {
     171             :         case USBREV_1_0:
     172             :         case USBREV_1_1:
     173           0 :                 sc->sc_speed = USB_SPEED_FULL;
     174           0 :                 break;
     175             :         case USBREV_2_0:
     176           0 :                 sc->sc_speed = USB_SPEED_HIGH;
     177           0 :                 break;
     178             :         case USBREV_3_0:
     179           0 :                 sc->sc_speed = USB_SPEED_SUPER;
     180           0 :                 break;
     181             :         default:
     182           0 :                 printf(", not supported\n");
     183           0 :                 sc->sc_bus->dying = 1;
     184           0 :                 return;
     185             :         }
     186           0 :         printf("\n");
     187             : 
     188             : #if NBPFILTER > 0
     189           0 :         sc->sc_bus->bpfif = bpfsattach(&sc->sc_bus->bpf, sc->sc_dev.dv_xname,
     190             :             DLT_USBPCAP, sizeof(struct usbpcap_pkt_hdr));
     191             : #endif
     192             : 
     193             :         /* Make sure not to use tsleep() if we are cold booting. */
     194           0 :         if (cold)
     195           0 :                 sc->sc_bus->use_polling++;
     196             : 
     197             :         /* Don't let hub interrupts cause explore until ready. */
     198           0 :         sc->sc_bus->flags |= USB_BUS_CONFIG_PENDING;
     199             : 
     200             :         /* explore task */
     201           0 :         usb_init_task(&sc->sc_explore_task, usb_explore, sc,
     202             :             USB_TASK_TYPE_EXPLORE);
     203             : 
     204           0 :         sc->sc_bus->soft = softintr_establish(IPL_SOFTUSB,
     205           0 :             sc->sc_bus->methods->soft_intr, sc->sc_bus);
     206           0 :         if (sc->sc_bus->soft == NULL) {
     207           0 :                 printf("%s: can't register softintr\n", sc->sc_dev.dv_xname);
     208           0 :                 sc->sc_bus->dying = 1;
     209           0 :                 return;
     210             :         }
     211             : 
     212           0 :         if (!usb_attach_roothub(sc)) {
     213           0 :                 struct usbd_device *dev = sc->sc_bus->root_hub;
     214             : #if 1
     215             :                 /*
     216             :                  * Turning this code off will delay attachment of USB devices
     217             :                  * until the USB task thread is running, which means that
     218             :                  * the keyboard will not work until after cold boot.
     219             :                  */
     220           0 :                 if (cold && (sc->sc_dev.dv_cfdata->cf_flags & 1))
     221           0 :                         dev->hub->explore(sc->sc_bus->root_hub);
     222             : #endif
     223           0 :         }
     224             : 
     225           0 :         if (cold)
     226           0 :                 sc->sc_bus->use_polling--;
     227             : 
     228           0 :         if (!sc->sc_bus->dying) {
     229           0 :                 getmicrouptime(&sc->sc_ptime);
     230           0 :                 if (sc->sc_bus->usbrev == USBREV_2_0)
     231           0 :                         explore_pending++;
     232           0 :                 config_pending_incr();
     233           0 :                 usb_needs_explore(sc->sc_bus->root_hub, 1);
     234           0 :         }
     235           0 : }
     236             : 
     237             : int
     238           0 : usb_attach_roothub(struct usb_softc *sc)
     239             : {
     240             :         struct usbd_device *dev;
     241             : 
     242           0 :         if (usbd_new_device(&sc->sc_dev, sc->sc_bus, 0, sc->sc_speed, 0,
     243           0 :             &sc->sc_port)) {
     244           0 :                 printf("%s: root hub problem\n", sc->sc_dev.dv_xname);
     245           0 :                 sc->sc_bus->dying = 1;
     246           0 :                 return (1);
     247             :         }
     248             : 
     249           0 :         dev = sc->sc_port.device;
     250           0 :         if (dev->hub == NULL) {
     251           0 :                 printf("%s: root device is not a hub\n", sc->sc_dev.dv_xname);
     252           0 :                 sc->sc_bus->dying = 1;
     253           0 :                 return (1);
     254             :         }
     255           0 :         sc->sc_bus->root_hub = dev;
     256             : 
     257           0 :         return (0);
     258           0 : }
     259             : 
     260             : void
     261           0 : usb_detach_roothub(struct usb_softc *sc)
     262             : {
     263             :         /*
     264             :          * To avoid races with the usb task thread, mark the root hub
     265             :          * as disconnecting and schedule an exploration task to detach
     266             :          * it.
     267             :          */
     268           0 :         sc->sc_bus->flags |= USB_BUS_DISCONNECTING;
     269             :         /*
     270             :          * Reset the dying flag in case it has been set by the interrupt
     271             :          * handler when unplugging an HC card otherwise the task wont be
     272             :          * scheduled.  This is safe since a dead HC should not trigger
     273             :          * new interrupt.
     274             :          */
     275           0 :         sc->sc_bus->dying = 0;
     276           0 :         usb_needs_explore(sc->sc_bus->root_hub, 0);
     277             : 
     278           0 :         usb_wait_task(sc->sc_bus->root_hub, &sc->sc_explore_task);
     279             : 
     280           0 :         sc->sc_bus->root_hub = NULL;
     281           0 : }
     282             : 
     283             : void
     284           0 : usb_create_task_threads(void *arg)
     285             : {
     286           0 :         if (kthread_create(usb_abort_task_thread, NULL,
     287             :             &usb_abort_task_thread_proc, "usbatsk"))
     288           0 :                 panic("unable to create usb abort task thread");
     289             : 
     290           0 :         if (kthread_create(usb_task_thread, NULL,
     291             :             &usb_task_thread_proc, "usbtask"))
     292           0 :                 panic("unable to create usb task thread");
     293           0 : }
     294             : 
     295             : /*
     296             :  * Add a task to be performed by the task thread.  This function can be
     297             :  * called from any context and the task will be executed in a process
     298             :  * context ASAP.
     299             :  */
     300             : void
     301           0 : usb_add_task(struct usbd_device *dev, struct usb_task *task)
     302             : {
     303             :         int s;
     304             : 
     305             :         /*
     306             :          * If the thread detaching ``dev'' is sleeping, waiting
     307             :          * for all submitted transfers to finish, we must be able
     308             :          * to enqueue abort tasks.  Otherwise timeouts can't give
     309             :          * back submitted transfers to the stack.
     310             :          */
     311           0 :         if (usbd_is_dying(dev) && (task->type != USB_TASK_TYPE_ABORT))
     312           0 :                 return;
     313             : 
     314             :         DPRINTFN(2,("%s: task=%p state=%d type=%d\n", __func__, task,
     315             :             task->state, task->type));
     316             : 
     317           0 :         s = splusb();
     318           0 :         if (!(task->state & USB_TASK_STATE_ONQ)) {
     319           0 :                 switch (task->type) {
     320             :                 case USB_TASK_TYPE_ABORT:
     321           0 :                         TAILQ_INSERT_TAIL(&usb_abort_tasks, task, next);
     322           0 :                         break;
     323             :                 case USB_TASK_TYPE_EXPLORE:
     324           0 :                         TAILQ_INSERT_TAIL(&usb_explore_tasks, task, next);
     325           0 :                         break;
     326             :                 case USB_TASK_TYPE_GENERIC:
     327           0 :                         TAILQ_INSERT_TAIL(&usb_generic_tasks, task, next);
     328           0 :                         break;
     329             :                 }
     330           0 :                 task->state |= USB_TASK_STATE_ONQ;
     331           0 :                 task->dev = dev;
     332           0 :         }
     333           0 :         if (task->type == USB_TASK_TYPE_ABORT)
     334           0 :                 wakeup(&usb_run_abort_tasks);
     335             :         else
     336           0 :                 wakeup(&usb_run_tasks);
     337           0 :         splx(s);
     338           0 : }
     339             : 
     340             : void
     341           0 : usb_rem_task(struct usbd_device *dev, struct usb_task *task)
     342             : {
     343             :         int s;
     344             : 
     345           0 :         if (!(task->state & USB_TASK_STATE_ONQ))
     346           0 :                 return;
     347             : 
     348             :         DPRINTFN(2,("%s: task=%p state=%d type=%d\n", __func__, task,
     349             :             task->state, task->type));
     350             : 
     351           0 :         s = splusb();
     352             : 
     353           0 :         switch (task->type) {
     354             :         case USB_TASK_TYPE_ABORT:
     355           0 :                 TAILQ_REMOVE(&usb_abort_tasks, task, next);
     356           0 :                 break;
     357             :         case USB_TASK_TYPE_EXPLORE:
     358           0 :                 TAILQ_REMOVE(&usb_explore_tasks, task, next);
     359           0 :                 break;
     360             :         case USB_TASK_TYPE_GENERIC:
     361           0 :                 TAILQ_REMOVE(&usb_generic_tasks, task, next);
     362           0 :                 break;
     363             :         }
     364           0 :         task->state &= ~USB_TASK_STATE_ONQ;
     365           0 :         if (task->state == USB_TASK_STATE_NONE)
     366           0 :                 wakeup(task);
     367             : 
     368           0 :         splx(s);
     369           0 : }
     370             : 
     371             : void
     372           0 : usb_wait_task(struct usbd_device *dev, struct usb_task *task)
     373             : {
     374             :         int s;
     375             : 
     376             :         DPRINTFN(2,("%s: task=%p state=%d type=%d\n", __func__, task,
     377             :             task->state, task->type));
     378             : 
     379           0 :         if (task->state == USB_TASK_STATE_NONE)
     380           0 :                 return;
     381             : 
     382           0 :         s = splusb();
     383           0 :         while (task->state != USB_TASK_STATE_NONE) {
     384             :                 DPRINTF(("%s: waiting for task to complete\n", __func__));
     385           0 :                 tsleep(task, PWAIT, "endtask", 0);
     386             :         }
     387           0 :         splx(s);
     388           0 : }
     389             : 
     390             : void
     391           0 : usb_rem_wait_task(struct usbd_device *dev, struct usb_task *task)
     392             : {
     393           0 :         usb_rem_task(dev, task);
     394           0 :         usb_wait_task(dev, task);
     395           0 : }
     396             : 
     397             : void
     398           0 : usb_task_thread(void *arg)
     399             : {
     400             :         struct usb_task *task;
     401             :         int s;
     402             : 
     403             :         DPRINTF(("usb_task_thread: start\n"));
     404             : 
     405           0 :         s = splusb();
     406           0 :         while (usb_run_tasks) {
     407           0 :                 if ((task = TAILQ_FIRST(&usb_explore_tasks)) != NULL)
     408           0 :                         TAILQ_REMOVE(&usb_explore_tasks, task, next);
     409           0 :                 else if ((task = TAILQ_FIRST(&usb_generic_tasks)) != NULL)
     410           0 :                         TAILQ_REMOVE(&usb_generic_tasks, task, next);
     411             :                 else {
     412           0 :                         tsleep(&usb_run_tasks, PWAIT, "usbtsk", 0);
     413           0 :                         continue;
     414             :                 }
     415             :                 /*
     416             :                  * Set the state run bit before clearing the onq bit.
     417             :                  * This avoids state == none between dequeue and
     418             :                  * execution, which could cause usb_wait_task() to do
     419             :                  * the wrong thing.
     420             :                  */
     421           0 :                 task->state |= USB_TASK_STATE_RUN;
     422           0 :                 task->state &= ~USB_TASK_STATE_ONQ;
     423             :                 /* Don't actually execute the task if dying. */
     424           0 :                 if (!usbd_is_dying(task->dev)) {
     425           0 :                         splx(s);
     426           0 :                         task->fun(task->arg);
     427           0 :                         s = splusb();
     428           0 :                 }
     429           0 :                 task->state &= ~USB_TASK_STATE_RUN;
     430           0 :                 if (task->state == USB_TASK_STATE_NONE)
     431           0 :                         wakeup(task);
     432             :         }
     433           0 :         splx(s);
     434             : 
     435           0 :         kthread_exit(0);
     436             : }
     437             : 
     438             : /*
     439             :  * This thread is ONLY for the HCI drivers to be able to abort xfers.
     440             :  * Synchronous xfers sleep the task thread, so the aborts need to happen
     441             :  * in a different thread.
     442             :  */
     443             : void
     444           0 : usb_abort_task_thread(void *arg)
     445             : {
     446             :         struct usb_task *task;
     447             :         int s;
     448             : 
     449             :         DPRINTF(("usb_xfer_abort_thread: start\n"));
     450             : 
     451           0 :         s = splusb();
     452           0 :         while (usb_run_abort_tasks) {
     453           0 :                 if ((task = TAILQ_FIRST(&usb_abort_tasks)) != NULL)
     454           0 :                         TAILQ_REMOVE(&usb_abort_tasks, task, next);
     455             :                 else {
     456           0 :                         tsleep(&usb_run_abort_tasks, PWAIT, "usbatsk", 0);
     457           0 :                         continue;
     458             :                 }
     459             :                 /*
     460             :                  * Set the state run bit before clearing the onq bit.
     461             :                  * This avoids state == none between dequeue and
     462             :                  * execution, which could cause usb_wait_task() to do
     463             :                  * the wrong thing.
     464             :                  */
     465           0 :                 task->state |= USB_TASK_STATE_RUN;
     466           0 :                 task->state &= ~USB_TASK_STATE_ONQ;
     467           0 :                 splx(s);
     468           0 :                 task->fun(task->arg);
     469           0 :                 s = splusb();
     470           0 :                 task->state &= ~USB_TASK_STATE_RUN;
     471           0 :                 if (task->state == USB_TASK_STATE_NONE)
     472           0 :                         wakeup(task);
     473             :         }
     474           0 :         splx(s);
     475             : 
     476           0 :         kthread_exit(0);
     477             : }
     478             : 
     479             : int
     480           0 : usbctlprint(void *aux, const char *pnp)
     481             : {
     482             :         /* only "usb"es can attach to host controllers */
     483           0 :         if (pnp)
     484           0 :                 printf("usb at %s", pnp);
     485             : 
     486           0 :         return (UNCONF);
     487             : }
     488             : 
     489             : int
     490           0 : usbopen(dev_t dev, int flag, int mode, struct proc *p)
     491             : {
     492           0 :         int unit = minor(dev);
     493             :         struct usb_softc *sc;
     494             : 
     495           0 :         if (unit >= usb_cd.cd_ndevs)
     496           0 :                 return (ENXIO);
     497           0 :         sc = usb_cd.cd_devs[unit];
     498           0 :         if (sc == NULL)
     499           0 :                 return (ENXIO);
     500             : 
     501           0 :         if (sc->sc_bus->dying)
     502           0 :                 return (EIO);
     503             : 
     504           0 :         return (0);
     505           0 : }
     506             : 
     507             : int
     508           0 : usbclose(dev_t dev, int flag, int mode, struct proc *p)
     509             : {
     510           0 :         return (0);
     511             : }
     512             : 
     513             : void
     514           0 : usb_fill_di_task(void *arg)
     515             : {
     516           0 :         struct usb_device_info *di = (struct usb_device_info *)arg;
     517             :         struct usb_softc *sc;
     518             :         struct usbd_device *dev;
     519             : 
     520             :         /* check that the bus and device are still present */
     521           0 :         if (di->udi_bus >= usb_cd.cd_ndevs)
     522           0 :                 return;
     523           0 :         sc = usb_cd.cd_devs[di->udi_bus];
     524           0 :         if (sc == NULL)
     525           0 :                 return;
     526           0 :         dev = sc->sc_bus->devices[di->udi_addr];
     527           0 :         if (dev == NULL)
     528           0 :                 return;
     529             : 
     530           0 :         usbd_fill_deviceinfo(dev, di);
     531           0 : }
     532             : 
     533             : void
     534           0 : usb_fill_udc_task(void *arg)
     535             : {
     536           0 :         struct usb_device_cdesc *udc = (struct usb_device_cdesc *)arg;
     537             :         struct usb_softc *sc;
     538             :         struct usbd_device *dev;
     539           0 :         int addr = udc->udc_addr;
     540             :         usb_config_descriptor_t *cdesc;
     541             : 
     542             :         /* check that the bus and device are still present */
     543           0 :         if (udc->udc_bus >= usb_cd.cd_ndevs)
     544           0 :                 return;
     545           0 :         sc = usb_cd.cd_devs[udc->udc_bus];
     546           0 :         if (sc == NULL)
     547           0 :                 return;
     548           0 :         dev = sc->sc_bus->devices[udc->udc_addr];
     549           0 :         if (dev == NULL)
     550           0 :                 return;
     551             : 
     552           0 :         cdesc = usbd_get_cdesc(sc->sc_bus->devices[addr],
     553           0 :             udc->udc_config_index, 0);
     554           0 :         if (cdesc == NULL)
     555           0 :                 return;
     556           0 :         udc->udc_desc = *cdesc;
     557           0 :         free(cdesc, M_TEMP, 0);
     558           0 : }
     559             : 
     560             : void
     561           0 : usb_fill_udf_task(void *arg)
     562             : {
     563           0 :         struct usb_device_fdesc *udf = (struct usb_device_fdesc *)arg;
     564             :         struct usb_softc *sc;
     565             :         struct usbd_device *dev;
     566           0 :         int addr = udf->udf_addr;
     567             :         usb_config_descriptor_t *cdesc;
     568             : 
     569             :         /* check that the bus and device are still present */
     570           0 :         if (udf->udf_bus >= usb_cd.cd_ndevs)
     571           0 :                 return;
     572           0 :         sc = usb_cd.cd_devs[udf->udf_bus];
     573           0 :         if (sc == NULL)
     574           0 :                 return;
     575           0 :         dev = sc->sc_bus->devices[udf->udf_addr];
     576           0 :         if (dev == NULL)
     577           0 :                 return;
     578             : 
     579           0 :         cdesc = usbd_get_cdesc(sc->sc_bus->devices[addr],
     580           0 :             udf->udf_config_index, &udf->udf_size);
     581           0 :         udf->udf_data = (char *)cdesc;
     582           0 : }
     583             : 
     584             : int
     585           0 : usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, struct proc *p)
     586             : {
     587             :         struct usb_softc *sc;
     588           0 :         int unit = minor(devt);
     589             :         int error;
     590             : 
     591           0 :         sc = usb_cd.cd_devs[unit];
     592             : 
     593           0 :         if (sc->sc_bus->dying)
     594           0 :                 return (EIO);
     595             : 
     596             :         error = 0;
     597           0 :         switch (cmd) {
     598             : #ifdef USB_DEBUG
     599             :         case USB_SETDEBUG:
     600             :                 /* only root can access to these debug flags */
     601             :                 if ((error = suser(curproc)) != 0)
     602             :                         return (error);
     603             :                 if (!(flag & FWRITE))
     604             :                         return (EBADF);
     605             :                 usbdebug  = ((*(unsigned int *)data) & 0x000000ff);
     606             : #if defined(UHCI_DEBUG) && NUHCI > 0
     607             :                 uhcidebug = ((*(unsigned int *)data) & 0x0000ff00) >> 8;
     608             : #endif
     609             : #if defined(OHCI_DEBUG) && NOHCI > 0
     610             :                 ohcidebug = ((*(unsigned int *)data) & 0x00ff0000) >> 16;
     611             : #endif
     612             : #if defined(EHCI_DEBUG) && NEHCI > 0
     613             :                 ehcidebug = ((*(unsigned int *)data) & 0xff000000) >> 24;
     614             : #endif
     615             :                 break;
     616             : #endif /* USB_DEBUG */
     617             :         case USB_REQUEST:
     618             :         {
     619           0 :                 struct usb_ctl_request *ur = (void *)data;
     620           0 :                 size_t len = UGETW(ur->ucr_request.wLength), mlen;
     621           0 :                 struct iovec iov;
     622           0 :                 struct uio uio;
     623             :                 void *ptr = NULL;
     624           0 :                 int addr = ur->ucr_addr;
     625             :                 usbd_status err;
     626             : 
     627           0 :                 if (!(flag & FWRITE))
     628           0 :                         return (EBADF);
     629             : 
     630             :                 DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%zu\n", addr, len));
     631             :                 /* Avoid requests that would damage the bus integrity. */
     632           0 :                 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
     633           0 :                      ur->ucr_request.bRequest == UR_SET_ADDRESS) ||
     634           0 :                     (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
     635           0 :                      ur->ucr_request.bRequest == UR_SET_CONFIG) ||
     636           0 :                     (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE &&
     637           0 :                      ur->ucr_request.bRequest == UR_SET_INTERFACE))
     638           0 :                         return (EINVAL);
     639             : 
     640           0 :                 if (len > 32767)
     641           0 :                         return (EINVAL);
     642           0 :                 if (addr < 0 || addr >= USB_MAX_DEVICES)
     643           0 :                         return (EINVAL);
     644           0 :                 if (sc->sc_bus->devices[addr] == NULL)
     645           0 :                         return (ENXIO);
     646           0 :                 if (len != 0) {
     647           0 :                         iov.iov_base = (caddr_t)ur->ucr_data;
     648           0 :                         iov.iov_len = len;
     649           0 :                         uio.uio_iov = &iov;
     650           0 :                         uio.uio_iovcnt = 1;
     651           0 :                         uio.uio_resid = len;
     652           0 :                         uio.uio_offset = 0;
     653           0 :                         uio.uio_segflg = UIO_USERSPACE;
     654           0 :                         uio.uio_rw =
     655           0 :                                 ur->ucr_request.bmRequestType & UT_READ ?
     656             :                                 UIO_READ : UIO_WRITE;
     657           0 :                         uio.uio_procp = p;
     658           0 :                         if ((ptr = malloc(len, M_TEMP, M_NOWAIT)) == NULL) {
     659             :                                 error = ENOMEM;
     660           0 :                                 goto ret;
     661             :                         }
     662           0 :                         if (uio.uio_rw == UIO_WRITE) {
     663           0 :                                 error = uiomove(ptr, len, &uio);
     664           0 :                                 if (error)
     665             :                                         goto ret;
     666             :                         }
     667             :                 }
     668           0 :                 err = usbd_do_request_flags(sc->sc_bus->devices[addr],
     669           0 :                           &ur->ucr_request, ptr, ur->ucr_flags,
     670           0 :                           &ur->ucr_actlen, USBD_DEFAULT_TIMEOUT);
     671           0 :                 if (err) {
     672             :                         error = EIO;
     673           0 :                         goto ret;
     674             :                 }
     675             :                 /* Only if USBD_SHORT_XFER_OK is set. */
     676             :                 mlen = len;
     677           0 :                 if (mlen > ur->ucr_actlen)
     678           0 :                         mlen = ur->ucr_actlen;
     679           0 :                 if (mlen != 0) {
     680           0 :                         if (uio.uio_rw == UIO_READ) {
     681           0 :                                 error = uiomove(ptr, mlen, &uio);
     682           0 :                                 if (error)
     683             :                                         goto ret;
     684             :                         }
     685             :                 }
     686             :         ret:
     687           0 :                 free(ptr, M_TEMP, len);
     688           0 :                 return (error);
     689           0 :         }
     690             : 
     691             :         case USB_DEVICEINFO:
     692             :         {
     693           0 :                 struct usb_device_info *di = (void *)data;
     694           0 :                 int addr = di->udi_addr;
     695           0 :                 struct usb_task di_task;
     696             :                 struct usbd_device *dev;
     697             : 
     698           0 :                 if (addr < 1 || addr >= USB_MAX_DEVICES)
     699           0 :                         return (EINVAL);
     700             : 
     701           0 :                 dev = sc->sc_bus->devices[addr];
     702           0 :                 if (dev == NULL)
     703           0 :                         return (ENXIO);
     704             : 
     705           0 :                 di->udi_bus = unit;
     706             : 
     707             :                 /* All devices get a driver, thanks to ugen(4).  If the
     708             :                  * task ends without adding a driver name, there was an error.
     709             :                  */
     710           0 :                 di->udi_devnames[0][0] = '\0';
     711             : 
     712           0 :                 usb_init_task(&di_task, usb_fill_di_task, di,
     713             :                     USB_TASK_TYPE_GENERIC);
     714           0 :                 usb_add_task(sc->sc_bus->root_hub, &di_task);
     715           0 :                 usb_wait_task(sc->sc_bus->root_hub, &di_task);
     716             : 
     717           0 :                 if (di->udi_devnames[0][0] == '\0')
     718           0 :                         return (ENXIO);
     719             : 
     720           0 :                 break;
     721           0 :         }
     722             : 
     723             :         case USB_DEVICESTATS:
     724           0 :                 *(struct usb_device_stats *)data = sc->sc_bus->stats;
     725           0 :                 break;
     726             : 
     727             :         case USB_DEVICE_GET_DDESC:
     728             :         {
     729           0 :                 struct usb_device_ddesc *udd = (struct usb_device_ddesc *)data;
     730           0 :                 int addr = udd->udd_addr;
     731             :                 struct usbd_device *dev;
     732             : 
     733           0 :                 if (addr < 1 || addr >= USB_MAX_DEVICES)
     734           0 :                         return (EINVAL);
     735             : 
     736           0 :                 dev = sc->sc_bus->devices[addr];
     737           0 :                 if (dev == NULL)
     738           0 :                         return (ENXIO);
     739             : 
     740           0 :                 udd->udd_bus = unit;
     741             : 
     742           0 :                 udd->udd_desc = *usbd_get_device_descriptor(dev);
     743           0 :                 break;
     744             :         }
     745             : 
     746             :         case USB_DEVICE_GET_CDESC:
     747             :         {
     748           0 :                 struct usb_device_cdesc *udc = (struct usb_device_cdesc *)data;
     749           0 :                 int addr = udc->udc_addr;
     750           0 :                 struct usb_task udc_task;
     751             : 
     752           0 :                 if (addr < 1 || addr >= USB_MAX_DEVICES)
     753           0 :                         return (EINVAL);
     754           0 :                 if (sc->sc_bus->devices[addr] == NULL)
     755           0 :                         return (ENXIO);
     756             : 
     757           0 :                 udc->udc_bus = unit;
     758             : 
     759           0 :                 udc->udc_desc.bLength = 0;
     760           0 :                 usb_init_task(&udc_task, usb_fill_udc_task, udc,
     761             :                     USB_TASK_TYPE_GENERIC);
     762           0 :                 usb_add_task(sc->sc_bus->root_hub, &udc_task);
     763           0 :                 usb_wait_task(sc->sc_bus->root_hub, &udc_task);
     764           0 :                 if (udc->udc_desc.bLength == 0)
     765           0 :                         return (EINVAL);
     766           0 :                 break;
     767           0 :         }
     768             : 
     769             :         case USB_DEVICE_GET_FDESC:
     770             :         {
     771           0 :                 struct usb_device_fdesc *udf = (struct usb_device_fdesc *)data;
     772           0 :                 int addr = udf->udf_addr;
     773           0 :                 struct usb_task udf_task;
     774           0 :                 struct usb_device_fdesc save_udf;
     775             :                 usb_config_descriptor_t *cdesc;
     776           0 :                 struct iovec iov;
     777           0 :                 struct uio uio;
     778             :                 size_t len;
     779             : 
     780           0 :                 if (addr < 1 || addr >= USB_MAX_DEVICES)
     781           0 :                         return (EINVAL);
     782           0 :                 if (sc->sc_bus->devices[addr] == NULL)
     783           0 :                         return (ENXIO);
     784             : 
     785           0 :                 udf->udf_bus = unit;
     786             : 
     787           0 :                 save_udf = *udf;
     788           0 :                 udf->udf_data = NULL;
     789           0 :                 usb_init_task(&udf_task, usb_fill_udf_task, udf,
     790             :                     USB_TASK_TYPE_GENERIC);
     791           0 :                 usb_add_task(sc->sc_bus->root_hub, &udf_task);
     792           0 :                 usb_wait_task(sc->sc_bus->root_hub, &udf_task);
     793           0 :                 len = udf->udf_size;
     794           0 :                 cdesc = (usb_config_descriptor_t *)udf->udf_data;
     795           0 :                 *udf = save_udf;
     796           0 :                 if (cdesc == NULL)
     797           0 :                         return (EINVAL);
     798           0 :                 if (len > udf->udf_size)
     799           0 :                         len = udf->udf_size;
     800           0 :                 iov.iov_base = (caddr_t)udf->udf_data;
     801           0 :                 iov.iov_len = len;
     802           0 :                 uio.uio_iov = &iov;
     803           0 :                 uio.uio_iovcnt = 1;
     804           0 :                 uio.uio_resid = len;
     805           0 :                 uio.uio_offset = 0;
     806           0 :                 uio.uio_segflg = UIO_USERSPACE;
     807           0 :                 uio.uio_rw = UIO_READ;
     808           0 :                 uio.uio_procp = p;
     809           0 :                 error = uiomove((void *)cdesc, len, &uio);
     810           0 :                 free(cdesc, M_TEMP, 0);
     811           0 :                 return (error);
     812           0 :         }
     813             : 
     814             :         default:
     815           0 :                 return (EINVAL);
     816             :         }
     817           0 :         return (0);
     818           0 : }
     819             : 
     820             : /*
     821             :  * Explore device tree from the root.  We need mutual exclusion to this
     822             :  * hub while traversing the device tree, but this is guaranteed since this
     823             :  * function is only called from the task thread, with one exception:
     824             :  * usb_attach() calls this function, but there shouldn't be anything else
     825             :  * trying to explore this hub at that time.
     826             :  */
     827             : void
     828           0 : usb_explore(void *v)
     829             : {
     830           0 :         struct usb_softc *sc = v;
     831           0 :         struct timeval now, waited;
     832             :         int pwrdly, waited_ms;
     833             : 
     834             :         DPRINTFN(2,("%s: %s\n", __func__, sc->sc_dev.dv_xname));
     835             : #ifdef USB_DEBUG
     836             :         if (usb_noexplore)
     837             :                 return;
     838             : #endif
     839             : 
     840           0 :         if (sc->sc_bus->dying)
     841           0 :                 return;
     842             : 
     843           0 :         if (sc->sc_bus->flags & USB_BUS_CONFIG_PENDING) {
     844             :                 /*
     845             :                  * If this is a low/full speed hub and there is a high
     846             :                  * speed hub that hasn't explored yet, reshedule this
     847             :                  * task, allowing the high speed explore task to run.
     848             :                  */
     849           0 :                 if (sc->sc_bus->usbrev < USBREV_2_0 && explore_pending > 0) {
     850           0 :                         usb_add_task(sc->sc_bus->root_hub,
     851           0 :                             &sc->sc_explore_task);
     852           0 :                         return;
     853             :                 }
     854             : 
     855             :                 /*
     856             :                  * Wait for power to stabilize.
     857             :                  */
     858           0 :                 getmicrouptime(&now);
     859           0 :                 timersub(&now, &sc->sc_ptime, &waited);
     860           0 :                 waited_ms = waited.tv_sec * 1000 + waited.tv_usec / 1000;
     861             : 
     862           0 :                 pwrdly = sc->sc_bus->root_hub->hub->powerdelay +
     863             :                     USB_EXTRA_POWER_UP_TIME;
     864           0 :                 if (pwrdly > waited_ms)
     865           0 :                         usb_delay_ms(sc->sc_bus, pwrdly - waited_ms);
     866             :         }
     867             : 
     868           0 :         if (sc->sc_bus->flags & USB_BUS_DISCONNECTING) {
     869             :                 /* Prevent new tasks from being scheduled. */
     870           0 :                 sc->sc_bus->dying = 1;
     871             : 
     872             :                 /* Make all devices disconnect. */
     873           0 :                 if (sc->sc_port.device != NULL) {
     874           0 :                         usbd_detach(sc->sc_port.device, (struct device *)sc);
     875           0 :                         sc->sc_port.device = NULL;
     876           0 :                 }
     877             : 
     878           0 :                 sc->sc_bus->flags &= ~USB_BUS_DISCONNECTING;
     879           0 :         } else {
     880           0 :                 sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
     881             :         }
     882             : 
     883           0 :         if (sc->sc_bus->flags & USB_BUS_CONFIG_PENDING) {
     884             :                 DPRINTF(("%s: %s: first explore done\n", __func__,
     885             :                     sc->sc_dev.dv_xname));
     886           0 :                 if (sc->sc_bus->usbrev == USBREV_2_0 && explore_pending)
     887           0 :                         explore_pending--;
     888           0 :                 config_pending_decr();
     889           0 :                 sc->sc_bus->flags &= ~(USB_BUS_CONFIG_PENDING);
     890           0 :         }
     891           0 : }
     892             : 
     893             : void
     894           0 : usb_needs_explore(struct usbd_device *dev, int first_explore)
     895             : {
     896           0 :         struct usb_softc *usbctl = (struct usb_softc *)dev->bus->usbctl;
     897             : 
     898             :         DPRINTFN(3,("%s: %s\n", usbctl->sc_dev.dv_xname, __func__));
     899             : 
     900           0 :         if (!first_explore && (dev->bus->flags & USB_BUS_CONFIG_PENDING)) {
     901             :                 DPRINTF(("%s: %s: not exploring before first explore\n",
     902             :                     __func__, usbctl->sc_dev.dv_xname));
     903           0 :                 return;
     904             :         }
     905             : 
     906           0 :         usb_add_task(dev, &usbctl->sc_explore_task);
     907           0 : }
     908             : 
     909             : void
     910           0 : usb_needs_reattach(struct usbd_device *dev)
     911             : {
     912             :         DPRINTFN(2,("usb_needs_reattach\n"));
     913           0 :         dev->powersrc->reattach = 1;
     914           0 :         usb_needs_explore(dev, 0);
     915           0 : }
     916             : 
     917             : void
     918           0 : usb_schedsoftintr(struct usbd_bus *bus)
     919             : {
     920             :         DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling));
     921             : 
     922           0 :         if (bus->use_polling) {
     923           0 :                 bus->methods->soft_intr(bus);
     924           0 :         } else {
     925           0 :                 softintr_schedule(bus->soft);
     926             :         }
     927           0 : }
     928             : 
     929             : int
     930           0 : usb_activate(struct device *self, int act)
     931             : {
     932           0 :         struct usb_softc *sc = (struct usb_softc *)self;
     933             :         int rv = 0;
     934             : 
     935           0 :         switch (act) {
     936             :         case DVACT_QUIESCE:
     937           0 :                 if (sc->sc_bus->root_hub != NULL)
     938           0 :                         usb_detach_roothub(sc);
     939             :                 break;
     940             :         case DVACT_RESUME:
     941           0 :                 sc->sc_bus->dying = 0;
     942             : 
     943             :                 /*
     944             :                  * Make sure the root hub is present before interrupts
     945             :                  * get enabled.   As long as the bus is in polling mode
     946             :                  * it is safe to call usbd_new_device() now since root
     947             :                  * hub transfers do not need to sleep.
     948             :                  */
     949           0 :                 sc->sc_bus->use_polling++;
     950           0 :                 if (!usb_attach_roothub(sc))
     951           0 :                         usb_needs_explore(sc->sc_bus->root_hub, 0);
     952           0 :                 sc->sc_bus->use_polling--;
     953           0 :                 break;
     954             :         default:
     955           0 :                 rv = config_activate_children(self, act);
     956           0 :                 break;
     957             :         }
     958           0 :         return (rv);
     959             : }
     960             : 
     961             : int
     962           0 : usb_detach(struct device *self, int flags)
     963             : {
     964           0 :         struct usb_softc *sc = (struct usb_softc *)self;
     965             : 
     966           0 :         if (sc->sc_bus->root_hub != NULL) {
     967           0 :                 usb_detach_roothub(sc);
     968             : 
     969           0 :                 if (--usb_nbuses == 0) {
     970           0 :                         usb_run_tasks = usb_run_abort_tasks = 0;
     971           0 :                         wakeup(&usb_run_abort_tasks);
     972           0 :                         wakeup(&usb_run_tasks);
     973           0 :                 }
     974             :         }
     975             : 
     976           0 :         if (sc->sc_bus->soft != NULL) {
     977           0 :                 softintr_disestablish(sc->sc_bus->soft);
     978           0 :                 sc->sc_bus->soft = NULL;
     979           0 :         }
     980             : 
     981             : #if NBPFILTER > 0
     982           0 :         bpfsdetach(sc->sc_bus->bpfif);
     983             : #endif
     984           0 :         return (0);
     985             : }
     986             : 
     987             : void
     988           0 : usb_tap(struct usbd_bus *bus, struct usbd_xfer *xfer, uint8_t dir)
     989             : {
     990             : #if NBPFILTER > 0
     991           0 :         struct usb_softc *sc = (struct usb_softc *)bus->usbctl;
     992           0 :         usb_endpoint_descriptor_t *ed = xfer->pipe->endpoint->edesc;
     993           0 :         union {
     994             :                 struct usbpcap_ctl_hdr          uch;
     995             :                 struct usbpcap_iso_hdr_full     uih;
     996             :         } h;
     997           0 :         struct usbpcap_pkt_hdr *uph = &h.uch.uch_hdr;
     998             :         uint32_t nframes, offset;
     999             :         unsigned int bpfdir;
    1000             :         void *data = NULL;
    1001             :         size_t flen;
    1002             :         caddr_t bpf;
    1003             :         int i;
    1004             : 
    1005           0 :         bpf = bus->bpf;
    1006           0 :         if (bpf == NULL)
    1007           0 :                 return;
    1008             : 
    1009           0 :         switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
    1010             :         case UE_CONTROL:
    1011             :                 /* Control transfer headers include an extra byte */
    1012           0 :                 uph->uph_hlen = htole16(sizeof(struct usbpcap_ctl_hdr));
    1013           0 :                 uph->uph_xfertype = USBPCAP_TRANSFER_CONTROL;
    1014           0 :                 break;
    1015             :         case UE_ISOCHRONOUS:
    1016             :                 offset = 0;
    1017           0 :                 nframes = xfer->nframes;
    1018             : #ifdef DIAGNOSTIC
    1019           0 :                 if (nframes > _USBPCAP_MAX_ISOFRAMES) {
    1020           0 :                         printf("%s: too many frames: %d > %d\n", __func__,
    1021             :                             xfer->nframes, _USBPCAP_MAX_ISOFRAMES);
    1022             :                         nframes = _USBPCAP_MAX_ISOFRAMES;
    1023           0 :                 }
    1024             : #endif
    1025             :                 /* Isochronous transfer headers include space for one frame */
    1026           0 :                 flen = (nframes - 1) * sizeof(struct usbpcap_iso_pkt);
    1027           0 :                 uph->uph_hlen = htole16(sizeof(struct usbpcap_iso_hdr) + flen);
    1028           0 :                 uph->uph_xfertype = USBPCAP_TRANSFER_ISOCHRONOUS;
    1029           0 :                 h.uih.uih_startframe = 0; /* not yet used */
    1030           0 :                 h.uih.uih_nframes = nframes;
    1031           0 :                 h.uih.uih_errors = 0; /* we don't have per-frame error */
    1032           0 :                 for (i = 0; i < nframes; i++) {
    1033           0 :                         h.uih.uih_frames[i].uip_offset = offset;
    1034           0 :                         h.uih.uih_frames[i].uip_length = xfer->frlengths[i];
    1035             :                         /* See above, we don't have per-frame error */
    1036           0 :                         h.uih.uih_frames[i].uip_status = 0;
    1037           0 :                         offset += xfer->frlengths[i];
    1038             :                 }
    1039             :                 break;
    1040             :         case UE_BULK:
    1041           0 :                 uph->uph_hlen = htole16(sizeof(*uph));
    1042           0 :                 uph->uph_xfertype = USBPCAP_TRANSFER_BULK;
    1043           0 :                 break;
    1044             :         case UE_INTERRUPT:
    1045           0 :                 uph->uph_hlen = htole16(sizeof(*uph));
    1046           0 :                 uph->uph_xfertype = USBPCAP_TRANSFER_INTERRUPT;
    1047           0 :                 break;
    1048             :         default:
    1049             :                 return;
    1050             :         }
    1051             : 
    1052           0 :         uph->uph_id = 0; /* not yet used */
    1053           0 :         uph->uph_status = htole32(xfer->status);
    1054           0 :         uph->uph_function = 0; /* not yet used */
    1055           0 :         uph->uph_bus = htole32(sc->sc_dev.dv_unit);
    1056           0 :         uph->uph_devaddr = htole16(xfer->device->address);
    1057           0 :         uph->uph_epaddr = ed->bEndpointAddress;
    1058           0 :         uph->uph_info = 0;
    1059             : 
    1060             :         /* Outgoing control requests start with a STAGE dump. */
    1061           0 :         if ((xfer->rqflags & URQ_REQUEST) && (dir == USBTAP_DIR_OUT)) {
    1062           0 :                 h.uch.uch_stage = USBPCAP_CONTROL_STAGE_SETUP;
    1063           0 :                 uph->uph_dlen = sizeof(usb_device_request_t);
    1064           0 :                 bpf_tap_hdr(bpf, uph, uph->uph_hlen, &xfer->request,
    1065             :                     uph->uph_dlen, BPF_DIRECTION_OUT);
    1066           0 :         }
    1067             : 
    1068           0 :         if (dir == USBTAP_DIR_OUT) {
    1069             :                 bpfdir = BPF_DIRECTION_OUT;
    1070           0 :                 if (!usbd_xfer_isread(xfer)) {
    1071           0 :                         data = KERNADDR(&xfer->dmabuf, 0);
    1072           0 :                         uph->uph_dlen = xfer->length;
    1073           0 :                         if (xfer->rqflags & URQ_REQUEST)
    1074           0 :                                 h.uch.uch_stage = USBPCAP_CONTROL_STAGE_DATA;
    1075             :                 } else {
    1076             :                         data = NULL;
    1077           0 :                         uph->uph_dlen = 0;
    1078           0 :                         if (xfer->rqflags & URQ_REQUEST)
    1079           0 :                                 h.uch.uch_stage = USBPCAP_CONTROL_STAGE_STATUS;
    1080             :                 }
    1081             :         } else { /* USBTAP_DIR_IN */
    1082             :                 bpfdir = BPF_DIRECTION_IN;
    1083           0 :                 uph->uph_info = USBPCAP_INFO_DIRECTION_IN;
    1084           0 :                 if (usbd_xfer_isread(xfer)) {
    1085           0 :                         data = KERNADDR(&xfer->dmabuf, 0);
    1086           0 :                         uph->uph_dlen = xfer->actlen;
    1087           0 :                         if (xfer->rqflags & URQ_REQUEST)
    1088           0 :                                 h.uch.uch_stage = USBPCAP_CONTROL_STAGE_DATA;
    1089             :                 } else {
    1090             :                         data = NULL;
    1091           0 :                         uph->uph_dlen = 0;
    1092           0 :                         if (xfer->rqflags & URQ_REQUEST)
    1093           0 :                                 h.uch.uch_stage = USBPCAP_CONTROL_STAGE_STATUS;
    1094             :                 }
    1095             :         }
    1096             : 
    1097             :         /* Dump bulk/intr/iso data, ctrl DATA or STATUS stage. */
    1098           0 :         bpf_tap_hdr(bpf, uph, uph->uph_hlen, data, uph->uph_dlen, bpfdir);
    1099             : 
    1100             :         /* Incoming control requests with DATA need a STATUS stage. */
    1101           0 :         if ((xfer->rqflags & URQ_REQUEST) && (dir == USBTAP_DIR_IN) &&
    1102           0 :             (h.uch.uch_stage == USBPCAP_CONTROL_STAGE_DATA)) {
    1103           0 :                 h.uch.uch_stage = USBPCAP_CONTROL_STAGE_STATUS;
    1104           0 :                 uph->uph_dlen = 0;
    1105           0 :                 bpf_tap_hdr(bpf, uph, uph->uph_hlen, NULL, 0, BPF_DIRECTION_IN);
    1106           0 :         }
    1107             : #endif
    1108           0 : }

Generated by: LCOV version 1.13