udev: Como você identifica o dispositivo físico ao qual um dispositivo sys pertence?

6

Eu tenho vários modems USB que possuem vários endpoints: muitos TTYs, uma interface de rede, uma porta cdc-wdm e algumas outras coisas. Eu estou tentando agrupá-los para que eu saiba, por exemplo, ttyUSB3, ttyUSB4, wwan1 e cdc-wdm1 todos pertencem ao mesmo dispositivo USB físico.

Achei que $id deveria identificar o dispositivo físico, por isso, tentei adicionar $id ao ambiente com ENV{id}=$id . Isso parece funcionar para as interfaces de rede e portas seriais, mas não para as portas cdc-wdm (o id é indefinido para essas portas).

Aqui estão alguns dados de exemplo depois de adicionar as regras ENV{id}=$id :

Regra

: SUBSYSTEM=="net", ATTRS{idVendor}=="106c", ATTRS{idProduct}=="3718", ENV{id}="$id"

# udevadm info --query=all --path=/devices/platform/atmel-ehci/usb1/1-1/1-1.3/1-
1.3:1.5/net/wwan0
P: /devices/platform/atmel-ehci/usb1/1-1/1-1.3/1-1.3:1.5/net/wwan0
E: DEVPATH=/devices/platform/atmel-ehci/usb1/1-1/1-1.3/1-1.3:1.5/net/wwan0
E: DEVTYPE=wwan
E: ID_BUS=usb
E: ID_MODEL=PANTECH_UML290
E: ID_MODEL_ENC=PANTECH\x20UML290
E: ID_MODEL_ID=3718
E: ID_REVISION=0000
E: ID_SERIAL=Pantech__Incorporated_PANTECH_UML290
E: ID_TYPE=generic
E: ID_USB_DRIVER=qmi_wwan
E: ID_USB_INTERFACES=:020201:0a0000:ffffff:fffdff:fffeff:fff1ff:
E: ID_USB_INTERFACE_NUM=05
E: ID_VENDOR=Pantech__Incorporated
E: ID_VENDOR_ENC=Pantech\x2c\x20Incorporated
E: ID_VENDOR_ID=106c
E: IFINDEX=5
E: INTERFACE=wwan0
E: SUBSYSTEM=net
E: USEC_INITIALIZED=174833330
E: id=1-1.3
Regra

: SUBSYSTEM=="usb", KERNEL=="*cdc-wdm*", ENV{id}="$id"

# udevadm info --query=all --path=/devices/platform/atmel-ehci/usb1/1-1/1-1.3/1-
1.3:1.5/usb/cdc-wdm0
P: /devices/platform/atmel-ehci/usb1/1-1/1-1.3/1-1.3:1.5/usb/cdc-wdm0
N: cdc-wdm0
E: DEVNAME=/dev/cdc-wdm0
E: DEVPATH=/devices/platform/atmel-ehci/usb1/1-1/1-1.3/1-1.3:1.5/usb/cdc-wdm0
E: MAJOR=180
E: MINOR=176
E: SUBSYSTEM=usb
E: USEC_INITIALIZED=174788259
    
por Shawn J. Goff 03.05.2013 / 00:22

1 resposta

4

Ok, primeiro eu entendo o que a documentação para $id significa por

The name of the device matched while searching the devpath upwards for SUBSYSTEMS, KERNELS, DRIVERS and ATTRS.

... e não é o que eu pensava (que foi formado por não entender a documentação combinada com alguma experimentação).

Por "O nome do dispositivo", está falando da mesma coisa que a chave KERNEL corresponde. A documentação diz sobre a chave KERNEL é:

Match the name of the event device.

É assim que você sabe "nome" e "KERNEL" estão relacionados.

A parte "correspondida ao pesquisar o devpath para SUBSYSTEMS, KERNELS, DRIVERS e ATTRS" significa que, se você especificou uma correspondência "SUBSYSTEMS, KERNELS, DRIVERS ou ATTRS" na regra, ela percorrerá a árvore de dispositivos até encontra um fósforo; o nome do dispositivo correspondente será usado.

Então, na minha primeira regra, ele combinava com a chave ATTRS e esse dispositivo era o dispositivo USB físico.

Agora, para minha outra regra, tive que olhar para a árvore e encontrar algo que correspondesse ao dispositivo físico, mas não algo abaixo dele. Aqui está a minha árvore de dispositivos:

# udevadm info --attribute-walk --name=/dev/cdc-wdm0

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/platform/atmel-ehci/usb1/1-1/1-1.7/1-1.7.2/1-1.7.2:1.5/usb/cdc-wdm0':
    KERNEL=="cdc-wdm0"
    SUBSYSTEM=="usb"
    DRIVER==""

  looking at parent device '/devices/platform/atmel-ehci/usb1/1-1/1-1.7/1-1.7.2/1-1.7.2:1.5':
    KERNELS=="1-1.7.2:1.5"
    SUBSYSTEMS=="usb"
    DRIVERS=="qmi_wwan"
    ATTRS{bInterfaceNumber}=="05"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bNumEndpoints}=="03"
    ATTRS{bInterfaceClass}=="ff"
    ATTRS{bInterfaceSubClass}=="f1"
    ATTRS{bInterfaceProtocol}=="ff"
    ATTRS{supports_autosuspend}=="1"

  looking at parent device '/devices/platform/atmel-ehci/usb1/1-1/1-1.7/1-1.7.2':
    KERNELS=="1-1.7.2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}=="Pantech, Incorporated"
    ATTRS{bNumInterfaces}==" 6"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="c0"
    ATTRS{bMaxPower}=="500mA"
    ATTRS{urbnum}=="496"
    ATTRS{idVendor}=="106c"
    ATTRS{idProduct}=="3718"
    ATTRS{bcdDevice}=="0000"
    ATTRS{bDeviceClass}=="02"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="12"
    ATTRS{devpath}=="1.7.2"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Pantech, Incorporated"
    ATTRS{product}=="PANTECH UML290"

  looking at parent device '/devices/platform/atmel-ehci/usb1/1-1/1-1.7':
    KERNELS=="1-1.7"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{urbnum}=="188"
    ATTRS{idVendor}=="1a40"
    ATTRS{idProduct}=="0101"
    ATTRS{bcdDevice}=="0111"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="3"
    ATTRS{devpath}=="1.7"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="4"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{product}=="USB 2.0 Hub"

  looking at parent device '/devices/platform/atmel-ehci/usb1/1-1':
    KERNELS=="1-1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{urbnum}=="53"
    ATTRS{idVendor}=="1a40"
    ATTRS{idProduct}=="0201"
    ATTRS{bcdDevice}=="0100"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="02"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="2"
    ATTRS{devpath}=="1"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="7"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{product}=="USB 2.0 Hub [MTT]"

  looking at parent device '/devices/platform/atmel-ehci/usb1':
    KERNELS=="usb1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}=="  0mA"
    ATTRS{urbnum}=="26"
    ATTRS{idVendor}=="1d6b"
    ATTRS{idProduct}=="0002"
    ATTRS{bcdDevice}=="0206"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="3"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Linux 2.6.39.4-acnbfx100 ehci_hcd"
    ATTRS{product}=="Atmel EHCI UHP HS"
    ATTRS{serial}=="atmel-ehci"
    ATTRS{authorized_default}=="1"

  looking at parent device '/devices/platform/atmel-ehci':
    KERNELS=="atmel-ehci"
    SUBSYSTEMS=="platform"
    DRIVERS=="atmel-ehci"
    ATTRS{companion}==""

  looking at parent device '/devices/platform':
    KERNELS=="platform"
    SUBSYSTEMS==""
    DRIVERS==""

O dispositivo que desejo corresponder é /devices/platform/atmel-ehci/usb1/1-1/1-1.7/1-1.7.2' . Você pode ver que os DRIVERS para esse dispositivo são 'usb' e nada abaixo dele irá corresponder a isso. A regra a seguir resolve meu problema, deve ser uma solução genérica, já que tenho certeza de que nenhum endpoint de um dispositivo seria manipulado pelo driver usb.

DRIVERS=="usb", KERNEL=="*cdc-wdm*", ENV{id}="$id", RUN="/usr/local/bin/modem_setup.sh"

E esse é o resultado que eu estava procurando o tempo todo:

# udevadm info --query=all --name=/dev/cdc-wdm0
P: /devices/platform/atmel-ehci/usb1/1-1/1-1.7/1-1.7.2/1-1.7.2:1.5/usb/cdc-wdm0
N: cdc-wdm0
E: DEVNAME=/dev/cdc-wdm0
E: DEVPATH=/devices/platform/atmel-ehci/usb1/1-1/1-1.7/1-1.7.2/1-1.7.2:1.5/usb/cdc-wdm0
E: MAJOR=180
E: MINOR=176
E: SUBSYSTEM=usb
E: USEC_INITIALIZED=12243969
E: id=1-1.7.2
    
por 03.05.2013 / 17:03

Tags