brintos

brintos / linux-shallow public Read only

0
0
Text · 7.5 KiB · ecf775a Raw
145 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Copyright (c) 2024 Kumar Swarnam Iyer (kumar.s.iyer65@gmail.com)3 */4 5#include "vmlinux.h"6#include "hid_bpf.h"7#include "hid_bpf_helpers.h"8#include <bpf/bpf_tracing.h>9 10#define VID_THRUSTMASTER 0x044F11#define PID_TCA_YOKE_BOEING 0x040912 13HID_BPF_CONFIG(14	HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, VID_THRUSTMASTER, PID_TCA_YOKE_BOEING)15);16 17/*  The original HID descriptor of the Thrustmaster TCA Yoke Boeing joystick contains18 *  an Input field that shows up as an axis, ABS_MISC in Linux. But it is not possible19 *  to assign an actual physical control to this axis as they're all taken up. There20 *  are 2 vendor-defined inputs where the Input type appears to be defined wrongly.21 *  This bpf attempts to fix this by changing the Inputs so that it doesn't show up in22 *  Linux at all.23 *  This version is the short version fix that only changes 2 fields in the descriptor24 *  instead of the whole report descriptor.25 *  For reference, this is the original report descriptor:26 *27 *  0x05, 0x01,                    // Usage Page (Generic Desktop)        028 *  0x09, 0x04,                    // Usage (Joystick)                    229 *  0xa1, 0x01,                    // Collection (Application)            430 *  0x85, 0x01,                    //  Report ID (1)                      631 *  0x09, 0x39,                    //  Usage (Hat switch)                 832 *  0x15, 0x00,                    //  Logical Minimum (0)                1033 *  0x25, 0x07,                    //  Logical Maximum (7)                1234 *  0x35, 0x00,                    //  Physical Minimum (0)               1435 *  0x46, 0x3b, 0x01,              //  Physical Maximum (315)             1636 *  0x65, 0x14,                    //  Unit (EnglishRotation: deg)        1937 *  0x75, 0x04,                    //  Report Size (4)                    2138 *  0x95, 0x01,                    //  Report Count (1)                   2339 *  0x81, 0x42,                    //  Input (Data,Var,Abs,Null)          2540 *  0x65, 0x00,                    //  Unit (None)                        2741 *  0x05, 0x09,                    //  Usage Page (Button)                2942 *  0x19, 0x01,                    //  Usage Minimum (1)                  3143 *  0x29, 0x12,                    //  Usage Maximum (18)                 3344 *  0x15, 0x00,                    //  Logical Minimum (0)                3545 *  0x25, 0x01,                    //  Logical Maximum (1)                3746 *  0x75, 0x01,                    //  Report Size (1)                    3947 *  0x95, 0x12,                    //  Report Count (18)                  4148 *  0x81, 0x02,                    //  Input (Data,Var,Abs)               4349 *  0x95, 0x02,                    //  Report Count (2)                   4550 *  0x81, 0x03,                    //  Input (Cnst,Var,Abs)               4751 *  0x05, 0x01,                    //  Usage Page (Generic Desktop)       4952 *  0x09, 0x31,                    //  Usage (Y)                          5153 *  0x09, 0x30,                    //  Usage (X)                          5354 *  0x09, 0x32,                    //  Usage (Z)                          5555 *  0x09, 0x34,                    //  Usage (Ry)                         5756 *  0x09, 0x33,                    //  Usage (Rx)                         5957 *  0x09, 0x35,                    //  Usage (Rz)                         6158 *  0x15, 0x00,                    //  Logical Minimum (0)                6359 *  0x27, 0xff, 0xff, 0x00, 0x00,  //  Logical Maximum (65535)            6560 *  0x75, 0x10,                    //  Report Size (16)                   7061 *  0x95, 0x06,                    //  Report Count (6)                   7262 *  0x81, 0x02,                    //  Input (Data,Var,Abs)               7463 *  0x06, 0xf0, 0xff,              //  Usage Page (Vendor Usage Page 0xfff0) 7664 *  0x09, 0x59,                    //  Usage (Vendor Usage 0x59)          7965 *  0x15, 0x00,                    //  Logical Minimum (0)                8166 *  0x26, 0xff, 0x00,              //  Logical Maximum (255)              8367 *  0x75, 0x08,                    //  Report Size (8)                    8668 *  0x95, 0x01,                    //  Report Count (1)                   8869 *  0x81, 0x02,                    //  Input (Data,Var,Abs)               90 --> Needs to be changed70 *  0x09, 0x51,                    //  Usage (Vendor Usage 0x51)          9271 *  0x15, 0x00,                    //  Logical Minimum (0)                9472 *  0x26, 0xff, 0x00,              //  Logical Maximum (255)              9673 *  0x75, 0x08,                    //  Report Size (8)                    9974 *  0x95, 0x20,                    //  Report Count (32)                  101 --> Needs to be changed75 *  0x81, 0x02,                    //  Input (Data,Var,Abs)               10376 *  0x09, 0x50,                    //  Usage (Vendor Usage 0x50)          10577 *  0x15, 0x00,                    //  Logical Minimum (0)                10778 *  0x26, 0xff, 0x00,              //  Logical Maximum (255)              10979 *  0x75, 0x08,                    //  Report Size (8)                    11280 *  0x95, 0x0f,                    //  Report Count (15)                  11481 *  0x81, 0x03,                    //  Input (Cnst,Var,Abs)               11682 *  0x09, 0x47,                    //  Usage (Vendor Usage 0x47)          11883 *  0x85, 0xf2,                    //  Report ID (242)                    12084 *  0x15, 0x00,                    //  Logical Minimum (0)                12285 *  0x26, 0xff, 0x00,              //  Logical Maximum (255)              12486 *  0x75, 0x08,                    //  Report Size (8)                    12787 *  0x95, 0x3f,                    //  Report Count (63)                  12988 *  0xb1, 0x02,                    //  Feature (Data,Var,Abs)             13189 *  0x09, 0x48,                    //  Usage (Vendor Usage 0x48)          13390 *  0x85, 0xf3,                    //  Report ID (243)                    13591 *  0x15, 0x00,                    //  Logical Minimum (0)                13792 *  0x26, 0xff, 0x00,              //  Logical Maximum (255)              13993 *  0x75, 0x08,                    //  Report Size (8)                    14294 *  0x95, 0x3f,                    //  Report Count (63)                  14495 *  0xb1, 0x02,                    //  Feature (Data,Var,Abs)             14696 *  0xc0,                          // End Collection                      14897 */98 99SEC(HID_BPF_RDESC_FIXUP)100int BPF_PROG(hid_fix_rdesc_tca_yoke, struct hid_bpf_ctx *hctx)101{102	const int expected_length = 148;103 104	if (hctx->size != expected_length)105		return 0;106 107	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, HID_MAX_DESCRIPTOR_SIZE /* size */);108 109	if (!data)110		return 0; /* EPERM */111 112	/* Safety check, our probe() should take care of this though */113	if (data[1] != 0x01 /* Generic Desktop */ || data[3] != 0x04 /* Joystick */)114		return 0;115 116	/* The report descriptor sets incorrect Input items in 2 places, resulting in a117	 * non-existing axis showing up.118	 * This change sets the correct Input which prevents the axis from showing up in Linux.119	 */120 121	if (data[90] == 0x81 && /* Input */122	    data[103] == 0x81) { /* Input */123		data[91] = 0x03; /* Input set to 0x03 Constant, Variable Absolute */124		data[104] = 0x03; /* Input set to 0X03 Constant, Variable Absolute */125	}126 127	return 0;128}129 130HID_BPF_OPS(tca_yoke) = {131	.hid_rdesc_fixup = (void *)hid_fix_rdesc_tca_yoke,132};133 134SEC("syscall")135int probe(struct hid_bpf_probe_args *ctx)136{137	/* ensure the kernel isn't fixed already */138	if (ctx->rdesc[91] != 0x02) /* Input for 0x59 Usage type has changed */139		ctx->retval = -EINVAL;140 141	return 0;142}143 144char _license[] SEC("license") = "GPL";145