diff options
-rw-r--r-- | drivers/usb/core/hub.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 90b8d43c6b33..1b1846e6473b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -432,15 +432,22 @@ static void hub_power_on(struct usb_hub *hub) | |||
432 | { | 432 | { |
433 | int port1; | 433 | int port1; |
434 | unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; | 434 | unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; |
435 | u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); | 435 | u16 wHubCharacteristics = |
436 | 436 | le16_to_cpu(hub->descriptor->wHubCharacteristics); | |
437 | /* if hub supports power switching, enable power on each port */ | 437 | |
438 | if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) { | 438 | /* Enable power on each port. Some hubs have reserved values |
439 | * of LPSM (> 2) in their descriptors, even though they are | ||
440 | * USB 2.0 hubs. Some hubs do not implement port-power switching | ||
441 | * but only emulate it. In all cases, the ports won't work | ||
442 | * unless we send these messages to the hub. | ||
443 | */ | ||
444 | if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) | ||
439 | dev_dbg(hub->intfdev, "enabling power on all ports\n"); | 445 | dev_dbg(hub->intfdev, "enabling power on all ports\n"); |
440 | for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) | 446 | else |
441 | set_port_feature(hub->hdev, port1, | 447 | dev_dbg(hub->intfdev, "trying to enable port power on " |
442 | USB_PORT_FEAT_POWER); | 448 | "non-switchable hub\n"); |
443 | } | 449 | for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) |
450 | set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER); | ||
444 | 451 | ||
445 | /* Wait at least 100 msec for power to become stable */ | 452 | /* Wait at least 100 msec for power to become stable */ |
446 | msleep(max(pgood_delay, (unsigned) 100)); | 453 | msleep(max(pgood_delay, (unsigned) 100)); |