Register (/ bind / match) device with driver

I am writing a USB driver (for a gamepad) on linux, and when I plug it in, ti loads usbhid. How can I do this so that it loads my driver (gp_driver)? I did unbind usbhid and bound it to my driver trick, but I don't want to do this every time.

Should my driver already be loaded? Do I have to code something in my driver? I have a vendor and product id in my driver.

thanks

+4
source share
3 answers

You need to create a udev rule for your device, which can take care of creating the file of your device, setting permissions in the device file, and loading the appropriate drivers.

Resources

Example

Taken from: http://plugcomputer.org/plugwiki/index.php/Load_Serial_Drivers_Automatically_Using_udev

# if no driver has claimed the interface yet, load ftdi_sio ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_interface", \ ATTRS{idVendor}=="9e88", ATTRS{idProduct}=="9e8f", \ DRIVER=="", \ RUN+="/sbin/modprobe -b ftdi_sio" 
+4
source

According to this Linux Journal article , you need to:

  • Pointer to the owner of your driver module
  • USB driver name
  • List of USB IDs that this driver should provide
  • Probe () function
  • Disconnect () function

Now, I suspect, because it loads the standard driver, you may not have 3, 4, or maybe you did not register the driver with the USB subsystem at all.

I have never written a USB driver before (only hacked char / mem.c), but this information may come in handy.

+1
source

Binding (in your case HID-) device to a specific driver is not a trivial task and depends on the kernel version used:

Kernel <4.16

Prior to kernel 4.16, you had to edit and recompile drivers/hid/HID-core.c since this file contained a list of devices that should not be processed by HID-generic ( hid_have_special_driver structure), you can see an example of how this was done here: https: //github.com/atar-axis/xpadneo/blob/master/misc/kernel_patches/0002-hid_generic_claims_devices.patch

Kernel> = 4.16

Starting with Kernel 4.16, the list has been deleted, and HID-generic checks to see if the device wants any of the other drivers, if so, then the HID-generic step back is not a HID-generic device. Associated patch: https://github.com/torvalds/linux/commit/e04a0442d33b8cf183bba38646447b891bb02123#diff-88d50bd989bbdf3bbd2f3c5dcd4edcb9

Workaround (always works)

You can always use the udev rule (for example, /etc/udev/rules.d/99-xpadneo.rules ), either until 4.16, or when your system has more than one specialized driver:

 # unbind the device from hid-generic on kernel < 4.16 # and bind it to the specialized driver (xpadneo in this case) ACTION=="add", KERNEL=="0005:045E:02FD.*|0005:045E:02E0.*", SUBSYSTEM=="hid",\ RUN+="/bin/bash -c 'echo $kernel > /sys/bus/hid/drivers/hid-generic/unbind'", \ RUN+="/bin/bash -c 'echo $kernel > /sys/bus/hid/drivers/xpadneo/bind'" # unbind the device from another specialized driver which came first # and bind it to xpadneo ACTION=="add", KERNEL=="0005:045E:02FD.*|0005:045E:02E0.*", SUBSYSTEM=="hid",\ RUN+="/bin/bash -c 'echo $kernel > /sys/bus/hid/drivers/microsoft/unbind'", \ RUN+="/bin/bash -c 'echo $kernel > /sys/bus/hid/drivers/xpadneo/bind'" 

Notes

  • Instead of bash you should use sh
  • I do not remember when bind and unbind where added, but it was quite a long time ago.

You can read a little more about loading , binding and registering (HID-) drivers here:

+1
source

All Articles