aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2012-11-29 09:05:57 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-11 15:15:14 -0500
commit07e72b95f5038cc82304b9a4a2eb7f9fc391ea68 (patch)
treeacaf6f915ee00be5931eaa570d8e8b246b8cdf50 /drivers/usb/core
parent036915a7a402753c05b8d0529f5fd08805ab46d0 (diff)
USB: hub: handle claim of enabled remote wakeup after reset
Some touchscreens have buggy firmware which claims remote wakeup to be enabled after a reset. They nevertheless crash if the feature is cleared by the host. Add a check for reset resume before checking for an enabled remote wakeup feature. On compliant devices the feature must be cleared after a reset anyway. Signed-off-by: Oliver Neukum <oneukum@suse.de> Acked-by: Alan Stern <stern@rowland.harvard.edu> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/hub.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 9641e9c1dec5..957ed2c41482 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3000,7 +3000,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
3000static int finish_port_resume(struct usb_device *udev) 3000static int finish_port_resume(struct usb_device *udev)
3001{ 3001{
3002 int status = 0; 3002 int status = 0;
3003 u16 devstatus; 3003 u16 devstatus = 0;
3004 3004
3005 /* caller owns the udev device lock */ 3005 /* caller owns the udev device lock */
3006 dev_dbg(&udev->dev, "%s\n", 3006 dev_dbg(&udev->dev, "%s\n",
@@ -3045,7 +3045,13 @@ static int finish_port_resume(struct usb_device *udev)
3045 if (status) { 3045 if (status) {
3046 dev_dbg(&udev->dev, "gone after usb resume? status %d\n", 3046 dev_dbg(&udev->dev, "gone after usb resume? status %d\n",
3047 status); 3047 status);
3048 } else if (udev->actconfig) { 3048 /*
3049 * There are a few quirky devices which violate the standard
3050 * by claiming to have remote wakeup enabled after a reset,
3051 * which crash if the feature is cleared, hence check for
3052 * udev->reset_resume
3053 */
3054 } else if (udev->actconfig && !udev->reset_resume) {
3049 le16_to_cpus(&devstatus); 3055 le16_to_cpus(&devstatus);
3050 if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { 3056 if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
3051 status = usb_control_msg(udev, 3057 status = usb_control_msg(udev,