diff options
| -rw-r--r-- | drivers/usb/core/hub.c | 11 | ||||
| -rw-r--r-- | drivers/usb/core/hub.h | 3 |
2 files changed, 12 insertions, 2 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 3924dd080bea..bdf5be099650 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -1658,6 +1658,8 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) | |||
| 1658 | 1658 | ||
| 1659 | // dev_dbg(hub->intfdev, "resume port %d\n", port1); | 1659 | // dev_dbg(hub->intfdev, "resume port %d\n", port1); |
| 1660 | 1660 | ||
| 1661 | set_bit(port1, hub->busy_bits); | ||
| 1662 | |||
| 1661 | /* see 7.1.7.7; affects power usage, but not budgeting */ | 1663 | /* see 7.1.7.7; affects power usage, but not budgeting */ |
| 1662 | status = clear_port_feature(hub->hdev, | 1664 | status = clear_port_feature(hub->hdev, |
| 1663 | port1, USB_PORT_FEAT_SUSPEND); | 1665 | port1, USB_PORT_FEAT_SUSPEND); |
| @@ -1707,6 +1709,10 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) | |||
| 1707 | if (status < 0) | 1709 | if (status < 0) |
| 1708 | hub_port_logical_disconnect(hub, port1); | 1710 | hub_port_logical_disconnect(hub, port1); |
| 1709 | 1711 | ||
| 1712 | clear_bit(port1, hub->busy_bits); | ||
| 1713 | if (!hub->hdev->parent && !hub->busy_bits[0]) | ||
| 1714 | usb_enable_root_hub_irq(hub->hdev->bus); | ||
| 1715 | |||
| 1710 | return status; | 1716 | return status; |
| 1711 | } | 1717 | } |
| 1712 | 1718 | ||
| @@ -2690,7 +2696,7 @@ static void hub_events(void) | |||
| 2690 | 2696 | ||
| 2691 | /* If this is a root hub, tell the HCD it's okay to | 2697 | /* If this is a root hub, tell the HCD it's okay to |
| 2692 | * re-enable port-change interrupts now. */ | 2698 | * re-enable port-change interrupts now. */ |
| 2693 | if (!hdev->parent) | 2699 | if (!hdev->parent && !hub->busy_bits[0]) |
| 2694 | usb_enable_root_hub_irq(hdev->bus); | 2700 | usb_enable_root_hub_irq(hdev->bus); |
| 2695 | 2701 | ||
| 2696 | loop: | 2702 | loop: |
| @@ -2865,6 +2871,9 @@ int usb_reset_device(struct usb_device *udev) | |||
| 2865 | break; | 2871 | break; |
| 2866 | } | 2872 | } |
| 2867 | clear_bit(port1, parent_hub->busy_bits); | 2873 | clear_bit(port1, parent_hub->busy_bits); |
| 2874 | if (!parent_hdev->parent && !parent_hub->busy_bits[0]) | ||
| 2875 | usb_enable_root_hub_irq(parent_hdev->bus); | ||
| 2876 | |||
| 2868 | if (ret < 0) | 2877 | if (ret < 0) |
| 2869 | goto re_enumerate; | 2878 | goto re_enumerate; |
| 2870 | 2879 | ||
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 29d5f45a8456..0f8e82a4d480 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
| @@ -212,7 +212,8 @@ struct usb_hub { | |||
| 212 | unsigned long event_bits[1]; /* status change bitmask */ | 212 | unsigned long event_bits[1]; /* status change bitmask */ |
| 213 | unsigned long change_bits[1]; /* ports with logical connect | 213 | unsigned long change_bits[1]; /* ports with logical connect |
| 214 | status change */ | 214 | status change */ |
| 215 | unsigned long busy_bits[1]; /* ports being reset */ | 215 | unsigned long busy_bits[1]; /* ports being reset or |
| 216 | resumed */ | ||
| 216 | #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ | 217 | #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ |
| 217 | #error event_bits[] is too short! | 218 | #error event_bits[] is too short! |
| 218 | #endif | 219 | #endif |
