stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [added to the 3.18 stable tree] HID: usbhid: fix inconsistent reset/resume/reset-resume behavior
@ 2016-04-23  1:59 Sasha Levin
  2016-04-23  1:59 ` [added to the 3.18 stable tree] ARM: OMAP2+: hwmod: Fix updating of sysconfig register Sasha Levin
                   ` (50 more replies)
  0 siblings, 51 replies; 54+ messages in thread
From: Sasha Levin @ 2016-04-23  1:59 UTC (permalink / raw)
  To: stable, stable-commits; +Cc: Alan Stern, Jiri Kosina, Sasha Levin

From: Alan Stern <stern@rowland.harvard.edu>

This patch has been added to the 3.18 stable tree. If you have any
objections, please let us know.

===============

[ Upstream commit 972e6a993f278b416a8ee3ec65475724fc36feb2 ]

The usbhid driver has inconsistently duplicated code in its post-reset,
resume, and reset-resume pathways.

	reset-resume doesn't check HID_STARTED before trying to
	restart the I/O queues.

	resume fails to clear the HID_SUSPENDED flag if HID_STARTED
	isn't set.

	resume calls usbhid_restart_queues() with usbhid->lock held
	and the others call it without holding the lock.

The first item in particular causes a problem following a reset-resume
if the driver hasn't started up its I/O.  URB submission fails because
usbhid->urbin is NULL, and this triggers an unending reset-retry loop.

This patch fixes the problem by creating a new subroutine,
hid_restart_io(), to carry out all the common activities.  It also
adds some checks that were missing in the original code:

	After a reset, there's no need to clear any halted endpoints.

	After a resume, if a reset is pending there's no need to
	restart any I/O until the reset is finished.

	After a resume, if the interrupt-IN endpoint is halted there's
	no need to submit the input URB until the halt has been
	cleared.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-by: Daniel Fraga <fragabr@gmail.com>
Tested-by: Daniel Fraga <fragabr@gmail.com>
CC: <stable@vger.kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
 drivers/hid/usbhid/hid-core.c | 73 ++++++++++++++++++++++---------------------
 1 file changed, 37 insertions(+), 36 deletions(-)

diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index e318980..d3fd973 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -939,14 +939,6 @@ static int usbhid_output_report(struct hid_device *hid, __u8 *buf, size_t count)
 	return ret;
 }
 
-static void usbhid_restart_queues(struct usbhid_device *usbhid)
-{
-	if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
-		usbhid_restart_out_queue(usbhid);
-	if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
-		usbhid_restart_ctrl_queue(usbhid);
-}
-
 static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
 {
 	struct usbhid_device *usbhid = hid->driver_data;
@@ -1392,6 +1384,37 @@ static void hid_cease_io(struct usbhid_device *usbhid)
 	usb_kill_urb(usbhid->urbout);
 }
 
+static void hid_restart_io(struct hid_device *hid)
+{
+	struct usbhid_device *usbhid = hid->driver_data;
+	int clear_halt = test_bit(HID_CLEAR_HALT, &usbhid->iofl);
+	int reset_pending = test_bit(HID_RESET_PENDING, &usbhid->iofl);
+
+	spin_lock_irq(&usbhid->lock);
+	clear_bit(HID_SUSPENDED, &usbhid->iofl);
+	usbhid_mark_busy(usbhid);
+
+	if (clear_halt || reset_pending)
+		schedule_work(&usbhid->reset_work);
+	usbhid->retry_delay = 0;
+	spin_unlock_irq(&usbhid->lock);
+
+	if (reset_pending || !test_bit(HID_STARTED, &usbhid->iofl))
+		return;
+
+	if (!clear_halt) {
+		if (hid_start_in(hid) < 0)
+			hid_io_error(hid);
+	}
+
+	spin_lock_irq(&usbhid->lock);
+	if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
+		usbhid_restart_out_queue(usbhid);
+	if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
+		usbhid_restart_ctrl_queue(usbhid);
+	spin_unlock_irq(&usbhid->lock);
+}
+
 /* Treat USB reset pretty much the same as suspend/resume */
 static int hid_pre_reset(struct usb_interface *intf)
 {
@@ -1441,14 +1464,14 @@ static int hid_post_reset(struct usb_interface *intf)
 		return 1;
 	}
 
+	/* No need to do another reset or clear a halted endpoint */
 	spin_lock_irq(&usbhid->lock);
 	clear_bit(HID_RESET_PENDING, &usbhid->iofl);
+	clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
 	spin_unlock_irq(&usbhid->lock);
 	hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
-	status = hid_start_in(hid);
-	if (status < 0)
-		hid_io_error(hid);
-	usbhid_restart_queues(usbhid);
+
+	hid_restart_io(hid);
 
 	return 0;
 }
@@ -1471,25 +1494,9 @@ void usbhid_put_power(struct hid_device *hid)
 #ifdef CONFIG_PM
 static int hid_resume_common(struct hid_device *hid, bool driver_suspended)
 {
-	struct usbhid_device *usbhid = hid->driver_data;
-	int status;
-
-	spin_lock_irq(&usbhid->lock);
-	clear_bit(HID_SUSPENDED, &usbhid->iofl);
-	usbhid_mark_busy(usbhid);
-
-	if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
-			test_bit(HID_RESET_PENDING, &usbhid->iofl))
-		schedule_work(&usbhid->reset_work);
-	usbhid->retry_delay = 0;
-
-	usbhid_restart_queues(usbhid);
-	spin_unlock_irq(&usbhid->lock);
-
-	status = hid_start_in(hid);
-	if (status < 0)
-		hid_io_error(hid);
+	int status = 0;
 
