diff options
Diffstat (limited to 'drivers/usb/core/hub.c')
| -rw-r--r-- | drivers/usb/core/hub.c | 10 | 
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2633acde7ac1..d4b1e70d1498 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -6038,6 +6038,11 @@ re_enumerate:   * the reset is over (using their post_reset method).   *   * Return: The same as for usb_reset_and_verify_device(). + * However, if a reset is already in progress (for instance, if a + * driver doesn't have pre_ or post_reset() callbacks, and while + * being unbound or re-bound during the ongoing reset its disconnect() + * or probe() routine tries to perform a second, nested reset), the + * routine returns -EINPROGRESS.   *   * Note:   * The caller must own the device lock.  For example, it's safe to use @@ -6071,6 +6076,10 @@ int usb_reset_device(struct usb_device *udev)  		return -EISDIR;  	} +	if (udev->reset_in_progress) +		return -EINPROGRESS; +	udev->reset_in_progress = 1; +  	port_dev = hub->ports[udev->portnum - 1];  	/* @@ -6135,6 +6144,7 @@ int usb_reset_device(struct usb_device *udev)  	usb_autosuspend_device(udev);  	memalloc_noio_restore(noio_flag); +	udev->reset_in_progress = 0;  	return ret;  }  EXPORT_SYMBOL_GPL(usb_reset_device);  | 
