Wie verwende ich die Linux-Kernel-Treiber-Bind / Unbind-Schnittstelle für USB-HID-Geräte?

26

Erster Hintergrund. Ich entwickle einen Treiber für Logitech-Game-Panel-Geräte. Es ist eine Tastatur mit einem Bildschirm. Der Treiber funktioniert einwandfrei, aber standardmäßig wird das Gerät von HID gehandhabt. Um zu verhindern, dass HID das Gerät vor meinem Treiber übernimmt, kann ich es in hid-core.c auf eine schwarze Liste setzen. Dies funktioniert, ist aber nicht die beste Lösung, da ich mit mehreren Leuten zusammenarbeite und wir alle weiterhin unser HID-Modul patchen müssen, was zu einer lästigen Aufgabe wird, zumal es oft um das Neuerstellen von initramfs und dergleichen geht.

Ich habe einige Nachforschungen zu diesem Problem angestellt und diesen Post auf der Mailingliste gefunden , der mich schließlich zu diesem Artikel über LWN führte . Dies beschreibt einen Mechanismus zum Binden von Geräten an bestimmte Treiber zur Laufzeit. Das scheint genau das zu sein, was ich brauche.

Also habe ich es versucht. Ich konnte die Tastatur von HID lösen. Dies funktionierte und wie erwartet konnte ich nicht mehr darauf tippen. Aber als ich versuchte, es an unseren Treiber zu binden, erhalte ich "Fehler: kein solches Gerät" und der Vorgang schlägt fehl.

Meine Frage lautet also: Wie kann ich Kernel-Bindungs- / Unbindungsoperationen verwenden, um zu replizieren, was passiert, wenn Sie ein HID-Gerät in HID-Core auf die Blacklist setzen und Ihren eigenen Treiber bereitstellen? - das heißt - die Notwendigkeit zu ersetzen, hid-core.c die ganze Zeit zu patchen?

Die Quelle unseres Treibers ist hier: https://github.com/ali1234/lg4l

ali1234
quelle

Antworten:

27

Ok, es stellte sich heraus, dass die Antwort mich ins Gesicht starrte.

Erstens, ob Sie unseren benutzerdefinierten Treiber oder den allgemeinen Treiber verwenden, der normalerweise das Gerät übernimmt, es wird letztendlich immer noch alles von HID gesteuert und nicht von USB.

Zuvor habe ich versucht, es von HID zu lösen, was nicht der richtige Weg ist. HID verfügt über Subtreiber. Der Treiber, der Geräte ohne speziellen Treiber übernimmt, wird als generischer USB-Anschluss bezeichnet. Daran musste ich mich binden, bevor ich mich an hid-g19 binden konnte. Außerdem musste ich die HID-Adresse verwenden, die wie "0003: 046d: c229.0036" aussieht, und nicht die USB-Adresse, die wie "1-1.1: 1.1" aussieht.

Vor dem erneuten Binden würde ich dies auf dmesg sehen:

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

Dann mach ich:

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

Und dann sehe ich auf 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

Also, wie ich schon sagte, starrte mich ins Gesicht, denn die beiden wichtigsten Informationen sind die ersten beiden Dinge in der Leitung, wenn das Gerät bindet ...

ali1234
quelle
Mussten Sie in Ihrem Treiber angeben, dass dieser Anbieter / dieses Produkt mit Ihrem Treiber kompatibel ist? Oder erzwingt das "Binden" einfach das Problem. Ich bekomme "kein solches Gerät" für ein Gerät, das auf die schwarze Liste gesetzt wurde, aber ich möchte es zwingen, gebunden zu werden, und ich bilde mir ein, dass die schwarze Liste nicht nur ein "automatisches Binden verhindern", sondern ein "Binden verhindern" ist was für "Art der Sache.
Dmansfield
Bind erzwingt dies, sodass es nicht erforderlich ist, die IDs in der Treiberquelle zu beanspruchen. Dies ist jedoch der Fall, wenn Sie möchten, dass es automatisch geladen wird.
Ali1234
Zwei Gründe, warum ich Probleme hatte: Erstens: Das Gerät ist in der hid_ignore_list des Kernels aufgeführt und wird daher nicht automatisch "versteckt". Ich musste "usbhid.quirks = 0x0b0e: 0x0412: 0x40000000" zur Kernel-Befehlszeile hinzufügen und neu starten. Das Flag 0x40000000 lautet "Nicht ignorieren". Zweitens lautet der letzte Teil der ID "0003: 046D: C229.0036" "0036". Was bedeutet das? Nicht sicher. Die einzige Möglichkeit, es zu finden (es scheint), besteht darin, es bereits gebunden zu haben, es dann zu lösen und erneut zu binden.
Dmansfield
Haben Sie eine Möglichkeit gefunden, automatisch neu zu binden?
Vladius
Meine eigene Lösung zum automatischen erneuten Binden wurde
hinzugefügt