Scopri quali moduli sono associati a un dispositivo USB?


35

Potresti consigliare un modo per capire quale driver viene utilizzato per un dispositivo USB. Sorta di un equivalente USB del lspci -kcomando.

Risposte:


57

Trovare i driver del kernel

Il dispositivo vittima

$ lsusb 
Bus 010 Device 002: ID 046d:c01e Logitech, Inc. MX518 Optical Mouse
Bus 010 Device 003: ID 051d:0002 American Power Conversion Uninterruptible Power Supply

Proveremo a scoprire quale driver viene utilizzato per l'UPS APC. Nota che ci sono due risposte a questa domanda: il driver che il kernel userebbe e il driver che è attualmente in uso. Userspace può indicare al kernel di utilizzare un driver diverso (e nel caso del mio UPS APC, nutha).

Metodo 1: Utilizzo di usbutils (facile)

Il usbutilspacchetto (almeno su Debian) include uno script chiamato usb-devices. Se lo esegui, genera informazioni sui dispositivi nel sistema, incluso il driver utilizzato:

$ usb-devices
⋮
T:  Bus=10 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#=  3 Spd=1.5 MxCh= 0
D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=051d ProdID=0002 Rev=01.06
S:  Manufacturer=American Power Conversion
S:  Product=Back-UPS RS 1500 FW:8.g9 .D USB FW:g9 
S:  SerialNumber=XXXXXXXXXXXX  
C:  #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=24mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbfs
⋮

Si noti che questo elenca il driver corrente, non quello predefinito. Non c'è modo di trovare quello predefinito.

Metodo 2: utilizzo di debugfs (richiede root)

Se hai montato il debug, il kernel mantiene un file nello stesso formato di usb-devicesstampa su /sys/kernel/debug/usb/devices; è possibile visualizzare con less, ecc. Si noti che le interfacce di debugfs non sono stabili, quindi versioni diverse del kernel possono essere stampate in un formato diverso o mancare del tutto il file.

Ancora una volta, questo mostra solo il driver corrente, non quello predefinito.

Metodo 3: utilizzare solo le utility di base per leggere / sys direttamente (meglio per script o ripristino)

Puoi ottenere le informazioni da /sys, pensato che sia più doloroso di lspci. Queste /sysinterfacce dovrebbero essere ragionevolmente stabili, quindi se stai scrivendo uno script di shell, probabilmente è così che vuoi farlo.

Inizialmente, lsusbsembra contare i dispositivi da 1, /sysda 0. Quindi 10-2 è una buona ipotesi su dove trovare UPS APC che lsusb fornisce come bus 10, dispositivo 3. Sfortunatamente, nel tempo la mappatura si interrompe: sysfs riutilizza i numeri anche quando i numeri di dispositivo non lo sono. Il devnumcontenuto del file corrisponderà al numero di dispositivo fornito da lsusb, quindi puoi fare qualcosa del genere:

$ grep -l '^3$' /sys/bus/usb/devices/10-*/devnum     # the ^ and $ to prevent also matching 13, 31, etc.
/sys/bus/usb/devices/10-2/devnum

Quindi, in questo caso, lo è sicuramente 10-2.

$ cd /sys/bus/usb/devices/10-2
$ ls
10-2:1.0             bDeviceClass     bMaxPower           descriptors  ep_00         maxchild   remove     urbnum
authorized           bDeviceProtocol  bNumConfigurations  dev          idProduct     power      serial     version
avoid_reset_quirk    bDeviceSubClass  bNumInterfaces      devnum       idVendor      product    speed
bcdDevice            bmAttributes     busnum              devpath      ltm_capable   quirks     subsystem
bConfigurationValue  bMaxPacketSize0  configuration       driver       manufacturer  removable  uevent

Possiamo essere sicuri che questo sia il dispositivo giusto catinging alcuni dei file:

$ cat idVendor idProduct manufacturer product 
051d
0002
American Power Conversion
Back-UPS RS 1500 FW:8.g9 .D USB FW:g9 

