16

I have some trouble understanding how the udev device attributes from different parent devices are evaluated in a rule. I want to write a rule for a specific serial usb device (HUAWEI Modem), with a attribute walk as follows:

$ udevadm info --attribute-walk --name=/dev/ttyUSB0

  looking at device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3:1.0/ttyUSB0/tty/ttyUSB0':
    KERNEL=="ttyUSB0"
    SUBSYSTEM=="tty"
    DRIVER==""

  looking at parent device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3:1.0/ttyUSB0':
    KERNELS=="ttyUSB0"
    SUBSYSTEMS=="usb-serial"
    DRIVERS=="generic"
    ATTRS{port_number}=="0"

  looking at parent device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.3/1-1.3:1.0':
    KERNELS=="1-1.3:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="usbserial_generic"
    ATTRS{bInterfaceClass}=="ff"
    ATTRS{bInterfaceSubClass}=="02"
    ATTRS{bInterfaceProtocol}=="01"
    ATTRS{bNumEndpoints}=="03"
    ATTRS{supports_autosuspend}=="1"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceNumber}=="00"

  looking at parent device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.3':
    KERNELS=="1-1.3"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{devpath}=="1.3"
    ATTRS{idVendor}=="12d1"
    ATTRS{speed}=="480"
    ATTRS{bNumInterfaces}==" 4"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="5"
    ATTRS{configuration}==""
    ATTRS{bMaxPower}=="500mA"
    ATTRS{authorized}=="1"
    ATTRS{bmAttributes}=="80"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{maxchild}=="0"
    ATTRS{bcdDevice}=="0001"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{version}==" 2.00"
    ATTRS{urbnum}=="4561"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="HUAWEI"
    ATTRS{removable}=="removable"
    ATTRS{idProduct}=="1506"
    ATTRS{bDeviceClass}=="00"
    ATTRS{product}=="HUAWEI MOBILE"

In order to identify this device I tried to use following udev rule:

ACTION=="add", KERNEL=="ttyUSB[0-9]*", SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="00", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1506", RUN+="/usr/bin/systemctl start modem_dialer"

but unfortunately I cannot use the attribute ATTRS{bInterfaceNumber}=="00" from the interface device and the attributes ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1506" from the physical device together. Using either of them works fine, but when using them together the rule does not work anymore.

Am I missing anything regarding the usage of attributes from different parent devices together in one rule? Is there any other reason why using the attributes from different parents might be a problem?

By the way, the distro is Arch Linux ARM.

3

3 Answers 3

9

To use attributes from multiple parents, you need to use multiple rules and GOTO. Something like this.

SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}!="00", GOTO="huawei_end"
ACTION=="add", KERNEL=="ttyUSB[0-9]*", SUBSYSTEMS=="usb", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1506", RUN+="/usr/bin/systemctl start modem_dialer"
LABEL="huawei_end"
1
  • Tricky to get the order of this right...
    – eMPee584
    Commented May 1, 2021 at 13:35
5

You could use two rules as described here (possibly combined with another neat trick found in this blog post to make it more generic/easily expendable):

ACTION=="add", SUBSYSTEM=="usb", ENV{USB_IDS}="%s{idVendor}:%s{idProduct}"
ACTION=="add", ENV{USB_IDS}=="12d1:1506", ATTRS{bInterfaceNumber}=="00", RUN+="/usr/bin/systemctl start modem_dialer"

However, the first rule has to uniquely match the node containing the right idVendor and idProduct else there is no guarantee that it sets USB_IDS to the correct values and the second rule is able to match. I am not aware of any attribute that would be able to generically match USB leaf nodes though. :/

1

Here's alternative with less inverted logic:

# Match our dongle
KERNEL=="ttyUSB[0-9]*", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1506", GOTO="huawei"
# Did not match our dongle, skip the dongle rules
SUBSYSTEMS=="usb", GOTO="huawei_end"

LABEL="huawei"
ATTRS{bInterfaceNumber}=="00", SYMLINK+="ttyHuawei0", RUN+="/usr/bin/systemctl start modem_dialer"
ATTRS{bInterfaceNumber}=="01", SYMLINK+="ttyHuawei1"

LABEL="huawei_end"

The jump to huawei_end must have a condition to be executed.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .