提交 948fea37 编写于 作者: A Alan Stern 提交者: Greg Kroah-Hartman

USB: optimize port debouncing during hub activation

This patch (as1082) makes a small optimization to the way the hub
driver carries out port debouncing immediately after a hub is
activated (i.e., initialized, reset, or resumed).  If any port-change
statuses are observed, the code will delay for a minimal debounce
period -- thereby making a good start at debouncing all the ports at
once.

If this wasn't sufficient then khubd will debounce any port that still
requires attention.  But in most cases it should suffice; it's rare
for a device to need more than a minimal debounce delay.  (In the
cases of hub initialization or reset even that is most likely not
needed, since any devices plugged in at such times have probably been
attached for a while.)
Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 8808f00c
...@@ -130,6 +130,10 @@ MODULE_PARM_DESC(use_both_schemes, ...@@ -130,6 +130,10 @@ MODULE_PARM_DESC(use_both_schemes,
DECLARE_RWSEM(ehci_cf_port_reset_rwsem); DECLARE_RWSEM(ehci_cf_port_reset_rwsem);
EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
#define HUB_DEBOUNCE_TIMEOUT 1500
#define HUB_DEBOUNCE_STEP 25
#define HUB_DEBOUNCE_STABLE 100
static inline char *portspeed(int portstatus) static inline char *portspeed(int portstatus)
{ {
...@@ -643,6 +647,7 @@ static void hub_restart(struct usb_hub *hub, enum hub_activation_type type) ...@@ -643,6 +647,7 @@ static void hub_restart(struct usb_hub *hub, enum hub_activation_type type)
{ {
struct usb_device *hdev = hub->hdev; struct usb_device *hdev = hub->hdev;
int port1; int port1;
bool need_debounce_delay = false;
/* Check each port and set hub->change_bits to let khubd know /* Check each port and set hub->change_bits to let khubd know
* which ports need attention. * which ports need attention.
...@@ -673,6 +678,18 @@ static void hub_restart(struct usb_hub *hub, enum hub_activation_type type) ...@@ -673,6 +678,18 @@ static void hub_restart(struct usb_hub *hub, enum hub_activation_type type)
portstatus &= ~USB_PORT_STAT_ENABLE; portstatus &= ~USB_PORT_STAT_ENABLE;
} }
/* Clear status-change flags; we'll debounce later */
if (portchange & USB_PORT_STAT_C_CONNECTION) {
need_debounce_delay = true;
clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_CONNECTION);
}
if (portchange & USB_PORT_STAT_C_ENABLE) {
need_debounce_delay = true;
clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_ENABLE);
}
if (!udev || udev->state == USB_STATE_NOTATTACHED) { if (!udev || udev->state == USB_STATE_NOTATTACHED) {
/* Tell khubd to disconnect the device or /* Tell khubd to disconnect the device or
* check for a new connection * check for a new connection
...@@ -702,6 +719,16 @@ static void hub_restart(struct usb_hub *hub, enum hub_activation_type type) ...@@ -702,6 +719,16 @@ static void hub_restart(struct usb_hub *hub, enum hub_activation_type type)
} }
} }
/* If no port-status-change flags were set, we don't need any
* debouncing. If flags were set we can try to debounce the
* ports all at once right now, instead of letting khubd do them
* one at a time later on.
*
* If any port-status changes do occur during this delay, khubd
* will see them later and handle them normally.
*/
if (need_debounce_delay)
msleep(HUB_DEBOUNCE_STABLE);
hub_activate(hub); hub_activate(hub);
} }
...@@ -2211,11 +2238,6 @@ static inline int remote_wakeup(struct usb_device *udev) ...@@ -2211,11 +2238,6 @@ static inline int remote_wakeup(struct usb_device *udev)
* 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 1500
#define HUB_DEBOUNCE_STEP 25
#define HUB_DEBOUNCE_STABLE 100
static int hub_port_debounce(struct usb_hub *hub, int port1) static int hub_port_debounce(struct usb_hub *hub, int port1)
{ {
int ret; int ret;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册