diff options
author | hselasky <hselasky@FreeBSD.org> | 2011-06-06 21:45:09 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2011-06-06 21:45:09 +0000 |
commit | 5f55faed0601b0486b09dd7ec3727f5312e33d5d (patch) | |
tree | 0b32799a28515b5c61e32d9d9a2ae9fedbba5065 /sys/dev/usb/usb_hub.c | |
parent | c8e197a2037e17686f997232419f8b02d1e61ffc (diff) | |
download | FreeBSD-src-5f55faed0601b0486b09dd7ec3727f5312e33d5d.zip FreeBSD-src-5f55faed0601b0486b09dd7ec3727f5312e33d5d.tar.gz |
Improve enumeration of Low- and Full-speed devices connected through a
High-speed USB HUB by resetting the transaction translator (TT)
before trying re-enumeration. Also when clear-stall fails multiple times
try a re-enumeration.
Suggested by: Trevor Blackwell
MFC after: 14 days
Diffstat (limited to 'sys/dev/usb/usb_hub.c')
-rw-r--r-- | sys/dev/usb/usb_hub.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index ce8a4a5..351b134 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -242,9 +242,14 @@ uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up) if (child->flags.usb_mode == USB_MODE_HOST) { usbd_enum_lock(child); if (child->re_enumerate_wait) { - err = usbd_set_config_index(child, USB_UNCONFIG_INDEX); - if (err == 0) - err = usbd_req_re_enumerate(child, NULL); + err = usbd_set_config_index(child, + USB_UNCONFIG_INDEX); + if (err != 0) { + DPRINTF("Unconfigure failed: " + "%s: Ignored.\n", + usbd_errstr(err)); + } + err = usbd_req_re_enumerate(child, NULL); if (err == 0) err = usbd_set_config_index(child, 0); if (err == 0) { @@ -2471,3 +2476,19 @@ usbd_filter_power_mode(struct usb_device *udev, uint8_t power_mode) /* use fixed power mode given by hardware driver */ return (temp); } + +/*------------------------------------------------------------------------* + * usbd_start_re_enumerate + * + * This function starts re-enumeration of the given USB device. This + * function does not need to be called BUS-locked. This function does + * not wait until the re-enumeration is completed. + *------------------------------------------------------------------------*/ +void +usbd_start_re_enumerate(struct usb_device *udev) +{ + if (udev->re_enumerate_wait == 0) { + udev->re_enumerate_wait = 1; + usb_needs_explore(udev->bus, 0); + } +} |