Skip to content

Commit f4eb142

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID fixes from Jiri Kosina: - functional regression fix for some of the Logitech unifying devices, from Hans de Goede - race condition fix in hid-sony for bug severely affecting Valve/Android deployments, from Roderick Colenbrander - several fixes for issues found by syzbot/kasan, from Oliver Neukum and Hillf Danton - functional regression fix for Wacom Cintiq device, from Aaron Armstrong Skomra - a few other assorted device-specific quirks * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: sony: Fix race condition between rumble and device remove. HID: hiddev: do cleanup in failure of opening a device HID: hiddev: avoid opening a disconnected device HID: input: fix a4tech horizontal wheel custom usage HID: Add quirk for HP X1200 PIXART OEM mouse HID: holtek: test for sanity of intfdata HID: wacom: fix bit shift for Cintiq Companion 2 HID: quirks: Set the INCREMENT_USAGE_ON_DUPLICATE quirk on Saitek X52 HID: logitech-dj: Really fix return value of logi_dj_recv_query_hidpp_devices HID: Add 044f:b320 ThrustMaster, Inc. 2 in 1 DT HID: logitech-dj: add the Powerplay receiver HID: logitech-hidpp: add USB PID for a few more supported mice HID: logitech-dj: rename "gaming" receiver to "lightspeed"
2 parents 4368c4b + e0f6974 commit f4eb142

File tree

10 files changed

+120
-19
lines changed

10 files changed

+120
-19
lines changed

drivers/hid/hid-a4tech.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,36 @@
2323
#define A4_2WHEEL_MOUSE_HACK_7 0x01
2424
#define A4_2WHEEL_MOUSE_HACK_B8 0x02
2525

26+
#define A4_WHEEL_ORIENTATION (HID_UP_GENDESK | 0x000000b8)
27+
2628
struct a4tech_sc {
2729
unsigned long quirks;
2830
unsigned int hw_wheel;
2931
__s32 delayed_value;
3032
};
3133

34+
static int a4_input_mapping(struct hid_device *hdev, struct hid_input *hi,
35+
struct hid_field *field, struct hid_usage *usage,
36+
unsigned long **bit, int *max)
37+
{
38+
struct a4tech_sc *a4 = hid_get_drvdata(hdev);
39+
40+
if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8 &&
41+
usage->hid == A4_WHEEL_ORIENTATION) {
42+
/*
43+
* We do not want to have this usage mapped to anything as it's
44+
* nonstandard and doesn't really behave like an HID report.
45+
* It's only selecting the orientation (vertical/horizontal) of
46+
* the previous mouse wheel report. The input_events will be
47+
* generated once both reports are recorded in a4_event().
48+
*/
49+
return -1;
50+
}
51+
52+
return 0;
53+
54+
}
55+
3256
static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi,
3357
struct hid_field *field, struct hid_usage *usage,
3458
unsigned long **bit, int *max)
@@ -52,8 +76,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
5276
struct a4tech_sc *a4 = hid_get_drvdata(hdev);
5377
struct input_dev *input;
5478

55-
if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
56-
!usage->type)
79+
if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput)
5780
return 0;
5881

5982
input = field->hidinput->input;
@@ -64,7 +87,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
6487
return 1;
6588
}
6689

