How to use Linux kernel driver bind/unbind interface for USB-HID devices?
Ok, turns out the answer was staring me in the face.
Firstly, whether using our custom driver, or using the generic one that normally takes over the device, it's still all ultimately controlled by HID, and not USB.
Previously I tried to unbind it from HID, which is not the way to go. HID has sub-drivers, the one that takes over devices that have no specialized driver is called generic-usb. This is what I needed to unbind from, before binding to hid-g19. Also, I needed to use the HID address which looks like "0003:046d:c229.0036" and not the USB address which looks "1-1.1:1.1".
So before rebinding I would see this on dmesg:
generic-usb 0003:046D:C229.0036: input,hiddev0,hidraw4: USB HID v1.11 Keypad [Logitech G19 Gaming Keyboard] on usb-0000:00:13.2-3.2/input1
Then I do:
echo -n "0003:046D:C229.0036" > /sys/bus/hid/drivers/generic-usb/unbind
echo -n "0003:046D:C229.0036" > /sys/bus/hid/drivers/hid-g19/bind
And then I see on dmesg:
hid-g19 0003:046D:C229.0036: input,hiddev0,hidraw4: USB HID v1.11 Keypad [Logitech G19 Gaming Keyboard] on usb-0000:00:13.2-3.2/input1
So like I said, staring me in the face, because the two key pieces of information are the first two things on the line when the device binds...
Related videos on Youtube
collegian
Updated on September 18, 2022Comments
-
collegian over 1 year
First background. I am developing a driver for Logitech game-panel devices. It's a keyboard with a screen on it. The driver is working nicely but by default the device is handled by HID. In order to prevent HID taking over the device before my driver, I can blacklist it in hid-core.c. This works but is not the best solution as I am working with several people and we all have to keep patching our HID module which is becoming a chore, especially as it often involves rebuilding initramfs and such.
I did some research on this problem and I found this mailing list post, which eventually took me to this article on LWN. This describes a mechanism for binding devices to specific drivers at runtime. This seems like exactly what I need.
So, I tried it. I was able to unbind the keyboard from HID. This worked and as expected I could no longer type on it. But when I tried to bind it to our driver I get "error: no such device" and the operation fails.
So my question is: How do I use kernel bind/unbind operations to replicate what happens when you blacklist a HID device in hid-core and supply your own driver? - that is - to replace the need to patch hid-core.c all the time?
The source of our driver is here: https://github.com/ali1234/lg4l
-
dmansfield over 9 yearsDid you have to specify in your driver that that vendor/product is compatible with your driver? Or does the "bind" simply force the issue. I am getting "no such device" for a device that has been blacklisted but I want to force it to be bound, and I'm imaginging the the blacklisting isn't just a "prevent automatic binding" think but a "prevent binding nomatter what" type of thing.
-
collegian over 9 yearsBind forces it, so it isn't required to claim the IDs in the driver source. It is if you want it to load automatically however.
-
dmansfield over 9 yearsTwo reasons I was having trouble: first - the device is listed in the kernel's hid_ignore_list and so it won't get "hid" bound nomatter what. I had to add "usbhid.quirks=0x0b0e:0x0412:0x40000000" to kernel command line and reboot. Flag 0x40000000 is "don't ignore". Second, the last part of the id "0003:046D:C229.0036" is '0036'. What does this represent? Not sure. The only way to find it (it seems) is to have it be bound already, then unbind it and rebind it.
-
Vladius over 5 yearsDid you find a way to rebind automatically?
-
Vladius over 5 yearsAdded my own auto-rebinding solution: unix.stackexchange.com/a/475277/96686
-
Raleigh L. over 2 yearsFor those using ZSH who were unable to run any of the binding commands. Try putting that entire command in quotes and then run
sudo bash -c <command>
.