¿Averigua qué módulos están asociados con un dispositivo usb?

35

¿Podría recomendar una forma de averiguar qué controlador se está utilizando para un dispositivo USB? Una especie de equivalente usb de lspci -kcomando.

El Ingeniero Significante
fuente

Respuestas:

57

Encontrar los controladores de kernel

El dispositivo víctima

$ 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

Intentaremos averiguar qué controlador se utiliza para el UPS APC. Tenga en cuenta que hay dos respuestas a esta pregunta: el controlador que usaría el kernel y el controlador que está actualmente en uso. El espacio de usuario puede indicarle al kernel que use un controlador diferente (y en el caso de mi APC UPS nut).

Método 1: Usando usbutils (fácil)

El usbutilspaquete (en Debian, al menos) incluye un script llamado usb-devices. Si lo ejecuta, genera información sobre los dispositivos en el sistema, incluido qué controlador se utiliza:

$ 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
⋮

Tenga en cuenta que esto enumera el controlador actual, no el predeterminado. No hay forma de encontrar el predeterminado.

Método 2: Usar debugfs (requiere root)

Si tiene debugfs montadas, el núcleo mantiene un archivo en el mismo formato que usb-devicesimprime a /sys/kernel/debug/usb/devices; Puede ver con less, etc. Tenga en cuenta que no son debugfs las interfaces estables, por lo que diferentes versiones del núcleo se pueden imprimir en un formato diferente, o ser falta el archivo completo.

Una vez más, esto sólo muestra el controlador actual, no el defecto.

Método 3: Usando sólo los servicios básicos para leer / SYS directamente (mejor para secuencias de comandos o de recuperación)

Puede obtener la información de /sys, pensado su más dolorosa que lspci. Estas /sysinterfaces deben ser razonablemente estable, por lo que si usted está escribiendo un script de shell, esta es probablemente la forma en que desea hacerlo.

Inicialmente, lsusbparece contar con dispositivos de 1, /sysdesde 0. Así 10-2 es una buena suposición de dónde encontrar la APC UPS lsusb da como bus 10, el dispositivo 3. Por desgracia, con el tiempo que se rompe hacia abajo mapeo-sysfs reutiliza los números incluso cuando los números de dispositivo no lo son. El devnumcontenido del archivo coincidirá con el número de dispositivo dada por lsusb, por lo que puede hacer algo como esto:

$ 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

Entonces, en este caso, definitivamente lo es 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

Podemos estar seguros de que este es el dispositivo correcto al incorporar catalgunos de los archivos:

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

Si mira en 10-2: 1.0 ( :1es la "configuración", .0la interfaz: un solo dispositivo USB puede hacer varias cosas y tener múltiples controladores; lsusb -vmostrará estos), hay un archivo modalias y un enlace simbólico de controlador:

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

Entonces, el controlador actual es usbfs. Puede encontrar el controlador predeterminado preguntando modinfopor las modalias:

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

Por lo tanto, el UPS APC por defecto es el hidcontrolador, lo cual es correcto. Y sus utilizando actualmente usbfs, lo cual es correcto, ya que nut's usbhid-upslo está supervisando.

¿Qué pasa con los controladores de espacio de usuario (usbfs)?

Cuando el controlador es usbfs, básicamente significa que un programa de espacio de usuario (no kernel) funciona como controlador. Encontrar el programa que necesita requiere root (a menos que el programa se esté ejecutando como su usuario) y es bastante fácil: cualquier programa que tenga abierto el archivo del dispositivo.

Sabemos que nuestro dispositivo "víctima" es el bus 10, dispositivo 3. Por lo tanto, el archivo del dispositivo es /dev/bus/usb/010/003(al menos en un Debian moderno) y lsofproporciona la respuesta:

# 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

Y de hecho, es usbhid-upscomo se esperaba (lsof truncó el nombre del comando para que el diseño se ajuste, si necesita el nombre completo, puede usarlo ps 4951para obtenerlo, o probablemente algunas opciones de formato de salida lsof).

derobert
fuente
Definitivamente voy a perder en mi debate con mi amigo de Windows vs Linux con este :). Le dará unos días para ver si aparece una solución más simple. Gracias por el esfuerzo.
TheMeaningfulEngineer
@ Alan OK, he encontrado dos formas más, una de ellas es bastante simple. Además, he aclarado cuál de las dos posibles respuestas a "¿qué controlador?" Cada método proporciona.
derobert el
No creo que su afirmación sobre la ubicación del dispositivo /sys/bus/usb/devicessea ​​correcta. Tengo un dispositivo en el bus 1 que usb-devicesdice que es el dispositivo 12, pero no hay ninguno /sys/bus/usb/devices/1-11en mi sistema.
Cerin
@Cerin de hecho no lo es. Pondré una mejor. Gracias.
derobert
13

lsusben sí mismo puede obtener buenos resultados. Para la salida compacta que uso lsusb -t, donde -tmuestra los dispositivos como un árbol; Este formato también informa el controlador.

Salida de ejemplo:

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

Si no se utiliza ningún controlador, la línea se verá así (el dispositivo en mi ejemplo es una cámara para la cual eliminé el controlador del núcleo):

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

Además de lo que escribió derobert, me encuentro usando

lsusb -t

Que imprimirá un árbol con información variada sobre los dispositivos conectados, incluida una parte útil del «Controlador».

y

dmesg | grep driver

que le mostrará los controladores de los últimos dispositivos conectados.

La ventaja es que estos dos comandos vienen instalados con todas las distribuciones.

FuzzyTern
fuente
0

También se puede usar, lshwque enumerará los dispositivos en todos los buses, incluidos USB, PCI, etc. para que pueda ver qué controlador usa y sus ID asociados:

sudo lshw
Pierz
fuente