]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
50b6987d6636a3ed58b2e91d42d1e8348ac11d44
[thirdparty/kernel/stable-queue.git] /
1 From b43f977dd281945960c26b3ef67bba0fa07d39d9 Mon Sep 17 00:00:00 2001
2 From: Jason Gerecke <killertofu@gmail.com>
3 Date: Wed, 8 Apr 2020 07:58:37 -0700
4 Subject: Revert "HID: wacom: generic: read the number of expected touches on a per collection basis"
5
6 From: Jason Gerecke <killertofu@gmail.com>
7
8 commit b43f977dd281945960c26b3ef67bba0fa07d39d9 upstream.
9
10 This reverts commit 15893fa40109f5e7c67eeb8da62267d0fdf0be9d.
11
12 The referenced commit broke pen and touch input for a variety of devices
13 such as the Cintiq Pro 32. Affected devices may appear to work normally
14 for a short amount of time, but eventually loose track of actual touch
15 state and can leave touch arbitration enabled which prevents the pen
16 from working. The commit is not itself required for any currently-available
17 Bluetooth device, and so we revert it to correct the behavior of broken
18 devices.
19
20 This breakage occurs due to a mismatch between the order of collections
21 and the order of usages on some devices. This commit tries to read the
22 contact count before processing events, but will fail if the contact
23 count does not occur prior to the first logical finger collection. This
24 is the case for devices like the Cintiq Pro 32 which place the contact
25 count at the very end of the report.
26
27 Without the contact count set, touches will only be partially processed.
28 The `wacom_wac_finger_slot` function will not open any slots since the
29 number of contacts seen is greater than the expectation of 0, but we will
30 still end up calling `input_mt_sync_frame` for each finger anyway. This
31 can cause problems for userspace separate from the issue currently taking
32 place in the kernel. Only once all of the individual finger collections
33 have been processed do we finally get to the enclosing collection which
34 contains the contact count. The value ends up being used for the *next*
35 report, however.
36
37 This delayed use of the contact count can cause the driver to loose track
38 of the actual touch state and believe that there are contacts down when
39 there aren't. This leaves touch arbitration enabled and prevents the pen
40 from working. It can also cause userspace to incorrectly treat single-
41 finger input as gestures.
42
43 Link: https://github.com/linuxwacom/input-wacom/issues/146
44 Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
45 Reviewed-by: Aaron Armstrong Skomra <aaron.skomra@wacom.com>
46 Fixes: 15893fa40109 ("HID: wacom: generic: read the number of expected touches on a per collection basis")
47 Cc: stable@vger.kernel.org # 5.3+
48 Signed-off-by: Jiri Kosina <jkosina@suse.cz>
49 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
50
51 ---
52 drivers/hid/wacom_wac.c | 79 +++++++++---------------------------------------
53 1 file changed, 16 insertions(+), 63 deletions(-)
54
55 --- a/drivers/hid/wacom_wac.c
56 +++ b/drivers/hid/wacom_wac.c
57 @@ -2637,9 +2637,25 @@ static void wacom_wac_finger_pre_report(
58 case HID_DG_TIPSWITCH:
59 hid_data->last_slot_field = equivalent_usage;
60 break;
61 + case HID_DG_CONTACTCOUNT:
62 + hid_data->cc_report = report->id;
63 + hid_data->cc_index = i;
64 + hid_data->cc_value_index = j;
65 + break;
66 }
67 }
68 }
69 +
70 + if (hid_data->cc_report != 0 &&
71 + hid_data->cc_index >= 0) {
72 + struct hid_field *field = report->field[hid_data->cc_index];
73 + int value = field->value[hid_data->cc_value_index];
74 + if (value)
75 + hid_data->num_expected = value;
76 + }
77 + else {
78 + hid_data->num_expected = wacom_wac->features.touch_max;
79 + }
80 }
81
82 static void wacom_wac_finger_report(struct hid_device *hdev,
83 @@ -2649,7 +2665,6 @@ static void wacom_wac_finger_report(stru
84 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
85 struct input_dev *input = wacom_wac->touch_input;
86 unsigned touch_max = wacom_wac->features.touch_max;
87 - struct hid_data *hid_data = &wacom_wac->hid_data;
88
89 /* If more packets of data are expected, give us a chance to
90 * process them rather than immediately syncing a partial
91 @@ -2663,7 +2678,6 @@ static void wacom_wac_finger_report(stru
92
93 input_sync(input);
94 wacom_wac->hid_data.num_received = 0;
95 - hid_data->num_expected = 0;
96
97 /* keep touch state for pen event */
98 wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac);
99 @@ -2738,73 +2752,12 @@ static void wacom_report_events(struct h
100 }
101 }
102
103 -static void wacom_set_num_expected(struct hid_device *hdev,
104 - struct hid_report *report,
105 - int collection_index,
106 - struct hid_field *field,
107 - int field_index)
108 -{
109 - struct wacom *wacom = hid_get_drvdata(hdev);
110 - struct wacom_wac *wacom_wac = &wacom->wacom_wac;
111 - struct hid_data *hid_data = &wacom_wac->hid_data;
112 - unsigned int original_collection_level =
113 - hdev->collection[collection_index].level;
114 - bool end_collection = false;
115 - int i;
116 -
117 - if (hid_data->num_expected)
118 - return;
119 -
120 - // find the contact count value for this segment
121 - for (i = field_index; i < report->maxfield && !end_collection; i++) {
122 - struct hid_field *field = report->field[i];
123 - unsigned int field_level =
124 - hdev->collection[field->usage[0].collection_index].level;
125 - unsigned int j;
126 -
127 - if (field_level != original_collection_level)
128 - continue;
129 -
130 - for (j = 0; j < field->maxusage; j++) {
131 - struct hid_usage *usage = &field->usage[j];
132 -
133 - if (usage->collection_index != collection_index) {
134 - end_collection = true;
135 - break;
136 - }
137 - if (wacom_equivalent_usage(usage->hid) == HID_DG_CONTACTCOUNT) {
138 - hid_data->cc_report = report->id;
139 - hid_data->cc_index = i;
140 - hid_data->cc_value_index = j;
141 -
142 - if (hid_data->cc_report != 0 &&
143 - hid_data->cc_index >= 0) {
144 -
145 - struct hid_field *field =
146 - report->field[hid_data->cc_index];
147 - int value =
148 - field->value[hid_data->cc_value_index];
149 -
150 - if (value)
151 - hid_data->num_expected = value;
152 - }
153 - }
154 - }
155 - }
156 -
157 - if (hid_data->cc_report == 0 || hid_data->cc_index < 0)
158 - hid_data->num_expected = wacom_wac->features.touch_max;
159 -}
160 -
161 static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report,
162 int collection_index, struct hid_field *field,
163 int field_index)
164 {
165 struct wacom *wacom = hid_get_drvdata(hdev);
166
167 - if (WACOM_FINGER_FIELD(field))
168 - wacom_set_num_expected(hdev, report, collection_index, field,
169 - field_index);
170 wacom_report_events(hdev, report, collection_index, field_index);
171
172 /*