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 libusb
biblioteca 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?
usbnet
no se cargará automáticamente, ya que no tiene información sobre el hardware, que puede usarlo. Intente encontrar el controlador adecuado y use, por ejemplomodinfo kalmia
,. En lasalias
líneas verá la identificación del proveedor xxxx y la identificación del producto aaaa comousb: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 dedepmod -a
este cambio desaparecerá ...Respuestas:
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:
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:Que debe coincidir con los usbalias (los comodines se utilizan para hacer coincidir varios dispositivos). Si
modalias
coincide 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
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 elmodules.alias
archivo (y usando la misma sintaxis).depmod -a
luego 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
usbnet
controlador 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. :)
fuente
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?