diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | compile_commands.json | 44 | ||||
| -rw-r--r-- | hid-tm.h | 49 | ||||
| -rw-r--r-- | hid-tminit.c | 75 |
4 files changed, 152 insertions, 18 deletions
@@ -1,4 +1,4 @@ -obj-m += hid-tmff2.o +obj-m += hid-tminit.o all: make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules diff --git a/compile_commands.json b/compile_commands.json index 0ac6efe..ea1a16a 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -1,24 +1,24 @@ [ { "arguments": [ - "gcc-9", + "gcc", "-c", - "-Wp,-MD,/home/kimi/Documents/Projects/hid-tmff2/.hid-tmff2.o.d", + "-Wp,-MD,/home/kimi/Documents/tmff2/.hid-tminit.o.d", "-nostdinc", "-isystem", "/usr/lib/gcc/x86_64-linux-gnu/9/include", - "-I/usr/src/linux-headers-5.7.0-1-common/arch/x86/include", + "-I./arch/x86/include", "-I./arch/x86/include/generated", - "-I/usr/src/linux-headers-5.7.0-1-common/include", "-I./include", - "-I/usr/src/linux-headers-5.7.0-1-common/arch/x86/include/uapi", + "-I./arch/x86/include/uapi", "-I./arch/x86/include/generated/uapi", - "-I/usr/src/linux-headers-5.7.0-1-common/include/uapi", + "-I./include/uapi", "-I./include/generated/uapi", "-include", - "/usr/src/linux-headers-5.7.0-1-common/include/linux/kconfig.h", + "./include/linux/kconfig.h", + "-Iubuntu/include", "-include", - "/usr/src/linux-headers-5.7.0-1-common/include/linux/compiler_types.h", + "./include/linux/compiler_types.h", "-D__KERNEL__", "-Wall", "-Wundef", @@ -48,6 +48,15 @@ "-mno-red-zone", "-mcmodel=kernel", "-DCONFIG_X86_X32_ABI", + "-DCONFIG_AS_CFI=1", + "-DCONFIG_AS_CFI_SIGNAL_FRAME=1", + "-DCONFIG_AS_CFI_SECTIONS=1", + "-DCONFIG_AS_SSSE3=1", + "-DCONFIG_AS_AVX=1", + "-DCONFIG_AS_AVX2=1", + "-DCONFIG_AS_AVX512=1", + "-DCONFIG_AS_SHA1_NI=1", + "-DCONFIG_AS_SHA256_NI=1", "-Wno-sign-compare", "-fno-asynchronous-unwind-tables", "-mindirect-branch=thunk-extern", @@ -60,13 +69,14 @@ "-Wno-address-of-packed-member", "-O2", "--param=allow-store-data-races=0", - "-Wframe-larger-than=2048", + "-Wframe-larger-than=1024", "-fstack-protector-strong", "-Wno-unused-but-set-variable", "-Wimplicit-fallthrough", "-Wno-unused-const-variable", + "-fno-omit-frame-pointer", + "-fno-optimize-sibling-calls", "-fno-var-tracking-assignments", - "-g", "-pg", "-mrecord-mcount", "-mfentry", @@ -88,17 +98,17 @@ "-Werror=date-time", "-Werror=incompatible-pointer-types", "-Werror=designated-init", - "-fmacro-prefix-map=/usr/src/linux-headers-5.7.0-1-common/=", + "-fmacro-prefix-map=./=", "-fcf-protection=none", "-Wno-packed-not-aligned", "-DMODULE", - "-DKBUILD_BASENAME=\"hid_tmff2\"", - "-DKBUILD_MODNAME=\"hid_tmff2\"", + "-DKBUILD_BASENAME=\"hid_tminit\"", + "-DKBUILD_MODNAME=\"hid_tminit\"", "-o", - "/home/kimi/Documents/Projects/hid-tmff2/hid-tmff2.o", - "../../../home/kimi/Documents/Projects/hid-tmff2/hid-tmff2.c" + "/home/kimi/Documents/tmff2/hid-tminit.o", + "../../../home/kimi/Documents/tmff2/hid-tminit.c" ], - "directory": "/usr/src/linux-headers-5.7.0-1-amd64", - "file": "../../../home/kimi/Documents/Projects/hid-tmff2/hid-tmff2.c" + "directory": "/usr/src/linux-headers-5.4.0-40-generic", + "file": "../../../home/kimi/Documents/tmff2/hid-tminit.c" } ]
\ No newline at end of file diff --git a/hid-tm.h b/hid-tm.h new file mode 100644 index 0000000..17cc741 --- /dev/null +++ b/hid-tm.h @@ -0,0 +1,49 @@ +#include <linux/hid.h> +#include <linux/usb.h> +#include <linux/input.h> +#include <linux/slab.h> +#include <linux/module.h> + +#define USB_VENDOR_ID_THRUSTMASTER 0x044f + +struct api_context { + struct completion done; + int status; +}; + +struct api_context ctx; + +int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) +{ + + unsigned long expire; + int retval; + + init_completion(&ctx.done); + urb->context = &ctx; + urb->actual_length = 0; + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (unlikely(retval)) + goto out; + + expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; + if (!wait_for_completion_timeout(&ctx.done, expire)) { + usb_kill_urb(urb); + retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); + + dev_dbg(&urb->dev->dev, + "%s timed out on ep%d%s len=%u/%u\n", + current->comm, + usb_endpoint_num(&urb->ep->desc), + usb_urb_dir_in(urb) ? "in" : "out", + urb->actual_length, + urb->transfer_buffer_length); + } else + retval = ctx.status; +out: + if (actual_length) + *actual_length = urb->actual_length; + + usb_free_urb(urb); + return retval; +} diff --git a/hid-tminit.c b/hid-tminit.c new file mode 100644 index 0000000..464b85c --- /dev/null +++ b/hid-tminit.c @@ -0,0 +1,75 @@ +#include "hid-tm.h" + +u8 hw_rq_in[] = { 0xc1, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00 }; +u8 hw_rq_out[] = { 0x41, 0x53, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +static void tminit_callback(struct urb *urb){ return; } + +int tminit(struct hid_device *hdev){ + struct urb *urb; + struct device *dev = &hdev->dev; + struct usb_interface *usbif = to_usb_interface(dev->parent); + struct usb_device *usbdev = interface_to_usbdev(usbif); + + urb = usb_alloc_urb(0, GFP_ATOMIC); + + usb_fill_control_urb(urb, + usbdev, + usb_sndctrlpipe(usbdev, 0), + &hw_rq_in[0], + &hw_rq_out[0], + 0, + tminit_callback, + hdev); + + /* we sort of have to go on faith that the message is sent, because the + * wheel usually completely dies as soon as it gets the message. + */ + return usb_start_wait_urb(urb, USB_CTRL_SET_TIMEOUT, NULL); +} + +static void tminit_remove(struct hid_device *hdev){ + /* we are dead */ + hid_hw_stop(hdev); +} + +static int tminit_probe(struct hid_device *hdev, const struct hid_device_id *id){ + int ret; + + ret = hid_parse(hdev); + if(ret){ + hid_err(hdev, "parse failed\n"); + goto err; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); + if(ret){ + hid_err(hdev, "hw start failed\n"); + goto err; + } + + ret = tminit(hdev); + if(ret){ + hid_err(hdev, "tminit failed, possibly as it should\n"); + goto err; + } +err: + return ret; +} + +static const struct hid_device_id tminit_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb56d)}, + {} +}; + +MODULE_DEVICE_TABLE(hid, tminit_devices); + +static struct hid_driver tminit_driver = { + .name = "thrustmaster init", + .id_table = tminit_devices, + .probe = tminit_probe, + .remove = tminit_remove, +}; +module_hid_driver(tminit_driver); + +MODULE_LICENSE("GPL"); |
