From: Greg Kroah-Hartman Date: Wed, 13 Mar 2013 18:29:25 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.8.3~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f123a3afc9cf1b978ca2a56a243beaa53d8b3d05;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: usb-fix-connected-device-switch-to-inactive-state.patch --- diff --git a/queue-3.4/series b/queue-3.4/series index 59b43987f48..659c480dbec 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -37,3 +37,4 @@ usb-don-t-use-ehci-port-sempahore-for-usb-3.0-hubs.patch usb-prepare-for-refactoring-by-adding-extra-udev-checks.patch usb-rip-out-recursive-call-on-warm-port-reset.patch revert-alsa-hda-hdmi-make-jacks-phantom-if-they-re-not-detectable.patch +usb-fix-connected-device-switch-to-inactive-state.patch diff --git a/queue-3.4/usb-fix-connected-device-switch-to-inactive-state.patch b/queue-3.4/usb-fix-connected-device-switch-to-inactive-state.patch new file mode 100644 index 00000000000..4a71b3e8580 --- /dev/null +++ b/queue-3.4/usb-fix-connected-device-switch-to-inactive-state.patch @@ -0,0 +1,91 @@ +From sarah.a.sharp@linux.intel.com Wed Mar 13 11:27:06 2013 +From: Sarah Sharp +Date: Wed, 13 Mar 2013 10:59:21 -0700 +Subject: USB: Fix connected device switch to Inactive state. +To: Greg KH +Cc: stable@vger.kernel.org, sarah.a.sharp@linux.intel.com +Message-ID: <20130313175801.GA5604@xanatos> + +From: Sarah Sharp + +[This is upstream commit d3b9d7a9051d7024a93c76a84b2f84b3b66ad6d5. +It needs to be backported to kernels as old as 3.2, because it fixes the +buggy commit 9dbcaec830cd97f44a0b91b315844e0d7144746b "USB: Handle warm +reset failure on empty port."] + +A USB 3.0 device can transition to the Inactive state if a U1 or U2 exit +transition fails. The current code in hub_events simply issues a warm +reset, but does not call any pre-reset or post-reset driver methods (or +unbind/rebind drivers without them). Therefore the drivers won't know +their device has just been reset. + +hub_events should instead call usb_reset_device. This means +hub_port_reset now needs to figure out whether it should issue a warm +reset or a hot reset. + +Remove the FIXME note about needing disconnect() for a NOTATTACHED +device. This patch fixes that. + +Signed-off-by: Sarah Sharp +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 30 +++++++++++++++++++++++++----- + 1 file changed, 25 insertions(+), 5 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -2274,7 +2274,6 @@ static void hub_port_finish_reset(struct + case -ENODEV: + clear_port_feature(hub->hdev, + port1, USB_PORT_FEAT_C_RESET); +- /* FIXME need disconnect() for NOTATTACHED device */ + if (hub_is_superspeed(hub->hdev)) { + clear_port_feature(hub->hdev, port1, + USB_PORT_FEAT_C_BH_PORT_RESET); +@@ -2308,6 +2307,18 @@ static int hub_port_reset(struct usb_hub + * Some companion controllers don't like it when they mix. + */ + down_read(&ehci_cf_port_reset_rwsem); ++ } else if (!warm) { ++ /* ++ * If the caller hasn't explicitly requested a warm reset, ++ * double check and see if one is needed. ++ */ ++ status = hub_port_status(hub, port1, ++ &portstatus, &portchange); ++ if (status < 0) ++ goto done; ++ ++ if (hub_port_warm_reset_required(hub, portstatus)) ++ warm = true; + } + + /* Reset the port */ +@@ -3866,12 +3877,21 @@ static void hub_events(void) + */ + if (hub_port_warm_reset_required(hub, portstatus)) { + int status; ++ struct usb_device *udev = ++ hub->hdev->children[i - 1]; + + dev_dbg(hub_dev, "warm reset port %d\n", i); +- status = hub_port_reset(hub, i, NULL, +- HUB_BH_RESET_TIME, true); +- if (status < 0) +- hub_port_disable(hub, i, 1); ++ if (!udev) { ++ status = hub_port_reset(hub, i, ++ NULL, HUB_BH_RESET_TIME, ++ true); ++ if (status < 0) ++ hub_port_disable(hub, i, 1); ++ } else { ++ usb_lock_device(udev); ++ status = usb_reset_device(udev); ++ usb_unlock_device(udev); ++ } + connect_change = 0; + } +