Sunday, February 21, 2016

Linux/udev: Unbinding from one kernel driver, and rebinding to a different one. Automatically, using udev.

Quite a lot of USB devices claim to be a human interface device, the rationale being that you can access them on Windows without the need to supply your own "proper" driver.

Under Linux, one can easily unbind the usbhid driver from a particular usb device, but this gets tedious after a few dozen times. But there's a workaround using udev and a short script to rebind to a different kernel module.

First, create a udev rule, e.g. in /etc/udev/rules.d/99-rebind-driver.sh:


ACTION=="add", DRIVER=="usbhid", SUBSYSTEMS=="usb",
ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="00de",
RUN+="/usr/local/sbin/rebind_sysfs_driver.sh %p %k /bus/usb/drivers/mcp2210"



(all in one line)

Then use the following small script, stored as /usr/local/sbin/rebind_sysfs_driver.sh to do the actual work:


#!/bin/sh

if [ "$#" != 3 ] ; then
echo "Usage: $0 sysfs_path kernel_name new_driver_path" >&2
echo "" >&2
echo "To be used in udev rules:" >&2
echo "   RUN+=\"$0 %p %k /bus/usb/drivers/mcp2210\"" >&2
echo "which rebinds a particular device to a new driver." >&2
exit 1
fi

set -e
logger -t "$0" "Rebind device $1($2) to driver $3."

cd "/sys$1"
echo "$2" >driver/unbind
sleep 1
echo "$2" >"/sys$3/bind"



No comments: