我正在尝试为最终作为 hid 设备加载的 USB 设备编写 udev 规则。这是udevadm info
该设备的:
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/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3.3/1-1.2.3.3:1.0/0003:20CE:0023.0010/hidraw/hidraw15':
KERNEL=="hidraw15"
SUBSYSTEM=="hidraw"
DRIVER==""
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3.3/1-1.2.3.3:1.0/0003:20CE:0023.0010':
KERNELS=="0003:20CE:0023.0010"
SUBSYSTEMS=="hid"
DRIVERS=="hid-generic"
ATTRS{country}=="00"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3.3/1-1.2.3.3:1.0':
KERNELS=="1-1.2.3.3:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="usbhid"
ATTRS{authorized}=="1"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceClass}=="03"
ATTRS{bInterfaceNumber}=="00"
ATTRS{bInterfaceProtocol}=="00"
ATTRS{bInterfaceSubClass}=="00"
ATTRS{bNumEndpoints}=="02"
ATTRS{supports_autosuspend}=="1"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3.3':
KERNELS=="1-1.2.3.3"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{bMaxPower}=="100mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="0100"
ATTRS{bmAttributes}=="c0"
ATTRS{busnum}=="1"
ATTRS{configuration}==""
ATTRS{devnum}=="25"
ATTRS{devpath}=="1.2.3.3"
ATTRS{idProduct}=="0023"
ATTRS{idVendor}=="20ce"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="MCL"
ATTRS{maxchild}=="0"
ATTRS{product}=="Mini-Circuits"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="unknown"
ATTRS{speed}=="12"
ATTRS{urbnum}=="12"
ATTRS{version}==" 1.10"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2.3':
KERNELS=="1-1.2.3"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="09"
ATTRS{bDeviceProtocol}=="02"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{bMaxPower}=="100mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="9224"
ATTRS{bmAttributes}=="e0"
ATTRS{busnum}=="1"
ATTRS{configuration}==""
ATTRS{devnum}=="6"
ATTRS{devpath}=="1.2.3"
ATTRS{idProduct}=="0610"
ATTRS{idVendor}=="05e3"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="GenesysLogic"
ATTRS{maxchild}=="4"
ATTRS{product}=="USB2.0 Hub"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="fixed"
ATTRS{speed}=="480"
ATTRS{urbnum}=="70"
ATTRS{version}==" 2.00"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2':
KERNELS=="1-1.2"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="09"
ATTRS{bDeviceProtocol}=="02"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{bMaxPower}=="100mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="9224"
ATTRS{bmAttributes}=="e0"
ATTRS{busnum}=="1"
ATTRS{configuration}==""
ATTRS{devnum}=="4"
ATTRS{devpath}=="1.2"
ATTRS{idProduct}=="0610"
ATTRS{idVendor}=="05e3"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="GenesysLogic"
ATTRS{maxchild}=="4"
ATTRS{product}=="USB2.0 Hub"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="removable"
ATTRS{speed}=="480"
ATTRS{urbnum}=="80"
ATTRS{version}==" 2.00"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1':
KERNELS=="1-1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="09"
ATTRS{bDeviceProtocol}=="02"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{bMaxPower}=="2mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="0200"
ATTRS{bmAttributes}=="e0"
ATTRS{busnum}=="1"
ATTRS{configuration}==""
ATTRS{devnum}=="2"
ATTRS{devpath}=="1"
ATTRS{idProduct}=="9514"
ATTRS{idVendor}=="0424"
ATTRS{ltm_capable}=="no"
ATTRS{maxchild}=="5"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="unknown"
ATTRS{speed}=="480"
ATTRS{urbnum}=="55"
ATTRS{version}==" 2.00"
looking at parent device '/devices/platform/soc/3f980000.usb/usb1':
KERNELS=="usb1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{authorized_default}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="09"
ATTRS{bDeviceProtocol}=="01"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{bMaxPower}=="0mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="0409"
ATTRS{bmAttributes}=="e0"
ATTRS{busnum}=="1"
ATTRS{configuration}==""
ATTRS{devnum}=="1"
ATTRS{devpath}=="0"
ATTRS{idProduct}=="0002"
ATTRS{idVendor}=="1d6b"
ATTRS{interface_authorized_default}=="1"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="Linux 4.9.60-1-ARCH dwc_otg_hcd"
ATTRS{maxchild}=="1"
ATTRS{product}=="DWC OTG Controller"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="unknown"
ATTRS{serial}=="3f980000.usb"
ATTRS{speed}=="480"
ATTRS{urbnum}=="26"
ATTRS{version}==" 2.00"
looking at parent device '/devices/platform/soc/3f980000.usb':
KERNELS=="3f980000.usb"
SUBSYSTEMS=="platform"
DRIVERS=="dwc_otg"
ATTRS{busconnected}=="Bus Connected = 0x1"
ATTRS{buspower}=="Bus Power = 0x1"
ATTRS{bussuspend}=="Bus Suspend = 0x0"
ATTRS{devspeed}=="Device Speed = 0x0"
ATTRS{driver_override}=="(null)"
ATTRS{enumspeed}=="Device Enumeration Speed = 0x1"
ATTRS{fr_interval}=="Frame Interval = 0x1d4b"
ATTRS{ggpio}=="GGPIO = 0x00000000"
ATTRS{gnptxfsiz}=="GNPTXFSIZ = 0x01000306"
ATTRS{gotgctl}=="GOTGCTL = 0x001c0001"
ATTRS{gpvndctl}=="GPVNDCTL = 0x00000000"
ATTRS{grxfsiz}=="GRXFSIZ = 0x00000306"
ATTRS{gsnpsid}=="GSNPSID = 0x4f54280a"
ATTRS{guid}=="GUID = 0x2708a000"
ATTRS{gusbcfg}=="GUSBCFG = 0x20001700"
ATTRS{hcd_frrem}=="HCD Dump Frame Remaining"
ATTRS{hcddump}=="HCD Dump"
ATTRS{hnp}=="HstNegScs = 0x0"
ATTRS{hnpcapable}=="HNPCapable = 0x1"
ATTRS{hprt0}=="HPRT0 = 0x00001405"
ATTRS{hptxfsiz}=="HPTXFSIZ = 0x02000406"
ATTRS{hsic_connect}=="HSIC Connect = 0x1"
ATTRS{inv_sel_hsic}=="Invert Select HSIC = 0x0"
ATTRS{mode}=="Mode = 0x1"
ATTRS{mode_ch_tim_en}=="Mode Change Ready Timer Enable = 0x0"
ATTRS{rd_reg_test}=="Time to read GNPTXFSIZ reg 10000000 times: 1330 msecs (133 jiffies)"
ATTRS{regdump}=="Register Dump"
ATTRS{regoffset}=="0xffffffff"
ATTRS{regvalue}=="invalid offset"
ATTRS{rem_wakeup_pwrdn}==""
ATTRS{remote_wakeup}=="Remote Wakeup Sig = 0 Enabled = 0 LPM Remote Wakeup = 0"
ATTRS{spramdump}=="SPRAM Dump"
ATTRS{srp}=="SesReqScs = 0x1"
ATTRS{srpcapable}=="SRPCapable = 0x1"
ATTRS{wr_reg_test}=="Time to write GNPTXFSIZ reg 10000000 times: 330 msecs (33 jiffies)"
looking at parent device '/devices/platform/soc':
KERNELS=="soc"
SUBSYSTEMS=="platform"
DRIVERS==""
ATTRS{driver_override}=="(null)"
looking at parent device '/devices/platform':
KERNELS=="platform"
SUBSYSTEMS==""
DRIVERS==""
我尝试创建的规则应通过idVendor
和过滤任何 USB 设备idProduct
,然后符号链接绘图设备到attenuators/%s{devpath}
.这devpath
是 usb 父级的属性,而不是 hidraw 设备本身的属性。
该规则似乎匹配并符号链接正确USB设备正确,但我需要它们链接到 hidraw 设备:
SUBSYSTEM=="usb", ATTRS{idVendor}=="20ce", ATTR{idProduct}=="0023", SYMLINK+="attenuators/%s{devpath}"
以下是我尝试的解决方案,但似乎都不起作用:
1:
SUBSYSTEM=="usb", ATTRS{idVendor}=="20ce", ATTR{idProduct}=="0023", ENV{IS_ATTENUATOR}="t", ENV{DEV_PATH}="%s{devpath}"
SUBSYSTEM=="hidraw", ENV{IS_ATTENUATOR}=="t", SYMLINK+="attenuators/%E{DEV_PATH}"
2:
SUBSYSTEM=="usb", ATTRS{idVendor}=="20ce", ATTR{idProduct}=="0023", ENV{IS_ATTENUATOR}="t", ENV{DEV_PATH}="%s{devpath}"
ENV{IS_ATTENUATOR}!="t", GOTO="attenuator_end"
SUBSYSTEM=="hidraw", SYMLINK+="attenuators/%E{DEV_PATH}"
LABEL="attenuator_end"
3、尝试仅引用父属性:
SUBSYSTEM=="hidraw", ATTR{idVendor}=="20ce", ATTR{idProduct}=="0023", SYMLINK+="attenuators/%s{devpath}"
除了几项测试之外,其中很少有似乎能够链接设备。我觉得我在这里缺少一些基本的理解。任何帮助,将不胜感激!
答案1
我认为你的主要问题是你尝试使用%s{devpath}
而不是简单地使用$devpath
.
所以这样的事情应该有效:
SUBSYSTEM=="usb", ATTRS{idVendor}=="20ce", ATTRS{idProduct}=="0023", SYMLINK+="attenuators/$devpath"
请注意,ATTRS
而不是ATTR
(注意末尾的 S,您多次混淆了这些),因为您正在某些父节点上进行过滤。看udev 规则中 ATTRS 和 ATTR 之间的区别?
答案2
尽管这可能不是最简单或最优雅的解决方案,但我最终编写了一个 python 脚本,以递归方式从 hidraw 设备的 DEVPATH 向上移动目录,直到找到名为“devpath”的文件(包含该设备的总线/端口路径)物理 USB 端口)。一旦找到,它就会根据(目前硬编码)正确的值检查 idVendor 和 idProduct 并打印devpath
设备的值(如果正确)。
我的规则最终是这样的:
SUBSYSTEM=="hidraw", PROGRAM="/path/to/script.py", SYMLINK+="attenuators/%c"
脚本如下所示:
#!/usr/bin/env python3
import os, sys
path = '/sys' + os.environ["DEVPATH"]
while path != '/':
if 'devpath' in os.listdir(path):
with open(path + '/idVendor') as f:
vendor = f.readline().rstrip()
with open(path + '/idProduct') as f:
product = f.readline().rstrip()
if vendor != '20ce' or product != '0023':
sys.exit(1)
with open(path + '/devpath') as f:
print(f.readline().rstrip())
sys.exit(0)
else:
path = os.path.dirname(path)