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_hub.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 /* $FreeBSD: releng/9.2/sys/dev/usb/usb_hub.c 248085 2013-03-09 02:36:32Z marius $ */
    2 /*-
    3  * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
    4  * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
    5  * Copyright (c) 2008-2010 Hans Petter Selasky. All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 /*
   30  * USB spec: http://www.usb.org/developers/docs/usbspec.zip 
   31  */
   32 
   33 #include <sys/stdint.h>
   34 #include <sys/stddef.h>
   35 #include <sys/param.h>
   36 #include <sys/queue.h>
   37 #include <sys/types.h>
   38 #include <sys/systm.h>
   39 #include <sys/kernel.h>
   40 #include <sys/bus.h>
   41 #include <sys/module.h>
   42 #include <sys/lock.h>
   43 #include <sys/mutex.h>
   44 #include <sys/condvar.h>
   45 #include <sys/sysctl.h>
   46 #include <sys/sx.h>
   47 #include <sys/unistd.h>
   48 #include <sys/callout.h>
   49 #include <sys/malloc.h>
   50 #include <sys/priv.h>
   51 
   52 #include <dev/usb/usb.h>
   53 #include <dev/usb/usb_ioctl.h>
   54 #include <dev/usb/usbdi.h>
   55 #include <dev/usb/usbdi_util.h>
   56 
   57 #define USB_DEBUG_VAR uhub_debug
   58 
   59 #include <dev/usb/usb_core.h>
   60 #include <dev/usb/usb_process.h>
   61 #include <dev/usb/usb_device.h>
   62 #include <dev/usb/usb_request.h>
   63 #include <dev/usb/usb_debug.h>
   64 #include <dev/usb/usb_hub.h>
   65 #include <dev/usb/usb_util.h>
   66 #include <dev/usb/usb_busdma.h>
   67 #include <dev/usb/usb_transfer.h>
   68 #include <dev/usb/usb_dynamic.h>
   69 
   70 #include <dev/usb/usb_controller.h>
   71 #include <dev/usb/usb_bus.h>
   72 
   73 #define UHUB_INTR_INTERVAL 250          /* ms */
   74 #define UHUB_N_TRANSFER 1
   75 
   76 #ifdef USB_DEBUG
   77 static int uhub_debug = 0;
   78 
   79 static SYSCTL_NODE(_hw_usb, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB HUB");
   80 SYSCTL_INT(_hw_usb_uhub, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN, &uhub_debug, 0,
   81     "Debug level");
   82 TUNABLE_INT("hw.usb.uhub.debug", &uhub_debug);
   83 #endif
   84 
   85 #if USB_HAVE_POWERD
   86 static int usb_power_timeout = 30;      /* seconds */
   87 
   88 SYSCTL_INT(_hw_usb, OID_AUTO, power_timeout, CTLFLAG_RW,
   89     &usb_power_timeout, 0, "USB power timeout");
   90 #endif
   91 
   92 struct uhub_current_state {
   93         uint16_t port_change;
   94         uint16_t port_status;
   95 };
   96 
   97 struct uhub_softc {
   98         struct uhub_current_state sc_st;/* current state */
   99         device_t sc_dev;                /* base device */
  100         struct mtx sc_mtx;              /* our mutex */
  101         struct usb_device *sc_udev;     /* USB device */
  102         struct usb_xfer *sc_xfer[UHUB_N_TRANSFER];      /* interrupt xfer */
  103         uint8_t sc_flags;
  104 #define UHUB_FLAG_DID_EXPLORE 0x01
  105         char    sc_name[32];
  106 };
  107 
  108 #define UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol)
  109 #define UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
  110 #define UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
  111 #define UHUB_IS_MULTI_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBMTT)
  112 #define UHUB_IS_SUPER_SPEED(sc) (UHUB_PROTO(sc) == UDPROTO_SSHUB)
  113 
  114 /* prototypes for type checking: */
  115 
  116 static device_probe_t uhub_probe;
  117 static device_attach_t uhub_attach;
  118 static device_detach_t uhub_detach;
  119 static device_suspend_t uhub_suspend;
  120 static device_resume_t uhub_resume;
  121 
  122 static bus_driver_added_t uhub_driver_added;
  123 static bus_child_location_str_t uhub_child_location_string;
  124 static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string;
  125 
  126 static usb_callback_t uhub_intr_callback;
  127 
  128 static void usb_dev_resume_peer(struct usb_device *udev);
  129 static void usb_dev_suspend_peer(struct usb_device *udev);
  130 static uint8_t usb_peer_should_wakeup(struct usb_device *udev);
  131 
  132 static const struct usb_config uhub_config[UHUB_N_TRANSFER] = {
  133 
  134         [0] = {
  135                 .type = UE_INTERRUPT,
  136                 .endpoint = UE_ADDR_ANY,
  137                 .direction = UE_DIR_ANY,
  138                 .timeout = 0,
  139                 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
  140                 .bufsize = 0,   /* use wMaxPacketSize */
  141                 .callback = &uhub_intr_callback,
  142                 .interval = UHUB_INTR_INTERVAL,
  143         },
  144 };
  145 
  146 /*
  147  * driver instance for "hub" connected to "usb"
  148  * and "hub" connected to "hub"
  149  */
  150 static devclass_t uhub_devclass;
  151 
  152 static device_method_t uhub_methods[] = {
  153         DEVMETHOD(device_probe, uhub_probe),
  154         DEVMETHOD(device_attach, uhub_attach),
  155         DEVMETHOD(device_detach, uhub_detach),
  156 
  157         DEVMETHOD(device_suspend, uhub_suspend),
  158         DEVMETHOD(device_resume, uhub_resume),
  159 
  160         DEVMETHOD(bus_child_location_str, uhub_child_location_string),
  161         DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string),
  162         DEVMETHOD(bus_driver_added, uhub_driver_added),
  163         {0, 0}
  164 };
  165 
  166 static driver_t uhub_driver = {
  167         .name = "uhub",
  168         .methods = uhub_methods,
  169         .size = sizeof(struct uhub_softc)
  170 };
  171 
  172 DRIVER_MODULE(uhub, usbus, uhub_driver, uhub_devclass, 0, 0);
  173 DRIVER_MODULE(uhub, uhub, uhub_driver, uhub_devclass, NULL, 0);
  174 MODULE_VERSION(uhub, 1);
  175 
  176 static void
  177 uhub_intr_callback(struct usb_xfer *xfer, usb_error_t error)
  178 {
  179         struct uhub_softc *sc = usbd_xfer_softc(xfer);
  180 
  181         switch (USB_GET_STATE(xfer)) {
  182         case USB_ST_TRANSFERRED:
  183                 DPRINTFN(2, "\n");
  184                 /*
  185                  * This is an indication that some port
  186                  * has changed status. Notify the bus
  187                  * event handler thread that we need
  188                  * to be explored again:
  189                  */
  190                 usb_needs_explore(sc->sc_udev->bus, 0);
  191 
  192         case USB_ST_SETUP:
  193                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
  194                 usbd_transfer_submit(xfer);
  195                 break;
  196 
  197         default:                        /* Error */
  198                 if (xfer->error != USB_ERR_CANCELLED) {
  199                         /*
  200                          * Do a clear-stall. The "stall_pipe" flag
  201                          * will get cleared before next callback by
  202                          * the USB stack.
  203                          */
  204                         usbd_xfer_set_stall(xfer);
  205                         usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
  206                         usbd_transfer_submit(xfer);
  207                 }
  208                 break;
  209         }
  210 }
  211 
  212 /*------------------------------------------------------------------------*
  213  *      uhub_explore_sub - subroutine
  214  *
  215  * Return values:
  216  *    0: Success
  217  * Else: A control transaction failed
  218  *------------------------------------------------------------------------*/
  219 static usb_error_t
  220 uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up)
  221 {
  222         struct usb_bus *bus;
  223         struct usb_device *child;
  224         uint8_t refcount;
  225         usb_error_t err;
  226 
  227         bus = sc->sc_udev->bus;
  228         err = 0;
  229 
  230         /* get driver added refcount from USB bus */
  231         refcount = bus->driver_added_refcount;
  232 
  233         /* get device assosiated with the given port */
  234         child = usb_bus_port_get_device(bus, up);
  235         if (child == NULL) {
  236                 /* nothing to do */
  237                 goto done;
  238         }
  239 
  240         /* check if device should be re-enumerated */
  241 
  242         if (child->flags.usb_mode == USB_MODE_HOST) {
  243                 uint8_t do_unlock;
  244                 
  245                 do_unlock = usbd_enum_lock(child);
  246                 if (child->re_enumerate_wait) {
  247                         err = usbd_set_config_index(child,
  248                             USB_UNCONFIG_INDEX);
  249                         if (err != 0) {
  250                                 DPRINTF("Unconfigure failed: "
  251                                     "%s: Ignored.\n",
  252                                     usbd_errstr(err));
  253                         }
  254                         err = usbd_req_re_enumerate(child, NULL);
  255                         if (err == 0)
  256                                 err = usbd_set_config_index(child, 0);
  257                         if (err == 0) {
  258                                 err = usb_probe_and_attach(child,
  259                                     USB_IFACE_INDEX_ANY);
  260                         }
  261                         child->re_enumerate_wait = 0;
  262                         err = 0;
  263                 }
  264                 if (do_unlock)
  265                         usbd_enum_unlock(child);
  266         }
  267 
  268         /* check if probe and attach should be done */
  269 
  270         if (child->driver_added_refcount != refcount) {
  271                 child->driver_added_refcount = refcount;
  272                 err = usb_probe_and_attach(child,
  273                     USB_IFACE_INDEX_ANY);
  274                 if (err) {
  275                         goto done;
  276                 }
  277         }
  278         /* start control transfer, if device mode */
  279 
  280         if (child->flags.usb_mode == USB_MODE_DEVICE)
  281                 usbd_ctrl_transfer_setup(child);
  282 
  283         /* if a HUB becomes present, do a recursive HUB explore */
  284 
  285         if (child->hub)
  286                 err = (child->hub->explore) (child);
  287 
  288 done:
  289         return (err);
  290 }
  291 
  292 /*------------------------------------------------------------------------*
  293  *      uhub_read_port_status - factored out code
  294  *------------------------------------------------------------------------*/
  295 static usb_error_t
  296 uhub_read_port_status(struct uhub_softc *sc, uint8_t portno)
  297 {
  298         struct usb_port_status ps;
  299         usb_error_t err;
  300 
  301         err = usbd_req_get_port_status(
  302             sc->sc_udev, NULL, &ps, portno);
  303 
  304         /* update status regardless of error */
  305 
  306         sc->sc_st.port_status = UGETW(ps.wPortStatus);
  307         sc->sc_st.port_change = UGETW(ps.wPortChange);
  308 
  309         /* debugging print */
  310 
  311         DPRINTFN(4, "port %d, wPortStatus=0x%04x, "
  312             "wPortChange=0x%04x, err=%s\n",
  313             portno, sc->sc_st.port_status,
  314             sc->sc_st.port_change, usbd_errstr(err));
  315         return (err);
  316 }
  317 
  318 /*------------------------------------------------------------------------*
  319  *      uhub_reattach_port
  320  *
  321  * Returns:
  322  *    0: Success
  323  * Else: A control transaction failed
  324  *------------------------------------------------------------------------*/
  325 static usb_error_t
  326 uhub_reattach_port(struct uhub_softc *sc, uint8_t portno)
  327 {
  328         struct usb_device *child;
  329         struct usb_device *udev;
  330         enum usb_dev_speed speed;
  331         enum usb_hc_mode mode;
  332         usb_error_t err;
  333         uint16_t power_mask;
  334         uint8_t timeout;
  335 
  336         DPRINTF("reattaching port %d\n", portno);
  337 
  338         err = 0;
  339         timeout = 0;
  340         udev = sc->sc_udev;
  341         child = usb_bus_port_get_device(udev->bus,
  342             udev->hub->ports + portno - 1);
  343 
  344 repeat:
  345 
  346         /* first clear the port connection change bit */
  347 
  348         err = usbd_req_clear_port_feature(udev, NULL,
  349             portno, UHF_C_PORT_CONNECTION);
  350 
  351         if (err) {
  352                 goto error;
  353         }
  354         /* check if there is a child */
  355 
  356         if (child != NULL) {
  357                 /*
  358                  * Free USB device and all subdevices, if any.
  359                  */
  360                 usb_free_device(child, 0);
  361                 child = NULL;
  362         }
  363         /* get fresh status */
  364 
  365         err = uhub_read_port_status(sc, portno);
  366         if (err) {
  367                 goto error;
  368         }
  369         /* check if nothing is connected to the port */
  370 
  371         if (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS)) {
  372                 goto error;
  373         }
  374         /* check if there is no power on the port and print a warning */
  375 
  376         switch (udev->speed) {
  377         case USB_SPEED_HIGH:
  378         case USB_SPEED_FULL:
  379         case USB_SPEED_LOW:
  380                 power_mask = UPS_PORT_POWER;
  381                 break;
  382         case USB_SPEED_SUPER:
  383                 if (udev->parent_hub == NULL)
  384                         power_mask = UPS_PORT_POWER;
  385                 else
  386                         power_mask = UPS_PORT_POWER_SS;
  387                 break;
  388         default:
  389                 power_mask = 0;
  390                 break;
  391         }
  392         if (!(sc->sc_st.port_status & power_mask)) {
  393                 DPRINTF("WARNING: strange, connected port %d "
  394                     "has no power\n", portno);
  395         }
  396 
  397         /* check if the device is in Host Mode */
  398 
  399         if (!(sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)) {
  400 
  401                 DPRINTF("Port %d is in Host Mode\n", portno);
  402 
  403                 if (sc->sc_st.port_status & UPS_SUSPEND) {
  404                         /*
  405                          * NOTE: Should not get here in SuperSpeed
  406                          * mode, because the HUB should report this
  407                          * bit as zero.
  408                          */
  409                         DPRINTF("Port %d was still "
  410                             "suspended, clearing.\n", portno);
  411                         err = usbd_req_clear_port_feature(udev,
  412                             NULL, portno, UHF_PORT_SUSPEND);
  413                 }
  414 
  415                 /* USB Host Mode */
  416 
  417                 /* wait for maximum device power up time */
  418 
  419                 usb_pause_mtx(NULL, 
  420                     USB_MS_TO_TICKS(usb_port_powerup_delay));
  421 
  422                 /* reset port, which implies enabling it */
  423 
  424                 err = usbd_req_reset_port(udev, NULL, portno);
  425 
  426                 if (err) {
  427                         DPRINTFN(0, "port %d reset "
  428                             "failed, error=%s\n",
  429                             portno, usbd_errstr(err));
  430                         goto error;
  431                 }
  432                 /* get port status again, it might have changed during reset */
  433 
  434                 err = uhub_read_port_status(sc, portno);
  435                 if (err) {
  436                         goto error;
  437                 }
  438                 /* check if something changed during port reset */
  439 
  440                 if ((sc->sc_st.port_change & UPS_C_CONNECT_STATUS) ||
  441                     (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS))) {
  442                         if (timeout) {
  443                                 DPRINTFN(0, "giving up port reset "
  444                                     "- device vanished\n");
  445                                 goto error;
  446                         }
  447                         timeout = 1;
  448                         goto repeat;
  449                 }
  450         } else {
  451                 DPRINTF("Port %d is in Device Mode\n", portno);
  452         }
  453 
  454         /*
  455          * Figure out the device speed
  456          */
  457         switch (udev->speed) {
  458         case USB_SPEED_HIGH:
  459                 if (sc->sc_st.port_status & UPS_HIGH_SPEED)
  460                         speed = USB_SPEED_HIGH;
  461                 else if (sc->sc_st.port_status & UPS_LOW_SPEED)
  462                         speed = USB_SPEED_LOW;
  463                 else
  464                         speed = USB_SPEED_FULL;
  465                 break;
  466         case USB_SPEED_FULL:
  467                 if (sc->sc_st.port_status & UPS_LOW_SPEED)
  468                         speed = USB_SPEED_LOW;
  469                 else
  470                         speed = USB_SPEED_FULL;
  471                 break;
  472         case USB_SPEED_LOW:
  473                 speed = USB_SPEED_LOW;
  474                 break;
  475         case USB_SPEED_SUPER:
  476                 if (udev->parent_hub == NULL) {
  477                         /* Root HUB - special case */
  478                         switch (sc->sc_st.port_status & UPS_OTHER_SPEED) {
  479                         case 0:
  480                                 speed = USB_SPEED_FULL;
  481                                 break;
  482                         case UPS_LOW_SPEED:
  483                                 speed = USB_SPEED_LOW;
  484                                 break;
  485                         case UPS_HIGH_SPEED:
  486                                 speed = USB_SPEED_HIGH;
  487                                 break;
  488                         default:
  489                                 speed = USB_SPEED_SUPER;
  490                                 break;
  491                         }
  492                 } else {
  493                         speed = USB_SPEED_SUPER;
  494                 }
  495                 break;
  496         default:
  497                 /* same speed like parent */
  498                 speed = udev->speed;
  499                 break;
  500         }
  501         if (speed == USB_SPEED_SUPER) {
  502                 err = usbd_req_set_hub_u1_timeout(udev, NULL,
  503                     portno, 128 - (2 * udev->depth));
  504                 if (err) {
  505                         DPRINTFN(0, "port %d U1 timeout "
  506                             "failed, error=%s\n",
  507                             portno, usbd_errstr(err));
  508                 }
  509                 err = usbd_req_set_hub_u2_timeout(udev, NULL,
  510                     portno, 128 - (2 * udev->depth));
  511                 if (err) {
  512                         DPRINTFN(0, "port %d U2 timeout "
  513                             "failed, error=%s\n",
  514                             portno, usbd_errstr(err));
  515                 }
  516         }
  517 
  518         /*
  519          * Figure out the device mode
  520          *
  521          * NOTE: This part is currently FreeBSD specific.
  522          */
  523         if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)
  524                 mode = USB_MODE_DEVICE;
  525         else
  526                 mode = USB_MODE_HOST;
  527 
  528         /* need to create a new child */
  529         child = usb_alloc_device(sc->sc_dev, udev->bus, udev,
  530             udev->depth + 1, portno - 1, portno, speed, mode);
  531         if (child == NULL) {
  532                 DPRINTFN(0, "could not allocate new device\n");
  533                 goto error;
  534         }
  535         return (0);                     /* success */
  536 
  537 error:
  538         if (child != NULL) {
  539                 /*
  540                  * Free USB device and all subdevices, if any.
  541                  */
  542                 usb_free_device(child, 0);
  543                 child = NULL;
  544         }
  545         if (err == 0) {
  546                 if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
  547                         err = usbd_req_clear_port_feature(
  548                             sc->sc_udev, NULL,
  549                             portno, UHF_PORT_ENABLE);
  550                 }
  551         }
  552         if (err) {
  553                 DPRINTFN(0, "device problem (%s), "
  554                     "disabling port %d\n", usbd_errstr(err), portno);
  555         }
  556         return (err);
  557 }
  558 
  559 /*------------------------------------------------------------------------*
  560  *      usb_device_20_compatible
  561  *
  562  * Returns:
  563  *    0: HUB does not support suspend and resume
  564  * Else: HUB supports suspend and resume
  565  *------------------------------------------------------------------------*/
  566 static uint8_t
  567 usb_device_20_compatible(struct usb_device *udev)
  568 {
  569         if (udev == NULL)
  570                 return (0);
  571         switch (udev->speed) {
  572         case USB_SPEED_LOW:
  573         case USB_SPEED_FULL:
  574         case USB_SPEED_HIGH:
  575                 return (1);
  576         default:
  577                 return (0);
  578         }
  579 }
  580 
  581 /*------------------------------------------------------------------------*
  582  *      uhub_suspend_resume_port
  583  *
  584  * Returns:
  585  *    0: Success
  586  * Else: A control transaction failed
  587  *------------------------------------------------------------------------*/
  588 static usb_error_t
  589 uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno)
  590 {
  591         struct usb_device *child;
  592         struct usb_device *udev;
  593         uint8_t is_suspend;
  594         usb_error_t err;
  595 
  596         DPRINTF("port %d\n", portno);
  597 
  598         udev = sc->sc_udev;
  599         child = usb_bus_port_get_device(udev->bus,
  600             udev->hub->ports + portno - 1);
  601 
  602         /* first clear the port suspend change bit */
  603 
  604         if (usb_device_20_compatible(udev)) {
  605                 err = usbd_req_clear_port_feature(udev, NULL,
  606                     portno, UHF_C_PORT_SUSPEND);
  607         } else {
  608                 err = usbd_req_clear_port_feature(udev, NULL,
  609                     portno, UHF_C_PORT_LINK_STATE);
  610         }
  611 
  612         if (err) {
  613                 DPRINTF("clearing suspend failed.\n");
  614                 goto done;
  615         }
  616         /* get fresh status */
  617 
  618         err = uhub_read_port_status(sc, portno);
  619         if (err) {
  620                 DPRINTF("reading port status failed.\n");
  621                 goto done;
  622         }
  623         /* convert current state */
  624 
  625         if (usb_device_20_compatible(udev)) {
  626                 if (sc->sc_st.port_status & UPS_SUSPEND) {
  627                         is_suspend = 1;
  628                 } else {
  629                         is_suspend = 0;
  630                 }
  631         } else {
  632                 switch (UPS_PORT_LINK_STATE_GET(sc->sc_st.port_status)) {
  633                 case UPS_PORT_LS_U3:
  634                         is_suspend = 1;
  635                         break;
  636                 case UPS_PORT_LS_SS_INA:
  637                         usbd_req_warm_reset_port(udev, NULL, portno);
  638                         is_suspend = 0;
  639                         break;
  640                 default:
  641                         is_suspend = 0;
  642                         break;
  643                 }
  644         }
  645 
  646         DPRINTF("suspended=%u\n", is_suspend);
  647 
  648         /* do the suspend or resume */
  649 
  650         if (child) {
  651                 /*
  652                  * This code handle two cases: 1) Host Mode - we can only
  653                  * receive resume here 2) Device Mode - we can receive
  654                  * suspend and resume here
  655                  */
  656                 if (is_suspend == 0)
  657                         usb_dev_resume_peer(child);
  658                 else if (child->flags.usb_mode == USB_MODE_DEVICE)
  659                         usb_dev_suspend_peer(child);
  660         }
  661 done:
  662         return (err);
  663 }
  664 
  665 /*------------------------------------------------------------------------*
  666  *      uhub_root_interrupt
  667  *
  668  * This function is called when a Root HUB interrupt has
  669  * happened. "ptr" and "len" makes up the Root HUB interrupt
  670  * packet. This function is called having the "bus_mtx" locked.
  671  *------------------------------------------------------------------------*/
  672 void
  673 uhub_root_intr(struct usb_bus *bus, const uint8_t *ptr, uint8_t len)
  674 {
  675         USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
  676 
  677         usb_needs_explore(bus, 0);
  678 }
  679 
  680 static uint8_t
  681 uhub_is_too_deep(struct usb_device *udev)
  682 {
  683         switch (udev->speed) {
  684         case USB_SPEED_FULL:
  685         case USB_SPEED_LOW:
  686         case USB_SPEED_HIGH:
  687                 if (udev->depth > USB_HUB_MAX_DEPTH)
  688                         return (1);
  689                 break;
  690         case USB_SPEED_SUPER:
  691                 if (udev->depth > USB_SS_HUB_DEPTH_MAX)
  692                         return (1);
  693                 break;
  694         default:
  695                 break;
  696         }
  697         return (0);
  698 }
  699 
  700 /*------------------------------------------------------------------------*
  701  *      uhub_explore
  702  *
  703  * Returns:
  704  *     0: Success
  705  *  Else: Failure
  706  *------------------------------------------------------------------------*/
  707 static usb_error_t
  708 uhub_explore(struct usb_device *udev)
  709 {
  710         struct usb_hub *hub;
  711         struct uhub_softc *sc;
  712         struct usb_port *up;
  713         usb_error_t err;
  714         uint8_t portno;
  715         uint8_t x;
  716         uint8_t do_unlock;
  717 
  718         hub = udev->hub;
  719         sc = hub->hubsoftc;
  720 
  721         DPRINTFN(11, "udev=%p addr=%d\n", udev, udev->address);
  722 
  723         /* ignore devices that are too deep */
  724         if (uhub_is_too_deep(udev))
  725                 return (USB_ERR_TOO_DEEP);
  726 
  727         /* check if device is suspended */
  728         if (udev->flags.self_suspended) {
  729                 /* need to wait until the child signals resume */
  730                 DPRINTF("Device is suspended!\n");
  731                 return (0);
  732         }
  733 
  734         /*
  735          * Make sure we don't race against user-space applications
  736          * like LibUSB:
  737          */
  738         do_unlock = usbd_enum_lock(udev);
  739 
  740         for (x = 0; x != hub->nports; x++) {
  741                 up = hub->ports + x;
  742                 portno = x + 1;
  743 
  744                 err = uhub_read_port_status(sc, portno);
  745                 if (err) {
  746                         /* most likely the HUB is gone */
  747                         break;
  748                 }
  749                 if (sc->sc_st.port_change & UPS_C_OVERCURRENT_INDICATOR) {
  750                         DPRINTF("Overcurrent on port %u.\n", portno);
  751                         err = usbd_req_clear_port_feature(
  752                             udev, NULL, portno, UHF_C_PORT_OVER_CURRENT);
  753                         if (err) {
  754                                 /* most likely the HUB is gone */
  755                                 break;
  756                         }
  757                 }
  758                 if (!(sc->sc_flags & UHUB_FLAG_DID_EXPLORE)) {
  759                         /*
  760                          * Fake a connect status change so that the
  761                          * status gets checked initially!
  762                          */
  763                         sc->sc_st.port_change |=
  764                             UPS_C_CONNECT_STATUS;
  765                 }
  766                 if (sc->sc_st.port_change & UPS_C_PORT_ENABLED) {
  767                         err = usbd_req_clear_port_feature(
  768                             udev, NULL, portno, UHF_C_PORT_ENABLE);
  769                         if (err) {
  770                                 /* most likely the HUB is gone */
  771                                 break;
  772                         }
  773                         if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) {
  774                                 /*
  775                                  * Ignore the port error if the device
  776                                  * has vanished !
  777                                  */
  778                         } else if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
  779                                 DPRINTFN(0, "illegal enable change, "
  780                                     "port %d\n", portno);
  781                         } else {
  782 
  783                                 if (up->restartcnt == USB_RESTART_MAX) {
  784                                         /* XXX could try another speed ? */
  785                                         DPRINTFN(0, "port error, giving up "
  786                                             "port %d\n", portno);
  787                                 } else {
  788                                         sc->sc_st.port_change |=
  789                                             UPS_C_CONNECT_STATUS;
  790                                         up->restartcnt++;
  791                                 }
  792                         }
  793                 }
  794                 if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) {
  795                         err = uhub_reattach_port(sc, portno);
  796                         if (err) {
  797                                 /* most likely the HUB is gone */
  798                                 break;
  799                         }
  800                 }
  801                 if (sc->sc_st.port_change & (UPS_C_SUSPEND |
  802                     UPS_C_PORT_LINK_STATE)) {
  803                         err = uhub_suspend_resume_port(sc, portno);
  804                         if (err) {
  805                                 /* most likely the HUB is gone */
  806                                 break;
  807                         }
  808                 }
  809                 err = uhub_explore_sub(sc, up);
  810                 if (err) {
  811                         /* no device(s) present */
  812                         continue;
  813                 }
  814                 /* explore succeeded - reset restart counter */
  815                 up->restartcnt = 0;
  816         }
  817 
  818         if (do_unlock)
  819                 usbd_enum_unlock(udev);
  820 
  821         /* initial status checked */
  822         sc->sc_flags |= UHUB_FLAG_DID_EXPLORE;
  823 
  824         /* return success */
  825         return (USB_ERR_NORMAL_COMPLETION);
  826 }
  827 
  828 static int
  829 uhub_probe(device_t dev)
  830 {
  831         struct usb_attach_arg *uaa = device_get_ivars(dev);
  832 
  833         if (uaa->usb_mode != USB_MODE_HOST)
  834                 return (ENXIO);
  835 
  836         /*
  837          * The subclass for USB HUBs is currently ignored because it
  838          * is 0 for some and 1 for others.
  839          */
  840         if (uaa->info.bConfigIndex == 0 &&
  841             uaa->info.bDeviceClass == UDCLASS_HUB)
  842                 return (0);
  843 
  844         return (ENXIO);
  845 }
  846 
  847 /* NOTE: The information returned by this function can be wrong. */
  848 usb_error_t
  849 uhub_query_info(struct usb_device *udev, uint8_t *pnports, uint8_t *ptt)
  850 {
  851         struct usb_hub_descriptor hubdesc20;
  852         struct usb_hub_ss_descriptor hubdesc30;
  853         usb_error_t err;
  854         uint8_t nports;
  855         uint8_t tt;
  856 
  857         if (udev->ddesc.bDeviceClass != UDCLASS_HUB)
  858                 return (USB_ERR_INVAL);
  859 
  860         nports = 0;
  861         tt = 0;
  862 
  863         switch (udev->speed) {
  864         case USB_SPEED_LOW:
  865         case USB_SPEED_FULL:
  866         case USB_SPEED_HIGH:
  867                 /* assuming that there is one port */
  868                 err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc20, 1);
  869                 if (err) {
  870                         DPRINTFN(0, "getting USB 2.0 HUB descriptor failed,"
  871                             "error=%s\n", usbd_errstr(err));
  872                         break;
  873                 }
  874                 nports = hubdesc20.bNbrPorts;
  875                 if (nports > 127)
  876                         nports = 127;
  877 
  878                 if (udev->speed == USB_SPEED_HIGH)
  879                         tt = (UGETW(hubdesc20.wHubCharacteristics) >> 5) & 3;
  880                 break;
  881 
  882         case USB_SPEED_SUPER:
  883                 err = usbd_req_get_ss_hub_descriptor(udev, NULL, &hubdesc30, 1);
  884                 if (err) {
  885                         DPRINTFN(0, "Getting USB 3.0 HUB descriptor failed,"
  886                             "error=%s\n", usbd_errstr(err));
  887                         break;
  888                 }
  889                 nports = hubdesc30.bNbrPorts;
  890                 if (nports > 16)
  891                         nports = 16;
  892                 break;
  893 
  894         default:
  895                 err = USB_ERR_INVAL;
  896                 break;
  897         }
  898 
  899         if (pnports != NULL)
  900                 *pnports = nports;
  901 
  902         if (ptt != NULL)
  903                 *ptt = tt;
  904 
  905         return (err);
  906 }
  907 
  908 static int
  909 uhub_attach(device_t dev)
  910 {
  911         struct uhub_softc *sc = device_get_softc(dev);
  912         struct usb_attach_arg *uaa = device_get_ivars(dev);
  913         struct usb_device *udev = uaa->device;
  914         struct usb_device *parent_hub = udev->parent_hub;
  915         struct usb_hub *hub;
  916         struct usb_hub_descriptor hubdesc20;
  917         struct usb_hub_ss_descriptor hubdesc30;
  918         uint16_t pwrdly;
  919         uint8_t x;
  920         uint8_t nports;
  921         uint8_t portno;
  922         uint8_t removable;
  923         uint8_t iface_index;
  924         usb_error_t err;
  925 
  926         sc->sc_udev = udev;
  927         sc->sc_dev = dev;
  928 
  929         mtx_init(&sc->sc_mtx, "USB HUB mutex", NULL, MTX_DEF);
  930 
  931         snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
  932             device_get_nameunit(dev));
  933 
  934         device_set_usb_desc(dev);
  935 
  936         DPRINTFN(2, "depth=%d selfpowered=%d, parent=%p, "
  937             "parent->selfpowered=%d\n",
  938             udev->depth,
  939             udev->flags.self_powered,
  940             parent_hub,
  941             parent_hub ?
  942             parent_hub->flags.self_powered : 0);
  943 
  944         if (uhub_is_too_deep(udev)) {
  945                 DPRINTFN(0, "HUB at depth %d, "
  946                     "exceeds maximum. HUB ignored\n", (int)udev->depth);
  947                 goto error;
  948         }
  949 
  950         if (!udev->flags.self_powered && parent_hub &&
  951             !parent_hub->flags.self_powered) {
  952                 DPRINTFN(0, "Bus powered HUB connected to "
  953                     "bus powered HUB. HUB ignored\n");
  954                 goto error;
  955         }
  956 
  957         if (UHUB_IS_MULTI_TT(sc)) {
  958                 err = usbd_set_alt_interface_index(udev, 0, 1);
  959                 if (err) {
  960                         device_printf(dev, "MTT could not be enabled\n");
  961                         goto error;
  962                 }
  963                 device_printf(dev, "MTT enabled\n");
  964         }
  965 
  966         /* get HUB descriptor */
  967 
  968         DPRINTFN(2, "Getting HUB descriptor\n");
  969 
  970         switch (udev->speed) {
  971         case USB_SPEED_LOW:
  972         case USB_SPEED_FULL:
  973         case USB_SPEED_HIGH:
  974                 /* assuming that there is one port */
  975                 err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc20, 1);
  976                 if (err) {
  977                         DPRINTFN(0, "getting USB 2.0 HUB descriptor failed,"
  978                             "error=%s\n", usbd_errstr(err));
  979                         goto error;
  980                 }
  981                 /* get number of ports */
  982                 nports = hubdesc20.bNbrPorts;
  983 
  984                 /* get power delay */
  985                 pwrdly = ((hubdesc20.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
  986                     usb_extra_power_up_time);
  987 
  988                 /* get complete HUB descriptor */
  989                 if (nports >= 8) {
  990                         /* check number of ports */
  991                         if (nports > 127) {
  992                                 DPRINTFN(0, "Invalid number of USB 2.0 ports,"
  993                                     "error=%s\n", usbd_errstr(err));
  994                                 goto error;
  995                         }
  996                         /* get complete HUB descriptor */
  997                         err = usbd_req_get_hub_descriptor(udev, NULL, &hubdesc20, nports);
  998 
  999                         if (err) {
 1000                                 DPRINTFN(0, "Getting USB 2.0 HUB descriptor failed,"
 1001                                     "error=%s\n", usbd_errstr(err));
 1002                                 goto error;
 1003                         }
 1004                         if (hubdesc20.bNbrPorts != nports) {
 1005                                 DPRINTFN(0, "Number of ports changed\n");
 1006                                 goto error;
 1007                         }
 1008                 }
 1009                 break;
 1010         case USB_SPEED_SUPER:
 1011                 if (udev->parent_hub != NULL) {
 1012                         err = usbd_req_set_hub_depth(udev, NULL,
 1013                             udev->depth - 1);
 1014                         if (err) {
 1015                                 DPRINTFN(0, "Setting USB 3.0 HUB depth failed,"
 1016                                     "error=%s\n", usbd_errstr(err));
 1017                                 goto error;
 1018                         }
 1019                 }
 1020                 err = usbd_req_get_ss_hub_descriptor(udev, NULL, &hubdesc30, 1);
 1021                 if (err) {
 1022                         DPRINTFN(0, "Getting USB 3.0 HUB descriptor failed,"
 1023                             "error=%s\n", usbd_errstr(err));
 1024                         goto error;
 1025                 }
 1026                 /* get number of ports */
 1027                 nports = hubdesc30.bNbrPorts;
 1028 
 1029                 /* get power delay */
 1030                 pwrdly = ((hubdesc30.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
 1031                     usb_extra_power_up_time);
 1032 
 1033                 /* get complete HUB descriptor */
 1034                 if (nports >= 8) {
 1035                         /* check number of ports */
 1036                         if (nports > ((udev->parent_hub != NULL) ? 15 : 127)) {
 1037                                 DPRINTFN(0, "Invalid number of USB 3.0 ports,"
 1038                                     "error=%s\n", usbd_errstr(err));
 1039                                 goto error;
 1040                         }
 1041                         /* get complete HUB descriptor */
 1042                         err = usbd_req_get_ss_hub_descriptor(udev, NULL, &hubdesc30, nports);
 1043 
 1044                         if (err) {
 1045                                 DPRINTFN(0, "Getting USB 2.0 HUB descriptor failed,"
 1046                                     "error=%s\n", usbd_errstr(err));
 1047                                 goto error;
 1048                         }
 1049                         if (hubdesc30.bNbrPorts != nports) {
 1050                                 DPRINTFN(0, "Number of ports changed\n");
 1051                                 goto error;
 1052                         }
 1053                 }
 1054                 break;
 1055         default:
 1056                 DPRINTF("Assuming HUB has only one port\n");
 1057                 /* default number of ports */
 1058                 nports = 1;
 1059                 /* default power delay */
 1060                 pwrdly = ((10 * UHD_PWRON_FACTOR) + usb_extra_power_up_time);
 1061                 break;
 1062         }
 1063         if (nports == 0) {
 1064                 DPRINTFN(0, "portless HUB\n");
 1065                 goto error;
 1066         }
 1067         hub = malloc(sizeof(hub[0]) + (sizeof(hub->ports[0]) * nports),
 1068             M_USBDEV, M_WAITOK | M_ZERO);
 1069 
 1070         if (hub == NULL) {
 1071                 goto error;
 1072         }
 1073         udev->hub = hub;
 1074 
 1075         /* initialize HUB structure */
 1076         hub->hubsoftc = sc;
 1077         hub->explore = &uhub_explore;
 1078         hub->nports = nports;
 1079         hub->hubudev = udev;
 1080 
 1081         /* if self powered hub, give ports maximum current */
 1082         if (udev->flags.self_powered) {
 1083                 hub->portpower = USB_MAX_POWER;
 1084         } else {
 1085                 hub->portpower = USB_MIN_POWER;
 1086         }
 1087 
 1088         /* set up interrupt pipe */
 1089         iface_index = 0;
 1090         if (udev->parent_hub == NULL) {
 1091                 /* root HUB is special */
 1092                 err = 0;
 1093         } else {
 1094                 /* normal HUB */
 1095                 err = usbd_transfer_setup(udev, &iface_index, sc->sc_xfer,
 1096                     uhub_config, UHUB_N_TRANSFER, sc, &sc->sc_mtx);
 1097         }
 1098         if (err) {
 1099                 DPRINTFN(0, "cannot setup interrupt transfer, "
 1100                     "errstr=%s\n", usbd_errstr(err));
 1101                 goto error;
 1102         }
 1103         /* wait with power off for a while */
 1104         usb_pause_mtx(NULL, USB_MS_TO_TICKS(USB_POWER_DOWN_TIME));
 1105 
 1106         /*
 1107          * To have the best chance of success we do things in the exact same
 1108          * order as Windoze98.  This should not be necessary, but some
 1109          * devices do not follow the USB specs to the letter.
 1110          *
 1111          * These are the events on the bus when a hub is attached:
 1112          *  Get device and config descriptors (see attach code)
 1113          *  Get hub descriptor (see above)
 1114          *  For all ports
 1115          *     turn on power
 1116          *     wait for power to become stable
 1117          * (all below happens in explore code)
 1118          *  For all ports
 1119          *     clear C_PORT_CONNECTION
 1120          *  For all ports
 1121          *     get port status
 1122          *     if device connected
 1123          *        wait 100 ms
 1124          *        turn on reset
 1125          *        wait
 1126          *        clear C_PORT_RESET
 1127          *        get port status
 1128          *        proceed with device attachment
 1129          */
 1130 
 1131         /* XXX should check for none, individual, or ganged power? */
 1132 
 1133         removable = 0;
 1134 
 1135         for (x = 0; x != nports; x++) {
 1136                 /* set up data structures */
 1137                 struct usb_port *up = hub->ports + x;
 1138 
 1139                 up->device_index = 0;
 1140                 up->restartcnt = 0;
 1141                 portno = x + 1;
 1142 
 1143                 /* check if port is removable */
 1144                 switch (udev->speed) {
 1145                 case USB_SPEED_LOW:
 1146                 case USB_SPEED_FULL:
 1147                 case USB_SPEED_HIGH:
 1148                         if (!UHD_NOT_REMOV(&hubdesc20, portno))
 1149                                 removable++;
 1150                         break;
 1151                 case USB_SPEED_SUPER:
 1152                         if (!UHD_NOT_REMOV(&hubdesc30, portno))
 1153                                 removable++;
 1154                         break;
 1155                 default:
 1156                         DPRINTF("Assuming removable port\n");
 1157                         removable++;
 1158                         break;
 1159                 }
 1160                 if (!err) {
 1161                         /* turn the power on */
 1162                         err = usbd_req_set_port_feature(udev, NULL,
 1163                             portno, UHF_PORT_POWER);
 1164                 }
 1165                 if (err) {
 1166                         DPRINTFN(0, "port %d power on failed, %s\n",
 1167                             portno, usbd_errstr(err));
 1168                 }
 1169                 DPRINTF("turn on port %d power\n",
 1170                     portno);
 1171 
 1172                 /* wait for stable power */
 1173                 usb_pause_mtx(NULL, USB_MS_TO_TICKS(pwrdly));
 1174         }
 1175 
 1176         device_printf(dev, "%d port%s with %d "
 1177             "removable, %s powered\n", nports, (nports != 1) ? "s" : "",
 1178             removable, udev->flags.self_powered ? "self" : "bus");
 1179 
 1180         /* Start the interrupt endpoint, if any */
 1181 
 1182         if (sc->sc_xfer[0] != NULL) {
 1183                 mtx_lock(&sc->sc_mtx);
 1184                 usbd_transfer_start(sc->sc_xfer[0]);
 1185                 mtx_unlock(&sc->sc_mtx);
 1186         }
 1187 
 1188         /* Enable automatic power save on all USB HUBs */
 1189 
 1190         usbd_set_power_mode(udev, USB_POWER_MODE_SAVE);
 1191 
 1192         return (0);
 1193 
 1194 error:
 1195         usbd_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
 1196 
 1197         if (udev->hub) {
 1198                 free(udev->hub, M_USBDEV);
 1199                 udev->hub = NULL;
 1200         }
 1201 
 1202         mtx_destroy(&sc->sc_mtx);
 1203 
 1204         return (ENXIO);
 1205 }
 1206 
 1207 /*
 1208  * Called from process context when the hub is gone.
 1209  * Detach all devices on active ports.
 1210  */
 1211 static int
 1212 uhub_detach(device_t dev)
 1213 {
 1214         struct uhub_softc *sc = device_get_softc(dev);
 1215         struct usb_hub *hub = sc->sc_udev->hub;
 1216         struct usb_device *child;
 1217         uint8_t x;
 1218 
 1219         if (hub == NULL)                /* must be partially working */
 1220                 return (0);
 1221 
 1222         /* Make sure interrupt transfer is gone. */
 1223         usbd_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
 1224 
 1225         /* Detach all ports */
 1226         for (x = 0; x != hub->nports; x++) {
 1227 
 1228                 child = usb_bus_port_get_device(sc->sc_udev->bus, hub->ports + x);
 1229 
 1230                 if (child == NULL) {
 1231                         continue;
 1232                 }
 1233 
 1234                 /*
 1235                  * Free USB device and all subdevices, if any.
 1236                  */
 1237                 usb_free_device(child, 0);
 1238         }
 1239 
 1240         free(hub, M_USBDEV);
 1241         sc->sc_udev->hub = NULL;
 1242 
 1243         mtx_destroy(&sc->sc_mtx);
 1244 
 1245         return (0);
 1246 }
 1247 
 1248 static int
 1249 uhub_suspend(device_t dev)
 1250 {
 1251         DPRINTF("\n");
 1252         /* Sub-devices are not suspended here! */
 1253         return (0);
 1254 }
 1255 
 1256 static int
 1257 uhub_resume(device_t dev)
 1258 {
 1259         DPRINTF("\n");
 1260         /* Sub-devices are not resumed here! */
 1261         return (0);
 1262 }
 1263 
 1264 static void
 1265 uhub_driver_added(device_t dev, driver_t *driver)
 1266 {
 1267         usb_needs_explore_all();
 1268 }
 1269 
 1270 struct hub_result {
 1271         struct usb_device *udev;
 1272         uint8_t portno;
 1273         uint8_t iface_index;
 1274 };
 1275 
 1276 static void
 1277 uhub_find_iface_index(struct usb_hub *hub, device_t child,
 1278     struct hub_result *res)
 1279 {
 1280         struct usb_interface *iface;
 1281         struct usb_device *udev;
 1282         uint8_t nports;
 1283         uint8_t x;
 1284         uint8_t i;
 1285 
 1286         nports = hub->nports;
 1287         for (x = 0; x != nports; x++) {
 1288                 udev = usb_bus_port_get_device(hub->hubudev->bus,
 1289                     hub->ports + x);
 1290                 if (!udev) {
 1291                         continue;
 1292                 }
 1293                 for (i = 0; i != USB_IFACE_MAX; i++) {
 1294                         iface = usbd_get_iface(udev, i);
 1295                         if (iface &&
 1296                             (iface->subdev == child)) {
 1297                                 res->iface_index = i;
 1298                                 res->udev = udev;
 1299                                 res->portno = x + 1;
 1300                                 return;
 1301                         }
 1302                 }
 1303         }
 1304         res->iface_index = 0;
 1305         res->udev = NULL;
 1306         res->portno = 0;
 1307 }
 1308 
 1309 static int
 1310 uhub_child_location_string(device_t parent, device_t child,
 1311     char *buf, size_t buflen)
 1312 {
 1313         struct uhub_softc *sc;
 1314         struct usb_hub *hub;
 1315         struct hub_result res;
 1316 
 1317         if (!device_is_attached(parent)) {
 1318                 if (buflen)
 1319                         buf[0] = 0;
 1320                 return (0);
 1321         }
 1322 
 1323         sc = device_get_softc(parent);
 1324         hub = sc->sc_udev->hub;
 1325 
 1326         mtx_lock(&Giant);
 1327         uhub_find_iface_index(hub, child, &res);
 1328         if (!res.udev) {
 1329                 DPRINTF("device not on hub\n");
 1330                 if (buflen) {
 1331                         buf[0] = '\0';
 1332                 }
 1333                 goto done;
 1334         }
 1335         snprintf(buf, buflen, "bus=%u hubaddr=%u port=%u devaddr=%u interface=%u",
 1336             (res.udev->parent_hub != NULL) ? res.udev->parent_hub->device_index : 0,
 1337             res.portno, device_get_unit(res.udev->bus->bdev),
 1338             res.udev->device_index, res.iface_index);
 1339 done:
 1340         mtx_unlock(&Giant);
 1341 
 1342         return (0);
 1343 }
 1344 
 1345 static int
 1346 uhub_child_pnpinfo_string(device_t parent, device_t child,
 1347     char *buf, size_t buflen)
 1348 {
 1349         struct uhub_softc *sc;
 1350         struct usb_hub *hub;
 1351         struct usb_interface *iface;
 1352         struct hub_result res;
 1353 
 1354         if (!device_is_attached(parent)) {
 1355                 if (buflen)
 1356                         buf[0] = 0;
 1357                 return (0);
 1358         }
 1359 
 1360         sc = device_get_softc(parent);
 1361         hub = sc->sc_udev->hub;
 1362 
 1363         mtx_lock(&Giant);
 1364         uhub_find_iface_index(hub, child, &res);
 1365         if (!res.udev) {
 1366                 DPRINTF("device not on hub\n");
 1367                 if (buflen) {
 1368                         buf[0] = '\0';
 1369                 }
 1370                 goto done;
 1371         }
 1372         iface = usbd_get_iface(res.udev, res.iface_index);
 1373         if (iface && iface->idesc) {
 1374                 snprintf(buf, buflen, "vendor=0x%04x product=0x%04x "
 1375                     "devclass=0x%02x devsubclass=0x%02x "
 1376                     "sernum=\"%s\" "
 1377                     "release=0x%04x "
 1378                     "mode=%s "
 1379                     "intclass=0x%02x intsubclass=0x%02x "
 1380                     "intprotocol=0x%02x " "%s%s",
 1381                     UGETW(res.udev->ddesc.idVendor),
 1382                     UGETW(res.udev->ddesc.idProduct),
 1383                     res.udev->ddesc.bDeviceClass,
 1384                     res.udev->ddesc.bDeviceSubClass,
 1385                     usb_get_serial(res.udev),
 1386                     UGETW(res.udev->ddesc.bcdDevice),
 1387                     (res.udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device",
 1388                     iface->idesc->bInterfaceClass,
 1389                     iface->idesc->bInterfaceSubClass,
 1390                     iface->idesc->bInterfaceProtocol,
 1391                     iface->pnpinfo ? " " : "",
 1392                     iface->pnpinfo ? iface->pnpinfo : "");
 1393         } else {
 1394                 if (buflen) {
 1395                         buf[0] = '\0';
 1396                 }
 1397                 goto done;
 1398         }
 1399 done:
 1400         mtx_unlock(&Giant);
 1401 
 1402         return (0);
 1403 }
 1404 
 1405 /*
 1406  * The USB Transaction Translator:
 1407  * ===============================
 1408  *
 1409  * When doing LOW- and FULL-speed USB transfers accross a HIGH-speed
 1410  * USB HUB, bandwidth must be allocated for ISOCHRONOUS and INTERRUPT
 1411  * USB transfers. To utilize bandwidth dynamically the "scatter and
 1412  * gather" principle must be applied. This means that bandwidth must
 1413  * be divided into equal parts of bandwidth. With regard to USB all
 1414  * data is transferred in smaller packets with length
 1415  * "wMaxPacketSize". The problem however is that "wMaxPacketSize" is
 1416  * not a constant!
 1417  *
 1418  * The bandwidth scheduler which I have implemented will simply pack
 1419  * the USB transfers back to back until there is no more space in the
 1420  * schedule. Out of the 8 microframes which the USB 2.0 standard
 1421  * provides, only 6 are available for non-HIGH-speed devices. I have
 1422  * reserved the first 4 microframes for ISOCHRONOUS transfers. The
 1423  * last 2 microframes I have reserved for INTERRUPT transfers. Without
 1424  * this division, it is very difficult to allocate and free bandwidth
 1425  * dynamically.
 1426  *
 1427  * NOTE about the Transaction Translator in USB HUBs:
 1428  *
 1429  * USB HUBs have a very simple Transaction Translator, that will
 1430  * simply pipeline all the SPLIT transactions. That means that the
 1431  * transactions will be executed in the order they are queued!
 1432  *
 1433  */
 1434 
 1435 /*------------------------------------------------------------------------*
 1436  *      usb_intr_find_best_slot
 1437  *
 1438  * Return value:
 1439  *   The best Transaction Translation slot for an interrupt endpoint.
 1440  *------------------------------------------------------------------------*/
 1441 static uint8_t
 1442 usb_intr_find_best_slot(usb_size_t *ptr, uint8_t start,
 1443     uint8_t end, uint8_t mask)
 1444 {
 1445         usb_size_t min = (usb_size_t)-1;
 1446         usb_size_t sum;
 1447         uint8_t x;
 1448         uint8_t y;
 1449         uint8_t z;
 1450 
 1451         y = 0;
 1452 
 1453         /* find the last slot with lesser used bandwidth */
 1454 
 1455         for (x = start; x < end; x++) {
 1456 
 1457                 sum = 0;
 1458 
 1459                 /* compute sum of bandwidth */
 1460                 for (z = x; z < end; z++) {
 1461                         if (mask & (1U << (z - x)))
 1462                                 sum += ptr[z];
 1463                 }
 1464 
 1465                 /* check if the current multi-slot is more optimal */
 1466                 if (min >= sum) {
 1467                         min = sum;
 1468                         y = x;
 1469                 }
 1470 
 1471                 /* check if the mask is about to be shifted out */
 1472                 if (mask & (1U << (end - 1 - x)))
 1473                         break;
 1474         }
 1475         return (y);
 1476 }
 1477 
 1478 /*------------------------------------------------------------------------*
 1479  *      usb_hs_bandwidth_adjust
 1480  *
 1481  * This function will update the bandwith usage for the microframe
 1482  * having index "slot" by "len" bytes. "len" can be negative.  If the
 1483  * "slot" argument is greater or equal to "USB_HS_MICRO_FRAMES_MAX"
 1484  * the "slot" argument will be replaced by the slot having least used
 1485  * bandwidth. The "mask" argument is used for multi-slot allocations.
 1486  *
 1487  * Returns:
 1488  *    The slot in which the bandwidth update was done: 0..7
 1489  *------------------------------------------------------------------------*/
 1490 static uint8_t
 1491 usb_hs_bandwidth_adjust(struct usb_device *udev, int16_t len,
 1492     uint8_t slot, uint8_t mask)
 1493 {
 1494         struct usb_bus *bus = udev->bus;
 1495         struct usb_hub *hub;
 1496         enum usb_dev_speed speed;
 1497         uint8_t x;
 1498 
 1499         USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
 1500 
 1501         speed = usbd_get_speed(udev);
 1502 
 1503         switch (speed) {
 1504         case USB_SPEED_LOW:
 1505         case USB_SPEED_FULL:
 1506                 if (speed == USB_SPEED_LOW) {
 1507                         len *= 8;
 1508                 }
 1509                 /*
 1510                  * The Host Controller Driver should have
 1511                  * performed checks so that the lookup
 1512                  * below does not result in a NULL pointer
 1513                  * access.
 1514                  */
 1515 
 1516                 hub = udev->parent_hs_hub->hub;
 1517                 if (slot >= USB_HS_MICRO_FRAMES_MAX) {
 1518                         slot = usb_intr_find_best_slot(hub->uframe_usage,
 1519                             USB_FS_ISOC_UFRAME_MAX, 6, mask);
 1520                 }
 1521                 for (x = slot; x < 8; x++) {
 1522                         if (mask & (1U << (x - slot))) {
 1523                                 hub->uframe_usage[x] += len;
 1524                                 bus->uframe_usage[x] += len;
 1525                         }
 1526                 }
 1527                 break;
 1528         default:
 1529                 if (slot >= USB_HS_MICRO_FRAMES_MAX) {
 1530                         slot = usb_intr_find_best_slot(bus->uframe_usage, 0,
 1531                             USB_HS_MICRO_FRAMES_MAX, mask);
 1532                 }
 1533                 for (x = slot; x < 8; x++) {
 1534                         if (mask & (1U << (x - slot))) {
 1535                                 bus->uframe_usage[x] += len;
 1536                         }
 1537                 }
 1538                 break;
 1539         }
 1540         return (slot);
 1541 }
 1542 
 1543 /*------------------------------------------------------------------------*
 1544  *      usb_hs_bandwidth_alloc
 1545  *
 1546  * This function is a wrapper function for "usb_hs_bandwidth_adjust()".
 1547  *------------------------------------------------------------------------*/
 1548 void
 1549 usb_hs_bandwidth_alloc(struct usb_xfer *xfer)
 1550 {
 1551         struct usb_device *udev;
 1552         uint8_t slot;
 1553         uint8_t mask;
 1554         uint8_t speed;
 1555 
 1556         udev = xfer->xroot->udev;
 1557 
 1558         if (udev->flags.usb_mode != USB_MODE_HOST)
 1559                 return;         /* not supported */
 1560 
 1561         xfer->endpoint->refcount_bw++;
 1562         if (xfer->endpoint->refcount_bw != 1)
 1563                 return;         /* already allocated */
 1564 
 1565         speed = usbd_get_speed(udev);
 1566 
 1567         switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
 1568         case UE_INTERRUPT:
 1569                 /* allocate a microframe slot */
 1570 
 1571                 mask = 0x01;
 1572                 slot = usb_hs_bandwidth_adjust(udev,
 1573                     xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX, mask);
 1574 
 1575                 xfer->endpoint->usb_uframe = slot;
 1576                 xfer->endpoint->usb_smask = mask << slot;
 1577 
 1578                 if ((speed != USB_SPEED_FULL) &&
 1579                     (speed != USB_SPEED_LOW)) {
 1580                         xfer->endpoint->usb_cmask = 0x00 ;
 1581                 } else {
 1582                         xfer->endpoint->usb_cmask = (-(0x04 << slot)) & 0xFE;
 1583                 }
 1584                 break;
 1585 
 1586         case UE_ISOCHRONOUS:
 1587                 switch (usbd_xfer_get_fps_shift(xfer)) {
 1588                 case 0:
 1589                         mask = 0xFF;
 1590                         break;
 1591                 case 1:
 1592                         mask = 0x55;
 1593                         break;
 1594                 case 2:
 1595                         mask = 0x11;
 1596                         break;
 1597                 default:
 1598                         mask = 0x01;
 1599                         break;
 1600                 }
 1601 
 1602                 /* allocate a microframe multi-slot */
 1603 
 1604                 slot = usb_hs_bandwidth_adjust(udev,
 1605                     xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX, mask);
 1606 
 1607                 xfer->endpoint->usb_uframe = slot;
 1608                 xfer->endpoint->usb_cmask = 0;
 1609                 xfer->endpoint->usb_smask = mask << slot;
 1610                 break;
 1611 
 1612         default:
 1613                 xfer->endpoint->usb_uframe = 0;
 1614                 xfer->endpoint->usb_cmask = 0;
 1615                 xfer->endpoint->usb_smask = 0;
 1616                 break;
 1617         }
 1618 
 1619         DPRINTFN(11, "slot=%d, mask=0x%02x\n", 
 1620             xfer->endpoint->usb_uframe, 
 1621             xfer->endpoint->usb_smask >> xfer->endpoint->usb_uframe);
 1622 }
 1623 
 1624 /*------------------------------------------------------------------------*
 1625  *      usb_hs_bandwidth_free
 1626  *
 1627  * This function is a wrapper function for "usb_hs_bandwidth_adjust()".
 1628  *------------------------------------------------------------------------*/
 1629 void
 1630 usb_hs_bandwidth_free(struct usb_xfer *xfer)
 1631 {
 1632         struct usb_device *udev;
 1633         uint8_t slot;
 1634         uint8_t mask;
 1635 
 1636         udev = xfer->xroot->udev;
 1637 
 1638         if (udev->flags.usb_mode != USB_MODE_HOST)
 1639                 return;         /* not supported */
 1640 
 1641         xfer->endpoint->refcount_bw--;
 1642         if (xfer->endpoint->refcount_bw != 0)
 1643                 return;         /* still allocated */
 1644 
 1645         switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
 1646         case UE_INTERRUPT:
 1647         case UE_ISOCHRONOUS:
 1648 
 1649                 slot = xfer->endpoint->usb_uframe;
 1650                 mask = xfer->endpoint->usb_smask;
 1651 
 1652                 /* free microframe slot(s): */    
 1653                 usb_hs_bandwidth_adjust(udev,
 1654                     -xfer->max_frame_size, slot, mask >> slot);
 1655 
 1656                 DPRINTFN(11, "slot=%d, mask=0x%02x\n", 
 1657                     slot, mask >> slot);
 1658 
 1659                 xfer->endpoint->usb_uframe = 0;
 1660                 xfer->endpoint->usb_cmask = 0;
 1661                 xfer->endpoint->usb_smask = 0;
 1662                 break;
 1663 
 1664         default:
 1665                 break;
 1666         }
 1667 }
 1668 
 1669 /*------------------------------------------------------------------------*
 1670  *      usb_isoc_time_expand
 1671  *
 1672  * This function will expand the time counter from 7-bit to 16-bit.
 1673  *
 1674  * Returns:
 1675  *   16-bit isochronous time counter.
 1676  *------------------------------------------------------------------------*/
 1677 uint16_t
 1678 usb_isoc_time_expand(struct usb_bus *bus, uint16_t isoc_time_curr)
 1679 {
 1680         uint16_t rem;
 1681 
 1682         USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
 1683 
 1684         rem = bus->isoc_time_last & (USB_ISOC_TIME_MAX - 1);
 1685 
 1686         isoc_time_curr &= (USB_ISOC_TIME_MAX - 1);
 1687 
 1688         if (isoc_time_curr < rem) {
 1689                 /* the time counter wrapped around */
 1690                 bus->isoc_time_last += USB_ISOC_TIME_MAX;
 1691         }
 1692         /* update the remainder */
 1693 
 1694         bus->isoc_time_last &= ~(USB_ISOC_TIME_MAX - 1);
 1695         bus->isoc_time_last |= isoc_time_curr;
 1696 
 1697         return (bus->isoc_time_last);
 1698 }
 1699 
 1700 /*------------------------------------------------------------------------*
 1701  *      usbd_fs_isoc_schedule_alloc_slot
 1702  *
 1703  * This function will allocate bandwidth for an isochronous FULL speed
 1704  * transaction in the FULL speed schedule.
 1705  *
 1706  * Returns:
 1707  *    <8: Success
 1708  * Else: Error
 1709  *------------------------------------------------------------------------*/
 1710 #if USB_HAVE_TT_SUPPORT
 1711 uint8_t
 1712 usbd_fs_isoc_schedule_alloc_slot(struct usb_xfer *isoc_xfer, uint16_t isoc_time)
 1713 {
 1714         struct usb_xfer *xfer;
 1715         struct usb_xfer *pipe_xfer;
 1716         struct usb_bus *bus;
 1717         usb_frlength_t len;
 1718         usb_frlength_t data_len;
 1719         uint16_t delta;
 1720         uint16_t slot;
 1721         uint8_t retval;
 1722 
 1723         data_len = 0;
 1724         slot = 0;
 1725 
 1726         bus = isoc_xfer->xroot->bus;
 1727 
 1728         TAILQ_FOREACH(xfer, &bus->intr_q.head, wait_entry) {
 1729 
 1730                 /* skip self, if any */
 1731 
 1732                 if (xfer == isoc_xfer)
 1733                         continue;
 1734 
 1735                 /* check if this USB transfer is going through the same TT */
 1736 
 1737                 if (xfer->xroot->udev->parent_hs_hub !=
 1738                     isoc_xfer->xroot->udev->parent_hs_hub) {
 1739                         continue;
 1740                 }
 1741                 if ((isoc_xfer->xroot->udev->parent_hs_hub->
 1742                     ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT) &&
 1743                     (xfer->xroot->udev->hs_port_no !=
 1744                     isoc_xfer->xroot->udev->hs_port_no)) {
 1745                         continue;
 1746                 }
 1747                 if (xfer->endpoint->methods != isoc_xfer->endpoint->methods)
 1748                         continue;
 1749 
 1750                 /* check if isoc_time is part of this transfer */
 1751 
 1752                 delta = xfer->isoc_time_complete - isoc_time;
 1753                 if (delta > 0 && delta <= xfer->nframes) {
 1754                         delta = xfer->nframes - delta;
 1755 
 1756                         len = xfer->frlengths[delta];
 1757                         len += 8;
 1758                         len *= 7;
 1759                         len /= 6;
 1760 
 1761                         data_len += len;
 1762                 }
 1763 
 1764                 /* check double buffered transfers */
 1765 
 1766                 TAILQ_FOREACH(pipe_xfer, &xfer->endpoint->endpoint_q.head,
 1767                     wait_entry) {
 1768 
 1769                         /* skip self, if any */
 1770 
 1771                         if (pipe_xfer == isoc_xfer)
 1772                                 continue;
 1773 
 1774                         /* check if isoc_time is part of this transfer */
 1775 
 1776                         delta = pipe_xfer->isoc_time_complete - isoc_time;
 1777                         if (delta > 0 && delta <= pipe_xfer->nframes) {
 1778                                 delta = pipe_xfer->nframes - delta;
 1779 
 1780                                 len = pipe_xfer->frlengths[delta];
 1781                                 len += 8;
 1782                                 len *= 7;
 1783                                 len /= 6;
 1784 
 1785                                 data_len += len;
 1786                         }
 1787                 }
 1788         }
 1789 
 1790         while (data_len >= USB_FS_BYTES_PER_HS_UFRAME) {
 1791                 data_len -= USB_FS_BYTES_PER_HS_UFRAME;
 1792                 slot++;
 1793         }
 1794 
 1795         /* check for overflow */
 1796 
 1797         if (slot >= USB_FS_ISOC_UFRAME_MAX)
 1798                 return (255);
 1799 
 1800         retval = slot;
 1801 
 1802         delta = isoc_xfer->isoc_time_complete - isoc_time;
 1803         if (delta > 0 && delta <= isoc_xfer->nframes) {
 1804                 delta = isoc_xfer->nframes - delta;
 1805 
 1806                 len = isoc_xfer->frlengths[delta];
 1807                 len += 8;
 1808                 len *= 7;
 1809                 len /= 6;
 1810 
 1811                 data_len += len;
 1812         }
 1813 
 1814         while (data_len >= USB_FS_BYTES_PER_HS_UFRAME) {
 1815                 data_len -= USB_FS_BYTES_PER_HS_UFRAME;
 1816                 slot++;
 1817         }
 1818 
 1819         /* check for overflow */
 1820 
 1821         if (slot >= USB_FS_ISOC_UFRAME_MAX)
 1822                 return (255);
 1823 
 1824         return (retval);
 1825 }
 1826 #endif
 1827 
 1828 /*------------------------------------------------------------------------*
 1829  *      usb_bus_port_get_device
 1830  *
 1831  * This function is NULL safe.
 1832  *------------------------------------------------------------------------*/
 1833 struct usb_device *
 1834 usb_bus_port_get_device(struct usb_bus *bus, struct usb_port *up)
 1835 {
 1836         if ((bus == NULL) || (up == NULL)) {
 1837                 /* be NULL safe */
 1838                 return (NULL);
 1839         }
 1840         if (up->device_index == 0) {
 1841                 /* nothing to do */
 1842                 return (NULL);
 1843         }
 1844         return (bus->devices[up->device_index]);
 1845 }
 1846 
 1847 /*------------------------------------------------------------------------*
 1848  *      usb_bus_port_set_device
 1849  *
 1850  * This function is NULL safe.
 1851  *------------------------------------------------------------------------*/
 1852 void
 1853 usb_bus_port_set_device(struct usb_bus *bus, struct usb_port *up,
 1854     struct usb_device *udev, uint8_t device_index)
 1855 {
 1856         if (bus == NULL) {
 1857                 /* be NULL safe */
 1858                 return;
 1859         }
 1860         /*
 1861          * There is only one case where we don't
 1862          * have an USB port, and that is the Root Hub!
 1863          */
 1864         if (up) {
 1865                 if (udev) {
 1866                         up->device_index = device_index;
 1867                 } else {
 1868                         device_index = up->device_index;
 1869                         up->device_index = 0;
 1870                 }
 1871         }
 1872         /*
 1873          * Make relationships to our new device
 1874          */
 1875         if (device_index != 0) {
 1876 #if USB_HAVE_UGEN
 1877                 mtx_lock(&usb_ref_lock);
 1878 #endif
 1879                 bus->devices[device_index] = udev;
 1880 #if USB_HAVE_UGEN
 1881                 mtx_unlock(&usb_ref_lock);
 1882 #endif
 1883         }
 1884         /*
 1885          * Debug print
 1886          */
 1887         DPRINTFN(2, "bus %p devices[%u] = %p\n", bus, device_index, udev);
 1888 }
 1889 
 1890 /*------------------------------------------------------------------------*
 1891  *      usb_needs_explore
 1892  *
 1893  * This functions is called when the USB event thread needs to run.
 1894  *------------------------------------------------------------------------*/
 1895 void
 1896 usb_needs_explore(struct usb_bus *bus, uint8_t do_probe)
 1897 {
 1898         uint8_t do_unlock;
 1899 
 1900         DPRINTF("\n");
 1901 
 1902         if (bus == NULL) {
 1903                 DPRINTF("No bus pointer!\n");
 1904                 return;
 1905         }
 1906         if ((bus->devices == NULL) ||
 1907             (bus->devices[USB_ROOT_HUB_ADDR] == NULL)) {
 1908                 DPRINTF("No root HUB\n");
 1909                 return;
 1910         }
 1911         if (mtx_owned(&bus->bus_mtx)) {
 1912                 do_unlock = 0;
 1913         } else {
 1914                 USB_BUS_LOCK(bus);
 1915                 do_unlock = 1;
 1916         }
 1917         if (do_probe) {
 1918                 bus->do_probe = 1;
 1919         }
 1920         if (usb_proc_msignal(&bus->explore_proc,
 1921             &bus->explore_msg[0], &bus->explore_msg[1])) {
 1922                 /* ignore */
 1923         }
 1924         if (do_unlock) {
 1925                 USB_BUS_UNLOCK(bus);
 1926         }
 1927 }
 1928 
 1929 /*------------------------------------------------------------------------*
 1930  *      usb_needs_explore_all
 1931  *
 1932  * This function is called whenever a new driver is loaded and will
 1933  * cause that all USB busses are re-explored.
 1934  *------------------------------------------------------------------------*/
 1935 void
 1936 usb_needs_explore_all(void)
 1937 {
 1938         struct usb_bus *bus;
 1939         devclass_t dc;
 1940         device_t dev;
 1941         int max;
 1942 
 1943         DPRINTFN(3, "\n");
 1944 
 1945         dc = usb_devclass_ptr;
 1946         if (dc == NULL) {
 1947                 DPRINTFN(0, "no devclass\n");
 1948                 return;
 1949         }
 1950         /*
 1951          * Explore all USB busses in parallell.
 1952          */
 1953         max = devclass_get_maxunit(dc);
 1954         while (max >= 0) {
 1955                 dev = devclass_get_device(dc, max);
 1956                 if (dev) {
 1957                         bus = device_get_softc(dev);
 1958                         if (bus) {
 1959                                 usb_needs_explore(bus, 1);
 1960                         }
 1961                 }
 1962                 max--;
 1963         }
 1964 }
 1965 
 1966 /*------------------------------------------------------------------------*
 1967  *      usb_bus_power_update
 1968  *
 1969  * This function will ensure that all USB devices on the given bus are
 1970  * properly suspended or resumed according to the device transfer
 1971  * state.
 1972  *------------------------------------------------------------------------*/
 1973 #if USB_HAVE_POWERD
 1974 void
 1975 usb_bus_power_update(struct usb_bus *bus)
 1976 {
 1977         usb_needs_explore(bus, 0 /* no probe */ );
 1978 }
 1979 #endif
 1980 
 1981 /*------------------------------------------------------------------------*
 1982  *      usbd_transfer_power_ref
 1983  *
 1984  * This function will modify the power save reference counts and
 1985  * wakeup the USB device associated with the given USB transfer, if
 1986  * needed.
 1987  *------------------------------------------------------------------------*/
 1988 #if USB_HAVE_POWERD
 1989 void
 1990 usbd_transfer_power_ref(struct usb_xfer *xfer, int val)
 1991 {
 1992         static const usb_power_mask_t power_mask[4] = {
 1993                 [UE_CONTROL] = USB_HW_POWER_CONTROL,
 1994                 [UE_BULK] = USB_HW_POWER_BULK,
 1995                 [UE_INTERRUPT] = USB_HW_POWER_INTERRUPT,
 1996                 [UE_ISOCHRONOUS] = USB_HW_POWER_ISOC,
 1997         };
 1998         struct usb_device *udev;
 1999         uint8_t needs_explore;
 2000         uint8_t needs_hw_power;
 2001         uint8_t xfer_type;
 2002 
 2003         udev = xfer->xroot->udev;
 2004 
 2005         if (udev->device_index == USB_ROOT_HUB_ADDR) {
 2006                 /* no power save for root HUB */
 2007                 return;
 2008         }
 2009         USB_BUS_LOCK(udev->bus);
 2010 
 2011         xfer_type = xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE;
 2012 
 2013         udev->pwr_save.last_xfer_time = ticks;
 2014         udev->pwr_save.type_refs[xfer_type] += val;
 2015 
 2016         if (xfer->flags_int.control_xfr) {
 2017                 udev->pwr_save.read_refs += val;
 2018                 if (xfer->flags_int.usb_mode == USB_MODE_HOST) {
 2019                         /*
 2020                          * It is not allowed to suspend during a
 2021                          * control transfer:
 2022                          */
 2023                         udev->pwr_save.write_refs += val;
 2024                 }
 2025         } else if (USB_GET_DATA_ISREAD(xfer)) {
 2026                 udev->pwr_save.read_refs += val;
 2027         } else {
 2028                 udev->pwr_save.write_refs += val;
 2029         }
 2030 
 2031         if (val > 0) {
 2032                 if (udev->flags.self_suspended)
 2033                         needs_explore = usb_peer_should_wakeup(udev);
 2034                 else
 2035                         needs_explore = 0;
 2036 
 2037                 if (!(udev->bus->hw_power_state & power_mask[xfer_type])) {
 2038                         DPRINTF("Adding type %u to power state\n", xfer_type);
 2039                         udev->bus->hw_power_state |= power_mask[xfer_type];
 2040                         needs_hw_power = 1;
 2041                 } else {
 2042                         needs_hw_power = 0;
 2043                 }
 2044         } else {
 2045                 needs_explore = 0;
 2046                 needs_hw_power = 0;
 2047         }
 2048 
 2049         USB_BUS_UNLOCK(udev->bus);
 2050 
 2051         if (needs_explore) {
 2052                 DPRINTF("update\n");
 2053                 usb_bus_power_update(udev->bus);
 2054         } else if (needs_hw_power) {
 2055                 DPRINTF("needs power\n");
 2056                 if (udev->bus->methods->set_hw_power != NULL) {
 2057                         (udev->bus->methods->set_hw_power) (udev->bus);
 2058                 }
 2059         }
 2060 }
 2061 #endif
 2062 
 2063 /*------------------------------------------------------------------------*
 2064  *      usb_peer_should_wakeup
 2065  *
 2066  * This function returns non-zero if the current device should wake up.
 2067  *------------------------------------------------------------------------*/
 2068 static uint8_t
 2069 usb_peer_should_wakeup(struct usb_device *udev)
 2070 {
 2071         return ((udev->power_mode == USB_POWER_MODE_ON) ||
 2072             (udev->driver_added_refcount != udev->bus->driver_added_refcount) ||
 2073             (udev->re_enumerate_wait != 0) ||
 2074             (udev->pwr_save.type_refs[UE_ISOCHRONOUS] != 0) ||
 2075             (udev->pwr_save.write_refs != 0) ||
 2076             ((udev->pwr_save.read_refs != 0) &&
 2077             (udev->flags.usb_mode == USB_MODE_HOST) &&
 2078             (usb_peer_can_wakeup(udev) == 0)));
 2079 }
 2080 
 2081 /*------------------------------------------------------------------------*
 2082  *      usb_bus_powerd
 2083  *
 2084  * This function implements the USB power daemon and is called
 2085  * regularly from the USB explore thread.
 2086  *------------------------------------------------------------------------*/
 2087 #if USB_HAVE_POWERD
 2088 void
 2089 usb_bus_powerd(struct usb_bus *bus)
 2090 {
 2091         struct usb_device *udev;
 2092         usb_ticks_t temp;
 2093         usb_ticks_t limit;
 2094         usb_ticks_t mintime;
 2095         usb_size_t type_refs[5];
 2096         uint8_t x;
 2097 
 2098         limit = usb_power_timeout;
 2099         if (limit == 0)
 2100                 limit = hz;
 2101         else if (limit > 255)
 2102                 limit = 255 * hz;
 2103         else
 2104                 limit = limit * hz;
 2105 
 2106         DPRINTF("bus=%p\n", bus);
 2107 
 2108         USB_BUS_LOCK(bus);
 2109 
 2110         /*
 2111          * The root HUB device is never suspended
 2112          * and we simply skip it.
 2113          */
 2114         for (x = USB_ROOT_HUB_ADDR + 1;
 2115             x != bus->devices_max; x++) {
 2116 
 2117                 udev = bus->devices[x];
 2118                 if (udev == NULL)
 2119                         continue;
 2120 
 2121                 temp = ticks - udev->pwr_save.last_xfer_time;
 2122 
 2123                 if (usb_peer_should_wakeup(udev)) {
 2124                         /* check if we are suspended */
 2125                         if (udev->flags.self_suspended != 0) {
 2126                                 USB_BUS_UNLOCK(bus);
 2127                                 usb_dev_resume_peer(udev);
 2128                                 USB_BUS_LOCK(bus);
 2129                         }
 2130                 } else if ((temp >= limit) &&
 2131                     (udev->flags.usb_mode == USB_MODE_HOST) &&
 2132                     (udev->flags.self_suspended == 0)) {
 2133                         /* try to do suspend */
 2134 
 2135                         USB_BUS_UNLOCK(bus);
 2136                         usb_dev_suspend_peer(udev);
 2137                         USB_BUS_LOCK(bus);
 2138                 }
 2139         }
 2140 
 2141         /* reset counters */
 2142 
 2143         mintime = (usb_ticks_t)-1;
 2144         type_refs[0] = 0;
 2145         type_refs[1] = 0;
 2146         type_refs[2] = 0;
 2147         type_refs[3] = 0;
 2148         type_refs[4] = 0;
 2149 
 2150         /* Re-loop all the devices to get the actual state */
 2151 
 2152         for (x = USB_ROOT_HUB_ADDR + 1;
 2153             x != bus->devices_max; x++) {
 2154 
 2155                 udev = bus->devices[x];
 2156                 if (udev == NULL)
 2157                         continue;
 2158 
 2159                 /* we found a non-Root-Hub USB device */
 2160                 type_refs[4] += 1;
 2161 
 2162                 /* "last_xfer_time" can be updated by a resume */
 2163                 temp = ticks - udev->pwr_save.last_xfer_time;
 2164 
 2165                 /*
 2166                  * Compute minimum time since last transfer for the complete
 2167                  * bus:
 2168                  */
 2169                 if (temp < mintime)
 2170                         mintime = temp;
 2171 
 2172                 if (udev->flags.self_suspended == 0) {
 2173                         type_refs[0] += udev->pwr_save.type_refs[0];
 2174                         type_refs[1] += udev->pwr_save.type_refs[1];
 2175                         type_refs[2] += udev->pwr_save.type_refs[2];
 2176                         type_refs[3] += udev->pwr_save.type_refs[3];
 2177                 }
 2178         }
 2179 
 2180         if (mintime >= (usb_ticks_t)(1 * hz)) {
 2181                 /* recompute power masks */
 2182                 DPRINTF("Recomputing power masks\n");
 2183                 bus->hw_power_state = 0;
 2184                 if (type_refs[UE_CONTROL] != 0)
 2185                         bus->hw_power_state |= USB_HW_POWER_CONTROL;
 2186                 if (type_refs[UE_BULK] != 0)
 2187                         bus->hw_power_state |= USB_HW_POWER_BULK;
 2188                 if (type_refs[UE_INTERRUPT] != 0)
 2189                         bus->hw_power_state |= USB_HW_POWER_INTERRUPT;
 2190                 if (type_refs[UE_ISOCHRONOUS] != 0)
 2191                         bus->hw_power_state |= USB_HW_POWER_ISOC;
 2192                 if (type_refs[4] != 0)
 2193                         bus->hw_power_state |= USB_HW_POWER_NON_ROOT_HUB;
 2194         }
 2195         USB_BUS_UNLOCK(bus);
 2196 
 2197         if (bus->methods->set_hw_power != NULL) {
 2198                 /* always update hardware power! */
 2199                 (bus->methods->set_hw_power) (bus);
 2200         }
 2201         return;
 2202 }
 2203 #endif
 2204 
 2205 /*------------------------------------------------------------------------*
 2206  *      usb_dev_resume_peer
 2207  *
 2208  * This function will resume an USB peer and do the required USB
 2209  * signalling to get an USB device out of the suspended state.
 2210  *------------------------------------------------------------------------*/
 2211 static void
 2212 usb_dev_resume_peer(struct usb_device *udev)
 2213 {
 2214         struct usb_bus *bus;
 2215         int err;
 2216 
 2217         /* be NULL safe */
 2218         if (udev == NULL)
 2219                 return;
 2220 
 2221         /* check if already resumed */
 2222         if (udev->flags.self_suspended == 0)
 2223                 return;
 2224 
 2225         /* we need a parent HUB to do resume */
 2226         if (udev->parent_hub == NULL)
 2227                 return;
 2228 
 2229         DPRINTF("udev=%p\n", udev);
 2230 
 2231         if ((udev->flags.usb_mode == USB_MODE_DEVICE) &&
 2232             (udev->flags.remote_wakeup == 0)) {
 2233                 /*
 2234                  * If the host did not set the remote wakeup feature, we can
 2235                  * not wake it up either!
 2236                  */
 2237                 DPRINTF("remote wakeup is not set!\n");
 2238                 return;
 2239         }
 2240         /* get bus pointer */
 2241         bus = udev->bus;
 2242 
 2243         /* resume parent hub first */
 2244         usb_dev_resume_peer(udev->parent_hub);
 2245 
 2246         /* reduce chance of instant resume failure by waiting a little bit */
 2247         usb_pause_mtx(NULL, USB_MS_TO_TICKS(20));
 2248 
 2249         if (usb_device_20_compatible(udev)) {
 2250                 /* resume current port (Valid in Host and Device Mode) */
 2251                 err = usbd_req_clear_port_feature(udev->parent_hub,
 2252                     NULL, udev->port_no, UHF_PORT_SUSPEND);
 2253                 if (err) {
 2254                         DPRINTFN(0, "Resuming port failed\n");
 2255                         return;
 2256                 }
 2257         } else {
 2258                 /* resume current port (Valid in Host and Device Mode) */
 2259                 err = usbd_req_set_port_link_state(udev->parent_hub,
 2260                     NULL, udev->port_no, UPS_PORT_LS_U0);
 2261                 if (err) {
 2262                         DPRINTFN(0, "Resuming port failed\n");
 2263                         return;
 2264                 }
 2265         }
 2266 
 2267         /* resume settle time */
 2268         usb_pause_mtx(NULL, USB_MS_TO_TICKS(usb_port_resume_delay));
 2269 
 2270         if (bus->methods->device_resume != NULL) {
 2271                 /* resume USB device on the USB controller */
 2272                 (bus->methods->device_resume) (udev);
 2273         }
 2274         USB_BUS_LOCK(bus);
 2275         /* set that this device is now resumed */
 2276         udev->flags.self_suspended = 0;
 2277 #if USB_HAVE_POWERD
 2278         /* make sure that we don't go into suspend right away */
 2279         udev->pwr_save.last_xfer_time = ticks;
 2280 
 2281         /* make sure the needed power masks are on */
 2282         if (udev->pwr_save.type_refs[UE_CONTROL] != 0)
 2283                 bus->hw_power_state |= USB_HW_POWER_CONTROL;
 2284         if (udev->pwr_save.type_refs[UE_BULK] != 0)
 2285                 bus->hw_power_state |= USB_HW_POWER_BULK;
 2286         if (udev->pwr_save.type_refs[UE_INTERRUPT] != 0)
 2287                 bus->hw_power_state |= USB_HW_POWER_INTERRUPT;
 2288         if (udev->pwr_save.type_refs[UE_ISOCHRONOUS] != 0)
 2289                 bus->hw_power_state |= USB_HW_POWER_ISOC;
 2290 #endif
 2291         USB_BUS_UNLOCK(bus);
 2292 
 2293         if (bus->methods->set_hw_power != NULL) {
 2294                 /* always update hardware power! */
 2295                 (bus->methods->set_hw_power) (bus);
 2296         }
 2297 
 2298         usbd_sr_lock(udev);
 2299 
 2300         /* notify all sub-devices about resume */
 2301         err = usb_suspend_resume(udev, 0);
 2302 
 2303         usbd_sr_unlock(udev);
 2304 
 2305         /* check if peer has wakeup capability */
 2306         if (usb_peer_can_wakeup(udev)) {
 2307                 /* clear remote wakeup */
 2308                 err = usbd_req_clear_device_feature(udev,
 2309                     NULL, UF_DEVICE_REMOTE_WAKEUP);
 2310                 if (err) {
 2311                         DPRINTFN(0, "Clearing device "
 2312                             "remote wakeup failed: %s\n",
 2313                             usbd_errstr(err));
 2314                 }
 2315         }
 2316 }
 2317 
 2318 /*------------------------------------------------------------------------*
 2319  *      usb_dev_suspend_peer
 2320  *
 2321  * This function will suspend an USB peer and do the required USB
 2322  * signalling to get an USB device into the suspended state.
 2323  *------------------------------------------------------------------------*/
 2324 static void
 2325 usb_dev_suspend_peer(struct usb_device *udev)
 2326 {
 2327         struct usb_device *child;
 2328         int err;
 2329         uint8_t x;
 2330         uint8_t nports;
 2331 
 2332 repeat:
 2333         /* be NULL safe */
 2334         if (udev == NULL)
 2335                 return;
 2336 
 2337         /* check if already suspended */
 2338         if (udev->flags.self_suspended)
 2339                 return;
 2340 
 2341         /* we need a parent HUB to do suspend */
 2342         if (udev->parent_hub == NULL)
 2343                 return;
 2344 
 2345         DPRINTF("udev=%p\n", udev);
 2346 
 2347         /* check if the current device is a HUB */
 2348         if (udev->hub != NULL) {
 2349                 nports = udev->hub->nports;
 2350 
 2351                 /* check if all devices on the HUB are suspended */
 2352                 for (x = 0; x != nports; x++) {
 2353                         child = usb_bus_port_get_device(udev->bus,
 2354                             udev->hub->ports + x);
 2355 
 2356                         if (child == NULL)
 2357                                 continue;
 2358 
 2359                         if (child->flags.self_suspended)
 2360                                 continue;
 2361 
 2362                         DPRINTFN(1, "Port %u is busy on the HUB!\n", x + 1);
 2363                         return;
 2364                 }
 2365         }
 2366 
 2367         if (usb_peer_can_wakeup(udev)) {
 2368                 /*
 2369                  * This request needs to be done before we set
 2370                  * "udev->flags.self_suspended":
 2371                  */
 2372 
 2373                 /* allow device to do remote wakeup */
 2374                 err = usbd_req_set_device_feature(udev,
 2375                     NULL, UF_DEVICE_REMOTE_WAKEUP);
 2376                 if (err) {
 2377                         DPRINTFN(0, "Setting device "
 2378                             "remote wakeup failed\n");
 2379                 }
 2380         }
 2381 
 2382         USB_BUS_LOCK(udev->bus);
 2383         /*
 2384          * Checking for suspend condition and setting suspended bit
 2385          * must be atomic!
 2386          */
 2387         err = usb_peer_should_wakeup(udev);
 2388         if (err == 0) {
 2389                 /*
 2390                  * Set that this device is suspended. This variable
 2391                  * must be set before calling USB controller suspend
 2392                  * callbacks.
 2393                  */
 2394                 udev->flags.self_suspended = 1;
 2395         }
 2396         USB_BUS_UNLOCK(udev->bus);
 2397 
 2398         if (err != 0) {
 2399                 if (usb_peer_can_wakeup(udev)) {
 2400                         /* allow device to do remote wakeup */
 2401                         err = usbd_req_clear_device_feature(udev,
 2402                             NULL, UF_DEVICE_REMOTE_WAKEUP);
 2403                         if (err) {
 2404                                 DPRINTFN(0, "Setting device "
 2405                                     "remote wakeup failed\n");
 2406                         }
 2407                 }
 2408 
 2409                 if (udev->flags.usb_mode == USB_MODE_DEVICE) {
 2410                         /* resume parent HUB first */
 2411                         usb_dev_resume_peer(udev->parent_hub);
 2412 
 2413                         /* reduce chance of instant resume failure by waiting a little bit */
 2414                         usb_pause_mtx(NULL, USB_MS_TO_TICKS(20));
 2415 
 2416                         /* resume current port (Valid in Host and Device Mode) */
 2417                         err = usbd_req_clear_port_feature(udev->parent_hub,
 2418                             NULL, udev->port_no, UHF_PORT_SUSPEND);
 2419 
 2420                         /* resume settle time */
 2421                         usb_pause_mtx(NULL, USB_MS_TO_TICKS(usb_port_resume_delay));
 2422                 }
 2423                 DPRINTF("Suspend was cancelled!\n");
 2424                 return;
 2425         }
 2426 
 2427         usbd_sr_lock(udev);
 2428 
 2429         /* notify all sub-devices about suspend */
 2430         err = usb_suspend_resume(udev, 1);
 2431 
 2432         usbd_sr_unlock(udev);
 2433 
 2434         if (udev->bus->methods->device_suspend != NULL) {
 2435                 usb_timeout_t temp;
 2436 
 2437                 /* suspend device on the USB controller */
 2438                 (udev->bus->methods->device_suspend) (udev);
 2439 
 2440                 /* do DMA delay */
 2441                 temp = usbd_get_dma_delay(udev);
 2442                 if (temp != 0)
 2443                         usb_pause_mtx(NULL, USB_MS_TO_TICKS(temp));
 2444 
 2445         }
 2446 
 2447         if (usb_device_20_compatible(udev)) {
 2448                 /* suspend current port */
 2449                 err = usbd_req_set_port_feature(udev->parent_hub,
 2450                     NULL, udev->port_no, UHF_PORT_SUSPEND);
 2451                 if (err) {
 2452                         DPRINTFN(0, "Suspending port failed\n");
 2453                         return;
 2454                 }
 2455         } else {
 2456                 /* suspend current port */
 2457                 err = usbd_req_set_port_link_state(udev->parent_hub,
 2458                     NULL, udev->port_no, UPS_PORT_LS_U3);
 2459                 if (err) {
 2460                         DPRINTFN(0, "Suspending port failed\n");
 2461                         return;
 2462                 }
 2463         }
 2464 
 2465         udev = udev->parent_hub;
 2466         goto repeat;
 2467 }
 2468 
 2469 /*------------------------------------------------------------------------*
 2470  *      usbd_set_power_mode
 2471  *
 2472  * This function will set the power mode, see USB_POWER_MODE_XXX for a
 2473  * USB device.
 2474  *------------------------------------------------------------------------*/
 2475 void
 2476 usbd_set_power_mode(struct usb_device *udev, uint8_t power_mode)
 2477 {
 2478         /* filter input argument */
 2479         if ((power_mode != USB_POWER_MODE_ON) &&
 2480             (power_mode != USB_POWER_MODE_OFF))
 2481                 power_mode = USB_POWER_MODE_SAVE;
 2482 
 2483         power_mode = usbd_filter_power_mode(udev, power_mode);  
 2484 
 2485         udev->power_mode = power_mode;  /* update copy of power mode */
 2486 
 2487 #if USB_HAVE_POWERD
 2488         usb_bus_power_update(udev->bus);
 2489 #endif
 2490 }
 2491 
 2492 /*------------------------------------------------------------------------*
 2493  *      usbd_filter_power_mode
 2494  *
 2495  * This function filters the power mode based on hardware requirements.
 2496  *------------------------------------------------------------------------*/
 2497 uint8_t
 2498 usbd_filter_power_mode(struct usb_device *udev, uint8_t power_mode)
 2499 {
 2500         struct usb_bus_methods *mtod;
 2501         int8_t temp;
 2502 
 2503         mtod = udev->bus->methods;
 2504         temp = -1;
 2505 
 2506         if (mtod->get_power_mode != NULL)
 2507                 (mtod->get_power_mode) (udev, &temp);
 2508 
 2509         /* check if we should not filter */
 2510         if (temp < 0)
 2511                 return (power_mode);
 2512 
 2513         /* use fixed power mode given by hardware driver */
 2514         return (temp);
 2515 }
 2516 
 2517 /*------------------------------------------------------------------------*
 2518  *      usbd_start_re_enumerate
 2519  *
 2520  * This function starts re-enumeration of the given USB device. This
 2521  * function does not need to be called BUS-locked. This function does
 2522  * not wait until the re-enumeration is completed.
 2523  *------------------------------------------------------------------------*/
 2524 void
 2525 usbd_start_re_enumerate(struct usb_device *udev)
 2526 {
 2527         if (udev->re_enumerate_wait == 0) {
 2528                 udev->re_enumerate_wait = 1;
 2529                 usb_needs_explore(udev->bus, 0);
 2530         }
 2531 }

Cache object: 0293cc0518acab46181a7de9fa887274


[ 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.