hrev45574 adds 4 changesets to branch 'master' old head: e94d7e41e8c0b8d16ec43276f9630551b6d06c95 new head: c4dbefe0b4597740fcae84fc088e4d4159a59b13 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=c4dbefe+%5Ee94d7e4 ---------------------------------------------------------------------------- 827c722: Implement debounce sequence according to USB 2.0 specs. This replaces waiting a fixed time of 300ms for the device power to stabilize. In the ideal case this reduces the boot time by 200ms per connected device (including internal hubs). This is very similar to what Linux implements and we use the same time values. An interval of 25ms is used to check for connection state changes, the stable time is at least 100ms as per the USB specs and the whole process times out after 1.5 seconds. 22af753: Reduce port reset recovery time from 250ms to 50ms. The specs say the reset recovery time is 10ms only. The extra 40ms are taken from the Linux hub driver. d057026: Poll more frequently for the first explore. This reduces needless waiting for the special case of the polled and synchronous first explore. c4dbefe: Fix build with tracing turned on. [ Michael Lotz <mmlr@xxxxxxxx> ] ---------------------------------------------------------------------------- 5 files changed, 52 insertions(+), 6 deletions(-) src/add-ons/kernel/bus_managers/usb/Hub.cpp | 44 +++++++++++++++++++- src/add-ons/kernel/bus_managers/usb/Stack.cpp | 2 +- .../kernel/bus_managers/usb/usb_private.h | 2 + .../kernel/bus_managers/usb/usbspec_private.h | 7 +++- src/add-ons/kernel/busses/usb/ehci.cpp | 3 +- ############################################################################ Commit: 827c7224a0aa44530aa8dfe11ec12c0e58bcb054 URL: http://cgit.haiku-os.org/haiku/commit/?id=827c722 Author: Michael Lotz <mmlr@xxxxxxxx> Date: Sun Apr 28 01:19:20 2013 UTC Implement debounce sequence according to USB 2.0 specs. This replaces waiting a fixed time of 300ms for the device power to stabilize. In the ideal case this reduces the boot time by 200ms per connected device (including internal hubs). This is very similar to what Linux implements and we use the same time values. An interval of 25ms is used to check for connection state changes, the stable time is at least 100ms as per the USB specs and the whole process times out after 1.5 seconds. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp index 271efaf..38f01a9 100644 --- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp @@ -221,8 +221,13 @@ Hub::Explore(change_item **changeList) int32 retry = 2; while (retry--) { - // wait some time for the device to power up - snooze(USB_DELAY_DEVICE_POWER_UP); + // wait for stable device power + result = _DebouncePort(i); + if (result != B_OK) { + TRACE_ERROR("debouncing port %" B_PRId32 + " failed: %s\n", i, strerror(result)); + break; + } // reset the port, this will also enable it result = ResetPort(i); @@ -433,3 +438,38 @@ Hub::BuildDeviceName(char *string, uint32 *index, size_t bufferSize, return B_OK; } + + +status_t +Hub::_DebouncePort(uint8 index) +{ + uint32 timeout = 0; + uint32 stableTime = 0; + while (timeout < USB_DEBOUNCE_TIMEOUT) { + snooze(USB_DEBOUNCE_CHECK_INTERVAL); + timeout += USB_DEBOUNCE_CHECK_INTERVAL; + + status_t result = UpdatePortStatus(index); + if (result != B_OK) + return result; + + if ((fPortStatus[index].change & PORT_STATUS_CONNECTION) == 0) { + stableTime += USB_DEBOUNCE_CHECK_INTERVAL; + if (stableTime >= USB_DEBOUNCE_STABLE_TIME) + return B_OK; + continue; + } + + // clear the connection change and reset stable time + result = DefaultPipe()->SendRequest(USB_REQTYPE_CLASS + | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, + C_PORT_CONNECTION, index + 1, 0, NULL, 0, NULL); + if (result != B_OK) + return result; + + TRACE("got connection change during debounce, resetting stable time\n"); + stableTime = 0; + } + + return B_TIMED_OUT; +} diff --git a/src/add-ons/kernel/bus_managers/usb/usb_private.h b/src/add-ons/kernel/bus_managers/usb/usb_private.h index be8b321..4f0ffc6 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_private.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_private.h @@ -610,6 +610,8 @@ virtual status_t BuildDeviceName(char *string, Device *device); private: + status_t _DebouncePort(uint8 index); + InterruptPipe * fInterruptPipe; usb_hub_descriptor fHubDescriptor; diff --git a/src/add-ons/kernel/bus_managers/usb/usbspec_private.h b/src/add-ons/kernel/bus_managers/usb/usbspec_private.h index 2103994..bd8fbc6 100644 --- a/src/add-ons/kernel/bus_managers/usb/usbspec_private.h +++ b/src/add-ons/kernel/bus_managers/usb/usbspec_private.h @@ -19,7 +19,6 @@ #define USB_MAX_PORT_COUNT 16 #define USB_DELAY_BUS_RESET 100000 -#define USB_DELAY_DEVICE_POWER_UP 300000 #define USB_DELAY_HUB_POWER_UP 200000 #define USB_DELAY_PORT_RESET 50000 #define USB_DELAY_PORT_RESET_RECOVERY 250000 @@ -28,6 +27,10 @@ #define USB_DELAY_SET_CONFIGURATION 50000 #define USB_DELAY_HUB_EXPLORE 1000000 +#define USB_DEBOUNCE_TIMEOUT 1500000 +#define USB_DEBOUNCE_CHECK_INTERVAL 25000 +#define USB_DEBOUNCE_STABLE_TIME 100000 + // For bandwidth calculation #define USB_BW_HOST_DELAY 1000 #define USB_BW_SETUP_LOW_SPEED_PORT_DELAY 333 ############################################################################ Commit: 22af7532d1671c0ce1794b6413673fc5f886c953 URL: http://cgit.haiku-os.org/haiku/commit/?id=22af753 Author: Michael Lotz <mmlr@xxxxxxxx> Date: Sun Apr 28 01:29:20 2013 UTC Reduce port reset recovery time from 250ms to 50ms. The specs say the reset recovery time is 10ms only. The extra 40ms are taken from the Linux hub driver. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/bus_managers/usb/usbspec_private.h b/src/add-ons/kernel/bus_managers/usb/usbspec_private.h index bd8fbc6..8d6f1c4 100644 --- a/src/add-ons/kernel/bus_managers/usb/usbspec_private.h +++ b/src/add-ons/kernel/bus_managers/usb/usbspec_private.h @@ -21,7 +21,7 @@ #define USB_DELAY_BUS_RESET 100000 #define USB_DELAY_HUB_POWER_UP 200000 #define USB_DELAY_PORT_RESET 50000 -#define USB_DELAY_PORT_RESET_RECOVERY 250000 +#define USB_DELAY_PORT_RESET_RECOVERY 50000 #define USB_DELAY_SET_ADDRESS_RETRY 200000 #define USB_DELAY_SET_ADDRESS 10000 #define USB_DELAY_SET_CONFIGURATION 50000 ############################################################################ Commit: d057026dc4ff0dd5985b4683ce430f47c504e4f0 URL: http://cgit.haiku-os.org/haiku/commit/?id=d057026 Author: Michael Lotz <mmlr@xxxxxxxx> Date: Sun Apr 28 01:30:41 2013 UTC Poll more frequently for the first explore. This reduces needless waiting for the special case of the polled and synchronous first explore. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp b/src/add-ons/kernel/bus_managers/usb/Stack.cpp index 6c81516..fbad834 100644 --- a/src/add-ons/kernel/bus_managers/usb/Stack.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Stack.cpp @@ -97,7 +97,7 @@ Stack::Stack() // is opening the module does not get rescanned while or before installing // its hooks. while (!fFirstExploreDone) - snooze(100000); + snooze(10000); } ############################################################################ Revision: hrev45574 Commit: c4dbefe0b4597740fcae84fc088e4d4159a59b13 URL: http://cgit.haiku-os.org/haiku/commit/?id=c4dbefe Author: Michael Lotz <mmlr@xxxxxxxx> Date: Sun Apr 28 01:32:53 2013 UTC Fix build with tracing turned on. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp b/src/add-ons/kernel/busses/usb/ehci.cpp index 1a93c63..0d7c2a8 100644 --- a/src/add-ons/kernel/busses/usb/ehci.cpp +++ b/src/add-ons/kernel/busses/usb/ehci.cpp @@ -802,7 +802,8 @@ EHCI::SubmitIsochronous(Transfer *transfer) uint16 pg = 0; itd->buffer_phy[pg] = currentPhy & 0xfffff000; uint32 offset = currentPhy & 0xfff; - TRACE("isochronous created itd, filling it with phy %lx\n", currentPhy); + TRACE("isochronous created itd, filling it with phy %" B_PRIxPHYSADDR + "\n", currentPhy); for (int32 i = 0; i < 8 && dataLength > 0; i++) { size_t length = min_c(dataLength, packetSize); itd->token[i] = (EHCI_ITD_STATUS_ACTIVE << EHCI_ITD_STATUS_SHIFT)