From 287b84bd847d9de0b941f845baaa205242fcaaa3 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 11 Nov 2010 14:19:09 +0100 Subject: Fix for single-touch firmware The current driver does not work for single-touch firmware, and the driver occasionally crashes. The HID report which resets the array index is never received, resulting in out-of-range memory access. This patch restores functionality by detecting the presence of the multitouch firmware, and adds a range check to make the driver resilient against additional unknown firmware versions. Signed-off-by: Henrik Rydberg --- usr/src/dkms_source_tree/hid-ntrig.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'usr/src') diff --git a/usr/src/dkms_source_tree/hid-ntrig.c b/usr/src/dkms_source_tree/hid-ntrig.c index 635b44d..462a9a7 100644 --- a/usr/src/dkms_source_tree/hid-ntrig.c +++ b/usr/src/dkms_source_tree/hid-ntrig.c @@ -55,6 +55,8 @@ struct ntrig_data { int nrow, ncol; int index, nindex; int nhold; + bool touch; + bool hasmt; }; @@ -187,6 +189,12 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, return 0; case 0xff000000: + switch (usage->hid) { + case 0xff000001: + /* multi-touch firmware */ + nd->hasmt = true; + break; + } /* we do not want to map these: no input-oriented meaning */ return -1; } @@ -340,7 +348,9 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, if (hid->claimed & HID_CLAIMED_INPUT) { switch (usage->hid) { case HID_DG_TIPSWITCH: - nd->index = nd->nindex++; + nd->touch = value; + if (nd->nindex < MAX_SLOTS) + nd->index = nd->nindex++; break; case HID_GD_X: nd->col[nd->index].x = value; @@ -353,11 +363,18 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, break; case HID_DG_HEIGHT: nd->col[nd->index].h = value; + if (!nd->hasmt) { + nd->nindex = 0; + nd->ncol = nd->touch; + report_frame(input, nd); + } break; case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ - nd->nindex = 0; - nd->ncol = value; - report_frame(input, nd); + if (nd->hasmt) { + nd->nindex = 0; + nd->ncol = value; + report_frame(input, nd); + } break; } } -- cgit v1.2.3