diff options
Diffstat (limited to 'drivers/usb/core/hub.c')
| -rw-r--r-- | drivers/usb/core/hub.c | 21 | 
1 files changed, 7 insertions, 14 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 47a1c8bddf86..1460857026e0 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2983,8 +2983,12 @@ static int hub_port_reset(struct usb_hub *hub, int port1,  						status);  		} -		/* Check for disconnect or reset */ -		if (status == 0 || status == -ENOTCONN || status == -ENODEV) { +		/* +		 * Check for disconnect or reset, and bail out after several +		 * reset attempts to avoid warm reset loop. +		 */ +		if (status == 0 || status == -ENOTCONN || status == -ENODEV || +		    (status == -EBUSY && i == PORT_RESET_TRIES - 1)) {  			usb_clear_port_feature(hub->hdev, port1,  					USB_PORT_FEAT_C_RESET); @@ -5005,6 +5009,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,  		retval = usb_get_bos_descriptor(udev);  		if (!retval) {  			udev->lpm_capable = usb_device_supports_lpm(udev); +			udev->lpm_disable_count = 1;  			usb_set_lpm_parameters(udev);  		}  	} @@ -5928,16 +5933,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev)  	 */  	usb_disable_usb2_hardware_lpm(udev); -	/* Disable LPM while we reset the device and reinstall the alt settings. -	 * Device-initiated LPM, and system exit latency settings are cleared -	 * when the device is reset, so we have to set them up again. -	 */ -	ret = usb_unlocked_disable_lpm(udev); -	if (ret) { -		dev_err(&udev->dev, "%s Failed to disable LPM\n", __func__); -		goto re_enumerate_no_bos; -	} -  	bos = udev->bos;  	udev->bos = NULL; @@ -6042,8 +6037,6 @@ done:  re_enumerate:  	usb_release_bos_descriptor(udev);  	udev->bos = bos; -re_enumerate_no_bos: -	/* LPM state doesn't matter when we're about to destroy the device. */  	hub_port_logical_disconnect(parent_hub, port1);  	return -ENODEV;  }  |