diff options
Diffstat (limited to 'debian/patches/debian/hid-avoid-abi-change-in-4.17.6.patch')
-rw-r--r-- | debian/patches/debian/hid-avoid-abi-change-in-4.17.6.patch | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/debian/patches/debian/hid-avoid-abi-change-in-4.17.6.patch b/debian/patches/debian/hid-avoid-abi-change-in-4.17.6.patch new file mode 100644 index 000000000000..050bdf2b4451 --- /dev/null +++ b/debian/patches/debian/hid-avoid-abi-change-in-4.17.6.patch @@ -0,0 +1,80 @@ +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 */ |