diff options
Diffstat (limited to 'drivers/usb/core/hub.c')
| -rw-r--r-- | drivers/usb/core/hub.c | 18 | 
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 25a7422ee65..8fb484984c8 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2324,12 +2324,16 @@ static unsigned hub_is_wusb(struct usb_hub *hub)  static int hub_port_reset(struct usb_hub *hub, int port1,  			struct usb_device *udev, unsigned int delay, bool warm); -/* Is a USB 3.0 port in the Inactive state? */ -static bool hub_port_inactive(struct usb_hub *hub, u16 portstatus) +/* Is a USB 3.0 port in the Inactive or Complinance Mode state? + * Port worm reset is required to recover + */ +static bool hub_port_warm_reset_required(struct usb_hub *hub, u16 portstatus)  {  	return hub_is_superspeed(hub->hdev) && -		(portstatus & USB_PORT_STAT_LINK_STATE) == -		USB_SS_PORT_LS_SS_INACTIVE; +		(((portstatus & USB_PORT_STAT_LINK_STATE) == +		  USB_SS_PORT_LS_SS_INACTIVE) || +		 ((portstatus & USB_PORT_STAT_LINK_STATE) == +		  USB_SS_PORT_LS_COMP_MOD)) ;  }  static int hub_port_wait_reset(struct usb_hub *hub, int port1, @@ -2365,7 +2369,7 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,  			 *  			 * See https://bugzilla.kernel.org/show_bug.cgi?id=41752  			 */ -			if (hub_port_inactive(hub, portstatus)) { +			if (hub_port_warm_reset_required(hub, portstatus)) {  				int ret;  				if ((portchange & USB_PORT_STAT_C_CONNECTION)) @@ -4408,9 +4412,7 @@ static void hub_events(void)  			/* Warm reset a USB3 protocol port if it's in  			 * SS.Inactive state.  			 */ -			if (hub_is_superspeed(hub->hdev) && -				(portstatus & USB_PORT_STAT_LINK_STATE) -					== USB_SS_PORT_LS_SS_INACTIVE) { +			if (hub_port_warm_reset_required(hub, portstatus)) {  				dev_dbg(hub_dev, "warm reset port %d\n", i);  				hub_port_reset(hub, i, NULL,  						HUB_BH_RESET_TIME, true);  | 
