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/controller/usb_controller.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$ */
    2 /*-
    3  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    4  *
    5  * Copyright (c) 2008 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 #ifdef USB_GLOBAL_INCLUDE_FILE
   30 #include USB_GLOBAL_INCLUDE_FILE
   31 #else
   32 #include "opt_ddb.h"
   33 
   34 #include <sys/stdint.h>
   35 #include <sys/stddef.h>
   36 #include <sys/param.h>
   37 #include <sys/queue.h>
   38 #include <sys/types.h>
   39 #include <sys/systm.h>
   40 #include <sys/kernel.h>
   41 #include <sys/bus.h>
   42 #include <sys/module.h>
   43 #include <sys/lock.h>
   44 #include <sys/mutex.h>
   45 #include <sys/condvar.h>
   46 #include <sys/sysctl.h>
   47 #include <sys/sx.h>
   48 #include <sys/unistd.h>
   49 #include <sys/callout.h>
   50 #include <sys/malloc.h>
   51 #include <sys/priv.h>
   52 
   53 #include <dev/usb/usb.h>
   54 #include <dev/usb/usbdi.h>
   55 
   56 #define USB_DEBUG_VAR usb_ctrl_debug
   57 
   58 #include <dev/usb/usb_core.h>
   59 #include <dev/usb/usb_debug.h>
   60 #include <dev/usb/usb_process.h>
   61 #include <dev/usb/usb_busdma.h>
   62 #include <dev/usb/usb_dynamic.h>
   63 #include <dev/usb/usb_device.h>
   64 #include <dev/usb/usb_dev.h>
   65 #include <dev/usb/usb_hub.h>
   66 
   67 #include <dev/usb/usb_controller.h>
   68 #include <dev/usb/usb_bus.h>
   69 #include <dev/usb/usb_pf.h>
   70 #include "usb_if.h"
   71 #endif                  /* USB_GLOBAL_INCLUDE_FILE */
   72 
   73 /* function prototypes  */
   74 
   75 static device_probe_t usb_probe;
   76 static device_attach_t usb_attach;
   77 static device_detach_t usb_detach;
   78 static device_suspend_t usb_suspend;
   79 static device_resume_t usb_resume;
   80 static device_shutdown_t usb_shutdown;
   81 
   82 static void     usb_attach_sub(device_t, struct usb_bus *);
   83 
   84 /* static variables */
   85 
   86 #ifdef USB_DEBUG
   87 static int usb_ctrl_debug = 0;
   88 
   89 static SYSCTL_NODE(_hw_usb, OID_AUTO, ctrl, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
   90     "USB controller");
   91 SYSCTL_INT(_hw_usb_ctrl, OID_AUTO, debug, CTLFLAG_RWTUN, &usb_ctrl_debug, 0,
   92     "Debug level");
   93 #endif
   94 
   95 #if USB_HAVE_ROOT_MOUNT_HOLD
   96 static int usb_no_boot_wait = 0;
   97 SYSCTL_INT(_hw_usb, OID_AUTO, no_boot_wait, CTLFLAG_RDTUN, &usb_no_boot_wait, 0,
   98     "No USB device enumerate waiting at boot.");
   99 #endif
  100 
  101 static int usb_no_suspend_wait = 0;
  102 SYSCTL_INT(_hw_usb, OID_AUTO, no_suspend_wait, CTLFLAG_RWTUN,
  103     &usb_no_suspend_wait, 0, "No USB device waiting at system suspend.");
  104 
  105 static int usb_no_shutdown_wait = 0;
  106 SYSCTL_INT(_hw_usb, OID_AUTO, no_shutdown_wait, CTLFLAG_RWTUN,
  107     &usb_no_shutdown_wait, 0, "No USB device waiting at system shutdown.");
  108 
  109 static device_method_t usb_methods[] = {
  110         DEVMETHOD(device_probe, usb_probe),
  111         DEVMETHOD(device_attach, usb_attach),
  112         DEVMETHOD(device_detach, usb_detach),
  113         DEVMETHOD(device_suspend, usb_suspend),
  114         DEVMETHOD(device_resume, usb_resume),
  115         DEVMETHOD(device_shutdown, usb_shutdown),
  116 
  117         DEVMETHOD_END
  118 };
  119 
  120 static driver_t usb_driver = {
  121         .name = "usbus",
  122         .methods = usb_methods,
  123         .size = 0,
  124 };
  125 
  126 /* Host Only Drivers */
  127 DRIVER_MODULE(usbus, ohci, usb_driver, 0, 0);
  128 DRIVER_MODULE(usbus, uhci, usb_driver, 0, 0);
  129 DRIVER_MODULE(usbus, ehci, usb_driver, 0, 0);
  130 DRIVER_MODULE(usbus, xhci, usb_driver, 0, 0);
  131 
  132 /* Device Only Drivers */
  133 DRIVER_MODULE(usbus, musbotg, usb_driver, 0, 0);
  134 DRIVER_MODULE(usbus, uss820dci, usb_driver, 0, 0);
  135 DRIVER_MODULE(usbus, octusb, usb_driver, 0, 0);
  136 
  137 /* Dual Mode Drivers */
  138 DRIVER_MODULE(usbus, dwcotg, usb_driver, 0, 0);
  139 DRIVER_MODULE(usbus, saf1761otg, usb_driver, 0, 0);
  140 
  141 /*------------------------------------------------------------------------*
  142  *      usb_probe
  143  *
  144  * This function is called from "{ehci,ohci,uhci}_pci_attach()".
  145  *------------------------------------------------------------------------*/
  146 static int
  147 usb_probe(device_t dev)
  148 {
  149         DPRINTF("\n");
  150         return (0);
  151 }
  152 
  153 #if USB_HAVE_ROOT_MOUNT_HOLD
  154 static void
  155 usb_root_mount_rel(struct usb_bus *bus)
  156 {
  157         if (bus->bus_roothold != NULL) {
  158                 DPRINTF("Releasing root mount hold %p\n", bus->bus_roothold);
  159                 root_mount_rel(bus->bus_roothold);
  160                 bus->bus_roothold = NULL;
  161         }
  162 }
  163 #endif
  164 
  165 /*------------------------------------------------------------------------*
  166  *      usb_attach
  167  *------------------------------------------------------------------------*/
  168 static int
  169 usb_attach(device_t dev)
  170 {
  171         struct usb_bus *bus = device_get_ivars(dev);
  172 
  173         DPRINTF("\n");
  174 
  175         if (bus == NULL) {
  176                 device_printf(dev, "USB device has no ivars\n");
  177                 return (ENXIO);
  178         }
  179 
  180 #if USB_HAVE_ROOT_MOUNT_HOLD
  181         if (usb_no_boot_wait == 0) {
  182                 /* delay vfs_mountroot until the bus is explored */
  183                 bus->bus_roothold = root_mount_hold(device_get_nameunit(dev));
  184         }
  185 #endif
  186         usb_attach_sub(dev, bus);
  187 
  188         return (0);                     /* return success */
  189 }
  190 
  191 /*------------------------------------------------------------------------*
  192  *      usb_detach
  193  *------------------------------------------------------------------------*/
  194 static int
  195 usb_detach(device_t dev)
  196 {
  197         struct usb_bus *bus = device_get_softc(dev);
  198 
  199         DPRINTF("\n");
  200 
  201         if (bus == NULL) {
  202                 /* was never setup properly */
  203                 return (0);
  204         }
  205         /* Stop power watchdog */
  206         usb_callout_drain(&bus->power_wdog);
  207 
  208 #if USB_HAVE_ROOT_MOUNT_HOLD
  209         /* Let the USB explore process detach all devices. */
  210         usb_root_mount_rel(bus);
  211 #endif
  212 
  213         USB_BUS_LOCK(bus);
  214 
  215         /* Queue detach job */
  216         usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
  217             &bus->detach_msg[0], &bus->detach_msg[1]);
  218 
  219         /* Wait for detach to complete */
  220         usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
  221             &bus->detach_msg[0], &bus->detach_msg[1]);
  222 
  223 #if USB_HAVE_UGEN
  224         /* Wait for cleanup to complete */
  225         usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
  226             &bus->cleanup_msg[0], &bus->cleanup_msg[1]);
  227 #endif
  228         USB_BUS_UNLOCK(bus);
  229 
  230 #if USB_HAVE_PER_BUS_PROCESS
  231         /* Get rid of USB callback processes */
  232 
  233         usb_proc_free(USB_BUS_GIANT_PROC(bus));
  234         usb_proc_free(USB_BUS_NON_GIANT_ISOC_PROC(bus));
  235         usb_proc_free(USB_BUS_NON_GIANT_BULK_PROC(bus));
  236 
  237         /* Get rid of USB explore process */
  238 
  239         usb_proc_free(USB_BUS_EXPLORE_PROC(bus));
  240 
  241         /* Get rid of control transfer process */
  242 
  243         usb_proc_free(USB_BUS_CONTROL_XFER_PROC(bus));
  244 #endif
  245 
  246 #if USB_HAVE_PF
  247         usbpf_detach(bus);
  248 #endif
  249         return (0);
  250 }
  251 
  252 /*------------------------------------------------------------------------*
  253  *      usb_suspend
  254  *------------------------------------------------------------------------*/
  255 static int
  256 usb_suspend(device_t dev)
  257 {
  258         struct usb_bus *bus = device_get_softc(dev);
  259 
  260         DPRINTF("\n");
  261 
  262         if (bus == NULL) {
  263                 /* was never setup properly */
  264                 return (0);
  265         }
  266 
  267         USB_BUS_LOCK(bus);
  268         usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
  269             &bus->suspend_msg[0], &bus->suspend_msg[1]);
  270         if (usb_no_suspend_wait == 0) {
  271                 /* wait for suspend callback to be executed */
  272                 usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
  273                     &bus->suspend_msg[0], &bus->suspend_msg[1]);
  274         }
  275         USB_BUS_UNLOCK(bus);
  276 
  277         return (0);
  278 }
  279 
  280 /*------------------------------------------------------------------------*
  281  *      usb_resume
  282  *------------------------------------------------------------------------*/
  283 static int
  284 usb_resume(device_t dev)
  285 {
  286         struct usb_bus *bus = device_get_softc(dev);
  287 
  288         DPRINTF("\n");
  289 
  290         if (bus == NULL) {
  291                 /* was never setup properly */
  292                 return (0);
  293         }
  294 
  295         USB_BUS_LOCK(bus);
  296         usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
  297             &bus->resume_msg[0], &bus->resume_msg[1]);
  298         USB_BUS_UNLOCK(bus);
  299 
  300         return (0);
  301 }
  302 
  303 /*------------------------------------------------------------------------*
  304  *      usb_bus_reset_async_locked
  305  *------------------------------------------------------------------------*/
  306 void
  307 usb_bus_reset_async_locked(struct usb_bus *bus)
  308 {
  309         USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
  310 
  311         DPRINTF("\n");
  312 
  313         if (bus->reset_msg[0].hdr.pm_qentry.tqe_prev != NULL ||
  314             bus->reset_msg[1].hdr.pm_qentry.tqe_prev != NULL) {
  315                 DPRINTF("Reset already pending\n");
  316                 return;
  317         }
  318 
  319         device_printf(bus->parent, "Resetting controller\n");
  320 
  321         usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
  322             &bus->reset_msg[0], &bus->reset_msg[1]);
  323 }
  324 
  325 /*------------------------------------------------------------------------*
  326  *      usb_shutdown
  327  *------------------------------------------------------------------------*/
  328 static int
  329 usb_shutdown(device_t dev)
  330 {
  331         struct usb_bus *bus = device_get_softc(dev);
  332 
  333         DPRINTF("\n");
  334 
  335         if (bus == NULL) {
  336                 /* was never setup properly */
  337                 return (0);
  338         }
  339 
  340         DPRINTF("%s: Controller shutdown\n", device_get_nameunit(bus->bdev));
  341 
  342         USB_BUS_LOCK(bus);
  343         usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
  344             &bus->shutdown_msg[0], &bus->shutdown_msg[1]);
  345         if (usb_no_shutdown_wait == 0) {
  346                 /* wait for shutdown callback to be executed */
  347                 usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
  348                     &bus->shutdown_msg[0], &bus->shutdown_msg[1]);
  349         }
  350         USB_BUS_UNLOCK(bus);
  351 
  352         DPRINTF("%s: Controller shutdown complete\n",
  353             device_get_nameunit(bus->bdev));
  354 
  355         return (0);
  356 }
  357 
  358 /*------------------------------------------------------------------------*
  359  *      usb_bus_explore
  360  *
  361  * This function is used to explore the device tree from the root.
  362  *------------------------------------------------------------------------*/
  363 static void
  364 usb_bus_explore(struct usb_proc_msg *pm)
  365 {
  366         struct usb_bus *bus;
  367         struct usb_device *udev;
  368 
  369         bus = ((struct usb_bus_msg *)pm)->bus;
  370         udev = bus->devices[USB_ROOT_HUB_ADDR];
  371 
  372         if (bus->no_explore != 0)
  373                 return;
  374 
  375         if (udev != NULL) {
  376                 USB_BUS_UNLOCK(bus);
  377                 uhub_explore_handle_re_enumerate(udev);
  378                 USB_BUS_LOCK(bus);
  379         }
  380 
  381         if (udev != NULL && udev->hub != NULL) {
  382                 if (bus->do_probe) {
  383                         bus->do_probe = 0;
  384                         bus->driver_added_refcount++;
  385                 }
  386                 if (bus->driver_added_refcount == 0) {
  387                         /* avoid zero, hence that is memory default */
  388                         bus->driver_added_refcount = 1;
  389                 }
  390 
  391 #ifdef DDB
  392                 /*
  393                  * The following three lines of code are only here to
  394                  * recover from DDB:
  395                  */
  396                 usb_proc_rewakeup(USB_BUS_CONTROL_XFER_PROC(bus));
  397                 usb_proc_rewakeup(USB_BUS_GIANT_PROC(bus));
  398                 usb_proc_rewakeup(USB_BUS_NON_GIANT_ISOC_PROC(bus));
  399                 usb_proc_rewakeup(USB_BUS_NON_GIANT_BULK_PROC(bus));
  400 #endif
  401 
  402                 USB_BUS_UNLOCK(bus);
  403 
  404 #if USB_HAVE_POWERD
  405                 /*
  406                  * First update the USB power state!
  407                  */
  408                 usb_bus_powerd(bus);
  409 #endif
  410                  /* Explore the Root USB HUB. */
  411                 (udev->hub->explore) (udev);
  412                 USB_BUS_LOCK(bus);
  413         }
  414 #if USB_HAVE_ROOT_MOUNT_HOLD
  415         usb_root_mount_rel(bus);
  416 #endif
  417 
  418         /* Nice the enumeration a bit, to avoid looping too fast. */
  419         usb_pause_mtx(&bus->bus_mtx, USB_MS_TO_TICKS(usb_enum_nice_time));
  420 }
  421 
  422 /*------------------------------------------------------------------------*
  423  *      usb_bus_detach
  424  *
  425  * This function is used to detach the device tree from the root.
  426  *------------------------------------------------------------------------*/
  427 static void
  428 usb_bus_detach(struct usb_proc_msg *pm)
  429 {
  430         struct usb_bus *bus;
  431         struct usb_device *udev;
  432         device_t dev;
  433 
  434         bus = ((struct usb_bus_msg *)pm)->bus;
  435         udev = bus->devices[USB_ROOT_HUB_ADDR];
  436         dev = bus->bdev;
  437         /* clear the softc */
  438         device_set_softc(dev, NULL);
  439         USB_BUS_UNLOCK(bus);
  440 
  441         /* detach children first */
  442         bus_topo_lock();
  443         bus_generic_detach(dev);
  444         bus_topo_unlock();
  445 
  446         /*
  447          * Free USB device and all subdevices, if any.
  448          */
  449         usb_free_device(udev, 0);
  450 
  451         USB_BUS_LOCK(bus);
  452         /* clear bdev variable last */
  453         bus->bdev = NULL;
  454 }
  455 
  456 /*------------------------------------------------------------------------*
  457  *      usb_bus_suspend
  458  *
  459  * This function is used to suspend the USB controller.
  460  *------------------------------------------------------------------------*/
  461 static void
  462 usb_bus_suspend(struct usb_proc_msg *pm)
  463 {
  464         struct usb_bus *bus;
  465         struct usb_device *udev;
  466         usb_error_t err;
  467         uint8_t do_unlock;
  468 
  469         DPRINTF("\n");
  470 
  471         bus = ((struct usb_bus_msg *)pm)->bus;
  472         udev = bus->devices[USB_ROOT_HUB_ADDR];
  473 
  474         if (udev == NULL || bus->bdev == NULL)
  475                 return;
  476 
  477         USB_BUS_UNLOCK(bus);
  478 
  479         /*
  480          * We use the shutdown event here because the suspend and
  481          * resume events are reserved for the USB port suspend and
  482          * resume. The USB system suspend is implemented like full
  483          * shutdown and all connected USB devices will be disconnected
  484          * subsequently. At resume all USB devices will be
  485          * re-connected again.
  486          */
  487 
  488         bus_generic_shutdown(bus->bdev);
  489 
  490         do_unlock = usbd_enum_lock(udev);
  491 
  492         err = usbd_set_config_index(udev, USB_UNCONFIG_INDEX);
  493         if (err)
  494                 device_printf(bus->bdev, "Could not unconfigure root HUB\n");
  495 
  496         USB_BUS_LOCK(bus);
  497         bus->hw_power_state = 0;
  498         bus->no_explore = 1;
  499         USB_BUS_UNLOCK(bus);
  500 
  501         if (bus->methods->set_hw_power != NULL)
  502                 (bus->methods->set_hw_power) (bus);
  503 
  504         if (bus->methods->set_hw_power_sleep != NULL)
  505                 (bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_SUSPEND);
  506 
  507         if (do_unlock)
  508                 usbd_enum_unlock(udev);
  509 
  510         USB_BUS_LOCK(bus);
  511 }
  512 
  513 /*------------------------------------------------------------------------*
  514  *      usb_bus_resume
  515  *
  516  * This function is used to resume the USB controller.
  517  *------------------------------------------------------------------------*/
  518 static void
  519 usb_bus_resume(struct usb_proc_msg *pm)
  520 {
  521         struct usb_bus *bus;
  522         struct usb_device *udev;
  523         usb_error_t err;
  524         uint8_t do_unlock;
  525 
  526         DPRINTF("\n");
  527 
  528         bus = ((struct usb_bus_msg *)pm)->bus;
  529         udev = bus->devices[USB_ROOT_HUB_ADDR];
  530 
  531         if (udev == NULL || bus->bdev == NULL)
  532                 return;
  533 
  534         USB_BUS_UNLOCK(bus);
  535 
  536         do_unlock = usbd_enum_lock(udev);
  537 #if 0
  538         DEVMETHOD(usb_take_controller, NULL);   /* dummy */
  539 #endif
  540         USB_TAKE_CONTROLLER(device_get_parent(bus->bdev));
  541 
  542         USB_BUS_LOCK(bus);
  543         bus->hw_power_state =
  544           USB_HW_POWER_CONTROL |
  545           USB_HW_POWER_BULK |
  546           USB_HW_POWER_INTERRUPT |
  547           USB_HW_POWER_ISOC |
  548           USB_HW_POWER_NON_ROOT_HUB;
  549         bus->no_explore = 0;
  550         USB_BUS_UNLOCK(bus);
  551 
  552         if (bus->methods->set_hw_power_sleep != NULL)
  553                 (bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_RESUME);
  554 
  555         if (bus->methods->set_hw_power != NULL)
  556                 (bus->methods->set_hw_power) (bus);
  557 
  558         /* restore USB configuration to index 0 */
  559         err = usbd_set_config_index(udev, 0);
  560         if (err)
  561                 device_printf(bus->bdev, "Could not configure root HUB\n");
  562 
  563         /* probe and attach */
  564         err = usb_probe_and_attach(udev, USB_IFACE_INDEX_ANY);
  565         if (err) {
  566                 device_printf(bus->bdev, "Could not probe and "
  567                     "attach root HUB\n");
  568         }
  569 
  570         if (do_unlock)
  571                 usbd_enum_unlock(udev);
  572 
  573         USB_BUS_LOCK(bus);
  574 }
  575 
  576 /*------------------------------------------------------------------------*
  577  *      usb_bus_reset
  578  *
  579  * This function is used to reset the USB controller.
  580  *------------------------------------------------------------------------*/
  581 static void
  582 usb_bus_reset(struct usb_proc_msg *pm)
  583 {
  584         struct usb_bus *bus;
  585 
  586         DPRINTF("\n");
  587 
  588         bus = ((struct usb_bus_msg *)pm)->bus;
  589 
  590         if (bus->bdev == NULL || bus->no_explore != 0)
  591                 return;
  592 
  593         /* a suspend and resume will reset the USB controller */
  594         usb_bus_suspend(pm);
  595         usb_bus_resume(pm);
  596 }
  597 
  598 /*------------------------------------------------------------------------*
  599  *      usb_bus_shutdown
  600  *
  601  * This function is used to shutdown the USB controller.
  602  *------------------------------------------------------------------------*/
  603 static void
  604 usb_bus_shutdown(struct usb_proc_msg *pm)
  605 {
  606         struct usb_bus *bus;
  607         struct usb_device *udev;
  608         usb_error_t err;
  609         uint8_t do_unlock;
  610 
  611         bus = ((struct usb_bus_msg *)pm)->bus;
  612         udev = bus->devices[USB_ROOT_HUB_ADDR];
  613 
  614         if (udev == NULL || bus->bdev == NULL)
  615                 return;
  616 
  617         USB_BUS_UNLOCK(bus);
  618 
  619         bus_generic_shutdown(bus->bdev);
  620 
  621         do_unlock = usbd_enum_lock(udev);
  622 
  623         err = usbd_set_config_index(udev, USB_UNCONFIG_INDEX);
  624         if (err)
  625                 device_printf(bus->bdev, "Could not unconfigure root HUB\n");
  626 
  627         USB_BUS_LOCK(bus);
  628         bus->hw_power_state = 0;
  629         bus->no_explore = 1;
  630         USB_BUS_UNLOCK(bus);
  631 
  632         if (bus->methods->set_hw_power != NULL)
  633                 (bus->methods->set_hw_power) (bus);
  634 
  635         if (bus->methods->set_hw_power_sleep != NULL)
  636                 (bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_SHUTDOWN);
  637 
  638         if (do_unlock)
  639                 usbd_enum_unlock(udev);
  640 
  641         USB_BUS_LOCK(bus);
  642 }
  643 
  644 /*------------------------------------------------------------------------*
  645  *      usb_bus_cleanup
  646  *
  647  * This function is used to cleanup leftover USB character devices.
  648  *------------------------------------------------------------------------*/
  649 #if USB_HAVE_UGEN
  650 static void
  651 usb_bus_cleanup(struct usb_proc_msg *pm)
  652 {
  653         struct usb_bus *bus;
  654         struct usb_fs_privdata *pd;
  655 
  656         bus = ((struct usb_bus_msg *)pm)->bus;
  657 
  658         while ((pd = LIST_FIRST(&bus->pd_cleanup_list)) != NULL) {
  659                 LIST_REMOVE(pd, pd_next);
  660                 USB_BUS_UNLOCK(bus);
  661 
  662                 usb_destroy_dev_sync(pd);
  663 
  664                 USB_BUS_LOCK(bus);
  665         }
  666 }
  667 #endif
  668 
  669 static void
  670 usb_power_wdog(void *arg)
  671 {
  672         struct usb_bus *bus = arg;
  673 
  674         USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
  675 
  676         usb_callout_reset(&bus->power_wdog,
  677             4 * hz, usb_power_wdog, arg);
  678 
  679 #ifdef DDB
  680         /*
  681          * The following line of code is only here to recover from
  682          * DDB:
  683          */
  684         usb_proc_rewakeup(USB_BUS_EXPLORE_PROC(bus));   /* recover from DDB */
  685 #endif
  686 
  687 #if USB_HAVE_POWERD
  688         USB_BUS_UNLOCK(bus);
  689 
  690         usb_bus_power_update(bus);
  691 
  692         USB_BUS_LOCK(bus);
  693 #endif
  694 }
  695 
  696 /*------------------------------------------------------------------------*
  697  *      usb_bus_attach
  698  *
  699  * This function attaches USB in context of the explore thread.
  700  *------------------------------------------------------------------------*/
  701 static void
  702 usb_bus_attach(struct usb_proc_msg *pm)
  703 {
  704         struct usb_bus *bus;
  705         struct usb_device *child;
  706         device_t dev;
  707         usb_error_t err;
  708         enum usb_dev_speed speed;
  709 
  710         bus = ((struct usb_bus_msg *)pm)->bus;
  711         dev = bus->bdev;
  712 
  713         DPRINTF("\n");
  714 
  715         switch (bus->usbrev) {
  716         case USB_REV_1_0:
  717                 speed = USB_SPEED_FULL;
  718                 device_printf(bus->bdev, "12Mbps Full Speed USB v1.0\n");
  719                 break;
  720 
  721         case USB_REV_1_1:
  722                 speed = USB_SPEED_FULL;
  723                 device_printf(bus->bdev, "12Mbps Full Speed USB v1.1\n");
  724                 break;
  725 
  726         case USB_REV_2_0:
  727                 speed = USB_SPEED_HIGH;
  728                 device_printf(bus->bdev, "480Mbps High Speed USB v2.0\n");
  729                 break;
  730 
  731         case USB_REV_2_5:
  732                 speed = USB_SPEED_VARIABLE;
  733                 device_printf(bus->bdev, "480Mbps Wireless USB v2.5\n");
  734                 break;
  735 
  736         case USB_REV_3_0:
  737                 speed = USB_SPEED_SUPER;
  738                 device_printf(bus->bdev, "5.0Gbps Super Speed USB v3.0\n");
  739                 break;
  740 
  741         default:
  742                 device_printf(bus->bdev, "Unsupported USB revision\n");
  743 #if USB_HAVE_ROOT_MOUNT_HOLD
  744                 usb_root_mount_rel(bus);
  745 #endif
  746                 return;
  747         }
  748 
  749         /* default power_mask value */
  750         bus->hw_power_state =
  751           USB_HW_POWER_CONTROL |
  752           USB_HW_POWER_BULK |
  753           USB_HW_POWER_INTERRUPT |
  754           USB_HW_POWER_ISOC |
  755           USB_HW_POWER_NON_ROOT_HUB;
  756 
  757         USB_BUS_UNLOCK(bus);
  758 
  759         /* make sure power is set at least once */
  760 
  761         if (bus->methods->set_hw_power != NULL) {
  762                 (bus->methods->set_hw_power) (bus);
  763         }
  764 
  765         /* allocate the Root USB device */
  766 
  767         child = usb_alloc_device(bus->bdev, bus, NULL, 0, 0, 1,
  768             speed, USB_MODE_HOST);
  769         if (child) {
  770                 err = usb_probe_and_attach(child,
  771                     USB_IFACE_INDEX_ANY);
  772                 if (!err) {
  773                         if ((bus->devices[USB_ROOT_HUB_ADDR] == NULL) ||
  774                             (bus->devices[USB_ROOT_HUB_ADDR]->hub == NULL)) {
  775                                 err = USB_ERR_NO_ROOT_HUB;
  776                         }
  777                 }
  778         } else {
  779                 err = USB_ERR_NOMEM;
  780         }
  781 
  782         USB_BUS_LOCK(bus);
  783 
  784         if (err) {
  785                 device_printf(bus->bdev, "Root HUB problem, error=%s\n",
  786                     usbd_errstr(err));
  787 #if USB_HAVE_ROOT_MOUNT_HOLD
  788                 usb_root_mount_rel(bus);
  789 #endif
  790         }
  791 
  792         /* set softc - we are ready */
  793         device_set_softc(dev, bus);
  794 
  795         /* start watchdog */
  796         usb_power_wdog(bus);
  797 }
  798 
  799 /*------------------------------------------------------------------------*
  800  *      usb_attach_sub
  801  *
  802  * This function creates a thread which runs the USB attach code.
  803  *------------------------------------------------------------------------*/
  804 static void
  805 usb_attach_sub(device_t dev, struct usb_bus *bus)
  806 {
  807         bus_topo_lock();
  808         if (usb_devclass_ptr == NULL)
  809                 usb_devclass_ptr = devclass_find("usbus");
  810         bus_topo_unlock();
  811 
  812 #if USB_HAVE_PF
  813         usbpf_attach(bus);
  814 #endif
  815         /* Initialise USB process messages */
  816         bus->explore_msg[0].hdr.pm_callback = &usb_bus_explore;
  817         bus->explore_msg[0].bus = bus;
  818         bus->explore_msg[1].hdr.pm_callback = &usb_bus_explore;
  819         bus->explore_msg[1].bus = bus;
  820 
  821         bus->detach_msg[0].hdr.pm_callback = &usb_bus_detach;
  822         bus->detach_msg[0].bus = bus;
  823         bus->detach_msg[1].hdr.pm_callback = &usb_bus_detach;
  824         bus->detach_msg[1].bus = bus;
  825 
  826         bus->attach_msg[0].hdr.pm_callback = &usb_bus_attach;
  827         bus->attach_msg[0].bus = bus;
  828         bus->attach_msg[1].hdr.pm_callback = &usb_bus_attach;
  829         bus->attach_msg[1].bus = bus;
  830 
  831         bus->suspend_msg[0].hdr.pm_callback = &usb_bus_suspend;
  832         bus->suspend_msg[0].bus = bus;
  833         bus->suspend_msg[1].hdr.pm_callback = &usb_bus_suspend;
  834         bus->suspend_msg[1].bus = bus;
  835 
  836         bus->resume_msg[0].hdr.pm_callback = &usb_bus_resume;
  837         bus->resume_msg[0].bus = bus;
  838         bus->resume_msg[1].hdr.pm_callback = &usb_bus_resume;
  839         bus->resume_msg[1].bus = bus;
  840 
  841         bus->reset_msg[0].hdr.pm_callback = &usb_bus_reset;
  842         bus->reset_msg[0].bus = bus;
  843         bus->reset_msg[1].hdr.pm_callback = &usb_bus_reset;
  844         bus->reset_msg[1].bus = bus;
  845 
  846         bus->shutdown_msg[0].hdr.pm_callback = &usb_bus_shutdown;
  847         bus->shutdown_msg[0].bus = bus;
  848         bus->shutdown_msg[1].hdr.pm_callback = &usb_bus_shutdown;
  849         bus->shutdown_msg[1].bus = bus;
  850 
  851 #if USB_HAVE_UGEN
  852         LIST_INIT(&bus->pd_cleanup_list);
  853         bus->cleanup_msg[0].hdr.pm_callback = &usb_bus_cleanup;
  854         bus->cleanup_msg[0].bus = bus;
  855         bus->cleanup_msg[1].hdr.pm_callback = &usb_bus_cleanup;
  856         bus->cleanup_msg[1].bus = bus;
  857 #endif
  858 
  859 #if USB_HAVE_PER_BUS_PROCESS
  860         /* Create USB explore and callback processes */
  861 
  862         if (usb_proc_create(USB_BUS_GIANT_PROC(bus),
  863             &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
  864                 device_printf(dev, "WARNING: Creation of USB Giant "
  865                     "callback process failed.\n");
  866         } else if (usb_proc_create(USB_BUS_NON_GIANT_ISOC_PROC(bus),
  867             &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_HIGHEST)) {
  868                 device_printf(dev, "WARNING: Creation of USB non-Giant ISOC "
  869                     "callback process failed.\n");
  870         } else if (usb_proc_create(USB_BUS_NON_GIANT_BULK_PROC(bus),
  871             &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_HIGH)) {
  872                 device_printf(dev, "WARNING: Creation of USB non-Giant BULK "
  873                     "callback process failed.\n");
  874         } else if (usb_proc_create(USB_BUS_EXPLORE_PROC(bus),
  875             &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
  876                 device_printf(dev, "WARNING: Creation of USB explore "
  877                     "process failed.\n");
  878         } else if (usb_proc_create(USB_BUS_CONTROL_XFER_PROC(bus),
  879             &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
  880                 device_printf(dev, "WARNING: Creation of USB control transfer "
  881                     "process failed.\n");
  882         } else
  883 #endif
  884         {
  885                 /* Get final attach going */
  886                 USB_BUS_LOCK(bus);
  887                 usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
  888                     &bus->attach_msg[0], &bus->attach_msg[1]);
  889                 USB_BUS_UNLOCK(bus);
  890 
  891                 /* Do initial explore */
  892                 usb_needs_explore(bus, 1);
  893         }
  894 }
  895 SYSUNINIT(usb_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb_bus_unload, NULL);
  896 
  897 /*------------------------------------------------------------------------*
  898  *      usb_bus_mem_flush_all_cb
  899  *------------------------------------------------------------------------*/
  900 #if USB_HAVE_BUSDMA
  901 static void
  902 usb_bus_mem_flush_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
  903     struct usb_page *pg, usb_size_t size, usb_size_t align)
  904 {
  905         usb_pc_cpu_flush(pc);
  906 }
  907 #endif
  908 
  909 /*------------------------------------------------------------------------*
  910  *      usb_bus_mem_flush_all - factored out code
  911  *------------------------------------------------------------------------*/
  912 #if USB_HAVE_BUSDMA
  913 void
  914 usb_bus_mem_flush_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
  915 {
  916         if (cb) {
  917                 cb(bus, &usb_bus_mem_flush_all_cb);
  918         }
  919 }
  920 #endif
  921 
  922 /*------------------------------------------------------------------------*
  923  *      usb_bus_mem_alloc_all_cb
  924  *------------------------------------------------------------------------*/
  925 #if USB_HAVE_BUSDMA
  926 static void
  927 usb_bus_mem_alloc_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
  928     struct usb_page *pg, usb_size_t size, usb_size_t align)
  929 {
  930         /* need to initialize the page cache */
  931         pc->tag_parent = bus->dma_parent_tag;
  932 
  933         if (usb_pc_alloc_mem(pc, pg, size, align)) {
  934                 bus->alloc_failed = 1;
  935         }
  936 }
  937 #endif
  938 
  939 /*------------------------------------------------------------------------*
  940  *      usb_bus_mem_alloc_all - factored out code
  941  *
  942  * Returns:
  943  *    0: Success
  944  * Else: Failure
  945  *------------------------------------------------------------------------*/
  946 uint8_t
  947 usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat,
  948     usb_bus_mem_cb_t *cb)
  949 {
  950         bus->alloc_failed = 0;
  951 
  952         mtx_init(&bus->bus_mtx, device_get_nameunit(bus->parent),
  953             "usb_def_mtx", MTX_DEF | MTX_RECURSE);
  954 
  955         mtx_init(&bus->bus_spin_lock, device_get_nameunit(bus->parent),
  956             "usb_spin_mtx", MTX_SPIN | MTX_RECURSE);
  957 
  958         usb_callout_init_mtx(&bus->power_wdog,
  959             &bus->bus_mtx, 0);
  960 
  961         TAILQ_INIT(&bus->intr_q.head);
  962 
  963 #if USB_HAVE_BUSDMA
  964         usb_dma_tag_setup(bus->dma_parent_tag, bus->dma_tags,
  965             dmat, &bus->bus_mtx, NULL, bus->dma_bits, USB_BUS_DMA_TAG_MAX);
  966 #endif
  967         if ((bus->devices_max > USB_MAX_DEVICES) ||
  968             (bus->devices_max < USB_MIN_DEVICES) ||
  969             (bus->devices == NULL)) {
  970                 DPRINTFN(0, "Devices field has not been "
  971                     "initialised properly\n");
  972                 bus->alloc_failed = 1;          /* failure */
  973         }
  974 #if USB_HAVE_BUSDMA
  975         if (cb) {
  976                 cb(bus, &usb_bus_mem_alloc_all_cb);
  977         }
  978 #endif
  979         if (bus->alloc_failed) {
  980                 usb_bus_mem_free_all(bus, cb);
  981         }
  982         return (bus->alloc_failed);
  983 }
  984 
  985 /*------------------------------------------------------------------------*
  986  *      usb_bus_mem_free_all_cb
  987  *------------------------------------------------------------------------*/
  988 #if USB_HAVE_BUSDMA
  989 static void
  990 usb_bus_mem_free_all_cb(struct usb_bus *bus, struct usb_page_cache *pc,
  991     struct usb_page *pg, usb_size_t size, usb_size_t align)
  992 {
  993         usb_pc_free_mem(pc);
  994 }
  995 #endif
  996 
  997 /*------------------------------------------------------------------------*
  998  *      usb_bus_mem_free_all - factored out code
  999  *------------------------------------------------------------------------*/
 1000 void
 1001 usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
 1002 {
 1003 #if USB_HAVE_BUSDMA
 1004         if (cb) {
 1005                 cb(bus, &usb_bus_mem_free_all_cb);
 1006         }
 1007         usb_dma_tag_unsetup(bus->dma_parent_tag);
 1008 #endif
 1009 
 1010         mtx_destroy(&bus->bus_mtx);
 1011         mtx_destroy(&bus->bus_spin_lock);
 1012 }
 1013 
 1014 /* convenience wrappers */
 1015 void
 1016 usb_proc_explore_mwait(struct usb_device *udev, void *pm1, void *pm2)
 1017 {
 1018         usb_proc_mwait(USB_BUS_EXPLORE_PROC(udev->bus), pm1, pm2);
 1019 }
 1020 
 1021 void    *
 1022 usb_proc_explore_msignal(struct usb_device *udev, void *pm1, void *pm2)
 1023 {
 1024         return (usb_proc_msignal(USB_BUS_EXPLORE_PROC(udev->bus), pm1, pm2));
 1025 }
 1026 
 1027 void
 1028 usb_proc_explore_lock(struct usb_device *udev)
 1029 {
 1030         USB_BUS_LOCK(udev->bus);
 1031 }
 1032 
 1033 void
 1034 usb_proc_explore_unlock(struct usb_device *udev)
 1035 {
 1036         USB_BUS_UNLOCK(udev->bus);
 1037 }

Cache object: 112a164072ecccadc1e771aac719fda7


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