aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2010-12-06 18:08:20 -0500
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2011-03-13 21:07:12 -0400
commitc70615740996823580bb8fb58461347b7ffaad9a (patch)
tree2fe76d3f9331c9561a6526732ea364c40fe307f4 /drivers/usb/core
parentdbe79bbe9dcb22cb3651c46f18943477141ca452 (diff)
USB: Clear "warm" port reset change.
In USB 3.0, there are two types of resets: a "hot" port reset and a "warm" port reset. The hot port reset is always tried first, and involves sending the reset signaling for a shorter amount of time. But sometimes devices don't respond to the hot reset, and a "Bigger Hammer" is needed. External hubs and roothubs will automatically try a warm reset when the hot reset fails, and they will set a status change bit to indicate when there is a "BH reset" change. Make sure the USB core clears that port status change bit, or we'll get lots of status change notifications on the interrupt endpoint of the USB 3.0 hub. (Side note: you may be confused why the USB 3.0 spec calls the same type of reset "warm reset" in some places and "BH reset" in other places. "BH" reset is supposed to stand for "Big Hammer" reset, but it also stands for "Brad Hosler". Brad died shortly after the USB 3.0 bus specification was started, and they decided to name the reset after him. The suggestion was made shortly before the spec was finalized, so the wording is a bit inconsistent.) Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/hub.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index feb6e596c7c9..0eb27006f846 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3476,6 +3476,14 @@ static void hub_events(void)
3476 clear_port_feature(hdev, i, 3476 clear_port_feature(hdev, i,
3477 USB_PORT_FEAT_C_RESET); 3477 USB_PORT_FEAT_C_RESET);
3478 } 3478 }
3479 if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
3480 hub_is_superspeed(hub->hdev)) {
3481 dev_dbg(hub_dev,
3482 "warm reset change on port %d\n",
3483 i);
3484 clear_port_feature(hdev, i,
3485 USB_PORT_FEAT_C_BH_PORT_RESET);
3486 }
3479 if (portchange & USB_PORT_STAT_C_LINK_STATE) { 3487 if (portchange & USB_PORT_STAT_C_LINK_STATE) {
3480 clear_port_feature(hub->hdev, i, 3488 clear_port_feature(hub->hdev, i,
3481 USB_PORT_FEAT_C_PORT_LINK_STATE); 3489 USB_PORT_FEAT_C_PORT_LINK_STATE);