[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180710182505.683450110@linuxfoundation.org>
Date: Tue, 10 Jul 2018 20:25:26 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org,
Mario Limonciello <mario.limonciello@...l.com>,
Benjamin Tissoires <benjamin.tissoires@...hat.com>,
Jiri Kosina <jkosina@...e.cz>
Subject: [PATCH 4.17 44/56] HID: core: allow concurrent registration of drivers
4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Tissoires <benjamin.tissoires@...hat.com>
commit 8f732850df1b2b4d8d719f7e606dfb3050e7ea11 upstream.
Detected on the Dell XPS 9365.
The laptop has 2 devices that benefit from the hid-generic auto-unbinding.
When those 2 devices are presented to the userspace, udev loads both wacom and
hid-multitouch. When this happens, the code in __hid_bus_reprobe_drivers() is
called concurrently and the second device gets reprobed twice.
An other bug in the power_supply subsystem prevent to remove the wacom driver
if it just finished its initialization, which basically kills the wacom node.
[jkosina@...e.cz: reformat changelog a bit]
Fixes c17a7476e4c4 ("HID: core: rewrite the hid-generic automatic unbind")
Cc: stable@...r.kernel.org # v4.17
Tested-by: Mario Limonciello <mario.limonciello@...l.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@...hat.com>
Signed-off-by: Jiri Kosina <jkosina@...e.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
drivers/hid/hid-core.c | 5 ++++-
include/linux/hid.h | 3 ++-
2 files changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1942,6 +1942,8 @@ static int hid_device_probe(struct devic
}
hdev->io_started = false;
+ clear_bit(ffs(HID_STAT_REPROBED), &hdev->status);
+
if (!hdev->driver) {
id = hid_match_device(hdev, hdrv);
if (id == NULL) {
@@ -2205,7 +2207,8 @@ static int __hid_bus_reprobe_drivers(str
struct hid_device *hdev = to_hid_device(dev);
if (hdev->driver == hdrv &&
- !hdrv->match(hdev, hid_ignore_special_drivers))
+ !hdrv->match(hdev, hid_ignore_special_drivers) &&
+ !test_and_set_bit(ffs(HID_STAT_REPROBED), &hdev->status))
return device_reprobe(dev);
return 0;
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -502,6 +502,7 @@ struct hid_output_fifo {
#define HID_STAT_ADDED BIT(0)
#define HID_STAT_PARSED BIT(1)
+#define HID_STAT_REPROBED BIT(3)
struct hid_input {
struct list_head list;
@@ -568,7 +569,7 @@ struct hid_device { /* device repo
bool battery_avoid_query;
#endif
- unsigned int status; /* see STAT flags above */
+ unsigned long status; /* see STAT flags above */
unsigned claimed; /* Claimed by hidinput, hiddev? */
unsigned quirks; /* Various quirks the device can pull on us */
bool io_started; /* If IO has started */
Powered by blists - more mailing lists