我正在尝试为udev
USB 串行设备赋予相关名称,但没有成功。
# lsusb -d 04e2:1412 -v
Bus 004 Device 028: ID 04e2:1412 Exar Corp.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 Common Class
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x04e2 Exar Corp.
idProduct 0x1412
bcdDevice 0.02
iManufacturer 0
iProduct 0
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 141
bNumInterfaces 4
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 94mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 2 Communications
bFunctionSubClass 2 Abstract (modem)
bFunctionProtocol 0 None
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 0
CDC Header:
bcdCDC 1.10
CDC ACM:
bmCapabilities 0x06
sends break
line coding and serial state
CDC Union:
bMasterInterface 0
bSlaveInterface 1
CDC Call Management:
bmCapabilities 0x01
call management
bDataInterface 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 2
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 Unused
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 2
bInterfaceCount 2
bFunctionClass 2 Communications
bFunctionSubClass 2 Abstract (modem)
bFunctionProtocol 0 None
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 0
CDC Header:
bcdCDC 1.10
CDC ACM:
bmCapabilities 0x06
sends break
line coding and serial state
CDC Union:
bMasterInterface 2
bSlaveInterface 3
CDC Call Management:
bmCapabilities 0x01
call management
bDataInterface 3
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 2
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 Unused
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Device Status: 0x0000
(Bus Powered)
我正在尝试的 udev 规则是:
KERNEL=="ttyUSB[0-9]*", SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="01", ATTRS{idVendor}=="04e2", ATTRS{idProduct}=="1412", ACTION=="add", SYMLINK+="test_USB0"
KERNEL=="ttyUSB[0-9]*", SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="01", ATTRS{idVendor}=="04e2", ATTRS{idProduct}=="1412", ACTION=="add", SYMLINK+="test_USB1"
KERNEL=="ttyUSB[0-9]*", SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="02", ATTRS{idVendor}=="04e2", ATTRS{idProduct}=="1412", ACTION=="add", SYMLINK+="test_USB2"
KERNEL=="ttyUSB[0-9]*", SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="03", ATTRS{idVendor}=="04e2", ATTRS{idProduct}=="1412", ACTION=="add", SYMLINK+="test_USB3"
当我仅使用第一条udev
规则而没有使用bInterfaceNumber
属性时,如下所示:
KERNEL=="ttyUSB[0-9]*", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04e2", ATTRS{idProduct}=="1412", ACTION=="add", SYMLINK+="test_USB0"
一切正常。我可以看到/dev/test_USB0
创建的指向的符号链接,但是当我插入此 USB 串行设备时创建的/dev/ttyUSB0
其他设备呢?ttyUSB
这就是为什么我想使用该bInterfaceNumber
属性,但是当我将其输入时,什么都没有发生,它似乎完全绕过了我的规则。
谁能帮我这个?
答案1
您可以使用ENV{ID_USB_INTERFACE_NUM}
,定义在/lib64/udev/rules.d/60-persistent-serial.rules
用于udevadm test
检查可用的环境。
答案2
看起来规则不起作用,因为您混合了来自不同父设备的属性。
文章编写 udev 规则在“udevinfo”部分中提到了这种情况:
您可能已经注意到上述示例中使用了颜色。这是为了说明,虽然将相关设备和单身父母设备,您不能混合搭配来自多个父设备的属性 - 您的规则将不起作用。
问题在于lsusb -v
它将设备本身及其父设备的信息一起列出,因此您无法判断属性是来自同一个父设备还是来自多个父设备。
但是,如果你使用udevadm info
(在 Ubuntu 上)或udevinfo
(如作者所用),你应该能够打印设备的层次结构。在文章中,作者给出了以下示例:
# udevinfo -a -p /sys/block/sda
looking at device '/block/sda':
KERNEL=="sda"
SUBSYSTEM=="block"
ATTR{stat}==" 128535 2246 2788977 766188 73998 317300 3132216 5735004 0 516516 6503316"
ATTR{size}=="234441648"
ATTR{removable}=="0"
ATTR{range}=="16"
ATTR{dev}=="8:0"
looking at parent device '/devices/pci0000:00/0000:00:07.0/host0/target0:0:0/0:0:0:0':
KERNELS=="0:0:0:0"
SUBSYSTEMS=="scsi"
DRIVERS=="sd"
ATTRS{ioerr_cnt}=="0x0"
ATTRS{iodone_cnt}=="0x31737"
ATTRS{iorequest_cnt}=="0x31737"
ATTRS{iocounterbits}=="32"
ATTRS{timeout}=="30"
ATTRS{state}=="running"
ATTRS{rev}=="3.42"
ATTRS{model}=="ST3120827AS "
ATTRS{vendor}=="ATA "
ATTRS{scsi_level}=="6"
ATTRS{type}=="0"
ATTRS{queue_type}=="none"
ATTRS{queue_depth}=="1"
ATTRS{device_blocked}=="0"
looking at parent device '/devices/pci0000:00/0000:00:07.0':
KERNELS=="0000:00:07.0"
SUBSYSTEMS=="pci"
DRIVERS=="sata_nv"
ATTRS{vendor}=="0x10de"
ATTRS{device}=="0x037f"
因此以下规则将有效,因为:
SUBSYSTEM=="block"
来自于设备本身。SUBSYSTEMS=="scsi"
和都ATTRS{model}=="ST3120827AS"
来自同一父设备/devices/pci0000:00/0000:00:07.0/host0/target0:0:0/0:0:0:0
。
SUBSYSTEM=="block", SUBSYSTEMS=="scsi", ATTRS{model}=="ST3120827AS", NAME="my_hard_disk"
然而,正如作者所说,以下规则将不是之所以有效,是因为ATTRS{model}=="ST3120827AS"
和DRIVERS=="sata_nv"
来自两个不同的父设备:
SUBSYSTEM=="block", ATTRS{model}=="ST3120827AS", DRIVERS=="sata_nv", NAME="my_hard_disk"
因此,我建议 OP 使用udevadm info
(或udevinfo
)命令检查设备层次结构,以查看是否混合了来自不同父设备的属性。
我今天碰巧在用 USB 设备,udevadm info
(我使用的是 Ubuntu 18.04)的输出显示供应商 ID 和产品 ID 属于一个父设备,但bInterfaceNumber
属于另一个父设备。因此,当您的规则仅包含供应商 ID 和产品 ID 时,它属于“单父设备”的情况,因此可以正常工作。当您添加bInterfaceNumber
到规则中时,如果您的 USB 设备具有与我的 USB 设备类似的设备层次结构,则该规则将不起作用,因为这是混合多个父设备的情况。