HID: introduce proper zeroing of unused bits in output reports
authorSimon Budig <simon@budig.de>
Mon, 12 Mar 2007 12:52:04 +0000 (13:52 +0100)
committerJiri Kosina <jkosina@suse.cz>
Wed, 11 Apr 2007 08:36:36 +0000 (10:36 +0200)
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>
drivers/hid/hid-core.c

index 67f3347afcf35620d941a893183f0883f0392f00..c16c9499d9c4af5d107ee61db5bc5994ad61c891 100644 (file)
@@ -872,8 +872,13 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
        unsigned count = field->report_count;
        unsigned offset = field->report_offset;
        unsigned size = field->report_size;
+       unsigned bitsused = offset + count * size;
        unsigned n;
 
+       /* make sure the unused bits in the last byte are zeros */
+       if (count > 0 && size > 0 && (bitsused % 8) != 0)
+               data[(bitsused-1)/8] &= (1 << (bitsused % 8)) - 1;
+
        for (n = 0; n < count; n++) {
                if (field->logical_minimum < 0) /* signed values */
                        implement(data, offset + n * size, size, s32ton(field->value[n], size));