summaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2014-04-30 17:48:40 -0400
committerJiri Kosina <jkosina@suse.cz>2014-05-05 09:54:40 -0400
commit19e4ec525b37cdecbdb4f86edaae7f56a67339ee (patch)
tree09ff821bfc4f821fd900a01da3b8e5eb6147d3a2 /drivers/hid
parent7c7606a2464fee1cf50efef34aa44aee1edf453a (diff)
HID: core: fix computation of the report size
The extra seven bits are only required when allocating the report buffer. We can not use those extra bytes for the length of the report in the generic implementation of .request because the device might (will) refuse the set_report command. This has been verified on the Atmel touchpad found on the Samsung Ativ 9 plus, which uses hid-multitouch and HID over I2C. Without this fix, the device refuses to switch to the multitouch mode, and it becomes unresponsive from the user point of view. Actually, this has been discussed during the initial submission of the commit 4fa5a7f76cc7b6ac87f57741edd2b124851d119f, see https://patchwork.kernel.org/patch/3621751/ Unfortunately, I completely forgot about it later. Reported-by: Matthias Bayer <thematthiasbayer@gmail.com> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-core.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 10a2c0866459..da52279de939 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1253,7 +1253,8 @@ EXPORT_SYMBOL_GPL(hid_output_report);
1253 1253
1254static int hid_report_len(struct hid_report *report) 1254static int hid_report_len(struct hid_report *report)
1255{ 1255{
1256 return ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7; 1256 /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
1257 return ((report->size - 1) >> 3) + 1 + (report->id > 0);
1257} 1258}
1258 1259
1259/* 1260/*
@@ -1266,7 +1267,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags)
1266 * of implement() working on 8 byte chunks 1267 * of implement() working on 8 byte chunks
1267 */ 1268 */
1268 1269
1269 int len = hid_report_len(report); 1270 int len = hid_report_len(report) + 7;
1270 1271
1271 return kmalloc(len, flags); 1272 return kmalloc(len, flags);
1272} 1273}