aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
authorPaul Bolle <pebolle@tiscali.nl>2011-03-11 18:03:52 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2011-03-11 14:18:52 -0800
commit752d57a8b7b97423bffa3452638aa0fd3c3bb9d1 (patch)
treee4589fb70401448c0f0393b2fdafe8f4d6923fd6 /drivers/usb/core/hub.c
parent0dfeefbc93e38c3a9bd6d4e579cc5a76d3f13dc2 (diff)
USB: Only treat lasting over-current conditions as errors
On a laptop I see these errors on (most) resumes: hub 3-0:1.0: over-current change on port 1 hub 3-0:1.0: over-current change on port 2 Since over-current conditions can disappear quite quickly it's better to downgrade that message to debug level, recheck for an over-current condition a little later and only print and over-current condition error if that condition (still) exists when it's rechecked. Add similar logic to hub over-current changes. (That code is untested, as those changes do not occur on this laptop.) Signed-off-by: Paul Bolle <pebolle@tiscali.nl> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 395754edd06..b574f9131b4 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3408,12 +3408,19 @@ static void hub_events(void)
}
if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
- dev_err (hub_dev,
- "over-current change on port %d\n",
- i);
+ u16 status = 0;
+ u16 unused;
+
+ dev_dbg(hub_dev, "over-current change on port "
+ "%d\n", i);
clear_port_feature(hdev, i,
USB_PORT_FEAT_C_OVER_CURRENT);
+ msleep(100); /* Cool down */
hub_power_on(hub, true);
+ hub_port_status(hub, i, &status, &unused);
+ if (status & USB_PORT_STAT_OVERCURRENT)
+ dev_err(hub_dev, "over-current "
+ "condition on port %d\n", i);
}
if (portchange & USB_PORT_STAT_C_RESET) {
@@ -3445,10 +3452,17 @@ static void hub_events(void)
hub->limited_power = 0;
}
if (hubchange & HUB_CHANGE_OVERCURRENT) {
- dev_dbg (hub_dev, "overcurrent change\n");
- msleep(500); /* Cool down */
+ u16 status = 0;
+ u16 unused;
+
+ dev_dbg(hub_dev, "over-current change\n");
clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
+ msleep(500); /* Cool down */
hub_power_on(hub, true);
+ hub_hub_status(hub, &status, &unused);
+ if (status & HUB_STATUS_OVERCURRENT)
+ dev_err(hub_dev, "over-current "
+ "condition\n");
}
}