2

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

2

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
  • Just stumbled upon USB Interface authorization, which might be useful for this purpose too. I did not try it though. See youtube.com/watch?v=6UHqtbiJX94 around 20 minutes in. – falstaff Mar 11 '17 at 1:23
0

Ok. sysfs docs seem to say you can't remove built-in ID's from a driver (unless you patch the source code). So you will need to manually unbind the driver each time it auto-binds. (I believe it's also possible to disable auto-binding for all USB devices, but that sounds like a terrible idea).

You will need to match on the KERNEL="ttyUSB*" as well as the USB IDs, in order to act after the driver is bound. Your script will have to find the parent USB device. I noticed there's a weird /sys/bus/usb-serial as well as /sys/bus/usb, I'm just hoping that doesn't get in the way here.

I'm not certain how to fill in the code because I don't know what your DEVPATH looks like (and I'm too lazy to write a loop for this). I expect something along the lines of USBID=$(basename $(dirname $TTY_DEVPATH))

# udev rule
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", KERNEL=="ttyUSB*" RUN+="/usr/local/bin/unbind_ftdi.sh %p"

#!/bin/bash
# unbind_ftdi.sh
TTY_DEVPATH="$1"

# traverse sysfs to find the USB ID
# of the USB device which is parent/ancestor of ttyUSB*
# something like "1-1.6:1.0"
....

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.