mirror of
https://github.com/torvalds/linux.git
synced 2026-09-12 12:34:02 +02:00
HID: multitouch: Fix stale MT slots when contact count drops to zero
The INGENIC 17EF:6161 touchscreen (Lenovo Yoga Book 9 14IAH10) reports HID_DG_CONTACTCOUNT=0 in the frame immediately following the last finger lift rather than omitting the frame entirely. In mt_touch_report() the existing code only updates num_expected when contact_count is non-zero, so a zero contact count on the first packet of a new frame leaves num_expected at its previous value (e.g. 2 for a two-finger gesture). The sync check "num_received >= num_expected" then evaluates "0 >= 2" and never fires, preventing INPUT_MT_DROP_UNUSED from releasing the stale slots. Those slots remain active in the kernel MT layer until the next touch, at which point they are released in a batch alongside the new contact — causing the userspace event consumer to miss the intervening finger-up sequence and corrupt its gesture session state. Fix by resetting num_expected to 0 when contact_count is zero and num_received is still 0 (i.e., this is the first and only packet of the frame, not a continuation packet in a multi-packet sequence). With num_expected=0 the sync check "0 >= 0" fires immediately, calling input_mt_sync_frame() which drops the stale slots via INPUT_MT_DROP_UNUSED. The num_received==0 guard is critical: continuation packets in a multi-packet frame arrive after at least one contact has already been processed (num_received>0), so they are correctly excluded from this path and the existing multi-packet logic is unaffected. Signed-off-by: Dave Carey <carvsdriver@gmail.com> Tested-by: Dave Carey <carvsdriver@gmail.com> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
This commit is contained in:
parent
1c942462c3
commit
e8e60b6439
|
|
@ -1321,21 +1321,18 @@ static void mt_touch_report(struct hid_device *hid,
|
|||
* Includes multi-packet support where subsequent
|
||||
* packets are sent with zero contactcount.
|
||||
*/
|
||||
if (contact_count >= 0) {
|
||||
if (contact_count > 0)
|
||||
app->num_expected = contact_count;
|
||||
else if (app->num_received == 0 && app->prev_scantime != scantime) {
|
||||
/*
|
||||
* New multi-report frame:
|
||||
*
|
||||
* For Win8 PTPs the first packet (td->num_received == 0) may
|
||||
* have a contactcount of 0 if there only is a button event.
|
||||
* We double check that this is not a continuation packet
|
||||
* of a possible multi-packet frame be checking that the
|
||||
* timestamp has changed.
|
||||
*
|
||||
* Some other devices use a sentinel frame with 0 to release all contacts
|
||||
*/
|
||||
if ((app->quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
|
||||
app->num_received == 0 &&
|
||||
app->prev_scantime != scantime)
|
||||
app->num_expected = contact_count;
|
||||
/* A non 0 contact count always indicates a first packet */
|
||||
else if (contact_count)
|
||||
app->num_expected = contact_count;
|
||||
app->num_expected = 0;
|
||||
}
|
||||
app->prev_scantime = scantime;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user