Debian – Blacklisting / Removing driver for a particular VID/PID

debiandevicesdriverslinuxusb

This is in continuation of my previous problem.
Accessing a USB device under Non – Privilaged user with FTDI2XX Driver

Here i have 2 usbserial hardware modules and it is provisionised that only one can be used at a time.

1. 0403:6014
2. 0403:6001

I also wanted to make sure device is R/W accesble to "plugdev" group

For device 0403:6014, I do not want to use inbuilt usbserial(ftdi_sio) driver. I want to access this device using FTD2XXX library.
and for device 0403:6001, I want to use inbulit usbserial(ftdi_sio) driver. I am trying to find a common way to acheive this.

Trails which I attempted so far. Since, 0403:6001 device uses inbuilt linux driver, I am trying to remove / blacklist ( 0403:6014 ) driver while loading

  1. TRIAL 1

    ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014",
    RUN+="/usr/local/bin/rmmod.sh 4", GROUP="plugdev"

    This removes the loaded FTDI driver, but it does not change the device group from ROOT to PLUGDEV

So address that issue added one more rule line

  1. TRIAL 2

    SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", GROUP="plugdev"
    ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", RUN+="/usr/local/bin/rmmod.sh 4"

    This trial sets my device GROUP as expected to "plugdev", but this does not remove the kernel usbserial module.

  2. TRIAL 3

    SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", GROUP="plugdev"

    Added ftdi_sio to /etc/modprobe.d/blacklist.conf , but this blacklists my 0403:6001 completely.

    This approach works well for 0403:6014 but this completely obseltes my 0403:6001 device

Request some guidance to fix this issue

Best Answer

I came across almost the same issue, and completed the script inspired by sourcejedi. I did not had to pass the device path since udev provides quite a bit of information through environment already (use export > /tmp/vars in case you wonder what your script receives). In particular, I use $DEVNAME which is the device name under /dev (e.g. ttyUSB0).

/etc/udev/rules.d/ftdi.rules

ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", KERNEL=="ttyUSB*" RUN+="/etc/udev/scripts/unbind_ftdi.sh"

/etc/udev/scripts/unbind_ftdi.sh

#!/bin/sh

# traverse sysfs to find the USB ID
# of the USB device which is parent/ancestor of ttyUSB*
# something like "1-1.6:1.0"
TTYDEV=$(basename $DEVNAME)
BOUND_DEVICES=/sys/bus/usb/drivers/ftdi_sio/*/
for DEVICE in ${BOUND_DEVICES}; do
    if [ -e $DEVICE/$TTYDEV ]; then
        USBID=$(basename $DEVICE)
        break
    fi
done

echo "$USBID" > /sys/bus/usb/drivers/ftdi_sio/unbind
Related Question