Message ID | 20200514111448.GA855579@jelly (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | HID: input: do not run GET_REPORT unless there's a Resolution Multiplier | expand |
Hey, On Thu, May 14, 2020 at 1:14 PM Peter Hutterer <peter.hutterer@who-t.net> wrote: > > 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. > > Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> > Tested-by: Wen He <wen.he_1@nxp.com> > --- > drivers/hid/hid-input.c | 22 ++++++++++++---------- > 1 file changed, 12 insertions(+), 10 deletions(-) > > diff --git drivers/hid/hid-input.c drivers/hid/hid-input.c Seems like you git format-patch is still busted, you are lacking the 'a/' and 'b/' in front of the files, and so the patch fails to apply because 'hid/hid-input.c' is not in the tree. Cheers, Benjamin > index dea9cc65bf80..a54824d451bf 100644 > --- drivers/hid/hid-input.c > +++ drivers/hid/hid-input.c > @@ -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,17 @@ 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. > + */ > + if (!get_report_completed && report->maxfield > 1) { > + 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; > } > -- > 2.26.2 >
diff --git drivers/hid/hid-input.c drivers/hid/hid-input.c index dea9cc65bf80..a54824d451bf 100644 --- drivers/hid/hid-input.c +++ drivers/hid/hid-input.c @@ -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,17 @@ 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. + */ + if (!get_report_completed && report->maxfield > 1) { + 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; }