Skip to content
Commit e583d9db authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

USB: global suspend and remote wakeup don't mix



The hub driver was recently changed to use "global" suspend for system
suspend transitions on non-SuperSpeed buses.  This means that we don't
suspend devices individually by setting the suspend feature on the
upstream hub port; instead devices all go into suspend automatically
when the root hub stops transmitting packets.  The idea was to save
time and to avoid certain kinds of wakeup races.

Now it turns out that many hubs are buggy; they don't relay wakeup
requests from a downstream port to their upstream port if the
downstream port's suspend feature is not set (depending on the speed
of the downstream port, whether or not the hub is enabled for remote
wakeup, and possibly other factors).

We can't have hubs dropping wakeup requests.  Therefore this patch
goes partway back to the old policy: It sets the suspend feature for a
port if the device attached to that port or any of its descendants is
enabled for wakeup.  People will still be able to benefit from the
time savings if they don't care about wakeup and leave it disabled on
all their devices.

In order to accomplish this, the patch adds a new field to the usb_hub
structure: wakeup_enabled_descendants is a count of how many devices
below a suspended hub are enabled for remote wakeup.  A corresponding
new subroutine determines the number of wakeup-enabled devices at or
below an arbitrary suspended USB device.

This should be applied to the 3.10 stable kernel.

Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Reported-and-tested-by: default avatarToralf Förster <toralf.foerster@gmx.de>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 36ff66db
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