Commit 4913d930 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

[PATCH] USB: Genuine changes to hub_port_debounce()

This patch includes the algorithmic changes I would like to see in
hub_port_debounce().  They are:

	Increase the total timeout period from 400 ms to 1500 ms.

	Check the port's connect-changed status during the polling
	loop.

	Return as soon as the connection has been stable for the
	required time, even if it has been stably _dis_-connected.
	(The current code waits for the full timeout period if there
	isn't a connection.)

In previous emails I have responded to all the concerns raised by others
about these changes, and I can't imagine how they could cause any trouble.

	Increasing the total timeout won't affect people with properly
	functioning hardware.  Their connections will quickly stabilize
	and the routine will return just as before.  People with flaky
	hardware that takes a long time to settle down will now be able
	to use their devices.

	Checking the connect-changed status during the polling loop will
	make the test more conservative.  The code will be able to
	detect transient disconnections that it would have missed
	before, and it won't return until the connection really _is_
	stable.  Furthermore, this makes the test compliant with the
	USB specification, which requires the stability timer to be
	restarted whenever a connection change occurs.

	Returning early for disconnections is a simple optimization.
	It's more important now that the total timeout length is 1.5
	seconds rather than 0.4 seconds.

I urge you to apply this patch and for people to try it out.  If there do
turn out to be problems... the patch is very small, well-contained, and
easy to revert.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent f4692b3e
...@@ -1197,13 +1197,13 @@ static int hub_port_disable(struct usb_device *hdev, int port) ...@@ -1197,13 +1197,13 @@ static int hub_port_disable(struct usb_device *hdev, int port)
* low-speed devices for which this debounce period may last over a second. * low-speed devices for which this debounce period may last over a second.
* Not covered by the spec - but easy to deal with. * Not covered by the spec - but easy to deal with.
* *
* This implementation uses a 400ms total debounce timeout; if the * This implementation uses a 1500ms total debounce timeout; if the
* connection isn't stable by then it returns -ETIMEDOUT. It checks * connection isn't stable by then it returns -ETIMEDOUT. It checks
* every 25ms for transient disconnects. When the port status has been * every 25ms for transient disconnects. When the port status has been
* unchanged for 100ms it returns the port status. * unchanged for 100ms it returns the port status.
*/ */
#define HUB_DEBOUNCE_TIMEOUT 400 /* 1500 */ #define HUB_DEBOUNCE_TIMEOUT 1500
#define HUB_DEBOUNCE_STEP 25 #define HUB_DEBOUNCE_STEP 25
#define HUB_DEBOUNCE_STABLE 100 #define HUB_DEBOUNCE_STABLE 100
...@@ -1219,10 +1219,10 @@ static int hub_port_debounce(struct usb_device *hdev, int port) ...@@ -1219,10 +1219,10 @@ static int hub_port_debounce(struct usb_device *hdev, int port)
if (ret < 0) if (ret < 0)
return ret; return ret;
if ( /* !(portchange & USB_PORT_STAT_C_CONNECTION) && */ if (!(portchange & USB_PORT_STAT_C_CONNECTION) &&
(portstatus & USB_PORT_STAT_CONNECTION) == connection) { (portstatus & USB_PORT_STAT_CONNECTION) == connection) {
stable_time += HUB_DEBOUNCE_STEP; stable_time += HUB_DEBOUNCE_STEP;
if (stable_time >= HUB_DEBOUNCE_STABLE && connection /* */) if (stable_time >= HUB_DEBOUNCE_STABLE)
break; break;
} else { } else {
stable_time = 0; stable_time = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment