Mappez le chemin du périphérique USB physique au numéro de bus / périphérique renvoyé par lsusb

9

J'ai besoin d'obtenir le titre du périphérique USB connecté. Je peux le faire avec lsusb.

udev autorise certaines substitutions lorsque j'écris des règles: disons, nous pouvons utiliser $kernelpour obtenir le nom du périphérique, ou $devpathpour obtenir le chemin vers le périphérique.

Mais le problème est que lsusbrenvoie une chaîne comme ça:

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

Mais le devpath d'udev est:

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

Le numéro de bus est le même ( 5), mais les numéros sont différents: Device 032semble être un certain nombre logique (lorsque je reconnecte le périphérique, ce nombre augmente), et 2semble être le numéro du périphérique physique.

Donc, udev renvoie un nombre physique, et j'ai besoin d'obtenir un nombre logique. Ensuite, je peux récupérer des données comme ceci:lsusb -D /dev/bus/usb/005/032

Alors, comment puis-je obtenir le numéro de périphérique logique 032par un chemin physique comme /devices/pci0000:00/0000:00:1d.0/usb5/5-2?

Dmitry Frank
la source

Réponses:

5

Tout d' abord, nous devons précédez /syssur le chemin retourné par udev, de sorte que ce chemin devient quelque chose: /sys/devices/pci0000:00/0000:00:1d.0/usb5/5-2. Ensuite, allez dans ce répertoire, et il y aura plusieurs fichiers. Entre autres, il existe busnumet des devnumfichiers, ils contiennent ces nombres "logiques". Donc, dans le script bash, nous pouvons les récupérer comme ça:

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"

Notez également que udevpeuvent renvoyer ceux busnum- ci et devnumdirectement: dans RUN+="..."nous pouvons utiliser des substitutions $attr{busnum}et $attr{devnum}respectivement.

Dmitry Frank
la source
1
Je suis confus par les différentes utilisations de udevvs lsusbet sys/devices/..vs /dev/bus/usb/..et à en juger par votre réponse, vous semblez être au courant :) Peut-être pouvez-vous éclairer ces deux questions? askubuntu.com/questions/342061/power-on-off-usb-ports et askubuntu.com/questions/498950/…
sur natty
@nuttyaboutnatty, malheureusement, je ne peux pas vous donner d'indice sur votre problème (sur la mise hors tension de l'appareil). J'apprends juste des trucs linux ces jours-ci, et je suis assez loin de tout type de gourou. Très peu de /sys/devices/...vs /dev/...: /sysest peuplé par le noyau, c'est une représentation de la hiérarchie réelle des périphériques du noyau. Udev est un démon de l'espace utilisateur qui gère la /syshiérarchie et remplit /dev/...(en tenant compte des règles). Ainsi, udev est entièrement responsable du /devcontenu.
Dmitry Frank
1

La réponse acceptée ne m'a vraiment pas beaucoup aidé. J'ai finalement trouvé un moyen en sondant idProduct et idVendor s'ils existent. Voici un script shell

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

Voici ce que j'obtiens sur mon système.

$ ./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

Ici, je peux voir que, par exemple 0a5c:21e6, qui est un appareil Bluetooth, est mappé 2-1.4.

Pour encore plus de commodité, vous pouvez définir cela comme une fonction dans votre shell, quelque chose comme

$ 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
kristopole
la source