Commit 4489a571 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

[PATCH] USB: usbcore: always turn on hub port power

Some hubs claim not to support port-power switching, and right now the
hub driver believes them and does not enable power to their ports.
However it turns out that even though they don't actually switch power,
they do ignore all events on a port until told to turn on the power!
This problem has been reported by several users.

This revised patch (as672b) makes the hub driver always try to turn on
port power to all hubs, regardless of what the hub descriptor says.  It
also adds a comment explaining the need for this.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9effa978
...@@ -432,15 +432,22 @@ static void hub_power_on(struct usb_hub *hub) ...@@ -432,15 +432,22 @@ static void hub_power_on(struct usb_hub *hub)
{ {
int port1; int port1;
unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); u16 wHubCharacteristics =
le16_to_cpu(hub->descriptor->wHubCharacteristics);
/* if hub supports power switching, enable power on each port */ /* Enable power on each port. Some hubs have reserved values
if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) { * of LPSM (> 2) in their descriptors, even though they are
* USB 2.0 hubs. Some hubs do not implement port-power switching
* but only emulate it. In all cases, the ports won't work
* unless we send these messages to the hub.
*/
if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2)
dev_dbg(hub->intfdev, "enabling power on all ports\n"); dev_dbg(hub->intfdev, "enabling power on all ports\n");
else
dev_dbg(hub->intfdev, "trying to enable port power on "
"non-switchable hub\n");
for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++)
set_port_feature(hub->hdev, port1, set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER);
USB_PORT_FEAT_POWER);
}
/* Wait at least 100 msec for power to become stable */ /* Wait at least 100 msec for power to become stable */
msleep(max(pgood_delay, (unsigned) 100)); msleep(max(pgood_delay, (unsigned) 100));
......
Markdown is supported
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