67-
if (usage->hid == 0x000100b8) {
90+
if (usage->hid == A4_WHEEL_ORIENTATION) {
6891
input_event(input, EV_REL, value ? REL_HWHEEL :
6992
REL_WHEEL, a4->delayed_value);
7093
input_event(input, EV_REL, value ? REL_HWHEEL_HI_RES :
@@ -131,6 +154,7 @@ MODULE_DEVICE_TABLE(hid, a4_devices);
131154
static struct hid_driver a4_driver = {
132155
.name = "a4tech",
133156
.id_table = a4_devices,
157+
.input_mapping = a4_input_mapping,
134158
.input_mapped = a4_input_mapped,
135159
.event = a4_event,
136160
.probe = a4_probe,

drivers/hid/hid-holtek-kbd.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,14 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type,
123123

124124
/* Locate the boot interface, to receive the LED change events */
125125
struct usb_interface *boot_interface = usb_ifnum_to_if(usb_dev, 0);
126+
struct hid_device *boot_hid;
127+
struct hid_input *boot_hid_input;
126128

127-
struct hid_device *boot_hid = usb_get_intfdata(boot_interface);
128-
struct hid_input *boot_hid_input = list_first_entry(&boot_hid->inputs,
129+
if (unlikely(boot_interface == NULL))
130+
return -ENODEV;
131+
132+
boot_hid = usb_get_intfdata(boot_interface);
133+
boot_hid_input = list_first_entry(&boot_hid->inputs,
129134
struct hid_input, list);
130135

131136
return boot_hid_input->input->event(boot_hid_input->input, type, code,

drivers/hid/hid-ids.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@
568568
#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a
569569
#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a
570570
#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A 0x094a
571+
#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641 0x0641
571572

572573
#define USB_VENDOR_ID_HUION 0x256c
573574
#define USB_DEVICE_ID_HUION_TABLET 0x006e
@@ -768,7 +769,8 @@
768769
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER 0xc52f
769770
#define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2 0xc532
770771
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534
771-
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_GAMING 0xc539
772+
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED 0xc539
773+
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
772774
#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
773775
#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626
774776
#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704
@@ -989,6 +991,7 @@
989991
#define USB_DEVICE_ID_SAITEK_RAT7 0x0cd7
990992
#define USB_DEVICE_ID_SAITEK_RAT9 0x0cfa
991993
#define USB_DEVICE_ID_SAITEK_MMO7 0x0cd0
994+
#define USB_DEVICE_ID_SAITEK_X52 0x075c
992995

993996
#define USB_VENDOR_ID_SAMSUNG 0x0419
994997
#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001

drivers/hid/hid-logitech-dj.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,7 @@ static int logi_dj_recv_query_hidpp_devices(struct dj_receiver_dev *djrcv_dev)
11251125
HID_REQ_SET_REPORT);
11261126

11271127
kfree(hidpp_report);
1128-
return retval;
1128+
return (retval < 0) ? retval : 0;
11291129
}
11301130

11311131
static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
@@ -1832,13 +1832,17 @@ static const struct hid_device_id logi_dj_receivers[] = {
18321832
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
18331833
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2),
18341834
.driver_data = recvr_type_hidpp},
1835-
{ /* Logitech gaming receiver (0xc539) */
1835+
{ /* Logitech lightspeed receiver (0xc539) */
18361836
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1837-
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_GAMING),
1837+
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED),
18381838
.driver_data = recvr_type_gaming_hidpp},
18391839
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
18401840
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
18411841
.driver_data = recvr_type_27mhz},
1842+
{ /* Logitech powerplay receiver (0xc53a) */
1843+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1844+
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY),
1845+
.driver_data = recvr_type_gaming_hidpp},
18421846
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc517) */
18431847
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
18441848
USB_DEVICE_ID_S510_RECEIVER_2),

drivers/hid/hid-logitech-hidpp.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3749,15 +3749,45 @@ static const struct hid_device_id hidpp_devices[] = {
37493749

37503750
{ L27MHZ_DEVICE(HID_ANY_ID) },
37513751

3752-
{ /* Logitech G403 Gaming Mouse over USB */
3752+
{ /* Logitech G203/Prodigy Gaming Mouse */
3753+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC084) },
3754+
{ /* Logitech G302 Gaming Mouse */
3755+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC07F) },
3756+
{ /* Logitech G303 Gaming Mouse */
3757+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC080) },
3758+
{ /* Logitech G400 Gaming Mouse */
3759+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC07E) },
3760+
{ /* Logitech G403 Wireless Gaming Mouse over USB */
37533761
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC082) },
3762+
{ /* Logitech G403 Gaming Mouse */
3763+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC083) },
3764+
{ /* Logitech G403 Hero Gaming Mouse over USB */
3765+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC08F) },
3766+
{ /* Logitech G502 Proteus Core Gaming Mouse */
3767+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC07D) },
3768+
{ /* Logitech G502 Proteus Spectrum Gaming Mouse over USB */
3769+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC332) },
3770+
{ /* Logitech G502 Hero Gaming Mouse over USB */
3771+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC08B) },
37543772
{ /* Logitech G700 Gaming Mouse over USB */
37553773
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC06B) },
3774+
{ /* Logitech G700s Gaming Mouse over USB */
3775+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC07C) },
3776+
{ /* Logitech G703 Gaming Mouse over USB */
3777+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC087) },
3778+
{ /* Logitech G703 Hero Gaming Mouse over USB */
3779+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC090) },
37563780
{ /* Logitech G900 Gaming Mouse over USB */
37573781
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC081) },
3782+
{ /* Logitech G903 Gaming Mouse over USB */
3783+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC086) },
3784+
{ /* Logitech G903 Hero Gaming Mouse over USB */
3785+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC091) },
37583786
{ /* Logitech G920 Wheel over USB */
37593787
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL),
37603788
.driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS},
3789+
{ /* Logitech G Pro Gaming Mouse over USB */
3790+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC088) },
37613791

