summaryrefslogtreecommitdiff
path: root/drivers/hid/hid-logitech-dj.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2019-04-20 13:21:50 +0200
committerBenjamin Tissoires <benjamin.tissoires@redhat.com>2019-04-23 18:00:41 +0200
commitf41d766c34cbab024412d433a43d2d83a37e5135 (patch)
tree2c86aad750cb8a407a61ef1f8b39329475a22cd5 /drivers/hid/hid-logitech-dj.c
parent61d14de2948e1281b178b5b890a72e9c00979cc4 (diff)
downloadlwn-f41d766c34cbab024412d433a43d2d83a37e5135.tar.gz
lwn-f41d766c34cbab024412d433a43d2d83a37e5135.zip
HID: logitech-dj: protect the paired_dj_devices access in add_djhid_dev with the lock
This protects against logi_dj_recv_add_djhid_device, adding a device to paired_dj_devices from the delayedwork callback, racing versus logi_dj_raw_event trying to access that device. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Diffstat (limited to 'drivers/hid/hid-logitech-dj.c')
-rw-r--r--drivers/hid/hid-logitech-dj.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index 9e5aac74808b..e9a165790482 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -393,12 +393,14 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
struct hid_device *dj_hiddev;
struct dj_device *dj_dev;
u8 device_index = workitem->device_index;
+ unsigned long flags;
/* Device index goes from 1 to 6, we need 3 bytes to store the
* semicolon, the index, and a null terminator
*/
unsigned char tmpstr[3];
+ /* We are the only one ever adding a device, no need to lock */
if (djrcv_dev->paired_dj_devices[device_index]) {
/* The device is already known. No need to reallocate it. */
dbg_hid("%s: device is already known\n", __func__);
@@ -443,7 +445,9 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
dj_dev->device_index = device_index;
dj_hiddev->driver_data = dj_dev;
+ spin_lock_irqsave(&djrcv_dev->lock, flags);
djrcv_dev->paired_dj_devices[device_index] = dj_dev;
+ spin_unlock_irqrestore(&djrcv_dev->lock, flags);
if (hid_add_device(dj_hiddev)) {
dev_err(&djrcv_hdev->dev, "%s: failed adding dj_device\n",
@@ -454,7 +458,9 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
return;
hid_add_device_fail:
+ spin_lock_irqsave(&djrcv_dev->lock, flags);
djrcv_dev->paired_dj_devices[device_index] = NULL;
+ spin_unlock_irqrestore(&djrcv_dev->lock, flags);
kfree(dj_dev);
dj_device_allocate_fail:
hid_destroy_device(dj_hiddev);