Create udev rule for USB device with multiple virtual ports

lilipop2513

New Member
Joined
Jun 15, 2023
Messages
3
Reaction score
0
Credits
36
Hello Linux Community !

In my embedded project, I came across working with multiple USB devices. So, to avoid checking each time the new port of each device and setting that in my code, I decided to use udev rules to have a unique access to each device.

However, in that process, one device is causing a problem since it has 2 virtual ports (config + data). If I do a standard udev rule for it, I get one access created to the config port only.

Any clues on how to set udev rules for device with 2 virtual ports ?

Thanks in advance,
Lilia :)
 


G'day Lilia and welcome to linux.org :)

This is beyond my knowledge but by my mentioning the following Members -

@JasKinasis , @dos2unix , @osprey , @f33dm3bits (and there are likely others) I have brought this Thread to their attention.

Make allowance for timezone differences.

Once one of those folks lets me know, I may move this Thread to our Command Line subforum, if it involves, as I suspect, writing udev rules.

Good luck

Chris Turner
wizardfromoz
 
What comes to mind as an initial thought is that it's quite possible to have multiple rules for the same device, so, for example, if you could create a rule each for the two components (the 2 virtual ports), they could be in files with numbers close to each other (e.g. 70-<name>.rules, and 71-<name2>.rules) to determine the order of execution, or, one can have multiple rules in the same file with the rules separated by new lines with each run on a single line. I suppose it's going to depend on whether udevadm identifies the two components. Just thinking.
 
What comes to mind as an initial thought is that it's quite possible to have multiple rules for the same device, so, for example, if you could create a rule each for the two components (the 2 virtual ports), they could be in files with numbers close to each other (e.g. 70-<name>.rules, and 71-<name2>.rules) to determine the order of execution, or, one can have multiple rules in the same file with the rules separated by new lines with each run on a single line. I suppose it's going to depend on whether udevadm identifies the two components. Just thinking.
Hey, thanks for the reply.

It is actually one component with 2 virtual ports, means the two has same vendor id, product id and so on. I don't seem to find something that could make the difference between the two.

If you have any ideas, tell me please.
 
Even though it's the same device, aren't the ports identified uniquely?
 
Even though it's the same device, aren't the ports identified uniquely?
Yes the ports are identified uniquely in the /dev directory (exp : ttyUSB0 & ttyUSB1).

Let me reput my question in a better way :

1- Here's a look at what my first tested rule looked like :
Bash:
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea70", SYMLINK+="ttyDevice"

I thought that since the device has 2 virtual ports, it would create 2 symlinks but when it takes effect it only gives one symlink that neither allows access to the config nor to the data (basically does nothing).

2- Now, to create my rule, I use the following command for each port (USB0 & USB1) :
Bash:
$udevadm info --attribute-walk /dev/ttyUSB0

However the result gives same details for both ports (Vendor Id, Product Id... everything). The only and unique difference I seem to find is the following :
USB0 : ATTRS{interface}=="Enhanced Com Port"
USB1 : ATTRS{interface}=="Standard Com Port"

If I test making two rules with this slight difference :
Bash:
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{interface}=="Standard Com Port", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea70", SYMLINK+="ttyDeviceStandard"
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{interface}=="Enhanced Com Port", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea70", SYMLINK+="ttyDeviceEnhanced"
It does not work.

PS : I make sure to reload the rules each time with the command below and a reboot
Bash:
sudo udevadm control --reload-rules && udevadm trigger

So to sum it up, my question is :
what's the thing that I can add in the rule of each virtual port to distinguish between them and make sure each has a proper symlink for it ?
Or is there a better way to proceed, am I doing things wrong ?
If you have any clues please share them :confused:
Thank you !
 
Same question here. Teensy set up for 3 serial ports appears in /dev/ as ttyACM(n), ttyACM(n+1), ttyACM(n+2) Where n depends on previous devices loaded or not. How to make udev rules to assign 3 symlinks where all device attributes are the same?
 
