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


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

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

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

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

Cache object: fb8cddd4a09ff49705bc44cb9bddf9eb


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