mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
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 <peter.hutterer@who-t.net> Tested-by: Wen He <wen.he_1@nxp.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
parent
8e9ddbde9d
commit
1ad273d6ff
@ -1560,21 +1560,12 @@ static bool __hidinput_change_resolution_multipliers(struct hid_device *hid,
|
||||
{
|
||||
struct hid_usage *usage;
|
||||
bool update_needed = false;
|
||||
bool get_report_completed = false;
|
||||
int i, j;
|
||||
|
||||
if (report->maxfield == 0)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If we have more than one feature within this report we
|
||||
* need to fill in the bits from the others before we can
|
||||
* overwrite the ones for the Resolution Multiplier.
|
||||
*/
|
||||
if (report->maxfield > 1) {
|
||||
hid_hw_request(hid, report, HID_REQ_GET_REPORT);
|
||||
hid_hw_wait(hid);
|
||||
}
|
||||
|
||||
for (i = 0; i < report->maxfield; i++) {
|
||||
__s32 value = use_logical_max ?
|
||||
report->field[i]->logical_maximum :
|
||||
@ -1593,6 +1584,25 @@ static bool __hidinput_change_resolution_multipliers(struct hid_device *hid,
|
||||
if (usage->hid != HID_GD_RESOLUTION_MULTIPLIER)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If we have more than one feature within this
|
||||
* report we need to fill in the bits from the
|
||||
* others before we can overwrite the ones for the
|
||||
* Resolution Multiplier.
|
||||
*
|
||||
* But if we're not allowed to read from the device,
|
||||
* we just bail. Such a device should not exist
|
||||
* anyway.
|
||||
*/
|
||||
if (!get_report_completed && report->maxfield > 1) {
|
||||
if (hid->quirks & HID_QUIRK_NO_INIT_REPORTS)
|
||||
return update_needed;
|
||||
|
||||
hid_hw_request(hid, report, HID_REQ_GET_REPORT);
|
||||
hid_hw_wait(hid);
|
||||
get_report_completed = true;
|
||||
}
|
||||
|
||||
report->field[i]->value[j] = value;
|
||||
update_needed = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user