Mappare il percorso del dispositivo USB fisico sul numero bus / dispositivo restituito da lsusb


9

Devo ottenere il titolo del dispositivo USB collegato. Posso farlo con lsusb.

udev consente alcune sostituzioni quando scrivo le regole: diciamo, possiamo usare $kernelper ottenere il nome del dispositivo o $devpathper ottenere il percorso del dispositivo.

Ma il problema è che lsusbrestituisce una stringa del genere:

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

Ma il devpath di udev è:

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

Il numero del bus è lo stesso ( 5), ma i numeri sono diversi: Device 032sembra essere un numero logico (quando ricollego il dispositivo, questo numero aumenta) e 2sembra essere il numero del dispositivo fisico.

Quindi udev restituisce un numero fisico e devo ottenere un numero logico. Quindi, posso recuperare i dati in questo modo:lsusb -D /dev/bus/usb/005/032

Quindi, come posso ottenere il numero di dispositivo logico 032per percorso fisico come /devices/pci0000:00/0000:00:1d.0/usb5/5-2?

Risposte:


5

In primo luogo, abbiamo bisogno di anteporre /sysal percorso restituito da udev, in modo che percorso diventa qualcosa come: /sys/devices/pci0000:00/0000:00:1d.0/usb5/5-2. Quindi vai a questa directory e ci saranno diversi file in essa contenuti. Tra gli altri, ci sono busnume devnumfile, contengono questi numeri "logici". Quindi, nello script bash, possiamo recuperarli in questo modo:

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"

Si noti inoltre che udevpossono restituire questi busnume devnumdirettamente: in RUN+="..."possiamo usare sostituzioni $attr{busnum}e $attr{devnum}rispettivamente.


1
Sono confuso dai diversi usi di udevvs. lsusbe sys/devices/..vs. /dev/bus/usb/..e, a giudicare dalla tua risposta, sembri essere al corrente :) Forse puoi far luce su queste due domande? askubuntu.com/questions/342061/power-on-off-usb-ports e askubuntu.com/questions/498950/…
per natty

@nuttyaboutnatty, sfortunatamente non posso darti alcun indizio sul tuo problema (sull'accensione del dispositivo). Sto imparando cose su Linux in questi giorni, e sono abbastanza lontano da qualsiasi tipo di guru. Molto poco /sys/devices/...rispetto a /dev/...: /sysè popolato dal kernel, è una rappresentazione della gerarchia dei dispositivi kernel reali. Udev è un demone dello spazio utente che gestisce la /sysgerarchia e popola /dev/...(prendendo in considerazione le regole). Quindi, udev è completamente responsabile dei /devcontenuti.
Dmitry Frank,

1

La risposta accettata non mi ha aiutato molto. Alla fine ho scoperto un modo sondando idProduct e idVendor se esistono. Ecco uno script di shell

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

Ecco cosa ottengo sul mio sistema.

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

Qui posso vedere che, ad esempio 0a5c:21e6, che è un dispositivo Bluetooth, è mappato a 2-1.4.

Per una comodità ancora maggiore, potresti definirla una funzione nella tua shell, qualcosa del genere

$ 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.