diff options
author | Benjamin Tissoires <benjamin.tissoires@gmail.com> | 2013-02-06 06:10:47 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-02-07 09:13:14 -0500 |
commit | 7e3cc447ff8906558619b1ecc46e4bd776a4f3a6 (patch) | |
tree | fb85c661a61af1354982ae83036dccf6d81b6d0b | |
parent | dc3e1d8052548f5b46288a1d43c93684f7d64804 (diff) |
HID: multitouch: do not use pointers towards hid-core
The previous implementation registered a pointer towards hid-core
to the value of contact count. This is not safe and may be difficult
to debug if hid-core ever changes its implementation.
The use of regular indexes is a better choice.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-multitouch.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 28af54fb07d9..e22fbd33ad8c 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -84,7 +84,8 @@ struct mt_device { | |||
84 | struct mt_class mtclass; /* our mt device class */ | 84 | struct mt_class mtclass; /* our mt device class */ |
85 | struct mt_fields *fields; /* temporary placeholder for storing the | 85 | struct mt_fields *fields; /* temporary placeholder for storing the |
86 | multitouch fields */ | 86 | multitouch fields */ |
87 | __s32 *contactcount; /* contact count value in the report */ | 87 | int cc_index; /* contact count field index in the report */ |
88 | int cc_value_index; /* contact count value index in the field */ | ||
88 | unsigned last_field_index; /* last field index of the report */ | 89 | unsigned last_field_index; /* last field index of the report */ |
89 | unsigned last_slot_field; /* the last field of a slot */ | 90 | unsigned last_slot_field; /* the last field of a slot */ |
90 | unsigned mt_report_id; /* the report ID of the multitouch device */ | 91 | unsigned mt_report_id; /* the report ID of the multitouch device */ |
@@ -269,7 +270,7 @@ static ssize_t mt_set_quirks(struct device *dev, | |||
269 | 270 | ||
270 | td->mtclass.quirks = val; | 271 | td->mtclass.quirks = val; |
271 | 272 | ||
272 | if (!td->contactcount) | 273 | if (td->cc_index < 0) |
273 | td->mtclass.quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; | 274 | td->mtclass.quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; |
274 | 275 | ||
275 | return count; | 276 | return count; |
@@ -483,7 +484,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
483 | td->last_field_index = field->index; | 484 | td->last_field_index = field->index; |
484 | return 1; | 485 | return 1; |
485 | case HID_DG_CONTACTCOUNT: | 486 | case HID_DG_CONTACTCOUNT: |
486 | td->contactcount = field->value + usage->usage_index; | 487 | td->cc_index = field->index; |
488 | td->cc_value_index = usage->usage_index; | ||
487 | td->last_field_index = field->index; | 489 | td->last_field_index = field->index; |
488 | return 1; | 490 | return 1; |
489 | case HID_DG_CONTACTMAX: | 491 | case HID_DG_CONTACTMAX: |
@@ -701,8 +703,12 @@ static void mt_report(struct hid_device *hid, struct hid_report *report) | |||
701 | * Includes multi-packet support where subsequent | 703 | * Includes multi-packet support where subsequent |
702 | * packets are sent with zero contactcount. | 704 | * packets are sent with zero contactcount. |
703 | */ | 705 | */ |
704 | if (td->contactcount && *td->contactcount) | 706 | if (td->cc_index >= 0) { |
705 | td->num_expected = *td->contactcount; | 707 | struct hid_field *field = report->field[td->cc_index]; |
708 | int value = field->value[td->cc_value_index]; | ||
709 | if (value) | ||
710 | td->num_expected = value; | ||
711 | } | ||
706 | 712 | ||
707 | for (r = 0; r < report->maxfield; r++) { | 713 | for (r = 0; r < report->maxfield; r++) { |
708 | field = report->field[r]; | 714 | field = report->field[r]; |
@@ -786,7 +792,7 @@ static void mt_post_parse(struct mt_device *td) | |||
786 | td->last_slot_field = f->usages[field_count_per_touch - 1]; | 792 | td->last_slot_field = f->usages[field_count_per_touch - 1]; |
787 | } | 793 | } |
788 | 794 | ||
789 | if (!td->contactcount) | 795 | if (td->cc_index < 0) |
790 | cls->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; | 796 | cls->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; |
791 | } | 797 | } |
792 | 798 | ||
@@ -845,6 +851,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
845 | td->mtclass = *mtclass; | 851 | td->mtclass = *mtclass; |
846 | td->inputmode = -1; | 852 | td->inputmode = -1; |
847 | td->maxcontact_report_id = -1; | 853 | td->maxcontact_report_id = -1; |
854 | td->cc_index = -1; | ||
848 | hid_set_drvdata(hdev, td); | 855 | hid_set_drvdata(hdev, td); |
849 | 856 | ||
850 | td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL); | 857 | td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL); |