How to use Linux kernel driver bind/unbind interface for USB-HID devices?

46,902

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...

Share:
46,902

Related videos on Youtube

collegian
Author by

collegian

Updated on September 18, 2022

Comments

  • collegian
    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
    dmansfield over 9 years
    Did 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
    collegian over 9 years
    Bind 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
    dmansfield over 9 years
    Two 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
    Vladius over 5 years
    Did you find a way to rebind automatically?
  • Vladius
    Vladius over 5 years
    Added my own auto-rebinding solution: unix.stackexchange.com/a/475277/96686
  • Raleigh L.
    Raleigh L. over 2 years
    For 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> .