I'm creating udev rules to map my USB devices (ttyUSB*) to the USB ports where they are connected. The usual way to do so is looking at the output of:
udevadm info --name=/dev/ttyUSB0 --attribute-walk
Here my output (I removed the ATTRS
lines not meaningful):
looking at device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.5/1-1.5.6/1-1.5.6:1.0/ttyUSB0/tty/ttyUSB0':
KERNEL=="ttyUSB0"
SUBSYSTEM=="tty"
DRIVER==""
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.5/1-1.5.6/1-1.5.6:1.0/ttyUSB0':
KERNELS=="ttyUSB0"
SUBSYSTEMS=="usb-serial"
DRIVERS=="ftdi_sio"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.5/1-1.5.6/1-1.5.6:1.0':
KERNELS=="1-1.5.6:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="ftdi_sio"
ATTRS{interface}=="USB-RS485 Cable"
ATTRS{supports_autosuspend}=="1"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.5/1-1.5.6':
KERNELS=="1-1.5.6"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{idProduct}=="6001"
ATTRS{idVendor}=="0403"
ATTRS{manufacturer}=="FTDI"
ATTRS{product}=="USB-RS485 Cable"
ATTRS{serial}=="FTY48GF2"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.5':
KERNELS=="1-1.5"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{product}=="USB 2.0 Hub [MTT]"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1':
KERNELS=="1-1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1':
KERNELS=="usb1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{manufacturer}=="Linux 4.9.41-v7+ dwc_otg_hcd"
ATTRS{product}=="DWC OTG Controller"
looking at parent device '/devices/platform/soc/3f980000.usb':
KERNELS=="3f980000.usb"
SUBSYSTEMS=="platform"
DRIVERS=="dwc_otg"
looking at parent device '/devices/platform/soc':
KERNELS=="soc"
SUBSYSTEMS=="platform"
DRIVERS==""
looking at parent device '/devices/platform':
KERNELS=="platform"
SUBSYSTEMS==""
DRIVERS==""
Here the connection: Raspberry Pi -> USB HUB -> FTDI dongle.
My rule is the following:
$ cat /etc/udev/rules.d/99-usb.rules
KERNEL=="1-1.5.6", SUBSYSTEM=="usb", SYMLINK+="rs485"
but:
# ls -l /dev/rs485
lrwxrwxrwx 1 root root 15 Oct 4 07:04 /dev/rs485 -> bus/usb/001/009
I was expecting the symlink should be created to /dev/ttyUSB0.
Now, I understand my dongle is at that usb position from:
$ lsusb
Bus 001 Device 006: ID 046d:c062 Logitech, Inc. M-UAS144 [LS1 Laser Mouse]
Bus 001 Device 009: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
...
but of course it IS NOT the serial port (i.e. I cannot echo
to it).
Trying to use 1-1.5.6:1.0
as KERNEL key doesn't work – no symlink created.
What value should I use?
Best Answer
If you look at
man udev
,KERNELS
searches the device path, whileKERNEL
matches the device itself, andSUBSYSTEM
represents the part of the kernel generating the event. When your USB dongle is plugged in, several udev events are created, as parts of the kernel discover the device and react according.You want your rule to trigger on the action for the device itself (
SUBSYSTEM=="tty"
, because you want a link for/dev/ttyUSB0
), but withSUBSYSTEMS=="usb"
, it triggers when the USB device itself is discovered, not when the driver for the USB device is started. That's why you get a link to the USB device as seen from the USB subsystem,bus/usb/001/009o
.So what you need is
(note the
S
and thetty
).