All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.