Linux hiddev MSR or timing is the king

Documentation about generic hiddev api in Linux is almost non-existent and there are little to none examples on the internet that can be easily googled. Nevertheless, I have been confronted with piece of software that reads USB MSR using HID interface. It was working all nice and fine only very rarely throwing up some glitch but most of the time that went by almost unnoticed. So was it until that piece of software was moved to new Linux kernel/hardware. Bummer, every 20th or so swipe would return previous card information. Totally not something one would expect looking at the sources et al.
After 2 days of debugging and messing around I found that cause for those hiccups were timing or good old race condition. No documentation of Linux hiddev tells you that you should give some time for driver to update data structures before trying to read them out and after event has been fired over “read” interface (Documentation/usb/hiddev.txt). So if you deal with generic linux hiddev API, use poll to check if something came in from device and use ioctls to read usages (just because device calls for that) make sure to insert some delay between poll/read and ioctl. I used 10ms, long enough for any modern computer to do lots of things, like update data structures in driver, short enough for human being not notice it.

Leave a Reply