35#ifdef USB_GLOBAL_INCLUDE_FILE
36#include USB_GLOBAL_INCLUDE_FILE
38#include <sys/stdint.h>
39#include <sys/stddef.h>
44#include <sys/kernel.h>
46#include <sys/module.h>
49#include <sys/condvar.h>
51#include <sys/sysctl.h>
53#include <sys/unistd.h>
54#include <sys/callout.h>
55#include <sys/malloc.h>
62#define USB_DEBUG_VAR uhub_debug
82static int uhub_debug = 0;
84static SYSCTL_NODE(_hw_usb, OID_AUTO, uhub, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
91static int usb_power_timeout = 30;
93SYSCTL_INT(_hw_usb, OID_AUTO, power_timeout, CTLFLAG_RWTUN,
94 &usb_power_timeout, 0,
"USB power timeout");
97#if USB_HAVE_DISABLE_ENUM
98static int usb_disable_enumeration = 0;
99SYSCTL_INT(_hw_usb, OID_AUTO, disable_enumeration, CTLFLAG_RWTUN,
100 &usb_disable_enumeration, 0,
"Set to disable all USB device enumeration. "
101 "This can secure against USB devices turning evil, "
102 "for example a USB memory stick becoming a USB keyboard.");
104static int usb_disable_port_power = 0;
105SYSCTL_INT(_hw_usb, OID_AUTO, disable_port_power, CTLFLAG_RWTUN,
106 &usb_disable_port_power, 0,
"Set to disable all USB port power.");
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)
124#if USB_HAVE_TT_SUPPORT
138 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
143#if USB_HAVE_TT_SUPPORT
144 [UHUB_RESET_TT_TRANSFER] = {
149 .callback = &uhub_reset_tt_callback,
228#if USB_HAVE_TT_SUPPORT
260#if USB_HAVE_TT_SUPPORT
271 if (child == NULL || ep == NULL)
274 udev =
child->parent_hs_hub;
275 port =
child->hs_port_no;
286 (port == 0) || (ep->
edesc == NULL)) {
293 up = hub->
ports + port - 1;
300 if (up->req_reset_tt.bRequest != 0) {
304 req.wIndex[0] = port;
309 ((
child->address & 0x7F) << 4) |
316 req.wIndex[0] = port;
320 up->req_reset_tt =
req;
323 &hub->tt_msg[0], &hub->tt_msg[1]);
327#if USB_HAVE_TT_SUPPORT
347 for (x = 0; x != udev->
hub->
nports; x++) {
350 if (up->req_reset_tt.bRequest == 0)
355 sizeof(up->req_reset_tt));
357 memset(&up->req_reset_tt, 0,
sizeof(up->req_reset_tt));
404 for (x = 0; x != hub->
nports; x++) {
409 child->speed == speed)
427 switch (
child->re_enumerate_wait) {
432 DPRINTF(
"Unconfigure failed: %s: Ignored.\n",
435 if (
child->parent_hub == NULL) {
437 DPRINTFN(6,
"cannot reset root HUB\n");
462 DPRINTFN(0,
"Could not unconfigure "
463 "device (ignored)\n");
465 if (
child->parent_hub == NULL) {
467 DPRINTFN(6,
"cannot set port feature\n");
474 DPRINTFN(0,
"Could not disable port "
483 child->next_config_index);
485 DPRINTF(
"Configure failed: %s: Ignored.\n",
566 DPRINTFN(4,
"port %d, HUB looks dead, too many errors\n", portno);
573 sc->
sc_udev, NULL, &ps, portno);
587 DPRINTFN(4,
"port %d, wPortStatus=0x%04x, "
588 "wPortChange=0x%04x, err=%s\n",
612 DPRINTF(
"reattaching port %d\n", portno);
644#if USB_HAVE_DISABLE_ENUM
646 if (usb_disable_enumeration != 0 ||
647 sc->sc_disable_enumeration != 0) {
648 DPRINTF(
"Enumeration is disabled!\n");
659 switch (udev->
speed) {
676 DPRINTF(
"WARNING: strange, connected port %d "
677 "has no power\n", portno);
683 DPRINTF(
"Port %d is in Host Mode\n", portno);
692 "suspended, clearing.\n", portno);
709 DPRINTFN(0,
"port %d reset "
710 "failed, error=%s\n",
725 DPRINTFN(1,
"giving up port %d reset - "
726 "device vanished: change %#x status %#x\n",
735 DPRINTF(
"Port %d is in Device Mode\n", portno);
741 switch (udev->
speed) {
787 portno, 128 - (2 * udev->
depth));
789 DPRINTFN(0,
"port %d U1 timeout "
790 "failed, error=%s\n",
794 portno, 128 - (2 * udev->
depth));
796 DPRINTFN(0,
"port %d U2 timeout "
797 "failed, error=%s\n",
817 udev->
depth + 1, portno - 1, portno,
speed, mode);
819 DPRINTFN(0,
"could not allocate new device\n");
840 DPRINTFN(0,
"device problem (%s), "
858 switch (udev->
speed) {
900 DPRINTF(
"clearing suspend failed.\n");
907 DPRINTF(
"reading port status failed.\n");
933 DPRINTF(
"suspended=%u\n", is_suspend);
970 switch (udev->
speed) {
1009 DPRINTFN(11,
"udev=%p addr=%d\n", udev, udev->
address);
1018 DPRINTF(
"Device is suspended!\n");
1034 for (x = 0; x != hub->
nports; x++) {
1035 up = hub->
ports + x;
1043 DPRINTF(
"Overcurrent on port %u.\n", portno);
1068 DPRINTFN(0,
"illegal enable change, "
1069 "port %d\n", portno);
1073 DPRINTFN(0,
"port error, giving up "
1074 "port %d\n", portno);
1123 return (BUS_PROBE_DEFAULT);
1144 switch (udev->
speed) {
1151 DPRINTFN(0,
"getting USB 2.0 HUB descriptor failed,"
1166 DPRINTFN(0,
"Getting USB 3.0 HUB descriptor failed,"
1180 if (pnports != NULL)
1199#if USB_HAVE_DISABLE_ENUM
1200 struct sysctl_ctx_list *sysctl_ctx;
1201 struct sysctl_oid *sysctl_tree;
1208 uint8_t iface_index;
1214 mtx_init(&sc->
sc_mtx,
"USB HUB mutex", NULL, MTX_DEF);
1218 DPRINTFN(2,
"depth=%d selfpowered=%d, parent=%p, "
1219 "parent->selfpowered=%d\n",
1227 DPRINTFN(0,
"HUB at depth %d, "
1228 "exceeds maximum. HUB ignored\n", (
int)udev->
depth);
1234 DPRINTFN(0,
"Bus powered HUB connected to "
1235 "bus powered HUB. HUB ignored\n");
1242 device_printf(
dev,
"MTT could not be enabled\n");
1245 device_printf(
dev,
"MTT enabled\n");
1250 DPRINTFN(2,
"Getting HUB descriptor\n");
1252 switch (udev->
speed) {
1259 DPRINTFN(0,
"getting USB 2.0 HUB descriptor failed,"
1274 DPRINTFN(0,
"Invalid number of USB 2.0 ports,"
1282 DPRINTFN(0,
"Getting USB 2.0 HUB descriptor failed,"
1287 DPRINTFN(0,
"Number of ports changed\n");
1297 DPRINTFN(0,
"Setting USB 3.0 HUB depth failed,"
1304 DPRINTFN(0,
"Getting USB 3.0 HUB descriptor failed,"
1318 if (nports > ((udev->
parent_hub != NULL) ? 15 : 127)) {
1319 DPRINTFN(0,
"Invalid number of USB 3.0 ports,"
1327 DPRINTFN(0,
"Getting USB 2.0 HUB descriptor failed,"
1332 DPRINTFN(0,
"Number of ports changed\n");
1338 DPRINTF(
"Assuming HUB has only one port\n");
1346 DPRINTFN(0,
"portless HUB\n");
1350 DPRINTF(
"Port limit exceeded\n");
1353#if (USB_HAVE_FIXED_PORT == 0)
1354 hub = malloc(
sizeof(hub[0]) + (
sizeof(hub->
ports[0]) * nports),
1355 M_USBDEV, M_WAITOK | M_ZERO);
1369#if USB_HAVE_TT_SUPPORT
1370 hub->tt_msg[0].hdr.pm_callback = &uhub_reset_tt_proc;
1371 hub->tt_msg[0].udev = udev;
1372 hub->tt_msg[1].hdr.pm_callback = &uhub_reset_tt_proc;
1373 hub->tt_msg[1].udev = udev;
1393 DPRINTFN(0,
"cannot setup interrupt transfer, "
1400#if USB_HAVE_DISABLE_ENUM
1403 sysctl_ctx = device_get_sysctl_ctx(
dev);
1404 sysctl_tree = device_get_sysctl_tree(
dev);
1406 if (sysctl_ctx != NULL && sysctl_tree != NULL) {
1407 (void) SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
1408 OID_AUTO,
"disable_enumeration", CTLFLAG_RWTUN,
1409 &sc->sc_disable_enumeration, 0,
1410 "Set to disable enumeration on this USB HUB.");
1412 (void) SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
1413 OID_AUTO,
"disable_port_power", CTLFLAG_RWTUN,
1414 &sc->sc_disable_port_power, 0,
1415 "Set to disable USB port power on this USB HUB.");
1447 for (x = 0; x != nports; x++) {
1456 switch (udev->
speed) {
1468 DPRINTF(
"Assuming removable port\n");
1473#if USB_HAVE_DISABLE_ENUM
1475 if (usb_disable_port_power != 0 ||
1476 sc->sc_disable_port_power != 0) {
1478 DPRINTFN(2,
"Turning port %d power off\n", portno);
1484 DPRINTFN(2,
"Turning port %d power on\n", portno);
1487#if USB_HAVE_DISABLE_ENUM
1492 DPRINTFN(0,
"port %d power on or off failed, %s\n",
1495 DPRINTF(
"turn on port %d power\n",
1502 device_printf(
dev,
"%d port%s with %d "
1503 "removable, %s powered\n", nports, (nports != 1) ?
"s" :
"",
1521#if (USB_HAVE_FIXED_PORT == 0)
1522 free(udev->
hub, M_USBDEV);
1526 mtx_destroy(&sc->
sc_mtx);
1554 if (
child == NULL) {
1564#if USB_HAVE_TT_SUPPORT
1568 &
hub->tt_msg[0], &
hub->tt_msg[1]);
1572#if (USB_HAVE_FIXED_PORT == 0)
1573 free(
hub, M_USBDEV);
1577 mtx_destroy(&sc->
sc_mtx);
1615 for (x = 0; x != nports; x++) {
1644 if (!device_is_attached(parent))
1647 sc = device_get_softc(parent);
1653 DPRINTF(
"device not on hub\n");
1656 sbuf_printf(sb,
"bus=%u hubaddr=%u port=%u devaddr=%u"
1666 , res.
udev->ugen_name
1684 if (strcmp(locator, BUS_LOCATOR_UEFI) == 0) {
1685 rv = bus_generic_get_device_path(device_get_parent(
bus),
bus, locator, sb);
1689 sc = device_get_softc(
bus);
1695 printf(
"device not on hub\n");
1705 return (bus_generic_get_device_path(
bus,
child, locator, sb));
1717 if (!device_is_attached(parent))
1720 sc = device_get_softc(parent);
1726 DPRINTF(
"device not on hub\n");
1730 if (iface && iface->
idesc) {
1734 sbuf_printf(sb,
"vendor=0x%04x product=0x%04x "
1735 "devclass=0x%02x devsubclass=0x%02x "
1740 "intclass=0x%02x intsubclass=0x%02x "
1741 "intprotocol=0x%02x" "%s%s",
1803 uint8_t end, uint8_t mask)
1815 for (x =
start; x < end; x++) {
1819 for (z = x; z < end; z++) {
1820 if (mask & (1U << (z - x)))
1831 if (mask & (1U << (end - 1 - x)))
1851 uint8_t slot, uint8_t mask)
1880 for (x =
slot; x < 8; x++) {
1881 if (mask & (1U << (x -
slot))) {
1883 bus->uframe_usage[x] +=
len;
1892 for (x =
slot; x < 8; x++) {
1893 if (mask & (1U << (x -
slot))) {
1894 bus->uframe_usage[x] +=
len;
1978 DPRINTFN(11,
"slot=%d, mask=0x%02x\n",
2015 DPRINTFN(11,
"slot=%d, mask=0x%02x\n",
2047 if (isoc_time_curr < rem) {
2069#if USB_HAVE_TT_SUPPORT
2071usbd_fs_isoc_schedule_alloc_slot(
struct usb_xfer *isoc_xfer, uint16_t isoc_time)
2087 TAILQ_FOREACH(xfer, &
bus->intr_q.head, wait_entry) {
2090 if (xfer == isoc_xfer)
2111 if (delta > 0 && delta <= xfer->nframes) {
2112 delta = xfer->
nframes - delta;
2130 if (pipe_xfer == isoc_xfer)
2136 if (delta > 0 && delta <= pipe_xfer->nframes) {
2137 delta = pipe_xfer->
nframes - delta;
2162 if (delta > 0 && delta <= isoc_xfer->nframes) {
2163 delta = isoc_xfer->
nframes - delta;
2195 if ((
bus == NULL) || (up == NULL)) {
2311 DPRINTFN(0,
"no devclass\n");
2317 max = devclass_get_maxunit(dc);
2319 dev = devclass_get_device(dc, max);
2321 bus = device_get_softc(
dev);
2346 DPRINTFN(-1,
"Cold variable is still set!\n");
2383 uint8_t needs_explore;
2384 uint8_t needs_hw_power;
2422 DPRINTF(
"Adding type %u to power state\n", xfer_type);
2435 if (needs_explore) {
2438 }
else if (needs_hw_power) {
2483 limit = usb_power_timeout;
2486 else if (limit > 255)
2514 }
else if ((temp >= limit) &&
2565 DPRINTF(
"Recomputing power masks\n");
2575 if (type_refs[4] != 0)
2664 DPRINTF(
"remote wakeup is not set!\n");
2687 DPRINTFN(0,
"Resuming port failed: %s (ignored)\n",
2694 if (
bus->methods->device_resume != NULL) {
2696 (
bus->methods->device_resume) (udev);
2717 if (
bus->methods->set_hw_power != NULL) {
2719 (
bus->methods->set_hw_power) (
bus);
2734 DPRINTFN(0,
"Clearing device "
2735 "remote wakeup failed: %s\n",
2771 if (udev->
hub != NULL) {
2775 for (x = 0; x != nports; x++) {
2782 if (
child->flags.self_suspended)
2785 DPRINTFN(1,
"Port %u is busy on the HUB!\n", x + 1);
2799 DPRINTFN(0,
"Setting device "
2800 "remote wakeup failed\n");
2825 DPRINTFN(0,
"Setting device "
2826 "remote wakeup failed\n");
2844 DPRINTF(
"Suspend was cancelled!\n");
2872 DPRINTFN(0,
"Suspending port failed\n");
2880 DPRINTFN(0,
"Suspending port failed\n");
2933 return (power_mode);
static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "USB DWC OTG")
SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, phy_type, CTLFLAG_RDTUN, &dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2/3 - ULPI/HSIC/INTERNAL/UTMI+")
struct usb_xfer * sc_xfer[UHUB_N_TRANSFER]
struct usb_device * sc_udev
struct uhub_current_state sc_st
uint8_t sc_usb_port_errors
enum usb_hc_mode usb_mode
struct usbd_lookup_info info
struct usb_device * device
void(* get_power_mode)(struct usb_device *udev, int8_t *pmode)
void(* device_suspend)(struct usb_device *)
void(* set_hw_power)(struct usb_bus *)
uint8_t driver_added_refcount
usb_power_mask_t hw_power_state
const struct usb_bus_methods * methods
struct usb_device ** devices
struct usb_bus_msg explore_msg[2]
enum usb_hc_mode usb_mode
struct usb_device * parent_hs_hub
struct usb_power_save pwr_save
struct usb_device_descriptor ddesc
uint8_t curr_config_index
struct usb_device * parent_hub
uint8_t next_config_index
uint8_t re_enumerate_wait
uint8_t driver_added_refcount
struct usb_device_flags flags
struct usb_xfer_queue endpoint_q[USB_MAX_EP_STREAMS]
const struct usb_pipe_methods * methods
struct usb_endpoint_descriptor * edesc
uWord wHubCharacteristics
usb_error_t(* explore)(struct usb_device *hub)
usb_size_t uframe_usage[USB_HS_MICRO_FRAMES_MAX]
struct usb_device * hubudev
struct usb_interface_descriptor * idesc
usb_ticks_t last_xfer_time
enum usb_hc_mode usb_mode
usb_frlength_t * frlengths
struct usb_page_cache * frbuffers
struct usb_endpoint * endpoint
struct usb_xfer_flags_int flags_int
struct usb_xfer_root * xroot
uint16_t isoc_time_complete
#define USB_INTERFACE_FUNC_SUSPEND_RW
#define UT_WRITE_INTERFACE
#define USB_INTERFACE_FUNC_SUSPEND
#define UPS_PORT_POWER_SS
#define UT_WRITE_CLASS_OTHER
#define UPS_C_PORT_ENABLED
#define UPS_C_OVERCURRENT_INDICATOR
#define UR_CLEAR_TT_BUFFER
#define UHF_C_PORT_SUSPEND
#define USB_POWER_DOWN_TIME
#define UPS_PORT_LS_SS_INA
#define UF_DEVICE_REMOTE_WAKEUP
#define USB_UNCONFIG_INDEX
#define USB_ROOT_HUB_ADDR
#define UHF_C_PORT_OVER_CURRENT
#define USB_POWER_MODE_SAVE
#define UPS_PORT_MODE_DEVICE
#define USB_SS_HUB_DEPTH_MAX
#define USB_INTERFACE_FUNC_SUSPEND_LP
#define UPS_C_PORT_LINK_STATE
#define USB_IFACE_INDEX_ANY
#define UPS_PORT_LINK_STATE_GET(x)
#define USB_HS_MICRO_FRAMES_MAX
#define USB_ISOC_TIME_MAX
#define USB_POWER_MODE_ON
#define USB_POWER_MODE_OFF
#define UHD_NOT_REMOV(desc, i)
#define USB_FS_BYTES_PER_HS_UFRAME
#define UHF_C_PORT_LINK_STATE
#define UPS_C_CONNECT_STATUS
#define UPS_CURRENT_CONNECT_STATUS
#define UHF_C_PORT_ENABLE
#define UHF_C_PORT_CONNECTION
#define USB_BUS_TT_PROC(bus)
void usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len)
#define USB_HW_POWER_BULK
#define USB_HW_POWER_NON_ROOT_HUB
#define USB_HW_POWER_CONTROL
#define USB_HW_POWER_ISOC
#define USB_HW_POWER_INTERRUPT
#define USB_GET_DATA_ISREAD(xfer)
#define USB_BUS_UNLOCK(_b)
#define USB_BUS_LOCK_ASSERT(_b, _t)
#define usb_port_resume_delay
#define usb_extra_power_up_time
#define usb_port_powerup_delay
usb_error_t usbd_set_alt_interface_index(struct usb_device *udev, uint8_t iface_index, uint8_t alt_index)
uint8_t usbd_enum_lock(struct usb_device *udev)
usb_error_t usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index)
const char * usb_get_serial(struct usb_device *udev)
void usbd_sr_lock(struct usb_device *udev)
enum usb_dev_speed usbd_get_speed(struct usb_device *udev)
usb_error_t usbd_set_config_index(struct usb_device *udev, uint8_t index)
void usb_free_device(struct usb_device *udev, uint8_t flag)
void usbd_sr_unlock(struct usb_device *udev)
uint8_t usb_peer_can_wakeup(struct usb_device *udev)
usb_error_t usb_suspend_resume(struct usb_device *udev, uint8_t do_suspend)
void usbd_enum_unlock(struct usb_device *udev)
uint8_t usbd_ctrl_lock(struct usb_device *udev)
void usb_set_device_strings(struct usb_device *udev)
void usbd_ctrl_unlock(struct usb_device *udev)
struct usb_device * usb_alloc_device(device_t parent_dev, struct usb_bus *bus, struct usb_device *parent_hub, uint8_t depth, uint8_t port_index, uint8_t port_no, enum usb_dev_speed speed, enum usb_hc_mode mode)
void usb_get_langid(struct usb_device *udev)
struct usb_interface * usbd_get_iface(struct usb_device *udev, uint8_t iface_index)
#define USB_RE_ENUM_START
#define USB_RE_ENUM_SET_CONFIG
#define USB_RE_ENUM_PWR_OFF
devclass_t usb_devclass_ptr
const char * usbd_errstr(usb_error_t err)
uint16_t usb_power_mask_t
#define USB_HUB_MAX_DEPTH
#define USB_FS_ISOC_UFRAME_MAX
SYSINIT(usb_needs_explore_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_SECOND, usb_needs_explore_init, NULL)
static bus_child_pnpinfo_t uhub_child_pnpinfo
void usbd_set_power_mode(struct usb_device *udev, uint8_t power_mode)
static void usb_dev_suspend_peer(struct usb_device *udev)
int uhub_get_device_path(device_t bus, device_t child, const char *locator, struct sbuf *sb)
static const struct usb_config uhub_config[UHUB_N_TRANSFER]
DRIVER_MODULE(uhub, usbus, uhub_driver, uhub_devclass, 0, 0)
static usb_error_t uhub_reattach_port(struct uhub_softc *sc, uint8_t portno)
int uhub_attach(device_t dev)
uint8_t uhub_count_active_host_ports(struct usb_device *udev, enum usb_dev_speed speed)
static usb_callback_t uhub_intr_callback
void uhub_root_intr(struct usb_bus *bus, const uint8_t *ptr, uint8_t len)
static void usb_dev_resume_peer(struct usb_device *udev)
static usb_error_t uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up)
static device_suspend_t uhub_suspend
int uhub_child_location(device_t parent, device_t child, struct sbuf *sb)
static device_resume_t uhub_resume
void uhub_find_iface_index(struct usb_hub *hub, device_t child, struct hub_result *res)
static uint8_t usb_device_20_compatible(struct usb_device *udev)
static device_method_t uhub_methods[]
usb_error_t usbd_start_set_config(struct usb_device *udev, uint8_t index)
static uint8_t usb_hs_bandwidth_adjust(struct usb_device *udev, int16_t len, uint8_t slot, uint8_t mask)
static void usb_needs_explore_init(void *arg)
void usb_needs_explore(struct usb_bus *bus, uint8_t do_probe)
void usb_hs_bandwidth_alloc(struct usb_xfer *xfer)
uint8_t usbd_filter_power_mode(struct usb_device *udev, uint8_t power_mode)
void usb_needs_explore_all(void)
void uhub_explore_handle_re_enumerate(struct usb_device *child)
static uint8_t usb_peer_should_wakeup(struct usb_device *udev)
void usb_hs_bandwidth_free(struct usb_xfer *xfer)
static usb_error_t uhub_read_port_status(struct uhub_softc *sc, uint8_t portno)
static usb_error_t uhub_explore(struct usb_device *udev)
usb_error_t uhub_query_info(struct usb_device *udev, uint8_t *pnports, uint8_t *ptt)
static usb_error_t uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno)
static devclass_t uhub_devclass
static uint8_t uhub_is_too_deep(struct usb_device *udev)
static usb_error_t usbd_device_30_remote_wakeup(struct usb_device *udev, uint8_t bRequest)
int uhub_probe(device_t dev)
static bus_driver_added_t uhub_driver_added
static uint8_t usb_intr_find_best_slot(usb_size_t *ptr, uint8_t start, uint8_t end, uint8_t mask)
void usbd_start_re_enumerate(struct usb_device *udev)
void usb_bus_port_set_device(struct usb_bus *bus, struct usb_port *up, struct usb_device *udev, uint8_t device_index)
#define UHUB_IS_MULTI_TT(sc)
uint16_t usb_isoc_time_expand(struct usb_bus *bus, uint16_t isoc_time_curr)
int uhub_detach(device_t dev)
static usb_error_t usbd_set_dev_wakeup(struct usb_device *udev)
struct usb_device * usb_bus_port_get_device(struct usb_bus *bus, struct usb_port *up)
static usb_error_t usbd_clear_dev_wakeup(struct usb_device *udev)
void usb_bus_powerd(struct usb_bus *bus)
void usb_bus_power_update(struct usb_bus *bus)
#define UHUB_USB_PORT_ERRORS_MAX
#define UHUB_INTR_INTERVAL
#define UHUB_FLAG_DID_EXPLORE
void usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
void * usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
usb_error_t usbd_req_set_hub_u2_timeout(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint8_t timeout)
usb_error_t usbd_req_get_hub_descriptor(struct usb_device *udev, struct mtx *mtx, struct usb_hub_descriptor *hd, uint8_t nports)
usb_error_t usbd_req_get_ss_hub_descriptor(struct usb_device *udev, struct mtx *mtx, struct usb_hub_ss_descriptor *hd, uint8_t nports)
usb_error_t usbd_req_set_port_link_state(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint8_t link_state)
usb_error_t usbd_req_set_device_feature(struct usb_device *udev, struct mtx *mtx, uint16_t sel)
usb_error_t usbd_req_set_hub_u1_timeout(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint8_t timeout)
usb_error_t usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
usb_error_t usbd_req_re_enumerate(struct usb_device *udev, struct mtx *mtx)
usb_error_t usbd_req_set_hub_depth(struct usb_device *udev, struct mtx *mtx, uint16_t depth)
usb_error_t usbd_req_clear_port_feature(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint16_t sel)
usb_error_t usbd_req_warm_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
usb_error_t usbd_req_clear_device_feature(struct usb_device *udev, struct mtx *mtx, uint16_t sel)
usb_error_t usbd_req_set_port_feature(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint16_t sel)
usb_error_t usbd_req_get_port_status(struct usb_device *udev, struct mtx *mtx, struct usb_port_status *ps, uint8_t port)
void usbd_transfer_submit(struct usb_xfer *xfer)
void usbd_transfer_unsetup(struct usb_xfer **pxfer, uint16_t n_setup)
void usbd_xfer_set_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex, usb_frlength_t len)
void usbd_ctrl_transfer_setup(struct usb_device *udev)
uint8_t usbd_xfer_get_fps_shift(struct usb_xfer *xfer)
usb_error_t usbd_transfer_setup(struct usb_device *udev, const uint8_t *ifaces, struct usb_xfer **ppxfer, const struct usb_config *setup_start, uint16_t n_setup, void *priv_sc, struct mtx *xfer_mtx)
void usbd_transfer_start(struct usb_xfer *xfer)
usb_timeout_t usbd_get_dma_delay(struct usb_device *udev)
void * usbd_xfer_softc(struct usb_xfer *xfer)
void usbd_xfer_set_stall(struct usb_xfer *xfer)
usb_frlength_t usbd_xfer_max_len(struct usb_xfer *xfer)
void usbd_transfer_power_ref(struct usb_xfer *xfer, int val)
void device_set_usb_desc(device_t dev)
void usb_pause_mtx(struct mtx *mtx, int timo)
#define USB_MTX_UNLOCK(_m)
@ USB_ERR_NORMAL_COMPLETION
@ USB_ERR_PENDING_REQUESTS
#define USB_ST_TRANSFERRED
#define USB_MS_TO_TICKS(ms)
void() usb_callback_t(struct usb_xfer *, usb_error_t)
#define USB_GET_STATE(xfer)
#define usbd_do_request(u, m, r, d)