37623792
{ /* MX5000 keyboard over Bluetooth */
37633793
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb305),

drivers/hid/hid-quirks.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ static const struct hid_device_id hid_quirks[] = {
9292
{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL },
9393
{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
9494
{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL },
95+
{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641), HID_QUIRK_ALWAYS_POLL },
9596
{ HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680), HID_QUIRK_MULTI_INPUT },
9697
{ HID_USB_DEVICE(USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI), HID_QUIRK_MULTI_INPUT },
9798
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X), HID_QUIRK_MULTI_INPUT },
@@ -141,6 +142,7 @@ static const struct hid_device_id hid_quirks[] = {
141142
{ HID_USB_DEVICE(USB_VENDOR_ID_RETROUSB, USB_DEVICE_ID_RETROUSB_SNES_RETROPAD), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
142143
{ HID_USB_DEVICE(USB_VENDOR_ID_RETROUSB, USB_DEVICE_ID_RETROUSB_SNES_RETROPORT), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
143144
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD), HID_QUIRK_BADPAD },
145+
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
144146
{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2), HID_QUIRK_NO_INIT_REPORTS },
145147
{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD), HID_QUIRK_NO_INIT_REPORTS },
146148
{ HID_USB_DEVICE(USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB), HID_QUIRK_NOGET },

