Path: blob/master/drivers/hid/bpf/progs/Mistel__MD770.bpf.c
26285 views
// SPDX-License-Identifier: GPL-2.01/* Copyright (c) 2024 Tatsuyuki Ishi2*/34#include "vmlinux.h"5#include "hid_bpf.h"6#include "hid_bpf_helpers.h"7#include <bpf/bpf_tracing.h>89#define VID_HOLTEK 0x04D910#define PID_MD770 0x033911#define RDESC_SIZE 2031213HID_BPF_CONFIG(14HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, VID_HOLTEK, PID_MD770)15);1617/*18* The Mistel MD770 keyboard reports the first 6 simultaneous key presses19* through the first interface, and anything beyond that through a second20* interface. Unfortunately, the second interface's report descriptor has an21* error, causing events to be malformed and ignored. This HID-BPF driver22* fixes the descriptor to allow NKRO to work again.23*24* For reference, this is the original report descriptor:25*26* 0x05, 0x01, // Usage Page (Generic Desktop) 027* 0x09, 0x80, // Usage (System Control) 228* 0xa1, 0x01, // Collection (Application) 429* 0x85, 0x01, // Report ID (1) 630* 0x19, 0x81, // Usage Minimum (129) 831* 0x29, 0x83, // Usage Maximum (131) 1032* 0x15, 0x00, // Logical Minimum (0) 1233* 0x25, 0x01, // Logical Maximum (1) 1434* 0x95, 0x03, // Report Count (3) 1635* 0x75, 0x01, // Report Size (1) 1836* 0x81, 0x02, // Input (Data,Var,Abs) 2037* 0x95, 0x01, // Report Count (1) 2238* 0x75, 0x05, // Report Size (5) 2439* 0x81, 0x01, // Input (Cnst,Arr,Abs) 2640* 0xc0, // End Collection 2841* 0x05, 0x0c, // Usage Page (Consumer Devices) 2942* 0x09, 0x01, // Usage (Consumer Control) 3143* 0xa1, 0x01, // Collection (Application) 3344* 0x85, 0x02, // Report ID (2) 3545* 0x15, 0x00, // Logical Minimum (0) 3746* 0x25, 0x01, // Logical Maximum (1) 3947* 0x95, 0x12, // Report Count (18) 4148* 0x75, 0x01, // Report Size (1) 4349* 0x0a, 0x83, 0x01, // Usage (AL Consumer Control Config) 4550* 0x0a, 0x8a, 0x01, // Usage (AL Email Reader) 4851* 0x0a, 0x92, 0x01, // Usage (AL Calculator) 5152* 0x0a, 0x94, 0x01, // Usage (AL Local Machine Browser) 5453* 0x09, 0xcd, // Usage (Play/Pause) 5754* 0x09, 0xb7, // Usage (Stop) 5955* 0x09, 0xb6, // Usage (Scan Previous Track) 6156* 0x09, 0xb5, // Usage (Scan Next Track) 6357* 0x09, 0xe2, // Usage (Mute) 6558* 0x09, 0xea, // Usage (Volume Down) 6759* 0x09, 0xe9, // Usage (Volume Up) 6960* 0x0a, 0x21, 0x02, // Usage (AC Search) 7161* 0x0a, 0x23, 0x02, // Usage (AC Home) 7462* 0x0a, 0x24, 0x02, // Usage (AC Back) 7763* 0x0a, 0x25, 0x02, // Usage (AC Forward) 8064* 0x0a, 0x26, 0x02, // Usage (AC Stop) 8365* 0x0a, 0x27, 0x02, // Usage (AC Refresh) 8666* 0x0a, 0x2a, 0x02, // Usage (AC Bookmarks) 8967* 0x81, 0x02, // Input (Data,Var,Abs) 9268* 0x95, 0x01, // Report Count (1) 9469* 0x75, 0x0e, // Report Size (14) 9670* 0x81, 0x01, // Input (Cnst,Arr,Abs) 9871* 0xc0, // End Collection 10072* 0x05, 0x01, // Usage Page (Generic Desktop) 10173* 0x09, 0x02, // Usage (Mouse) 10374* 0xa1, 0x01, // Collection (Application) 10575* 0x09, 0x01, // Usage (Pointer) 10776* 0xa1, 0x00, // Collection (Physical) 10977* 0x85, 0x03, // Report ID (3) 11178* 0x05, 0x09, // Usage Page (Button) 11379* 0x19, 0x01, // Usage Minimum (1) 11580* 0x29, 0x08, // Usage Maximum (8) 11781* 0x15, 0x00, // Logical Minimum (0) 11982* 0x25, 0x01, // Logical Maximum (1) 12183* 0x75, 0x01, // Report Size (1) 12384* 0x95, 0x08, // Report Count (8) 12585* 0x81, 0x02, // Input (Data,Var,Abs) 12786* 0x05, 0x01, // Usage Page (Generic Desktop) 12987* 0x09, 0x30, // Usage (X) 13188* 0x09, 0x31, // Usage (Y) 13389* 0x16, 0x01, 0x80, // Logical Minimum (-32767) 13590* 0x26, 0xff, 0x7f, // Logical Maximum (32767) 13891* 0x75, 0x10, // Report Size (16) 14192* 0x95, 0x02, // Report Count (2) 14393* 0x81, 0x06, // Input (Data,Var,Rel) 14594* 0x09, 0x38, // Usage (Wheel) 14795* 0x15, 0x81, // Logical Minimum (-127) 14996* 0x25, 0x7f, // Logical Maximum (127) 15197* 0x75, 0x08, // Report Size (8) 15398* 0x95, 0x01, // Report Count (1) 15599* 0x81, 0x06, // Input (Data,Var,Rel) 157100* 0x05, 0x0c, // Usage Page (Consumer Devices) 159101* 0x0a, 0x38, 0x02, // Usage (AC Pan) 161102* 0x95, 0x01, // Report Count (1) 164103* 0x81, 0x06, // Input (Data,Var,Rel) 166104* 0xc0, // End Collection 168105* 0xc0, // End Collection 169106* 0x05, 0x01, // Usage Page (Generic Desktop) 170107* 0x09, 0x06, // Usage (Keyboard) 172108* 0xa1, 0x01, // Collection (Application) 174109* 0x85, 0x04, // Report ID (4) 176110* 0x05, 0x07, // Usage Page (Keyboard) 178111* 0x95, 0x01, // Report Count (1) 180112* 0x75, 0x08, // Report Size (8) 182113* 0x81, 0x03, // Input (Cnst,Var,Abs) 184114* 0x95, 0xe8, // Report Count (232) 186115* 0x75, 0x01, // Report Size (1) 188116* 0x15, 0x00, // Logical Minimum (0) 190117* 0x25, 0x01, // Logical Maximum (1) 192118* 0x05, 0x07, // Usage Page (Keyboard) 194119* 0x19, 0x00, // Usage Minimum (0) 196120* 0x29, 0xe7, // Usage Maximum (231) 198121* 0x81, 0x00, // Input (Data,Arr,Abs) 200 <- change to 0x81, 0x02 (Data,Var,Abs)122* 0xc0, // End Collection 202123*/124125SEC(HID_BPF_RDESC_FIXUP)126int BPF_PROG(hid_rdesc_fixup_mistel_md770, struct hid_bpf_ctx *hctx)127{128__u8 *data = hid_bpf_get_data(hctx, 0, HID_MAX_DESCRIPTOR_SIZE);129130if (!data)131return 0; /* EPERM check */132133if (data[201] == 0x00)134data[201] = 0x02;135136return 0;137}138139HID_BPF_OPS(mistel_md770) = {140.hid_rdesc_fixup = (void *)hid_rdesc_fixup_mistel_md770,141};142143SEC("syscall")144int probe(struct hid_bpf_probe_args *ctx)145{146ctx->retval = ctx->rdesc_size != RDESC_SIZE;147if (ctx->retval)148ctx->retval = -EINVAL;149150return 0;151}152153char _license[] SEC("license") = "GPL";154155156