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

Cache object: 8c7a5251db09ddd12cdf2ce981da46f0


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