Skip to content

Commit d9cbf02

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: Revert "HID: magicmouse: ignore 'ivalid report id' while switching modes" HID: hid-multitouch: fix broken eGalax HID: MAINTAINERS: Update USB HID/HIDBP DRIVERS pattern HID: hid-multitouch: add support for Chunghwa multi-touch panel HID: hiddev: fix use after free in hiddev_release HID: add quirk for HyperPen 10000U HID: hiddev: fix potential use-after-free
2 parents 0835619 + c3a4924 commit d9cbf02

File tree

8 files changed

+59
-30
lines changed

8 files changed

+59
-30
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6463,7 +6463,7 @@ M: Jiri Kosina <jkosina@suse.cz>
64636463
L: linux-usb@vger.kernel.org
64646464
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git
64656465
S: Maintained
6466-
F: Documentation/usb/hiddev.txt
6466+
F: Documentation/hid/hiddev.txt
64676467
F: drivers/hid/usbhid/
64686468

64696469
USB ISP116X DRIVER

drivers/hid/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ config HID_MULTITOUCH
305305
- 3M PCT touch screens
306306
- ActionStar dual touch panels
307307
- Cando dual touch panels
308+
- Chunghwa panels
308309
- CVTouch panels
309310
- Cypress TrueTouch panels
310311
- Elo TouchSystems IntelliTouch Plus panels

drivers/hid/hid-core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,6 +1359,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
13591359
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
13601360
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
13611361
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
1362+
{ HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
13621363
{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
13631364
{ HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) },
13641365
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },

drivers/hid/hid-ids.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@
173173
#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d
174174
#define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618
175175

176+
#define USB_VENDOR_ID_CHUNGHWAT 0x2247
177+
#define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001
178+
176179
#define USB_VENDOR_ID_CIDC 0x1677
177180

178181
#define USB_VENDOR_ID_CMEDIA 0x0d8c
@@ -622,6 +625,7 @@
622625
#define USB_VENDOR_ID_UCLOGIC 0x5543
623626
#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
624627
#define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001
628+
#define USB_DEVICE_ID_UCLOGIC_TABLET_TWA60 0x0064
625629
#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003
626630
#define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004
627631
#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005

drivers/hid/hid-magicmouse.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -501,17 +501,9 @@ static int magicmouse_probe(struct hid_device *hdev,
501501
}
502502
report->size = 6;
503503

504-
/*
505-
* The device reponds with 'invalid report id' when feature
506-
* report switching it into multitouch mode is sent to it.
507-
*
508-
* This results in -EIO from the _raw low-level transport callback,
509-
* but there seems to be no other way of switching the mode.
510-
* Thus the super-ugly hacky success check below.
511-
*/
512504
ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
513505
HID_FEATURE_REPORT);
514-
if (ret != -EIO) {
506+
if (ret != sizeof(feature)) {
515507
hid_err(hdev, "unable to request touch data (%d)\n", ret);
516508
goto err_stop_hw;
517509
}

drivers/hid/hid-multitouch.c

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct mt_device {
6464
struct mt_class *mtclass; /* our mt device class */
6565
unsigned last_field_index; /* last field index of the report */
6666
unsigned last_slot_field; /* the last field of a slot */
67+
int last_mt_collection; /* last known mt-related collection */
6768
__s8 inputmode; /* InputMode HID feature, -1 if non-existent */
6869
__u8 num_received; /* how many contacts we received */
6970
__u8 num_expected; /* expected last contact index */
@@ -225,8 +226,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
225226
cls->sn_move);
226227
/* touchscreen emulation */
227228
set_abs(hi->input, ABS_X, field, cls->sn_move);
228-
td->last_slot_field = usage->hid;
229-
td->last_field_index = field->index;
229+
if (td->last_mt_collection == usage->collection_index) {
230+
td->last_slot_field = usage->hid;
231+
td->last_field_index = field->index;
232+
}
230233
return 1;
231234
case HID_GD_Y:
232235
if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
@@ -237,40 +240,51 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
237240
cls->sn_move);
238241
/* touchscreen emulation */
239242
set_abs(hi->input, ABS_Y, field, cls->sn_move);
240-
td->last_slot_field = usage->hid;
241-
td->last_field_index = field->index;
243+
if (td->last_mt_collection == usage->collection_index) {
244+
td->last_slot_field = usage->hid;
245+
td->last_field_index = field->index;
246+
}
242247
return 1;
243248
}
244249
return 0;
245250

