Cómo asignar un controlador USB al dispositivo

30

Esta pregunta es doble:

Primero, ¿cómo desconecta manualmente un controlador de un dispositivo USB y conecta uno diferente? Por ejemplo, tengo un dispositivo que, cuando está conectado, usa automáticamente el controlador de almacenamiento usb.

salida usbview

Vendor Id: xxxx
Product Id: xxxx
...
    Number of Interfaces: 2
    Interface Number: 0
        Name: usb-storage
        Number of Endpoints: 2
        ...
    Interface Number: 1
        Name: (none)
        Number of Endpoints: 2
        ...

No quiero usar el controlador de almacenamiento usb, así que en mi aplicación uso la libusbbiblioteca para desconectar el controlador de almacenamiento usb y luego reclamo la interfaz. Luego puedo enviar datos desde y hacia las aplicaciones que se ejecutan en mi dispositivo USB y en mi sistema Linux host.

¿Cómo desconecta un controlador manualmente fuera de una aplicación?


En segundo lugar, ¿cómo asigno automáticamente el controlador para que se adjunte al complemento del dispositivo? Actualmente tengo una configuración de regla de udev para configurar los permisos del dispositivo automáticamente:

SUBSYSTEM=="usb", ATTR{idVendor}=="xxxx", MODE="0666"

¿Puedo usar las reglas de udev para asignar controladores a interfaces específicas en el dispositivo USB? Por ejemplo, si quisiera que el módulo usbnet se usara automáticamente en la interfaz 0 en lugar de usb-storage, ¿es eso posible en udev?

linsek
fuente
1
Si parte del problema es cargar el módulo correcto, vea Webcam en Angström
Gilles 'SO- deja de ser malvado'
1
¿Necesita en absoluto el módulo de almacenamiento usb? porque si no puedes ponerlo en una lista negra y no se cargará en absoluto.
Hanan N.
@Gilles, puedo cargar con éxito el LKM. Mi pregunta es ¿cómo lo adjunto manual y automáticamente al dispositivo?
linsek
@ Hanan, actualmente no tengo uso para el módulo de almacenamiento usb. Puede que necesite terminar en una lista negra para conectar automáticamente el módulo correcto, pero primero necesito saber cómo conectar el usbnet.
linsek
1
El módulo @njozwiak usbnetno se cargará automáticamente, ya que no tiene información sobre el hardware, que puede usarlo. Intente encontrar el controlador adecuado y use, por ejemplo modinfo kalmia,. En las aliaslíneas verá la identificación del proveedor xxxx y la identificación del producto aaaa como usb:vxxxxpyyyy. O puede editar el archivo /lib/modules/kernel_version/modules.usbmap y para su HW puede eliminar la línea, donde está el almacenamiento usb del módulo HW o cambiar el almacenamiento usb con el controlador de red adecuado. Pero después de depmod -aeste cambio desaparecerá ...
Jan Marek

Respuestas:

20

Para la primera parte de la pregunta, busqué y no pude encontrar una mejor manera de desconectar un controlador USB que lo que ya está haciendo con libusb.

En cuanto a la segunda parte de la pregunta, udev puede reaccionar a la carga del controlador, pero no forzar la asignación de un controlador específico a un dispositivo.

Cada controlador en el kernel de Linux es responsable de uno o más dispositivos. El controlador mismo elige qué dispositivos admite. Lo hace mediante programación, es decir, verificando el proveedor del dispositivo y la identificación del producto o, si no están disponibles (por ejemplo, un dispositivo antiguo), realizando algunas heurísticas de detección automática y comprobaciones de estado. Una vez que el controlador está seguro de haber encontrado un dispositivo compatible, se adhiere a él. En resumen, a menudo no puede forzar a un controlador en particular a usar un dispositivo en particular. A veces, sin embargo, un controlador de dispositivo es generoso con lo que acepta, y un dispositivo puede funcionar sin que lo sepa. ¡Su millaje variará! En el pasado, tuve que agregar manualmente ID de dispositivos / proveedores PCI extraños a los controladores que deberían admitirlos, con éxito mixto y algunos bloqueos divertidos del kernel.

Ahora, en el caso de los módulos, hay un paso adicional. El kernel despierta el cargador de módulos cuando se detecta un nuevo dispositivo. Se le pasó una cadena 'modalias', que identifica el dispositivo y se ve más o menos así para los dispositivos USB:

usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00

Esta cadena contiene la clase de dispositivo ( usb) y la información específica de la clase (proveedor / dispositivo / número de serie, clase de dispositivo, etc.). Cada controlador de kernel contiene una línea como:

MODULE_ALIAS("usb:...")

Que debe coincidir con los usbalias (los comodines se utilizan para hacer coincidir varios dispositivos). Si modaliascoincide con el que admite el controlador, este controlador se carga (o se le notifica sobre el nuevo dispositivo, si ya está allí).

Puede ver los dispositivos compatibles (por modalias) y sus módulos asociados con

less /lib/modules/`uname -r`/modules.alias

Si busca el controlador de dispositivo de almacenamiento usb, verá que tiene algunos dispositivos específicos que admite por proveedor e ID de dispositivo, y también intentará admitir cualquier dispositivo con la clase (almacenamiento) correcta, sin importar el proveedor / dispositivo .

Puede influir en esto utilizando mecanismos de espacio de usuario en su sistema operativo ( /etc/modprobe.d/en Debian y sus amigos). Puede incluir en la lista negra los módulos, o puede especificar módulos que se cargarán por modalias, al igual que el modules.aliasarchivo (y usando la misma sintaxis). depmod -aluego regenerará los patrones del cargador de módulos.

Sin embargo, aunque puedes llevar a este caballo en particular al agua, pero no puedes obligarlo a beber. Si el controlador no tiene soporte para su dispositivo, debería ignorarlo.

Esta es la teoría en el caso general.

En la práctica, y en el caso de USB, veo que su dispositivo parece tener dos interfaces , de las cuales el almacenamiento es una. El núcleo se conectará a la interfaz de almacenamiento del dispositivo en general. Si la otra interfaz tiene la clase correcta, el usbnetcontrolador podría conectarse a ella. Sí, puede tener múltiples controladores conectados al mismo dispositivo físico , porque un dispositivo USB exporta múltiples interfaces (por ejemplo, mi teclado Logitech G15 exporta dos porque tiene un dispositivo de teclado y una pantalla LCD, cada uno de los cuales es manejado por un controlador separado) .

El hecho de que no se detecte la segunda interfaz de su dispositivo USB es indicativo de falta de soporte en el núcleo. Cualquiera sea el caso, puede enumerar las interfaces / puntos finales del dispositivo con un detalle insoportable lsusb -v | less, luego desplácese hacia abajo a su dispositivo en particular (puede limitar la salida por dispositivo: ID del proveedor o ruta USB si así lo desea).

Tenga en cuenta: estoy simplificando un poco aquí con respecto a la estructura lógica de los dispositivos USB. Culpa al consorcio USB. :)

Alexios
fuente
44
Ya existe static struct usb_device_id id_table [] = { { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, { }, }; MODULE_DEVICE_TABLE (usb, id_table);en el código, ¿es redundante con modalias?
Thomas
En mi caso, esas líneas son autogeneradas por un poco de magia Makefile en cualquier lugar dentro del controlador. Es por eso que agregué tres veces las líneas para MODULE_ALIAS pero nunca aparece en la lista. De todos modos, gracias por el lsusb -v. con eso pude comprobarlo y encontrar la falla en mi idea. Luego busqué la fuente de un identificador conocido y encontré la matriz con las entradas que tuve que manipular.
JackGrinningCat