Skip to content

Commit 1ad273d

Browse files
whotJiri Kosina
authored andcommitted
HID: input: do not run GET_REPORT unless there's a Resolution Multiplier
hid-multitouch currently runs GET_REPORT for Contact Max and again to retrieve the Win8 blob. If both are within the same report, the Resolution Multiplier code calls GET_FEATURE again and this time, possibly due to timing, it causes the ILITEK-TP device interpret the GET_FEATURE as an instruction to change the mode and effectively stop the device from functioning as expected. Notably: the device doesn't even have a Resolution Multiplier so it shouldn't be affected by any of this at all. Fix this by making sure we only execute GET_REPORT if there is a Resolution Multiplier in the respective report. Where the HID_QUIRK_NO_INIT_REPORTS field is set we just bail out immediately. This shouldn't be triggered by any real device anyway. Signed-off-by: Peter Hutterer <[email protected]> Tested-by: Wen He <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 8e9ddbd commit 1ad273d

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

drivers/hid/hid-input.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,21 +1560,12 @@ static bool __hidinput_change_resolution_multipliers(struct hid_device *hid,
15601560
{
15611561
struct hid_usage *usage;
15621562
bool update_needed = false;
1563+
bool get_report_completed = false;
15631564
int i, j;
15641565

15651566
if (report->maxfield == 0)
15661567
return false;
15671568

1568-
/*
1569-
* If we have more than one feature within this report we
1570-
* need to fill in the bits from the others before we can
1571-
* overwrite the ones for the Resolution Multiplier.
1572-
*/
1573-
if (report->maxfield > 1) {
1574-
hid_hw_request(hid, report, HID_REQ_GET_REPORT);
1575-
hid_hw_wait(hid);
1576-
}
1577-
15781569
for (i = 0; i < report->maxfield; i++) {
15791570
__s32 value = use_logical_max ?
15801571
report->field[i]->logical_maximum :
@@ -1593,6 +1584,25 @@ static bool __hidinput_change_resolution_multipliers(struct hid_device *hid,
15931584
if (usage->hid != HID_GD_RESOLUTION_MULTIPLIER)
15941585
continue;
15951586

1587+
/*
1588+
* If we have more than one feature within this
1589+
* report we need to fill in the bits from the
1590+
* others before we can overwrite the ones for the
1591+
* Resolution Multiplier.
1592+
*
1593+
* But if we're not allowed to read from the device,
1594+
* we just bail. Such a device should not exist
1595+
* anyway.
1596+
*/
1597+
if (!get_report_completed && report->maxfield > 1) {
1598+
if (hid->quirks & HID_QUIRK_NO_INIT_REPORTS)
1599+
return update_needed;
1600+
1601+
hid_hw_request(hid, report, HID_REQ_GET_REPORT);
1602+
hid_hw_wait(hid);
1603+
get_report_completed = true;
1604+
}
1605+
15961606
report->field[i]->value[j] = value;
15971607
update_needed = true;
15981608
}

0 commit comments

Comments
 (0)