Сопоставьте физический путь USB-устройства с номером шины / устройства, возвращенным lsusb

9

Мне нужно получить название подключенного USB-устройства. Я могу сделать это с lsusb.

Когда я пишу правила, udev допускает некоторые замены: скажем, мы можем использовать, $kernelчтобы получить имя устройства или $devpathполучить путь к устройству.

Но проблема в том, что lsusbвозвращает такую ​​строку:

Bus 005 Device 032: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC

Но Devath путь Udev является:

/devices/pci0000:00/0000:00:1d.0/usb5/5-2 

Номер шины тот же ( 5), но номера разные: Device 032кажется, что это логическое число (когда я снова подключаю устройство, это число увеличивается), и 2кажется , что это номер физического устройства.

Итак, udev возвращает физический номер, и мне нужно получить логический номер. Затем я могу получить данные, как это:lsusb -D /dev/bus/usb/005/032

Итак, как я могу получить логический номер устройства 032по физическому пути, как /devices/pci0000:00/0000:00:1d.0/usb5/5-2?

Дмитрий Франк
источник

Ответы:

5

Во - первых, нам нужно препендом /sysна пути возвращаемом udev, так что путь становится чем - то вроде: /sys/devices/pci0000:00/0000:00:1d.0/usb5/5-2. Затем перейдите в этот каталог, и в нем будет несколько файлов. Среди прочего есть busnumи devnumфайлы, в них содержатся эти «логические» числа. Итак, в скрипте bash мы можем получить их так:

devpath='/devices/pci0000:00/0000:00:1d.0/usb5/5-2'

busnum=$(cat "/sys/$devpath/busnum")
devnum=$(cat "/sys/$devpath/devnum")

# we might want to make busnum and devnum have leading zeros
# (say, "003" instead of "3", and "012" instead of "12")
busnum=$(printf %03d $busnum)
devnum=$(printf %03d $devnum)

# now, we can retrieve device data by   lsusb -D /dev/bus/usb/$busnum/$devnum

echo "busnum=$busnum, devnum=$devnum"

Также обратите внимание, что udevможно вернуть их busnumи devnumнапрямую: в RUN+="..."мы можем использовать подстановки $attr{busnum}и $attr{devnum}соответственно.

Дмитрий Франк
источник
1
Меня смущают различные варианты использования « udevпротив» lsusbи « sys/devices/..против», /dev/bus/usb/..и, судя по вашему ответу, вы, кажется, в курсе :) Может быть, вы можете пролить свет на эти два вопроса? askubuntu.com/questions/342061/power-on-off-usb-ports and askubuntu.com/questions/498950/…
сумасшедший о неточном
@nuttyaboutnatty, к сожалению, я не могу дать вам никакой подсказки по вашей проблеме (о выключении устройства). Сейчас я просто изучаю Linux, и я довольно далеко от любого гуру. Очень мало о /sys/devices/...vs /dev/...: /sysзаполняется ядром, это представление реальной иерархии устройств ядра. Udev - это демон пользовательского пространства, который обрабатывает /sysиерархию и заполняет ее /dev/...(принимая во внимание правила). Итак, udev полностью отвечает за /devсодержимое.
Дмитрий Франк
1

Принятый ответ действительно не очень помог мне. Я наконец нашел способ, исследуя idProduct и idVendor, если они существуют. Вот сценарий оболочки

#!/bin/bash
{ 
  cd /sys/bus/usb/devices
  for i in *; do 
    [ -e $i/idProduct ] && echo $(cat $i/idVendor $i/idProduct) $i
  done
}

Вот что я получаю в своей системе.

$ ./script
0424 2514 1-3
8087 0024 2-1
0a5c 21e6 2-1.4
8087 0024 4-1
1d6b 0002 usb1
1d6b 0002 usb2
1d6b 0003 usb3
1d6b 0002 usb4

$ lsusb
Bus 004 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 006: ID 0a5c:21e6 Broadcom Corp. BCM20702 Bluetooth 4.0 [ThinkPad]
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Здесь я вижу, что, например 0a5c:21e6, устройство Bluetooth, отображается на 2-1.4.

Для еще большего удобства вы можете определить это как функцию в вашей оболочке, что-то вроде

$ cat >> ~/.bashrc << ENDL
gousb() {
  for i in /sys/bus/usb/devices/*; do 
    if [ -e \$i/idProduct ]; then
      if [ \$(cat \$i/idVendor):\$(cat \$i/idProduct) = \$1 ]; then 
        cd \$i
        return
      fi
    fi
  done

  echo "\$1 not found :-("
}
ENDL
$ source ~/.bashrc
$ gousb 0a5c:21e6
$ pwd 
/sys/bus/usb/devices/2-1.4
kristopolous
источник