Encontrando o (s) driver (s) do Kernel
O dispositivo da vítima
$ 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
Vamos tentar descobrir qual driver é usado para o no-break da APC. Observe que há duas respostas para essa pergunta: O driver que o kernel usaria e o driver que está atualmente em uso. O espaço do usuário pode instruir o kernel a usar um driver diferente (e no caso do meu APC UPS, nut
tem).
Método 1: Usando usbutils (fácil)
O pacote usbutils
(no Debian, pelo menos) inclui um script chamado usb-devices
. Se você executá-lo, ele exibe informações sobre os dispositivos no sistema, incluindo qual driver é usado:
$ 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
⋮
Observe que isso lista o driver atual, não o padrão. Não há como encontrar o padrão.
Método 2: Usando o debugfs (requer raiz)
Se você tiver o debugfs montado, o kernel manterá um arquivo no mesmo formato que usb-devices
imprime em /sys/kernel/debug/usb/devices
; você pode ver com less
, etc. Note que as interfaces debugfs não são estáveis, portanto versões diferentes do kernel podem ser impressas em um formato diferente, ou estar faltando o arquivo completamente.
Mais uma vez, isso mostra apenas o driver atual, não o padrão.
Método 3: Usando apenas utilitários básicos para ler / sys diretamente (melhor para scripts ou recuperação)
Você pode obter as informações de /sys
, o que é mais doloroso do que lspci
. Essas /sys
interfaces devem ser razoavelmente estáveis, então se você está escrevendo um script de shell, provavelmente é assim que você quer fazer isso.
Inicialmente, lsusb
parece contar dispositivos a partir de 1, /sys
de 0. Então, 10-2 é um bom palpite para onde encontrar o UPS da APC que o lsusb fornece como barramento 10, dispositivo 3. Infelizmente, com o tempo o mapeamento é interrompido - o sysfs reutiliza os números mesmo quando os números dos dispositivos não são. O conteúdo do arquivo devnum
corresponderá ao número do dispositivo fornecido por lsusb, para que você possa fazer algo assim:
$ 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
Então, neste caso, é definitivamente 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 ter certeza de que este é o dispositivo certo por cat
ing alguns dos arquivos:
$ cat idVendor idProduct manufacturer product
051d
0002
American Power Conversion
Back-UPS RS 1500 FW:8.g9 .D USB FW:g9
Se você olhar em 10-2: 1,0 ( :1
é a "configuração", .0
da interface - um único dispositivo USB pode fazer várias coisas e ter vários drivers; lsusb -v
mostrará isso), existe um arquivo modalias e um link simbólico do driver:
$ cat 10-2\:1.0/modalias
usb:v051Dp0002d0106dc00dsc00dp00ic03isc00ip00in00
$ readlink driver
../../../../../../bus/usb/drivers/usbfs
Portanto, o driver atual é usbfs
. Você pode encontrar o driver padrão perguntando modinfo
sobre os 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)
Assim, o no-break da APC é padronizado para o driver hid
, o que é correto. E atualmente está usando usbfs, o que é correto, pois nut
' usbhid-ups
está monitorando isso.
E os drivers do espaço do usuário (usbfs)?
Quando o driver é usbfs
, significa basicamente que um programa de espaço de usuário (não-kernel) está funcionando como o driver. Encontrar qual programa é requer raiz (a menos que o programa esteja sendo executado como usuário) e é bastante fácil: qualquer programa que tenha o arquivo do dispositivo aberto.
Sabemos que o nosso dispositivo "vítima" é o barramento 10, dispositivo 3. Portanto, o arquivo do dispositivo é /dev/bus/usb/010/003
(pelo menos em um Debian moderno) e lsof
fornece a resposta:
# 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, de fato, seu usbhid-ups
como esperado (lsof truncou o nome do comando para ajustar o layout, se você precisar do nome completo, você pode usar ps 4951
para obtê-lo, ou provavelmente algumas opções de formatação de saída).