aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-core.c
diff options
context:
space:
mode:
authorSimon Budig <simon@budig.de>2007-03-12 08:52:04 -0400
committerJiri Kosina <jkosina@suse.cz>2007-04-11 04:36:36 -0400
commit46386b587086c8d2698222a031bf749688464032 (patch)
tree47eba4258864a9f34801fda490a7602b4ba90ebb /drivers/hid/hid-core.c
parenta21bd69e1509b43823c317c3bf3f7ffa99884356 (diff)
HID: introduce proper zeroing of unused bits in output reports
Some HID devices are looking on the unused bits in the HID reports they receive. This is violating the specification, but we want to make those devices work. Well-behaving devices are unaffected, as they don't care about the unused bits. If bitsused % 8 is 0 all bits in data[] get used and we don't need to clear anything. Otherwise (bitsused % 8) bits of the last byte get used. By shifting 1 for (bitsused % 8) bits and subtracting 1 we create a mask consisting of (bitsused % 8) ones and remaining zeroes. By ANDing we clear the upper unused bits. Signed-off-by: Simon Budig <simon@budig.de> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-core.c')
-rw-r--r--drivers/hid/hid-core.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 67f3347afcf3..c16c9499d9c4 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -872,8 +872,13 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
872 unsigned count = field->report_count; 872 unsigned count = field->report_count;
873 unsigned offset = field->report_offset; 873 unsigned offset = field->report_offset;
874 unsigned size = field->report_size; 874 unsigned size = field->report_size;
875 unsigned bitsused = offset + count * size;
875 unsigned n; 876 unsigned n;
876 877
878 /* make sure the unused bits in the last byte are zeros */
879 if (count > 0 && size > 0 && (bitsused % 8) != 0)
880 data[(bitsused-1)/8] &= (1 << (bitsused % 8)) - 1;
881
877 for (n = 0; n < count; n++) { 882 for (n = 0; n < count; n++) {
878 if (field->logical_minimum < 0) /* signed values */ 883 if (field->logical_minimum < 0) /* signed values */
879 implement(data, offset + n * size, size, s32ton(field->value[n], size)); 884 implement(data, offset + n * size, size, s32ton(field->value[n], size));