Potresti consigliare un modo per capire quale driver viene utilizzato per un dispositivo USB. Sorta di un equivalente USB del lspci -k
comando.
Potresti consigliare un modo per capire quale driver viene utilizzato per un dispositivo USB. Sorta di un equivalente USB del lspci -k
comando.
Risposte:
$ 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, nut
ha).
Il usbutils
pacchetto (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.
Se hai montato il debug, il kernel mantiene un file nello stesso formato di usb-devices
stampa 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.
Puoi ottenere le informazioni da /sys
, pensato che sia più doloroso di lspci
. Queste /sys
interfacce dovrebbero essere ragionevolmente stabili, quindi se stai scrivendo uno script di shell, probabilmente è così che vuoi farlo.
Inizialmente, lsusb
sembra contare i dispositivi da 1, /sys
da 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 devnum
contenuto 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 cat
inging 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", .0
l'interfaccia: un singolo dispositivo USB può fare più cose e avere più driver; lsusb -v
li 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 modinfo
le 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 hid
driver, il che è effettivamente corretto. E i suoi che attualmente utilizzano usbfs, che è corretta in quanto nut
's usbhid-ups
sta monitorando esso.
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 lsof
fornisce 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-ups
come previsto (lsof ha troncato il nome del comando per adattare il layout, se hai bisogno del nome completo, puoi usarlo ps 4951
per ottenerlo, o probabilmente alcune opzioni di formattazione dell'output di lsof).
/sys/bus/usb/devices
sia corretta. Ho un dispositivo sul bus 1 che usb-devices
dice che è il dispositivo 12, ma non c'è nessun /sys/bus/usb/devices/1-11
sul mio sistema.
lsusb
stesso può ottenere buoni risultati. Per output compatto che uso lsusb -t
, dove -t
mostra 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
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.