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 /drivers | |
| 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>
Diffstat (limited to 'drivers')
| -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); |
