aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2014-03-18 10:39:05 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-03-19 17:00:32 -0400
commit1d10255c1c496557a5674e651c4ebbe0f61279f2 (patch)
tree7d65e464bc4ba39240f124111c8c4d30dd7e76e8
parent6aec044cc2f5670cf3b143c151c8be846499bd15 (diff)
USB: disable reset-resume when USB_QUIRK_RESET is set
The USB_QUIRK_RESET flag indicates that a USB device changes its identity in some way when it is reset. It may lose its firmware, its descriptors may change, or it may switch back to a default mode of operation. If a device does this, the kernel needs to avoid resetting it. Resets are likely to fail, or worse, succeed while changing the device's state in a way the system can't detect. This means we should disable the reset-resume mechanism whenever this quirk flag is present. An attempted reset-resume will fail, the device will be logically disconnected, and later on the hub driver will rediscover and re-enumerate the device. This will cause the appropriate udev events to be generated, so that userspace will have a chance to switch the device into its normal operating mode, if necessary. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> CC: Oliver Neukum <oliver@neukum.org> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/core/hub.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 2d74dfb9c989..d670aaf13a3d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3105,9 +3105,19 @@ static int finish_port_resume(struct usb_device *udev)
3105 * operation is carried out here, after the port has been 3105 * operation is carried out here, after the port has been
3106 * resumed. 3106 * resumed.
3107 */ 3107 */
3108 if (udev->reset_resume) 3108 if (udev->reset_resume) {
3109 /*
3110 * If the device morphs or switches modes when it is reset,
3111 * we don't want to perform a reset-resume. We'll fail the
3112 * resume, which will cause a logical disconnect, and then
3113 * the device will be rediscovered.
3114 */
3109 retry_reset_resume: 3115 retry_reset_resume:
3110 status = usb_reset_and_verify_device(udev); 3116 if (udev->quirks & USB_QUIRK_RESET)
3117 status = -ENODEV;
3118 else
3119 status = usb_reset_and_verify_device(udev);
3120 }
3111 3121
3112 /* 10.5.4.5 says be sure devices in the tree are still there. 3122 /* 10.5.4.5 says be sure devices in the tree are still there.
3113 * For now let's assume the device didn't go crazy on resume, 3123 * For now let's assume the device didn't go crazy on resume,