246251
case HID_UP_DIGITIZER:
247252
switch (usage->hid) {
248253
case HID_DG_INRANGE:
249-
td->last_slot_field = usage->hid;
250-
td->last_field_index = field->index;
254+
if (td->last_mt_collection == usage->collection_index) {
255+
td->last_slot_field = usage->hid;
256+
td->last_field_index = field->index;
257+
}
251258
return 1;
252259
case HID_DG_CONFIDENCE:
253-
td->last_slot_field = usage->hid;
254-
td->last_field_index = field->index;
260+
if (td->last_mt_collection == usage->collection_index) {
261+
td->last_slot_field = usage->hid;
262+
td->last_field_index = field->index;
263+
}
255264
return 1;
256265
case HID_DG_TIPSWITCH:
257266
hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
258267
input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
259-
td->last_slot_field = usage->hid;
260-
td->last_field_index = field->index;
268+
if (td->last_mt_collection == usage->collection_index) {
269+
td->last_slot_field = usage->hid;
270+
td->last_field_index = field->index;
271+
}
261272
return 1;
262273
case HID_DG_CONTACTID:
263274
input_mt_init_slots(hi->input, td->maxcontacts);
264275
td->last_slot_field = usage->hid;
265276
td->last_field_index = field->index;
277+
td->last_mt_collection = usage->collection_index;
266278
return 1;
267279
case HID_DG_WIDTH:
268280
hid_map_usage(hi, usage, bit, max,
269281
EV_ABS, ABS_MT_TOUCH_MAJOR);
270282
set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
271283
cls->sn_width);
272-
td->last_slot_field = usage->hid;
273-
td->last_field_index = field->index;
284+
if (td->last_mt_collection == usage->collection_index) {
285+
td->last_slot_field = usage->hid;
286+
td->last_field_index = field->index;
287+
}
274288
return 1;
275289
case HID_DG_HEIGHT:
276290
hid_map_usage(hi, usage, bit, max,
@@ -279,8 +293,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
279293
cls->sn_height);
280294
input_set_abs_params(hi->input,
281295
ABS_MT_ORIENTATION, 0, 1, 0, 0);
282-
td->last_slot_field = usage->hid;
283-
td->last_field_index = field->index;
296+
if (td->last_mt_collection == usage->collection_index) {
297+
td->last_slot_field = usage->hid;
298+
td->last_field_index = field->index;
299+
}
284300
return 1;
285301
case HID_DG_TIPPRESSURE:
286302
if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
@@ -292,16 +308,20 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
292308
/* touchscreen emulation */
293309
set_abs(hi->input, ABS_PRESSURE, field,
294310
cls->sn_pressure);
295-
td->last_slot_field = usage->hid;
296-
td->last_field_index = field->index;
311+
if (td->last_mt_collection == usage->collection_index) {
312+
td->last_slot_field = usage->hid;
313+
td->last_field_index = field->index;
314+
}
297315
return 1;
298316
case HID_DG_CONTACTCOUNT:
299-
td->last_field_index = field->index;
317+
if (td->last_mt_collection == usage->collection_index)
318+
td->last_field_index = field->index;
300319
return 1;
301320
case HID_DG_CONTACTMAX:
302321
/* we don't set td->last_slot_field as contactcount and
303322
* contact max are global to the report */
304-
td->last_field_index = field->index;
323+
if (td->last_mt_collection == usage->collection_index)
324+
td->last_field_index = field->index;
305325
return -1;
306326
}
307327
/* let hid-input decide for the others */
@@ -516,6 +536,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
516536
}
517537
td->mtclass = mtclass;
518538
td->inputmode = -1;
539+
td->last_mt_collection = -1;
519540
hid_set_drvdata(hdev, td);
520541

521542
ret = hid_parse(hdev);
@@ -593,6 +614,11 @@ static const struct hid_device_id mt_devices[] = {
593614
HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
594615
USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) },
595616

617+
/* Chunghwa Telecom touch panels */
618+
{ .driver_data = MT_CLS_DEFAULT,
619+
HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT,
620+
USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
621+
596622
/* CVTouch panels */
597623
{ .driver_data = MT_CLS_DEFAULT,
598624
HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH,

drivers/hid/usbhid/hid-quirks.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ static const struct hid_blacklist {
7474
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
7575
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT },
7676
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT },
77+
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60, HID_QUIRK_MULTI_INPUT },
7778
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U, HID_QUIRK_MULTI_INPUT },
7879
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT },
7980
{ USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },

drivers/hid/usbhid/hiddev.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,15 @@ static int hiddev_release(struct inode * inode, struct file * file)
248248
usbhid_close(list->hiddev->hid);
249249
usbhid_put_power(list->hiddev->hid);
250250
} else {
251+
mutex_unlock(&list->hiddev->existancelock);
251252
kfree(list->hiddev);
253+
kfree(list);
254+
return 0;
252255
}
253256
}
254257

255-
kfree(list);
256258
mutex_unlock(&list->hiddev->existancelock);
259+
kfree(list);
257260

258261
return 0;
259262
}
@@ -923,10 +926,11 @@ void hiddev_disconnect(struct hid_device *hid)
923926
usb_deregister_dev(usbhid->intf, &hiddev_class);
924927

925928
if (hiddev->open) {
929+
mutex_unlock(&hiddev->existancelock);
926930
usbhid_close(hiddev->hid);
927931
wake_up_interruptible(&hiddev->wait);
928932
} else {
933+
mutex_unlock(&hiddev->existancelock);
929934
kfree(hiddev);
930935
}
931-
mutex_unlock(&hiddev->existancelock);
932936
}

0 commit comments

Comments
 (0)