Distribution: All (anything with hiddev) Hardware Environment: Absolute positioning USB device using hiddev Software Environment: All Problem Description: In trying to use a hiddev usb device in linux, we found the following bug. It causes hiddev_events to be missing when reading from the device (eg. /dev/hiddev0). All that is required is that any value in a field be the same as it was the last time it was read from the device. After they are eaten by the kernel, there is no way to get these missing events from user-space. Since it is not known which events are missing, it is impossible to reconstruct what is actually coming from the device. This renders hiddev useless for many devices. Anyway, I would like to know where else I should post this or where I can post a patch that fixes the problem for a future release. hid-core.c : static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data) { ... for (n = 0; n < count; n++) { if (HID_MAIN_ITEM_VARIABLE & field->flags) { if (field->flags & HID_MAIN_ITEM_RELATIVE) { if (!value[n]) continue; } else { if (value[n] == field->value[n]) continue;//BUG! } hid_process_event(hid, field, &field->usage[n], value[n]); //Never gets called !!!! no hiddev_event on /dev/hiddev0 continue; } } ... } Steps to reproduce: Pretty much use any hiddev device that uses absolute positioning. Even if the device is relative, I don't think the kernel should be eating events like it is above. One has to expect a certain order of hiddev_events when reading from /dev/hiddevX in order to determine what they mean. When the kernel eats a few of them up they become meaningless. Fix: Remove the following code: if (field->flags & HID_MAIN_ITEM_RELATIVE) { if (!value[n]) continue; } else { if (value[n] == field->value[n]) continue; }
This bug also stops CRYPTOCard initializers from working. Is there any particular reason why this report caching is needed?
The HID protocol is supposed to be stateless (describing only the current state of the device) and thus duplicate VARIABLE reports are, according to the specification, carrying no information and the kernel is allowed to filter them out. However, many devices abuse the HID protocol for non-human-input uses, and also abuse the reports as a generic data transport channel. Since the filtering isn't strictly needed in the kernel (it only saves some CPU cycles in processing the events) and it breaks these out-of-spec devices, I removed it in 2.6.12-pre. Consider the bug fixed.