+	hid_restart_io(hid);
 	if (driver_suspended && hid->driver && hid->driver->resume)
 		status = hid->driver->resume(hid);
 	return status;
@@ -1558,12 +1565,8 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
 static int hid_resume(struct usb_interface *intf)
 {
 	struct hid_device *hid = usb_get_intfdata (intf);
-	struct usbhid_device *usbhid = hid->driver_data;
 	int status;
 
-	if (!test_bit(HID_STARTED, &usbhid->iofl))
-		return 0;
-
 	status = hid_resume_common(hid, true);
 	dev_dbg(&intf->dev, "resume status %d\n", status);
 	return 0;
@@ -1572,10 +1575,8 @@ static int hid_resume(struct usb_interface *intf)
 static int hid_reset_resume(struct usb_interface *intf)
 {
 	struct hid_device *hid = usb_get_intfdata(intf);
-	struct usbhid_device *usbhid = hid->driver_data;
 	int status;
 
-	clear_bit(HID_SUSPENDED, &usbhid->iofl);
 	status = hid_post_reset(intf);
 	if (status >= 0 && hid->driver && hid->driver->reset_resume) {
 		int ret = hid->driver->reset_resume(hid);
-- 
2.5.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2016-04-24 11:53 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-23  1:59 [added to the 3.18 stable tree] HID: usbhid: fix inconsistent reset/resume/reset-resume behavior Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] ARM: OMAP2+: hwmod: Fix updating of sysconfig register Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] usb: renesas_usbhs: avoid NULL pointer derefernce in usbhsf_pkt_handler() Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] usb: renesas_usbhs: disable TX IRQ before starting TX DMAC transfer Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] drm/qxl: fix cursor position with non-zero hotspot Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] USB: mct_u232: add sanity checking in probe Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] USB: cypress_m8: add endpoint sanity check Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] USB: digi_acceleport: do sanity checking for the number of ports Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] sd: Fix excessive capacity printing on devices with blocks bigger than 512 bytes Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] ext4: add lockdep annotations for i_data_sem Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] KVM: x86: Inject pending interrupt even if pending nmi exist Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] ext4: ignore quota mount options if the quota feature is enabled Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] ALSA: usb-audio: don't try to get Outlaw RR2150 sample rate Sasha Levin
2016-04-23  1:59 ` [added to the 3.18 stable tree] ALSA: usb-audio: Add sample rate inquiry quirk for AudioQuest DragonFly Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] ALSA: usb-audio: Add a sample rate quirk for Phoenix Audio TMX320 Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] xen/events: Mask a moving irq Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] usb: renesas_usbhs: fix spinlock suspected in a gadget complete function Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] usb: renesas_usbhs: fix to avoid using a disabled ep in usbhsg_queue_done() Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] compiler-gcc: integrate the various compiler-gcc[345].h files Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] compiler-gcc: disable -ftracer for __noclone functions Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] rbd: use GFP_NOIO consistently for request allocations Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] ALSA: usb-audio: Add a quirk for Plantronics BT300 Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] assoc_array: don't call compare_object() on a node Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] Btrfs: fix fsync data loss after append write Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] Btrfs: fix fsync xattr loss in the fast fsync path Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] Btrfs: fix fsync after truncate when no_holes feature is enabled Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] Btrfs: fix file/data loss caused by fsync after rename and new inode Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] USB: serial: ftdi_sio: Add support for ICP DAS I-756xU devices Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] USB: serial: cp210x: Adding GE Healthcare Device ID Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] USB: option: add "D-Link DWM-221 B1" device id Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] gpio: pca953x: Use correct u16 value for register word write Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] parisc: Avoid function pointers for kernel exception routines Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] parisc: Fix kernel crash with reversed copy_from_user() Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] parisc: percpu: update comments referring to __get_cpu_var Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] parisc: Unbreak handling exceptions from kernel modules Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] kvm: x86: do not leak guest xcr0 into host interrupt handlers Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] ALSA: hda - fix front mic problem for a HP desktop Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] ALSA: usb-audio: Skip volume controls triggers hangup on Dell USB Dock Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] dmaengine: dw: fix master selection Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] lib: lz4: fixed zram with lz4 on big endian machines Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] usb: xhci: applying XHCI_PME_STUCK_QUIRK to Intel BXT B0 host Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] xhci: resume USB 3 roothub first Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] usb: host: xhci: add a new quirk XHCI_NO_64BIT_SUPPORT Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] usb: xhci: fix wild pointers in xhci_mem_cleanup Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] usb: xhci: fix xhci locking up during hcd remove Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] xhci: fix 10 second timeout on removal of PCI hotpluggable xhci controllers Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] USB: uas: Add a new NO_REPORT_LUNS quirk Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] usb: hcd: out of bounds access in for_each_companion Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] tcp_cubic: better follow cubic curve after idle period Sasha Levin
2016-04-23 14:04   ` Neal Cardwell
2016-04-24 11:53     ` Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] usb: musb: cppi41: correct the macro name EP_MODE_AUTOREG_* Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] Correct backport of fa3c776 ("Thermal: Ignore invalid trip points") Sasha Levin
2016-04-23  2:00 ` [added to the 3.18 stable tree] Btrfs: fix list transaction->pending_ordered corruption Sasha Levin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).