| From: Bin Liu <b-liu@ti.com> |
| Date: Thu, 19 Jul 2018 14:39:37 -0500 |
| Subject: usb: core: handle hub C_PORT_OVER_CURRENT condition |
| |
| commit 249a32b7eeb3edb6897dd38f89651a62163ac4ed upstream. |
| |
| Based on USB2.0 Spec Section 11.12.5, |
| |
| "If a hub has per-port power switching and per-port current limiting, |
| an over-current on one port may still cause the power on another port |
| to fall below specific minimums. In this case, the affected port is |
| placed in the Power-Off state and C_PORT_OVER_CURRENT is set for the |
| port, but PORT_OVER_CURRENT is not set." |
| |
| so let's check C_PORT_OVER_CURRENT too for over current condition. |
| |
| Fixes: 08d1dec6f405 ("usb:hub set hub->change_bits when over-current happens") |
| Tested-by: Alessandro Antenucci <antenucci@korg.it> |
| Signed-off-by: Bin Liu <b-liu@ti.com> |
| Acked-by: Alan Stern <stern@rowland.harvard.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| [bwh: Backported to 3.16: adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/usb/core/hub.c | 8 ++++++-- |
| 1 file changed, 6 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/usb/core/hub.c |
| +++ b/drivers/usb/core/hub.c |
| @@ -1119,10 +1119,14 @@ static void hub_activate(struct usb_hub |
| |
| if (!udev || udev->state == USB_STATE_NOTATTACHED) { |
| /* Tell khubd to disconnect the device or |
| - * check for a new connection |
| + * check for a new connection or over current condition. |
| + * Based on USB2.0 Spec Section 11.12.5, |
| + * C_PORT_OVER_CURRENT could be set while |
| + * PORT_OVER_CURRENT is not. So check for any of them. |
| */ |
| if (udev || (portstatus & USB_PORT_STAT_CONNECTION) || |
| - (portstatus & USB_PORT_STAT_OVERCURRENT)) |
| + (portstatus & USB_PORT_STAT_OVERCURRENT) || |
| + (portchange & USB_PORT_STAT_C_OVERCURRENT)) |
| set_bit(port1, hub->change_bits); |
| |
| } else if (portstatus & USB_PORT_STAT_ENABLE) { |