summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-11-11 14:19:09 +0100
committerHenrik Rydberg <rydberg@euromail.se>2010-11-11 14:20:34 +0100
commit287b84bd847d9de0b941f845baaa205242fcaaa3 (patch)
treeec8cddda359ef6c0e5a78e82b18c54b5a5f56d89 /usr/src
parentac71d2327135ad0d313397305a841dbfc34abb92 (diff)
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 <rydberg@euromail.se>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/dkms_source_tree/hid-ntrig.c25
1 files changed, 21 insertions, 4 deletions
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 {
55 int nrow, ncol; 55 int nrow, ncol;
56 int index, nindex; 56 int index, nindex;
57 int nhold; 57 int nhold;
58 bool touch;
59 bool hasmt;
58}; 60};
59 61
60 62
@@ -187,6 +189,12 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
187 return 0; 189 return 0;
188 190
189 case 0xff000000: 191 case 0xff000000:
192 switch (usage->hid) {
193 case 0xff000001:
194 /* multi-touch firmware */
195 nd->hasmt = true;
196 break;
197 }
190 /* we do not want to map these: no input-oriented meaning */ 198 /* we do not want to map these: no input-oriented meaning */
191 return -1; 199 return -1;
192 } 200 }
@@ -340,7 +348,9 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
340 if (hid->claimed & HID_CLAIMED_INPUT) { 348 if (hid->claimed & HID_CLAIMED_INPUT) {
341 switch (usage->hid) { 349 switch (usage->hid) {
342 case HID_DG_TIPSWITCH: 350 case HID_DG_TIPSWITCH:
343 nd->index = nd->nindex++; 351 nd->touch = value;
352 if (nd->nindex < MAX_SLOTS)
353 nd->index = nd->nindex++;
344 break; 354 break;
345 case HID_GD_X: 355 case HID_GD_X:
346 nd->col[nd->index].x = value; 356 nd->col[nd->index].x = value;
@@ -353,11 +363,18 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
353 break; 363 break;
354 case HID_DG_HEIGHT: 364 case HID_DG_HEIGHT:
355 nd->col[nd->index].h = value; 365 nd->col[nd->index].h = value;
366 if (!nd->hasmt) {
367 nd->nindex = 0;
368 nd->ncol = nd->touch;
369 report_frame(input, nd);
370 }
356 break; 371 break;
357 case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ 372 case HID_DG_CONTACTCOUNT: /* End of a multitouch group */
358 nd->nindex = 0; 373 if (nd->hasmt) {
359 nd->ncol = value; 374 nd->nindex = 0;
360 report_frame(input, nd); 375 nd->ncol = value;
376 report_frame(input, nd);
377 }
361 break; 378 break;
362 } 379 }
363 } 380 }