I just had a similar issue. Specifically. I have a ICOM IC-7610 (ham radio) that runs on Windows, but I added 128GB of memory and installed Linux on it so I could make it a home lab.

Naturally, I still want to run Ham Radio Deluxe which is a windows app so I installed KVM and installed Windows on it so I could run it on that PC (it sits in front of my radio)

Anyhow. When I turn on my radio, it installs the "Prolific Technology Inc. IC-7610 SuperSpeed-FIFO Bridge" which I don't need, but it also installs two virtual com ports. Specifically "Silicon Labs CP210x UART Bridge"

These are used for Rig Control (where I can control the radio from the PC).

The problem is, udev rules don't seem to trigger for the virtual com ports.

The trick I used was to trigger on the SuperSpeed-FIFO Bridge, yet install the CP210x devices since they appear together when I turn the ICOM on.

Anyhow. I got it to work to install them, but the remove rule isn't working yet, but should be a blueprint for anyone needing to do something similar if something does get installed when plugged in / turned on.

Here is my udev rule.

Code:
ACTION=="bind", SUBSYSTEM=="usb", ATTRS{idVendor}=="0c26", ATTRS{idProduct}=="0029", ENV{ID_VENDOR_ID}="10c4", ENV{ID_MODEL_ID}="ea60", RUN+="/root/bin/kvm-udev attach Windows10"

ACTION=="remove", SUBSYSTEM=="usb", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ENV{ID_VENDOR_ID}="10c4", ENV{ID_MODEL_ID}="ea60", RUN+="/root/bin/kvm-udev detach Windows10"

When the FIFO bridge gets detected it triggers this rule. It's vendor id is 0c26 anbd the product od is 0029. I then set an environment variable of ID_VENDOR_ID to 10c4 and the model top ea60 which are the two comm ports. (there are two! So we must specify an address too otherwise it will complain about which one to install!)

Since there are two, My script that gets executed actually does the same things twice to get both ports installed.

The script:
Code:
#!/bin/bash

# Usage: ./kvm-udev.sh attach|detach <domain>

set -e

touch /root/bin/udevrules

ACTION=$1
DOMAIN=$2

ADDR1=`udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB1) | grep -A 20 'KERNELS=="1-1.2"' | grep devnum | cut -d '"' -f 2`
ADDR2=`udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB2) | grep -A 20 'KERNELS=="1-1.3"' | grep devnum | cut -d '"' -f 2`

CONF_FILE1=$(mktemp --suffix=.kvm-udev)
CONF_FILE2=$(mktemp --suffix=.kvm-udev)

cat << EOF >$CONF_FILE1
<hostdev mode='subsystem' type='usb'>
  <source>
    <vendor id='0x${ID_VENDOR_ID}' />
    <product id='0x${ID_MODEL_ID}' />
    <address bus="1" device='${ADDR1}' />
  </source>
</hostdev>
EOF


cat << EOF >$CONF_FILE2
<hostdev mode='subsystem' type='usb'>
  <source>
    <vendor id='0x${ID_VENDOR_ID}' />
    <product id='0x${ID_MODEL_ID}' />
    <address bus="1" device='${ADDR2}' />
  </source>
</hostdev>
EOF

virsh "${ACTION}-device" "$DOMAIN" "$CONF_FILE1"
virsh "${ACTION}-device" "$DOMAIN" "$CONF_FILE2"

rm "$CONF_FILE1"
rm "$CONF_FILE2"

So from here, I assign the ACTION and DOMAIN (virtual host name) and then I use udevadm info to grab the address ID of the virtual comm ports. I use KERNELS (I know which ones they will be by checking) and use devnum (the bus / id) and cut to only get the bus id and assign it to addr1/2 for each.

Then I make a temp file and inject the XML required for virsh and populate the proper info for each device.

I then execute the virsh command with that config/xml file and then remove the temp config file.

As soon as I turn the radio on, it automatically maps the virtual comm ports to my Windows10 virtual machine that is running Ham Radio Deluxe.

Anyhow,. I hope that helps someone.
Dave
 

Members online


Top