Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07e72b95 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman
Browse files

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: default avatarOliver Neukum <oneukum@suse.de>
Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 036915a7
Loading
Loading
Loading
Loading
+8 −2
Original line number Original line Diff line number Diff line
@@ -3000,7 +3000,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
static int finish_port_resume(struct usb_device *udev)
static int finish_port_resume(struct usb_device *udev)
{
{
	int	status = 0;
	int	status = 0;
	u16	devstatus;
	u16	devstatus = 0;


	/* caller owns the udev device lock */
	/* caller owns the udev device lock */
	dev_dbg(&udev->dev, "%s\n",
	dev_dbg(&udev->dev, "%s\n",
@@ -3045,7 +3045,13 @@ static int finish_port_resume(struct usb_device *udev)
	if (status) {
	if (status) {
		dev_dbg(&udev->dev, "gone after usb resume? status %d\n",
		dev_dbg(&udev->dev, "gone after usb resume? status %d\n",
				status);
				status);
	} else if (udev->actconfig) {
	/*
	 * There are a few quirky devices which violate the standard
	 * by claiming to have remote wakeup enabled after a reset,
	 * which crash if the feature is cleared, hence check for
	 * udev->reset_resume
	 */
	} else if (udev->actconfig && !udev->reset_resume) {
		le16_to_cpus(&devstatus);
		le16_to_cpus(&devstatus);
		if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
		if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
			status = usb_control_msg(udev,
			status = usb_control_msg(udev,