¿Cómo utilizar la interfaz de enlace / desconexión del controlador del kernel de Linux para dispositivos USB-HID?

26

Primer fondo Estoy desarrollando un controlador para dispositivos de panel de juego Logitech. Es un teclado con una pantalla. El controlador funciona bien, pero por defecto el dispositivo es manejado por HID. Para evitar que HID se apodere del dispositivo antes que mi controlador, puedo ponerlo en la lista negra en hid-core.c. Esto funciona, pero no es la mejor solución, ya que estoy trabajando con varias personas y todos tenemos que seguir parcheando nuestro módulo HID, que se está convirtiendo en una tarea, especialmente porque a menudo implica la reconstrucción de initramfs y demás.

Investigué un poco sobre este problema y encontré esta publicación en la lista de correo , que finalmente me llevó a este artículo sobre LWN . Esto describe un mecanismo para vincular dispositivos a controladores específicos en tiempo de ejecución. Esto parece exactamente lo que necesito.

Entonces lo intenté. Pude desvincular el teclado de HID. Esto funcionó y, como era de esperar, ya no podía escribir en él. Pero cuando traté de vincularlo a nuestro controlador, recibí un "error: no existe tal dispositivo" y la operación falla.

Entonces, mi pregunta es: ¿Cómo uso las operaciones de vinculación / desvinculación del núcleo para replicar lo que sucede cuando pone en la lista negra un dispositivo HID en hid-core y proporciona su propio controlador? es decir, para reemplazar la necesidad de parchear hid-core.c todo el tiempo

La fuente de nuestro controlador está aquí: https://github.com/ali1234/lg4l

ali1234
fuente

Respuestas:

27

Ok, resulta que la respuesta me estaba mirando a la cara.

En primer lugar, ya sea que use nuestro controlador personalizado o el genérico que normalmente se hace cargo del dispositivo, en última instancia, todo está controlado por HID y no por USB.

Anteriormente traté de desvincularlo de HID, que no es el camino a seguir. HID tiene sub-controladores, el que se hace cargo de los dispositivos que no tienen un controlador especializado se llama genérico-usb. Esto es de lo que necesitaba desvincularme, antes de vincular a hid-g19. Además, necesitaba usar la dirección HID que se parece a "0003: 046d: c229.0036" y no la dirección USB que se ve "1-1.1: 1.1".

Entonces, antes de volver a vincular, vería esto en dmesg:

generic-usb 0003:046D:C229.0036: input,hiddev0,hidraw4: USB HID v1.11 Keypad [Logitech G19 Gaming Keyboard] on usb-0000:00:13.2-3.2/input1

Entonces lo hago:

echo -n "0003:046D:C229.0036" > /sys/bus/hid/drivers/generic-usb/unbind
echo -n "0003:046D:C229.0036" > /sys/bus/hid/drivers/hid-g19/bind

Y luego veo en dmesg:

hid-g19 0003:046D:C229.0036: input,hiddev0,hidraw4: USB HID v1.11 Keypad [Logitech G19 Gaming Keyboard] on usb-0000:00:13.2-3.2/input1

Entonces, como dije, mirándome a la cara, porque las dos piezas clave de información son las dos primeras cosas en la línea cuando el dispositivo se une ...

ali1234
fuente
¿Tuvo que especificar en su controlador que ese proveedor / producto es compatible con su controlador? ¿O el "vínculo" simplemente fuerza el problema. Estoy obteniendo "no existe tal dispositivo" para un dispositivo que ha sido incluido en la lista negra pero quiero forzarlo a estar vinculado, y estoy imaginando que la inclusión en la lista negra no es solo un "impedimento de enlace automático", sino un "impedimento de enlace obligatorio qué "tipo de cosa".
dmansfield
Bind lo fuerza, por lo que no es necesario reclamar los ID en la fuente del controlador. Sin embargo, es si quieres que se cargue automáticamente.
ali1234
Dos razones por las que tenía problemas: primero: el dispositivo aparece en la lista hid_ignore_list del kernel y, por lo tanto, no se "oculta". Tuve que agregar "usbhid.quirks = 0x0b0e: 0x0412: 0x40000000" a la línea de comando del kernel y reiniciar. El indicador 0x40000000 es "no ignorar". En segundo lugar, la última parte de la identificación "0003: 046D: C229.0036" es '0036'. ¿Qué representa esto? No es seguro. La única forma de encontrarlo (parece) es tenerlo ya atado, luego desenlazarlo y volverlo a unir.
dmansfield
¿Encontraste una manera de volver a unir automáticamente?
Vladius
Agregué
Vladius el