drivers/hid/hid-sony.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -585,10 +585,14 @@ static void sony_set_leds(struct sony_sc *sc);
585585
static inline void sony_schedule_work(struct sony_sc *sc,
586586
enum sony_worker which)
587587
{
588+
unsigned long flags;
589+
588590
switch (which) {
589591
case SONY_WORKER_STATE:
590-
if (!sc->defer_initialization)
592+
spin_lock_irqsave(&sc->lock, flags);
593+
if (!sc->defer_initialization && sc->state_worker_initialized)
591594
schedule_work(&sc->state_worker);
595+
spin_unlock_irqrestore(&sc->lock, flags);
592596
break;
593597
case SONY_WORKER_HOTPLUG:
594598
if (sc->hotplug_worker_initialized)
@@ -2558,13 +2562,18 @@ static inline void sony_init_output_report(struct sony_sc *sc,
25582562

25592563
static inline void sony_cancel_work_sync(struct sony_sc *sc)
25602564
{
2565+
unsigned long flags;
2566+
25612567
if (sc->hotplug_worker_initialized)
25622568
cancel_work_sync(&sc->hotplug_worker);
2563-
if (sc->state_worker_initialized)
2569+
if (sc->state_worker_initialized) {
2570+
spin_lock_irqsave(&sc->lock, flags);
2571+
sc->state_worker_initialized = 0;
2572+
spin_unlock_irqrestore(&sc->lock, flags);
25642573
cancel_work_sync(&sc->state_worker);
2574+
}
25652575
}
25662576

2567-
25682577
static int sony_input_configured(struct hid_device *hdev,
25692578
struct hid_input *hidinput)
25702579
{

drivers/hid/hid-tmff.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
#include "hid-ids.h"
2424

25+
#define THRUSTMASTER_DEVICE_ID_2_IN_1_DT 0xb320
26+
2527
static const signed short ff_rumble[] = {
2628
FF_RUMBLE,
2729
-1
@@ -76,6 +78,7 @@ static int tmff_play(struct input_dev *dev, void *data,
7678
struct hid_field *ff_field = tmff->ff_field;
7779
int x, y;
7880
int left, right; /* Rumbling */
81+
int motor_swap;
7982

8083
switch (effect->type) {
8184
case FF_CONSTANT:
@@ -100,6 +103,13 @@ static int tmff_play(struct input_dev *dev, void *data,
100103
ff_field->logical_minimum,
101104
ff_field->logical_maximum);
102105

106+
/* 2-in-1 strong motor is left */
107+
if (hid->product == THRUSTMASTER_DEVICE_ID_2_IN_1_DT) {
108+
motor_swap = left;
109+
left = right;
110+
right = motor_swap;
111+
}
112+
103113
dbg_hid("(left,right)=(%08x, %08x)\n", left, right);
104114
ff_field->value[0] = left;
105115
ff_field->value[1] = right;
@@ -226,6 +236,8 @@ static const struct hid_device_id tm_devices[] = {
226236
.driver_data = (unsigned long)ff_rumble },
227237
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304), /* FireStorm Dual Power 2 (and 3) */
228238
.driver_data = (unsigned long)ff_rumble },
239+
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, THRUSTMASTER_DEVICE_ID_2_IN_1_DT), /* Dual Trigger 2-in-1 */
240+
.driver_data = (unsigned long)ff_rumble },
229241
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323), /* Dual Trigger 3-in-1 (PC Mode) */
230242
.driver_data = (unsigned long)ff_rumble },
231243
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324), /* Dual Trigger 3-in-1 (PS3 Mode) */

drivers/hid/usbhid/hiddev.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,14 @@ static int hiddev_open(struct inode *inode, struct file *file)
284284
spin_unlock_irq(&list->hiddev->list_lock);
285285

286286
mutex_lock(&hiddev->existancelock);
287+
/*
288+
* recheck exist with existance lock held to
289+
* avoid opening a disconnected device
290+
*/
291+
if (!list->hiddev->exist) {
292+
res = -ENODEV;
293+
goto bail_unlock;
294+
}
287295
if (!list->hiddev->open++)
288296
if (list->hiddev->exist) {
289297
struct hid_device *hid = hiddev->hid;
@@ -300,6 +308,10 @@ static int hiddev_open(struct inode *inode, struct file *file)
300308
hid_hw_power(hid, PM_HINT_NORMAL);
301309
bail_unlock:
302310
mutex_unlock(&hiddev->existancelock);
311+
312+
spin_lock_irq(&list->hiddev->list_lock);
313+
list_del(&list->node);
314+
spin_unlock_irq(&list->hiddev->list_lock);
303315
bail:
304316
file->private_data = NULL;
305317
vfree(list);

drivers/hid/wacom_wac.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -533,14 +533,14 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
533533
*/
534534
buttons = (data[4] << 1) | (data[3] & 0x01);
535535
} else if (features->type == CINTIQ_COMPANION_2) {
536-
/* d-pad right -> data[4] & 0x10
537-
* d-pad up -> data[4] & 0x20
538-
* d-pad left -> data[4] & 0x40
539-
* d-pad down -> data[4] & 0x80
540-
* d-pad center -> data[3] & 0x01
536+
/* d-pad right -> data[2] & 0x10
537+
* d-pad up -> data[2] & 0x20
538+
* d-pad left -> data[2] & 0x40
539+
* d-pad down -> data[2] & 0x80
540+
* d-pad center -> data[1] & 0x01
541541
*/
542542
buttons = ((data[2] >> 4) << 7) |
543-
((data[1] & 0x04) << 6) |
543+
((data[1] & 0x04) << 4) |
544544
((data[2] & 0x0F) << 2) |
545545
(data[1] & 0x03);
546546
} else if (features->type >= INTUOS5S && features->type <= INTUOSPL) {

0 commit comments

Comments
 (0)