Se si guarda in 10-2: 1.0 ( :1è la "configurazione", .0l'interfaccia: un singolo dispositivo USB può fare più cose e avere più driver; lsusb -vli mostrerà), c'è un file modalias e un link simbolico al driver:

$ cat 10-2\:1.0/modalias 
usb:v051Dp0002d0106dc00dsc00dp00ic03isc00ip00in00
$ readlink driver
../../../../../../bus/usb/drivers/usbfs

Quindi, l'attuale driver è usbfs. È possibile trovare il driver predefinito chiedendo modinfole modalità:

$ /sbin/modinfo `cat 10-2\:1.0/modalias`
filename:       /lib/modules/3.6-trunk-amd64/kernel/drivers/hid/usbhid/usbhid.ko
license:        GPL
description:    USB HID core driver
author:         Jiri Kosina
author:         Vojtech Pavlik
author:         Andreas Gal
alias:          usb:v*p*d*dc*dsc*dp*ic03isc*ip*in*
depends:        hid,usbcore
intree:         Y
vermagic:       3.6-trunk-amd64 SMP mod_unload modversions 
parm:           mousepoll:Polling interval of mice (uint)
parm:           ignoreled:Autosuspend with active leds (uint)
parm:           quirks:Add/modify USB HID quirks by specifying  quirks=vendorID:productID:quirks where vendorID, productID, and quirks are all in 0x-prefixed hex (array of charp)

Quindi, l'UPS APC imposta automaticamente il hiddriver, il che è effettivamente corretto. E i suoi che attualmente utilizzano usbfs, che è corretta in quanto nut's usbhid-upssta monitorando esso.

Che dire dei driver userspace (usbfs)?

Quando il driver è usbfs, significa sostanzialmente che un programma userspace (non kernel) funziona come driver. Trovare quale programma è richiede root (a meno che il programma non sia in esecuzione come utente) ed è abbastanza semplice: qualunque programma abbia il file del dispositivo aperto.

Sappiamo che il nostro dispositivo "vittima" è il bus 10, dispositivo 3. Quindi il file del dispositivo è /dev/bus/usb/010/003(almeno su un moderno Debian) e lsoffornisce la risposta:

# lsof /dev/bus/usb/010/003 
COMMAND    PID USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
usbhid-up 4951  nut    4u   CHR 189,1154      0t0 8332 /dev/bus/usb/010/003

E infatti, è usbhid-upscome previsto (lsof ha troncato il nome del comando per adattare il layout, se hai bisogno del nome completo, puoi usarlo ps 4951per ottenerlo, o probabilmente alcune opzioni di formattazione dell'output di lsof).


Sicuramente perderò nel mio dibattito in corso con il mio amico di Windows vs Linux con questo :). Ci vorranno alcuni giorni per vedere se viene visualizzata una soluzione più semplice. Grazie per lo sforzo.
TheMeaningfulEngineer

@Alan OK, ho trovato altri due modi, uno dei quali è abbastanza semplice. Inoltre, ho chiarito quale delle due possibili risposte a "quale driver?" ogni metodo fornisce.
derobert,

Non credo che la tua richiesta di localizzazione del dispositivo /sys/bus/usb/devicessia corretta. Ho un dispositivo sul bus 1 che usb-devicesdice che è il dispositivo 12, ma non c'è nessun /sys/bus/usb/devices/1-11sul mio sistema.
Cerin,

@Cerin infatti non lo è. Ne inserirò uno migliore. Grazie.
derobert,

13

lsusbstesso può ottenere buoni risultati. Per output compatto che uso lsusb -t, dove -tmostra i dispositivi come un albero; questo formato riporta anche il driver.

Esempio di output:

 $ lsusb -t
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 5000M
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/3p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M
...

Se non viene utilizzato alcun driver, la linea apparirà così (il dispositivo nel mio esempio è una videocamera per la quale ho rimosso il driver dal kernel):

    |__ Port 6: Dev 4, If 1, Class=Video, Driver=, 480M

0

Oltre a ciò che ha scritto Derobert, mi trovo a usare

lsusb -t

Che stamperà un albero con varie informazioni sui dispositivi collegati tra cui una parte utile «Driver».

e

dmesg | grep driver

che ti elencherà i driver degli ultimi dispositivi collegati.

Il vantaggio è che questi due comandi vengono installati con tutte le distribuzioni.


0

Si può anche usare lshwche enumera i dispositivi su tutti i bus inclusi USB, PCI, ecc in modo da poter vedere quale driver utilizza e gli ID associati:

sudo lshw
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.