Bagaimana cara menggunakan antarmuka kernel Linux mengikat / melepaskan ikatan untuk perangkat USB-HID?

26

Latar belakang pertama. Saya mengembangkan driver untuk perangkat panel game Logitech. Ini adalah keyboard dengan layar di atasnya. Driver berfungsi dengan baik tetapi secara default perangkat ditangani oleh HID. Untuk mencegah HID mengambil alih perangkat sebelum driver saya, saya bisa daftar hitam di hid-core.c. Ini bekerja tetapi bukan solusi terbaik karena saya bekerja dengan beberapa orang dan kita semua harus terus menambal modul HID kami yang menjadi tugas, terutama karena sering melibatkan pembangunan kembali initramfs dan semacamnya.

Saya melakukan penelitian pada masalah ini dan saya menemukan posting milis ini , yang akhirnya membawa saya ke artikel ini di LWN . Ini menjelaskan mekanisme untuk mengikat perangkat ke driver tertentu saat runtime. Sepertinya ini yang saya butuhkan.

Jadi, saya mencobanya. Saya dapat melepaskan ikatan keyboard dari HID. Ini berhasil dan seperti yang diharapkan, saya tidak bisa lagi mengetiknya. Tetapi ketika saya mencoba untuk mengikatnya ke driver kami, saya mendapatkan "kesalahan: tidak ada perangkat seperti itu" dan operasi gagal.

Jadi pertanyaan saya adalah: Bagaimana cara menggunakan operasi bind / unbind kernel untuk mereplikasi apa yang terjadi ketika Anda memasukkan perangkat HID ke black-core dan menyediakan driver Anda sendiri? - yaitu - untuk mengganti kebutuhan untuk menambal hid-core.c sepanjang waktu?

Sumber driver kami ada di sini: https://github.com/ali1234/lg4l

ali1234
sumber

Jawaban:

27

Ok, ternyata jawabannya menatapku.

Pertama, apakah menggunakan driver khusus kami, atau menggunakan driver generik yang biasanya mengambil alih perangkat, semuanya masih pada akhirnya dikendalikan oleh HID, dan bukan USB.

Sebelumnya saya mencoba melepaskan ikatannya dari HID, yang bukan jalan yang harus ditempuh. HID memiliki sub-driver, yang mengambil alih perangkat yang tidak memiliki driver khusus disebut generic-usb. Inilah yang perlu saya lepaskan, sebelum mengikat ke hid-g19. Juga, saya perlu menggunakan alamat HID yang terlihat seperti "0003: 046d: c229.0036" dan bukan alamat USB yang terlihat "1-1.1: 1.1".

Jadi sebelum memberontak saya akan melihat ini di 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

Maka saya lakukan:

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

Dan kemudian saya melihat di 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

Jadi seperti yang saya katakan, menatap wajah saya, karena dua informasi kunci adalah dua hal pertama di telepon ketika perangkat mengikat ...

ali1234
sumber
Apakah Anda harus menentukan dalam driver Anda bahwa vendor / produk itu kompatibel dengan driver Anda? Atau apakah "ikatan" hanya memaksa masalah. Saya mendapatkan "tidak ada perangkat seperti itu" untuk perangkat yang telah di-blacklist tapi saya ingin memaksanya untuk diikat, dan saya membayangkan blacklist bukan hanya "mencegah pengikatan otomatis" tetapi juga "mencegah pengikatan mengikat" apa jenisnya.
dmansfield
Bind memaksakannya, jadi tidak perlu mengklaim ID di sumber driver. Itu jika Anda ingin memuat secara otomatis.
ali1234
Dua alasan saya mengalami masalah: pertama - perangkat terdaftar di hid_ignore_list kernel sehingga tidak akan "bersembunyi" terikat apa pun. Saya harus menambahkan "usbhid.quirks = 0x0b0e: 0x0412: 0x40000000" ke baris perintah kernel dan reboot. Bendera 0x40000000 adalah "jangan abaikan". Kedua, bagian terakhir dari id "0003: 046D: C229.0036" adalah '0036'. Ini mewakili apa? Tidak yakin. Satu-satunya cara untuk menemukannya (tampaknya) adalah dengan mengikatnya, lalu melepaskannya dan membaliknya.
dmansfield
Apakah Anda menemukan cara untuk memberontak secara otomatis?
Vladius
Menambahkan solusi auto-rebinding saya sendiri: unix.stackexchange.com/a/475277/96686
Vladius