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.
This commit is contained in:
parent
e94d7e41e8
commit
827c7224a0
@ -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;
|
||||
}
|
||||
|
@ -610,6 +610,8 @@ virtual status_t BuildDeviceName(char *string,
|
||||
Device *device);
|
||||
|
||||
private:
|
||||
status_t _DebouncePort(uint8 index);
|
||||
|
||||
InterruptPipe * fInterruptPipe;
|
||||
usb_hub_descriptor fHubDescriptor;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user