linux/debian/patches/debian/hid-avoid-abi-change-in-4.1...

81 lines
2.3 KiB
Diff

From: Ben Hutchings <ben@decadent.org.uk>
Date: Thu, 12 Jul 2018 00:39:38 +0100
Subject: HID: Avoid ABI change in 4.17.6
Forwarded: not-needed
Commit 8f732850df1b "HID: core: allow concurrent registration of
drivers" introduced atomic bit-operations on hid_device::status, and
changed its type from unsigned int to unsigned long as required for
those operations.
Revert the type change and use cmpxchg() for the bit-operations,
since it supports unsigned int.
---
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1929,6 +1929,34 @@ static int hid_bus_match(struct device *
return hid_match_device(hdev, hdrv) != NULL;
}
+static void clear_status_flag(unsigned int flag, unsigned int *status)
+{
+ unsigned int expect, old;
+
+ expect = READ_ONCE(*status);
+ for (;;) {
+ old = cmpxchg(status, expect, expect & ~flag);
+ if (old == expect)
+ break;
+ expect = old;
+ }
+}
+
+static bool test_and_set_status_flag(unsigned int flag, unsigned int *status)
+{
+ unsigned int expect, old;
+
+ expect = READ_ONCE(*status);
+ for (;;) {
+ old = cmpxchg(status, expect, expect | flag);
+ if (old == expect)
+ break;
+ expect = old;
+ }
+
+ return old & flag;
+}
+
static int hid_device_probe(struct device *dev)
{
struct hid_driver *hdrv = to_hid_driver(dev->driver);
@@ -1942,7 +1970,7 @@ static int hid_device_probe(struct devic
}
hdev->io_started = false;
- clear_bit(ffs(HID_STAT_REPROBED), &hdev->status);
+ clear_status_flag(HID_STAT_REPROBED, &hdev->status);
if (!hdev->driver) {
id = hid_match_device(hdev, hdrv);
@@ -2208,7 +2236,7 @@ static int __hid_bus_reprobe_drivers(str
if (hdev->driver == hdrv &&
!hdrv->match(hdev, hid_ignore_special_drivers) &&
- !test_and_set_bit(ffs(HID_STAT_REPROBED), &hdev->status))
+ !test_and_set_status_flag(HID_STAT_REPROBED, &hdev->status))
return device_reprobe(dev);
return 0;
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -569,7 +569,7 @@ struct hid_device { /* device repo
bool battery_avoid_query;
#endif
- unsigned long status; /* see STAT flags above */
+ unsigned int 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 */