From db12c7bead4154929668badaade14db135dab6d9 Mon Sep 17 00:00:00 2001 From: kimi Date: Wed, 8 Jul 2020 11:17:48 -0400 Subject: initial commit for memory --- Makefile | 2 +- compile_commands.json | 44 ++++++++++++++++++------------ hid-tm.h | 49 +++++++++++++++++++++++++++++++++ hid-tminit.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+), 18 deletions(-) create mode 100644 hid-tm.h create mode 100644 hid-tminit.c diff --git a/Makefile b/Makefile index ba704a9..d666a97 100644 --- a/Makefile +++ b/Makefile @@ -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 +#include +#include +#include +#include + +#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"); -- cgit v1.3 From 9d17b5ed83e46122966d663b0bb05e82fb9dd01c Mon Sep 17 00:00:00 2001 From: kimi Date: Wed, 8 Jul 2020 13:38:00 -0400 Subject: added first version of generic Thrustmaster FFB device driver --- hid-tminit.c | 37 +++++++++++++++++++++++++------------ hid-tminit.h | 18 ++++++++++++++++++ 2 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 hid-tminit.h diff --git a/hid-tminit.c b/hid-tminit.c index 464b85c..e48b419 100644 --- a/hid-tminit.c +++ b/hid-tminit.c @@ -1,35 +1,47 @@ -#include "hid-tm.h" +#include "hid-tminit.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; } +static void tminit_callback(struct urb *urb){ + ctx.status = urb->status; + hid_info(urb->dev, "urb status %d received\n", urb->status); +} int tminit(struct hid_device *hdev){ struct urb *urb; + u8 *setup_packet, *transfer_buffer; struct device *dev = &hdev->dev; struct usb_interface *usbif = to_usb_interface(dev->parent); struct usb_device *usbdev = interface_to_usbdev(usbif); + int ret; + + setup_packet = kmalloc(8, GFP_ATOMIC); + transfer_buffer = kmalloc(8, GFP_ATOMIC); + + memcpy(setup_packet, hw_rq_out, 8); + memcpy(transfer_buffer, hw_rq_in, 8); 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], + setup_packet, + transfer_buffer, 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. + * wheel usually completely dies as soon as it receives the message. */ - return usb_start_wait_urb(urb, USB_CTRL_SET_TIMEOUT, NULL); + ret = usb_start_wait_urb(urb, 5, NULL); + + kfree(setup_packet); + kfree(transfer_buffer); + return ret; } static void tminit_remove(struct hid_device *hdev){ - /* we are dead */ + /* we are dead, hopefully without any serious side effects */ hid_hw_stop(hdev); } @@ -50,15 +62,16 @@ static int tminit_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = tminit(hdev); if(ret){ - hid_err(hdev, "tminit failed, possibly as it should\n"); + hid_err(hdev, "tminit exited, error might be intended behaviour\n"); goto err; } + err: return ret; } static const struct hid_device_id tminit_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb56d)}, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65d)}, {} }; diff --git a/hid-tminit.h b/hid-tminit.h new file mode 100644 index 0000000..cd12f9b --- /dev/null +++ b/hid-tminit.h @@ -0,0 +1,18 @@ +#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 }; + +u8 setup_0[] = { 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +u8 setup_1[] = { 0x0a, 0x04, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00 }; +u8 setup_2[] = { 0x0a, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00 }; +u8 setup_3[] = { 0x0a, 0x04, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00 }; +u8 setup_4[] = { 0x0a, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00 }; +u8 *setup_arr[] = { setup_0, setup_1, setup_2, setup_3, setup_4 }; +unsigned int setup_arr_sizes[] = { + ARRAY_SIZE(setup_0), + ARRAY_SIZE(setup_1), + ARRAY_SIZE(setup_2), + ARRAY_SIZE(setup_3), + ARRAY_SIZE(setup_4) +}; -- cgit v1.3 From 5e6836ce8a481aa0dde3a1b5ed33ae872e3844d9 Mon Sep 17 00:00:00 2001 From: kimi Date: Wed, 8 Jul 2020 13:38:34 -0400 Subject: remove old test code --- hid-tmff2.c | 872 ------------------------------------------------------------ 1 file changed, 872 deletions(-) delete mode 100644 hid-tmff2.c diff --git a/hid-tmff2.c b/hid-tmff2.c deleted file mode 100644 index b26185f..0000000 --- a/hid-tmff2.c +++ /dev/null @@ -1,872 +0,0 @@ -/*This file has been modified from the Linux kernel driver drivers/hid/hid-tmff.c, starting from May 7 2020*/ - -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Force feedback support for various HID compliant devices by ThrustMaster: - * ThrustMaster FireStorm Dual Power 2 - * and possibly others whose device ids haven't been added. - * - * Modified to support ThrustMaster devices by Zinx Verituse - * on 2003-01-25 from the Logitech force feedback driver, - * which is by Johann Deneux. - * - * Copyright (c) 2003 Zinx Verituse - * Copyright (c) 2002 Johann Deneux - */ - -/* -*/ - -#include -#include -#include -#include -#include - -#define USB_VENDOR_ID_THRUSTMASTER 0x044f -#define THRUSTMASTER_DEVICE_ID_2_IN_1_DT 0xb320 -#define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL 0x001e - -unsigned long last = 0; - -static const signed short ff_rumble[] = { - FF_RUMBLE, - -1 -}; - -static const signed short ff_constant[] = { - FF_CONSTANT, - -1 -}; - -static const signed short ff_joystick[] = { - FF_CONSTANT, - -1 -}; - -#ifdef CONFIG_THRUSTMASTER_FF - -/* Usages for thrustmaster devices I know about */ -#define THRUSTMASTER_USAGE_FF (HID_UP_GENDESK | 0xbb) - -u16 tmff_gain = 0xffff; - -static u8 setup_0[] = { 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static u8 setup_1[] = { 0x0a, 0x04, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00 }; -static u8 setup_2[] = { 0x0a, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00 }; -static u8 setup_3[] = { 0x0a, 0x04, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00 }; -static u8 setup_4[] = { 0x0a, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00 }; -static u8 *setup_arr[] = { setup_0, setup_1, setup_2, setup_3, setup_4 }; -static unsigned int setup_arr_sizes[] = { - ARRAY_SIZE(setup_0), - ARRAY_SIZE(setup_1), - ARRAY_SIZE(setup_2), - ARRAY_SIZE(setup_3), - ARRAY_SIZE(setup_4) -}; - -static u8 hw_rq_in[] = { 0xc1, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00 }; -static u8 hw_rq_out[] = { 0x41, 0x53, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static u8 ff_constant_array[] = { - 0x60, 0x00, 0x01, 0x0a, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static u8 ff_stop_array[] = { - 0x60, 0x00, 0x01, 0x0a, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static u8 t300rs_0[] = { - 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -}; - -static u8 t300rs_1[] = { - 0x0a, 0x04, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -}; - -static u8 t300rs_2[] = { - 0x0a, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -}; - -static u8 t300rs_3[] = { - 0x0a, 0x04, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -}; - -static u8 t300rs_4[] = { - 0x0a, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -}; - -static u8 t300rs_re[] = { - 0x0a, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static u8 *t300rs_arr[] = { t300rs_0, t300rs_1, t300rs_2, t300rs_3, t300rs_4, }; -static unsigned int t300rs_arr_sizes[] = { - ARRAY_SIZE(t300rs_0), - ARRAY_SIZE(t300rs_1), - ARRAY_SIZE(t300rs_2), - ARRAY_SIZE(t300rs_3), - ARRAY_SIZE(t300rs_4), -}; - -static u8 t300rs_ctrl_out[] = { 0x41, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, }; - -static u8 t300rs_ctrl_in_0[] = { 0xc1, 0x42, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, }; -static u8 t300rs_ctrl_in_1[] = { 0xc1, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, }; -static u8 t300rs_ctrl_in_2[] = { 0xc1, 0x56, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, }; -static u8 t300rs_ctrl_in_re[] = { 0xc1, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00 }; -static u8 *t300rs_ctrl_in_arr[] = {t300rs_ctrl_in_0, t300rs_ctrl_in_1, t300rs_ctrl_in_2 }; -static unsigned int t300rs_ctrl_in_sizes[] = { - ARRAY_SIZE(t300rs_ctrl_in_0), - ARRAY_SIZE(t300rs_ctrl_in_1), - ARRAY_SIZE(t300rs_ctrl_in_2) -}; - -static u8 t300rs_in_0[] = { 0xc1, 0x56, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, }; -static u8 t300rs_in_1[] = { 0xc1, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, }; -static u8 t300rs_in_2[] = { 0xc1, 0x48, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, }; -static u8 t300rs_in_3[] = { 0xc1, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, }; -static u8 *t300rs_in_arr[] = {t300rs_in_0, t300rs_in_1, t300rs_in_2, t300rs_in_3}; -static unsigned int t300rs_in_sizes[] = { - ARRAY_SIZE(t300rs_in_0), - ARRAY_SIZE(t300rs_in_1), - ARRAY_SIZE(t300rs_in_2), - ARRAY_SIZE(t300rs_in_3) -}; - -static u8 t300rs_fin_0[] = { - 0x60, 0x09, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static u8 t300rs_fin_1[] = { - 0x60, 0x0b, 0x05, 0xbf, 0x03, 0xc3, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static u8 t300rs_fin_2[] = { - 0x60, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static u8 t300rs_fin_3[] = { - 0x60, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static u8 t300rs_fin_4[] = { - 0x60, 0x00, 0x01, 0x6a, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static u8 t300rs_fin_5[] = { - 0x60, 0x00, 0x02, 0x6b, 0xfc, 0x7f, 0xfe, 0xff, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x80, 0x00, 0x00, - 0xfc, 0x7f, 0x00, 0x00, 0xfc, 0x7f, 0x03, 0x4f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static u8 t300rs_fin_6[] = { - 0x60, 0x00, 0x03, 0x64, 0xfd, 0x3f, 0xfd, 0x3f, 0x31, 0x03, 0xcb, 0xfc, 0xfd, 0x5f, 0xfd, 0x5f, - 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xdf, 0x58, 0xa6, 0x6a, 0x06, 0x4f, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static u8 t300rs_fin_7[] = { - 0x60, 0x00, 0x01, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static u8 *t300rs_fin_arr[] = {t300rs_fin_0, t300rs_fin_1, t300rs_fin_2, t300rs_fin_3, t300rs_fin_4, t300rs_fin_5, t300rs_fin_6, t300rs_fin_7 }; -static unsigned int t300rs_fin_sizes[] = { - ARRAY_SIZE(t300rs_fin_0), - ARRAY_SIZE(t300rs_fin_1), - ARRAY_SIZE(t300rs_fin_2), - ARRAY_SIZE(t300rs_fin_3), - ARRAY_SIZE(t300rs_fin_4), - ARRAY_SIZE(t300rs_fin_5), - ARRAY_SIZE(t300rs_fin_6), - ARRAY_SIZE(t300rs_fin_7) -}; - -struct tmff_device { - struct hid_report *report; - struct hid_field *ff_field; - spinlock_t report_lock; -}; - -static spinlock_t *report_lock; -static int flags; - -struct api_context { - struct completion done; - int status; -}; - -static struct api_context ctx; - -/* Changes values from 0 to 0xffff into values from minimum to maximum */ -static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum) -{ - int ret; - - ret = (in * (maximum - minimum) / 0xffff) + minimum; - if (ret < minimum) - return minimum; - if (ret > maximum) - return maximum; - return ret; -} - -/* Changes values from -0x80 to 0x7f into values from minimum to maximum */ -static inline int tmff_scale_s8(int in, int minimum, int maximum) -{ - int ret; - - ret = (((in + 0x80) * (maximum - minimum)) / 0xff) + minimum; - if (ret < minimum) - return minimum; - if (ret > maximum) - return maximum; - return ret; -} -bool transferred = true; -static void tmff_ctrl(struct urb *urb){ - if(urb->status){ - hid_warn(urb->dev, "urb status %d received\n", urb->status); - } - usb_free_urb(urb); - transferred = true; -} - -static void tmff_init_ctrl(struct urb *urb){ - if(urb->status){ - hid_warn(urb->dev, "urb status %d received\n", urb->status); - ctx.status = urb->status; - } -} - - -static void tmff_t300rs_ctrl(struct urb *urb){ - if(urb->status){ - hid_warn(urb->dev, "urb status %d received\n", urb->status); - } -} - -static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) -{ - - unsigned long expire; - int retval; - - printk("1"); - init_completion(&ctx.done); - urb->context = &ctx; - urb->actual_length = 0; - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(retval)) - goto out; - - printk("2"); - - 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: - printk("3"); - if (actual_length) - *actual_length = urb->actual_length; - - usb_free_urb(urb); - return retval; -} - -bool last_stop = false; - -static int tmff_play(struct input_dev *dev, void *data, - struct ff_effect *effect) -{ - - //spin_lock_irqsave(report_lock, flags); - struct hid_device *hid = input_get_drvdata(dev); - struct device *d_dev = &hid->dev; - struct usb_interface *usbif = to_usb_interface(d_dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - struct usb_host_endpoint *ep; - struct tmff_device *tmff = data; - struct hid_field *ff_field = tmff->ff_field; - struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC); - u8 *send_buf = kmalloc(1024, GFP_ATOMIC); - __s16 x; - - if(!transferred){ - return 0; - } - - - memcpy(send_buf, ff_constant_array, ARRAY_SIZE(ff_constant_array)); - - ep = &usbif->cur_altsetting->endpoint[1]; - - switch (effect->type) { - case FF_CONSTANT: - // this only works with input_ff_create_memless, which clamps - // constant forces to s8 for some reason - x = tmff_scale_s8(effect->u.constant.level, - ff_field->logical_minimum, - ff_field->logical_maximum); - - send_buf[4] = x & 0xff; - send_buf[5] = x >> 8; - - usb_fill_int_urb( - urb, - usbdev, - usb_sndintpipe(usbdev, 1), - send_buf, - ARRAY_SIZE(ff_constant_array), - tmff_ctrl, - hid, - ep->desc.bInterval - ); - transferred = false; - usb_submit_urb(urb, GFP_ATOMIC); - - - break; - default: - break; - } - -// msleep(2); - kfree(send_buf); - return 0; -} - -static int tmff_init_t300rs(struct hid_device *hid){ - - int trans, b_ep, bb_ep, i, err; - u8 *send_buf, *rq_buf; - struct device *dev = &hid->dev; - struct usb_interface *usbif = to_usb_interface(dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - struct usb_host_endpoint *ep; - struct urb *urb; - - ep = &usbif->cur_altsetting->endpoint[0]; - bb_ep = ep->desc.bEndpointAddress; - - ep = &usbif->cur_altsetting->endpoint[1]; - b_ep = ep->desc.bEndpointAddress; - - send_buf = kmalloc(256, GFP_ATOMIC); /* overkill but whatever */ - rq_buf = kmalloc(256, GFP_ATOMIC); - - for(i = 0; i < ARRAY_SIZE(t300rs_in_arr); ++i){ - memcpy(rq_buf, t300rs_in_arr[i], t300rs_in_sizes[i]); - urb = usb_alloc_urb(0, GFP_KERNEL); - usb_fill_control_urb(urb, - usbdev, - usb_rcvctrlpipe(usbdev, 0), - rq_buf, - send_buf, - 0, - tmff_t300rs_ctrl, - hid); - - err = usb_start_wait_urb(urb, 1, &trans); - if(err != 0){ - hid_err(hid, "Failed sending pre-ctrin with ERRNO: %i", err); - goto error; - } - } - - for(i = 0; i < ARRAY_SIZE(t300rs_ctrl_in_arr); ++i){ - memcpy(rq_buf, t300rs_ctrl_in_arr[i], t300rs_ctrl_in_sizes[i]); - urb = usb_alloc_urb(0, GFP_KERNEL); - usb_fill_control_urb(urb, - usbdev, - usb_rcvctrlpipe(usbdev, 0), - rq_buf, - send_buf, - 0, - tmff_t300rs_ctrl, - hid - ); - - err = usb_start_wait_urb(urb, 1, &trans); - if(err != 0){ - hid_err(hid, "Failed sending T300RS ctrl out with ERRNO: %i", err); - goto error; - } - - - } - printk("Sent initial ctrlouts"); - - for(i = 0; i < ARRAY_SIZE(t300rs_arr); ++i){ - memcpy(send_buf, t300rs_arr[i], t300rs_arr_sizes[i]); - - err = usb_interrupt_msg(usbdev, - usb_sndintpipe(usbdev, b_ep), - send_buf, - t300rs_arr_sizes[i], - &trans, - USB_CTRL_SET_TIMEOUT); - - if(err){ - hid_err(hid, "T300RS setup data at index %i couldn't be sent, ERRNO: %i\n", i, err); - goto error; - } - - err = usb_interrupt_msg(usbdev, - usb_rcvintpipe(usbdev, bb_ep), - send_buf, - 64, - &trans, - USB_CTRL_SET_TIMEOUT); - if(err != 0){ - hid_err(hid, "FUCK, ERRNO: %i", err); - goto error; - } - } - - memcpy(rq_buf, t300rs_ctrl_in_re, ARRAY_SIZE(t300rs_ctrl_in_re)); - for(i = 0; i < 16; ++i){ - urb = usb_alloc_urb(0, GFP_KERNEL); - usb_fill_control_urb(urb, - usbdev, - usb_rcvctrlpipe(usbdev, 0), - rq_buf, - send_buf, - 0, - tmff_t300rs_ctrl, - hid - ); - - err = usb_start_wait_urb(urb, 1, &trans); - if(err != 0){ - hid_err(hid, "Failed sending T300RS ctrl out with ERRNO: %i", err); - goto error; - } - } - - printk("Sent first 16 ctrlins"); - - memcpy(rq_buf, t300rs_ctrl_out, ARRAY_SIZE(t300rs_ctrl_out)); - urb = usb_alloc_urb(0, GFP_KERNEL); - usb_fill_control_urb(urb, - usbdev, - usb_sndctrlpipe(usbdev, 0), - rq_buf, - send_buf, - 0, - tmff_t300rs_ctrl, - hid - ); - - err = usb_start_wait_urb(urb, 1, &trans); - if(err != 0){ - hid_err(hid, "Failed sending ctrl out with ERRNO: %i", err); - goto error; - } - - memcpy(rq_buf, t300rs_ctrl_in_re, ARRAY_SIZE(t300rs_ctrl_in_re)); - for(i = 0; i < 8; ++i){ - urb = usb_alloc_urb(0, GFP_KERNEL); - usb_fill_control_urb(urb, - usbdev, - usb_rcvctrlpipe(usbdev, 0), - rq_buf, - send_buf, - 0, - tmff_t300rs_ctrl, - hid - ); - - err = usb_start_wait_urb(urb, 1, &trans); - if(err != 0){ - hid_err(hid, "Failed sending T300RS ctrl out with ERRNO: %i", err); - goto error; - } - } - - memcpy(send_buf, t300rs_re, ARRAY_SIZE(t300rs_re)); - - for(i = 0; i < 3; ++i){ - err = usb_interrupt_msg(usbdev, - usb_sndintpipe(usbdev, b_ep), - send_buf, - ARRAY_SIZE(t300rs_re), - &trans, - USB_CTRL_SET_TIMEOUT); - - if(err){ - hid_err(hid, "T300RS after-init data couldn't be sent, ERRNO: %i", err); - goto error; - } - } - - -error: - kfree(send_buf); - kfree(rq_buf); - - return 0; -} - -static int tmff_clear_init(struct hid_device *hid){ - /* die */ - - int trans, b_ep, i, err; - u8 *send_buf, *rq_buf; - struct device *dev = &hid->dev; - struct usb_interface *usbif = to_usb_interface(dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - struct usb_host_endpoint *ep; - struct urb *urb; - - ep = &usbif->cur_altsetting->endpoint[1]; - b_ep = ep->desc.bEndpointAddress; - - send_buf = kmalloc(256, GFP_KERNEL); /* overkill but whatever */ - rq_buf = kmalloc(256, GFP_KERNEL); - - for(i = 0; i < ARRAY_SIZE(setup_arr); ++i){ - memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]); - hid_info(hid, "Sent interrupt at %i\n", i); - err = usb_interrupt_msg(usbdev, - usb_sndintpipe(usbdev, b_ep), - send_buf, - setup_arr_sizes[i], - &trans, - USB_CTRL_SET_TIMEOUT); - - if(err){ - hid_err(hid, "Setup data at index %i couldn't be sent, ERRNO: %i\n", i, err); - goto error; - } - } - - - urb = usb_alloc_urb(0, GFP_ATOMIC); - - - memcpy(send_buf, hw_rq_in, 8); - memcpy(rq_buf, hw_rq_out, 8); - - usb_fill_control_urb(urb, - usbdev, - usb_sndctrlpipe(usbdev, 0), - rq_buf, - send_buf, - 0, - tmff_init_ctrl, - hid - ); - - err = usb_start_wait_urb(urb, 5, &trans); - if(err != 0){ - hid_err(hid, "Failed sending ctrl out with ERRNO: %i", err); - goto error; - } - hid_info(hid, "URB submission didn't fail?"); - -error: - kfree(rq_buf); - kfree(send_buf); - return err; -} - -static int tmff_delete(struct kref *kref){ - /* reserved for future use */ - /* currently the errors we get aren't pretty */ - - return 0; -}; - -static void tmff_set_gain(struct input_dev *dev, u16 gain){ - tmff_gain = gain; -} - -static int tmff_init(struct hid_device *hid, const signed short *ff_bits) -{ - - struct tmff_device *tmff; - struct hid_report *report; - struct list_head *report_list; - struct hid_input *hidinput = list_entry(hid->inputs.next, - struct hid_input, list); - struct input_dev *input_dev = hidinput->input; - struct ff_device *ff; - int error; - int i; - - if(hid->product == 0xb65d) - return tmff_clear_init(hid); - - tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL); - if (!tmff) - return -ENOMEM; - - hid_info(hid, "what is going ong here???"); - spin_lock_init(&tmff->report_lock); - report_lock = &tmff->report_lock; - - /* Find the report to use */ - report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - list_for_each_entry(report, report_list, list) { - int fieldnum; - - for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) { - struct hid_field *field = report->field[fieldnum]; - printk("found field at fieldnum %i\n", fieldnum); - - if (field->maxusage <= 0) - continue; - - switch (field->usage[0].hid) { - case 0xff00000a: - case THRUSTMASTER_USAGE_FF: - if (field->report_count < 2) { - hid_warn(hid, "ignoring FF field with report_count < 2\n"); - continue; - } - - if (field->logical_maximum == - field->logical_minimum) { - hid_warn(hid, "ignoring FF field with logical_maximum == logical_minimum\n"); - continue; - } - - if (tmff->report && tmff->report != report) { - hid_warn(hid, "ignoring FF field in other report\n"); - continue; - } - - if (tmff->ff_field && tmff->ff_field != field) { - hid_warn(hid, "ignoring duplicate FF field\n"); - continue; - } - - tmff->report = report; - tmff->ff_field = field; - - for (i = 0; ff_bits[i] >= 0; i++) - set_bit(ff_bits[i], input_dev->ffbit); - - break; - - default: - hid_warn(hid, "ignoring unknown output usage %08x\n", - field->usage[0].hid); - continue; - } - } - } - - if (!tmff->report) { - hid_err(hid, "can't find FF field in output reports\n"); - error = -ENODEV; - goto fail; - } - - error = input_ff_create_memless(input_dev, tmff, tmff_play); - if (error) - goto fail; - - ff = input_dev->ff; - ff->set_gain = tmff_set_gain; - - hid_info(hid, "force feedback for ThrustMaster devices by Zinx Verituse \n"); - return 0; - -fail: - hid_err(hid, "We have failed creating a force feedback memless device!!!\n"); - kfree(tmff); - return error; -} -#else -static inline int tmff_init(struct hid_device *hid, const signed short *ff_bits) -{ - return 0; -} -#endif -static int tmff_afterthought_t300rs(struct hid_device *hid){ - int trans, b_ep, bb_ep, i, err; - u8 *send_buf, *rq_buf; - struct device *dev = &hid->dev; - struct usb_interface *usbif = to_usb_interface(dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - struct usb_host_endpoint *ep; - - ep = &usbif->cur_altsetting->endpoint[0]; - bb_ep = ep->desc.bEndpointAddress; - - ep = &usbif->cur_altsetting->endpoint[1]; - b_ep = ep->desc.bEndpointAddress; - - send_buf = kmalloc(256, GFP_ATOMIC); /* overkill but whatever */ - rq_buf = kmalloc(256, GFP_ATOMIC); - - for(i = 0; i < ARRAY_SIZE(t300rs_fin_sizes); ++i){ - memcpy(send_buf, t300rs_fin_arr[i], t300rs_fin_sizes[i]); - - err = usb_interrupt_msg(usbdev, - usb_sndintpipe(usbdev, b_ep), - send_buf, - t300rs_fin_sizes[i], - &trans, - USB_CTRL_SET_TIMEOUT); - hid_info(hid, "sent %i:th message", i); - if(err){ - hid_err(hid, "T300RS setup data at index %i couldn't be sent, ERRNO: %i\n", i, err); - goto error; - } - } - - -error: - kfree(send_buf); - kfree(rq_buf); - return err; -} - - -static int tm_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; - } - - if(hdev->product == 0xb66e){ - ret = tmff_init_t300rs(hdev); - - if(ret){ - hid_err(hdev, "t300rs init failed\n"); - goto err; - } - } - - printk("woot\n"); - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); - if (ret) { - hid_err(hdev, "hw start failed\n"); - goto err; - } - printk("waat\n"); - - ret = tmff_init(hdev, (void *)id->driver_data); - - if(ret){ - hid_err(hdev, "what the fuck is going on?\n"); - if(ret == -32){ - //hid_hw_stop(hdev); - return 0; - } - goto err; - } - - if(hdev->product == 0xb66e){ - ret = tmff_afterthought_t300rs(hdev); - - if(ret){ - hid_err(hdev, "t300rs afterinit failed\n"); - goto err; - } - } - return 0; -err: - return ret; -} - -static void tm_remove(struct hid_device *hdev){ - hid_hw_stop(hdev); -} - -static __u8 t300rs_rdesc_fixed[] = {0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x85, 0x07, 0x09, 0x30, 0x15, 0x00, 0x27, 0xff, 0xff, 0x00, 0x00, 0x35, 0x00, 0x47, 0xff, 0xff, 0x00, 0x00, 0x75, 0x10, 0x95, 0x01, 0x81, 0x02, 0x09, 0x31, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x81, 0x02, 0x09, 0x35, 0x81, 0x02, 0x09, 0x36, 0x81, 0x02, 0x81, 0x03, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0d, 0x25, 0x01, 0x45, 0x01, 0x75, 0x01, 0x95, 0x0d, 0x81, 0x02, 0x75, 0x0b, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01, 0x09, 0x39, 0x25, 0x07, 0x46, 0x3b, 0x01, 0x55, 0x00, 0x65, 0x14, 0x75, 0x04, 0x81, 0x42, 0x65, 0x00, 0x81, 0x03, 0x85, 0x0a, 0x06, 0x00, 0xff, 0x09, 0x0a, 0x75, 0x08, 0x95, 0x3f, - 0x26, 0xff, 0x7f, - 0x16, 0x00, 0x80, - 0x46, 0xff, 0x7f, - 0x36, 0x00, 0x80, - 0x91, 0x02, 0x85, 0x02, 0x09, 0x02, 0x81, 0x02, 0x09, 0x14, 0x85, 0x14, 0x81, 0x02, 0xc0, 0xc0,}; - -static __u8 *tmff_t300rs_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize){ - if(hdev->product != 0xb66e){ - return rdesc; - } - printk("wahey"); - rdesc = t300rs_rdesc_fixed; - *rsize = sizeof(t300rs_rdesc_fixed); - return rdesc; -}; - -static const struct hid_device_id tm_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65d), - .driver_data = (unsigned long)ff_constant }, /* die */ - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb66e), - .driver_data = (unsigned long)ff_constant }, - { } -}; -MODULE_DEVICE_TABLE(hid, tm_devices); - -static struct hid_driver tm_driver = { - .name = "thrustmaster", - .id_table = tm_devices, - .probe = tm_probe, - .remove = tm_remove, - .report_fixup = tmff_t300rs_report_fixup, -}; -module_hid_driver(tm_driver); - -MODULE_LICENSE("GPL"); -- cgit v1.3 From 1ce1a2445a6189637226434fb18942429679c9ef Mon Sep 17 00:00:00 2001 From: kimi Date: Wed, 8 Jul 2020 13:38:34 -0400 Subject: remove old test code --- compile_commands.json | 114 ------- hid-tmff2.c | 872 -------------------------------------------------- 2 files changed, 986 deletions(-) delete mode 100644 compile_commands.json delete mode 100644 hid-tmff2.c diff --git a/compile_commands.json b/compile_commands.json deleted file mode 100644 index ea1a16a..0000000 --- a/compile_commands.json +++ /dev/null @@ -1,114 +0,0 @@ -[ - { - "arguments": [ - "gcc", - "-c", - "-Wp,-MD,/home/kimi/Documents/tmff2/.hid-tminit.o.d", - "-nostdinc", - "-isystem", - "/usr/lib/gcc/x86_64-linux-gnu/9/include", - "-I./arch/x86/include", - "-I./arch/x86/include/generated", - "-I./include", - "-I./arch/x86/include/uapi", - "-I./arch/x86/include/generated/uapi", - "-I./include/uapi", - "-I./include/generated/uapi", - "-include", - "./include/linux/kconfig.h", - "-Iubuntu/include", - "-include", - "./include/linux/compiler_types.h", - "-D__KERNEL__", - "-Wall", - "-Wundef", - "-Werror=strict-prototypes", - "-Wno-trigraphs", - "-fno-strict-aliasing", - "-fno-common", - "-fshort-wchar", - "-fno-PIE", - "-Werror=implicit-function-declaration", - "-Werror=implicit-int", - "-Wno-format-security", - "-std=gnu89", - "-mno-sse", - "-mno-mmx", - "-mno-sse2", - "-mno-3dnow", - "-mno-avx", - "-m64", - "-falign-jumps=1", - "-falign-loops=1", - "-mno-80387", - "-mno-fp-ret-in-387", - "-mpreferred-stack-boundary=3", - "-mskip-rax-setup", - "-mtune=generic", - "-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", - "-mindirect-branch-register", - "-fno-jump-tables", - "-fno-delete-null-pointer-checks", - "-Wno-frame-address", - "-Wno-format-truncation", - "-Wno-format-overflow", - "-Wno-address-of-packed-member", - "-O2", - "--param=allow-store-data-races=0", - "-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", - "-pg", - "-mrecord-mcount", - "-mfentry", - "-DCC_USING_FENTRY", - "-flive-patching=inline-clone", - "-Wdeclaration-after-statement", - "-Wvla", - "-Wno-pointer-sign", - "-Wno-stringop-truncation", - "-Wno-array-bounds", - "-Wno-stringop-overflow", - "-Wno-restrict", - "-Wno-maybe-uninitialized", - "-fno-strict-overflow", - "-fno-merge-all-constants", - "-fmerge-constants", - "-fno-stack-check", - "-fconserve-stack", - "-Werror=date-time", - "-Werror=incompatible-pointer-types", - "-Werror=designated-init", - "-fmacro-prefix-map=./=", - "-fcf-protection=none", - "-Wno-packed-not-aligned", - "-DMODULE", - "-DKBUILD_BASENAME=\"hid_tminit\"", - "-DKBUILD_MODNAME=\"hid_tminit\"", - "-o", - "/home/kimi/Documents/tmff2/hid-tminit.o", - "../../../home/kimi/Documents/tmff2/hid-tminit.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-tmff2.c b/hid-tmff2.c deleted file mode 100644 index b26185f..0000000 --- a/hid-tmff2.c +++ /dev/null @@ -1,872 +0,0 @@ -/*This file has been modified from the Linux kernel driver drivers/hid/hid-tmff.c, starting from May 7 2020*/ - -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Force feedback support for various HID compliant devices by ThrustMaster: - * ThrustMaster FireStorm Dual Power 2 - * and possibly others whose device ids haven't been added. - * - * Modified to support ThrustMaster devices by Zinx Verituse - * on 2003-01-25 from the Logitech force feedback driver, - * which is by Johann Deneux. - * - * Copyright (c) 2003 Zinx Verituse - * Copyright (c) 2002 Johann Deneux - */ - -/* -*/ - -#include -#include -#include -#include -#include - -#define USB_VENDOR_ID_THRUSTMASTER 0x044f -#define THRUSTMASTER_DEVICE_ID_2_IN_1_DT 0xb320 -#define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL 0x001e - -unsigned long last = 0; - -static const signed short ff_rumble[] = { - FF_RUMBLE, - -1 -}; - -static const signed short ff_constant[] = { - FF_CONSTANT, - -1 -}; - -static const signed short ff_joystick[] = { - FF_CONSTANT, - -1 -}; - -#ifdef CONFIG_THRUSTMASTER_FF - -/* Usages for thrustmaster devices I know about */ -#define THRUSTMASTER_USAGE_FF (HID_UP_GENDESK | 0xbb) - -u16 tmff_gain = 0xffff; - -static u8 setup_0[] = { 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static u8 setup_1[] = { 0x0a, 0x04, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00 }; -static u8 setup_2[] = { 0x0a, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00 }; -static u8 setup_3[] = { 0x0a, 0x04, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00 }; -static u8 setup_4[] = { 0x0a, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00 }; -static u8 *setup_arr[] = { setup_0, setup_1, setup_2, setup_3, setup_4 }; -static unsigned int setup_arr_sizes[] = { - ARRAY_SIZE(setup_0), - ARRAY_SIZE(setup_1), - ARRAY_SIZE(setup_2), - ARRAY_SIZE(setup_3), - ARRAY_SIZE(setup_4) -}; - -static u8 hw_rq_in[] = { 0xc1, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00 }; -static u8 hw_rq_out[] = { 0x41, 0x53, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static u8 ff_constant_array[] = { - 0x60, 0x00, 0x01, 0x0a, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static u8 ff_stop_array[] = { - 0x60, 0x00, 0x01, 0x0a, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static u8 t300rs_0[] = { - 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -}; - -static u8 t300rs_1[] = { - 0x0a, 0x04, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -}; - -static u8 t300rs_2[] = { - 0x0a, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -}; - -static u8 t300rs_3[] = { - 0x0a, 0x04, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -}; - -static u8 t300rs_4[] = { - 0x0a, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -}; - -static u8 t300rs_re[] = { - 0x0a, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static u8 *t300rs_arr[] = { t300rs_0, t300rs_1, t300rs_2, t300rs_3, t300rs_4, }; -static unsigned int t300rs_arr_sizes[] = { - ARRAY_SIZE(t300rs_0), - ARRAY_SIZE(t300rs_1), - ARRAY_SIZE(t300rs_2), - ARRAY_SIZE(t300rs_3), - ARRAY_SIZE(t300rs_4), -}; - -static u8 t300rs_ctrl_out[] = { 0x41, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, }; - -static u8 t300rs_ctrl_in_0[] = { 0xc1, 0x42, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, }; -static u8 t300rs_ctrl_in_1[] = { 0xc1, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, }; -static u8 t300rs_ctrl_in_2[] = { 0xc1, 0x56, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, }; -static u8 t300rs_ctrl_in_re[] = { 0xc1, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00 }; -static u8 *t300rs_ctrl_in_arr[] = {t300rs_ctrl_in_0, t300rs_ctrl_in_1, t300rs_ctrl_in_2 }; -static unsigned int t300rs_ctrl_in_sizes[] = { - ARRAY_SIZE(t300rs_ctrl_in_0), - ARRAY_SIZE(t300rs_ctrl_in_1), - ARRAY_SIZE(t300rs_ctrl_in_2) -}; - -static u8 t300rs_in_0[] = { 0xc1, 0x56, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, }; -static u8 t300rs_in_1[] = { 0xc1, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, }; -static u8 t300rs_in_2[] = { 0xc1, 0x48, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, }; -static u8 t300rs_in_3[] = { 0xc1, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, }; -static u8 *t300rs_in_arr[] = {t300rs_in_0, t300rs_in_1, t300rs_in_2, t300rs_in_3}; -static unsigned int t300rs_in_sizes[] = { - ARRAY_SIZE(t300rs_in_0), - ARRAY_SIZE(t300rs_in_1), - ARRAY_SIZE(t300rs_in_2), - ARRAY_SIZE(t300rs_in_3) -}; - -static u8 t300rs_fin_0[] = { - 0x60, 0x09, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static u8 t300rs_fin_1[] = { - 0x60, 0x0b, 0x05, 0xbf, 0x03, 0xc3, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static u8 t300rs_fin_2[] = { - 0x60, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static u8 t300rs_fin_3[] = { - 0x60, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static u8 t300rs_fin_4[] = { - 0x60, 0x00, 0x01, 0x6a, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static u8 t300rs_fin_5[] = { - 0x60, 0x00, 0x02, 0x6b, 0xfc, 0x7f, 0xfe, 0xff, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x80, 0x00, 0x00, - 0xfc, 0x7f, 0x00, 0x00, 0xfc, 0x7f, 0x03, 0x4f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static u8 t300rs_fin_6[] = { - 0x60, 0x00, 0x03, 0x64, 0xfd, 0x3f, 0xfd, 0x3f, 0x31, 0x03, 0xcb, 0xfc, 0xfd, 0x5f, 0xfd, 0x5f, - 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xdf, 0x58, 0xa6, 0x6a, 0x06, 0x4f, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static u8 t300rs_fin_7[] = { - 0x60, 0x00, 0x01, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static u8 *t300rs_fin_arr[] = {t300rs_fin_0, t300rs_fin_1, t300rs_fin_2, t300rs_fin_3, t300rs_fin_4, t300rs_fin_5, t300rs_fin_6, t300rs_fin_7 }; -static unsigned int t300rs_fin_sizes[] = { - ARRAY_SIZE(t300rs_fin_0), - ARRAY_SIZE(t300rs_fin_1), - ARRAY_SIZE(t300rs_fin_2), - ARRAY_SIZE(t300rs_fin_3), - ARRAY_SIZE(t300rs_fin_4), - ARRAY_SIZE(t300rs_fin_5), - ARRAY_SIZE(t300rs_fin_6), - ARRAY_SIZE(t300rs_fin_7) -}; - -struct tmff_device { - struct hid_report *report; - struct hid_field *ff_field; - spinlock_t report_lock; -}; - -static spinlock_t *report_lock; -static int flags; - -struct api_context { - struct completion done; - int status; -}; - -static struct api_context ctx; - -/* Changes values from 0 to 0xffff into values from minimum to maximum */ -static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum) -{ - int ret; - - ret = (in * (maximum - minimum) / 0xffff) + minimum; - if (ret < minimum) - return minimum; - if (ret > maximum) - return maximum; - return ret; -} - -/* Changes values from -0x80 to 0x7f into values from minimum to maximum */ -static inline int tmff_scale_s8(int in, int minimum, int maximum) -{ - int ret; - - ret = (((in + 0x80) * (maximum - minimum)) / 0xff) + minimum; - if (ret < minimum) - return minimum; - if (ret > maximum) - return maximum; - return ret; -} -bool transferred = true; -static void tmff_ctrl(struct urb *urb){ - if(urb->status){ - hid_warn(urb->dev, "urb status %d received\n", urb->status); - } - usb_free_urb(urb); - transferred = true; -} - -static void tmff_init_ctrl(struct urb *urb){ - if(urb->status){ - hid_warn(urb->dev, "urb status %d received\n", urb->status); - ctx.status = urb->status; - } -} - - -static void tmff_t300rs_ctrl(struct urb *urb){ - if(urb->status){ - hid_warn(urb->dev, "urb status %d received\n", urb->status); - } -} - -static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) -{ - - unsigned long expire; - int retval; - - printk("1"); - init_completion(&ctx.done); - urb->context = &ctx; - urb->actual_length = 0; - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(retval)) - goto out; - - printk("2"); - - 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: - printk("3"); - if (actual_length) - *actual_length = urb->actual_length; - - usb_free_urb(urb); - return retval; -} - -bool last_stop = false; - -static int tmff_play(struct input_dev *dev, void *data, - struct ff_effect *effect) -{ - - //spin_lock_irqsave(report_lock, flags); - struct hid_device *hid = input_get_drvdata(dev); - struct device *d_dev = &hid->dev; - struct usb_interface *usbif = to_usb_interface(d_dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - struct usb_host_endpoint *ep; - struct tmff_device *tmff = data; - struct hid_field *ff_field = tmff->ff_field; - struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC); - u8 *send_buf = kmalloc(1024, GFP_ATOMIC); - __s16 x; - - if(!transferred){ - return 0; - } - - - memcpy(send_buf, ff_constant_array, ARRAY_SIZE(ff_constant_array)); - - ep = &usbif->cur_altsetting->endpoint[1]; - - switch (effect->type) { - case FF_CONSTANT: - // this only works with input_ff_create_memless, which clamps - // constant forces to s8 for some reason - x = tmff_scale_s8(effect->u.constant.level, - ff_field->logical_minimum, - ff_field->logical_maximum); - - send_buf[4] = x & 0xff; - send_buf[5] = x >> 8; - - usb_fill_int_urb( - urb, - usbdev, - usb_sndintpipe(usbdev, 1), - send_buf, - ARRAY_SIZE(ff_constant_array), - tmff_ctrl, - hid, - ep->desc.bInterval - ); - transferred = false; - usb_submit_urb(urb, GFP_ATOMIC); - - - break; - default: - break; - } - -// msleep(2); - kfree(send_buf); - return 0; -} - -static int tmff_init_t300rs(struct hid_device *hid){ - - int trans, b_ep, bb_ep, i, err; - u8 *send_buf, *rq_buf; - struct device *dev = &hid->dev; - struct usb_interface *usbif = to_usb_interface(dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - struct usb_host_endpoint *ep; - struct urb *urb; - - ep = &usbif->cur_altsetting->endpoint[0]; - bb_ep = ep->desc.bEndpointAddress; - - ep = &usbif->cur_altsetting->endpoint[1]; - b_ep = ep->desc.bEndpointAddress; - - send_buf = kmalloc(256, GFP_ATOMIC); /* overkill but whatever */ - rq_buf = kmalloc(256, GFP_ATOMIC); - - for(i = 0; i < ARRAY_SIZE(t300rs_in_arr); ++i){ - memcpy(rq_buf, t300rs_in_arr[i], t300rs_in_sizes[i]); - urb = usb_alloc_urb(0, GFP_KERNEL); - usb_fill_control_urb(urb, - usbdev, - usb_rcvctrlpipe(usbdev, 0), - rq_buf, - send_buf, - 0, - tmff_t300rs_ctrl, - hid); - - err = usb_start_wait_urb(urb, 1, &trans); - if(err != 0){ - hid_err(hid, "Failed sending pre-ctrin with ERRNO: %i", err); - goto error; - } - } - - for(i = 0; i < ARRAY_SIZE(t300rs_ctrl_in_arr); ++i){ - memcpy(rq_buf, t300rs_ctrl_in_arr[i], t300rs_ctrl_in_sizes[i]); - urb = usb_alloc_urb(0, GFP_KERNEL); - usb_fill_control_urb(urb, - usbdev, - usb_rcvctrlpipe(usbdev, 0), - rq_buf, - send_buf, - 0, - tmff_t300rs_ctrl, - hid - ); - - err = usb_start_wait_urb(urb, 1, &trans); - if(err != 0){ - hid_err(hid, "Failed sending T300RS ctrl out with ERRNO: %i", err); - goto error; - } - - - } - printk("Sent initial ctrlouts"); - - for(i = 0; i < ARRAY_SIZE(t300rs_arr); ++i){ - memcpy(send_buf, t300rs_arr[i], t300rs_arr_sizes[i]); - - err = usb_interrupt_msg(usbdev, - usb_sndintpipe(usbdev, b_ep), - send_buf, - t300rs_arr_sizes[i], - &trans, - USB_CTRL_SET_TIMEOUT); - - if(err){ - hid_err(hid, "T300RS setup data at index %i couldn't be sent, ERRNO: %i\n", i, err); - goto error; - } - - err = usb_interrupt_msg(usbdev, - usb_rcvintpipe(usbdev, bb_ep), - send_buf, - 64, - &trans, - USB_CTRL_SET_TIMEOUT); - if(err != 0){ - hid_err(hid, "FUCK, ERRNO: %i", err); - goto error; - } - } - - memcpy(rq_buf, t300rs_ctrl_in_re, ARRAY_SIZE(t300rs_ctrl_in_re)); - for(i = 0; i < 16; ++i){ - urb = usb_alloc_urb(0, GFP_KERNEL); - usb_fill_control_urb(urb, - usbdev, - usb_rcvctrlpipe(usbdev, 0), - rq_buf, - send_buf, - 0, - tmff_t300rs_ctrl, - hid - ); - - err = usb_start_wait_urb(urb, 1, &trans); - if(err != 0){ - hid_err(hid, "Failed sending T300RS ctrl out with ERRNO: %i", err); - goto error; - } - } - - printk("Sent first 16 ctrlins"); - - memcpy(rq_buf, t300rs_ctrl_out, ARRAY_SIZE(t300rs_ctrl_out)); - urb = usb_alloc_urb(0, GFP_KERNEL); - usb_fill_control_urb(urb, - usbdev, - usb_sndctrlpipe(usbdev, 0), - rq_buf, - send_buf, - 0, - tmff_t300rs_ctrl, - hid - ); - - err = usb_start_wait_urb(urb, 1, &trans); - if(err != 0){ - hid_err(hid, "Failed sending ctrl out with ERRNO: %i", err); - goto error; - } - - memcpy(rq_buf, t300rs_ctrl_in_re, ARRAY_SIZE(t300rs_ctrl_in_re)); - for(i = 0; i < 8; ++i){ - urb = usb_alloc_urb(0, GFP_KERNEL); - usb_fill_control_urb(urb, - usbdev, - usb_rcvctrlpipe(usbdev, 0), - rq_buf, - send_buf, - 0, - tmff_t300rs_ctrl, - hid - ); - - err = usb_start_wait_urb(urb, 1, &trans); - if(err != 0){ - hid_err(hid, "Failed sending T300RS ctrl out with ERRNO: %i", err); - goto error; - } - } - - memcpy(send_buf, t300rs_re, ARRAY_SIZE(t300rs_re)); - - for(i = 0; i < 3; ++i){ - err = usb_interrupt_msg(usbdev, - usb_sndintpipe(usbdev, b_ep), - send_buf, - ARRAY_SIZE(t300rs_re), - &trans, - USB_CTRL_SET_TIMEOUT); - - if(err){ - hid_err(hid, "T300RS after-init data couldn't be sent, ERRNO: %i", err); - goto error; - } - } - - -error: - kfree(send_buf); - kfree(rq_buf); - - return 0; -} - -static int tmff_clear_init(struct hid_device *hid){ - /* die */ - - int trans, b_ep, i, err; - u8 *send_buf, *rq_buf; - struct device *dev = &hid->dev; - struct usb_interface *usbif = to_usb_interface(dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - struct usb_host_endpoint *ep; - struct urb *urb; - - ep = &usbif->cur_altsetting->endpoint[1]; - b_ep = ep->desc.bEndpointAddress; - - send_buf = kmalloc(256, GFP_KERNEL); /* overkill but whatever */ - rq_buf = kmalloc(256, GFP_KERNEL); - - for(i = 0; i < ARRAY_SIZE(setup_arr); ++i){ - memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]); - hid_info(hid, "Sent interrupt at %i\n", i); - err = usb_interrupt_msg(usbdev, - usb_sndintpipe(usbdev, b_ep), - send_buf, - setup_arr_sizes[i], - &trans, - USB_CTRL_SET_TIMEOUT); - - if(err){ - hid_err(hid, "Setup data at index %i couldn't be sent, ERRNO: %i\n", i, err); - goto error; - } - } - - - urb = usb_alloc_urb(0, GFP_ATOMIC); - - - memcpy(send_buf, hw_rq_in, 8); - memcpy(rq_buf, hw_rq_out, 8); - - usb_fill_control_urb(urb, - usbdev, - usb_sndctrlpipe(usbdev, 0), - rq_buf, - send_buf, - 0, - tmff_init_ctrl, - hid - ); - - err = usb_start_wait_urb(urb, 5, &trans); - if(err != 0){ - hid_err(hid, "Failed sending ctrl out with ERRNO: %i", err); - goto error; - } - hid_info(hid, "URB submission didn't fail?"); - -error: - kfree(rq_buf); - kfree(send_buf); - return err; -} - -static int tmff_delete(struct kref *kref){ - /* reserved for future use */ - /* currently the errors we get aren't pretty */ - - return 0; -}; - -static void tmff_set_gain(struct input_dev *dev, u16 gain){ - tmff_gain = gain; -} - -static int tmff_init(struct hid_device *hid, const signed short *ff_bits) -{ - - struct tmff_device *tmff; - struct hid_report *report; - struct list_head *report_list; - struct hid_input *hidinput = list_entry(hid->inputs.next, - struct hid_input, list); - struct input_dev *input_dev = hidinput->input; - struct ff_device *ff; - int error; - int i; - - if(hid->product == 0xb65d) - return tmff_clear_init(hid); - - tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL); - if (!tmff) - return -ENOMEM; - - hid_info(hid, "what is going ong here???"); - spin_lock_init(&tmff->report_lock); - report_lock = &tmff->report_lock; - - /* Find the report to use */ - report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - list_for_each_entry(report, report_list, list) { - int fieldnum; - - for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) { - struct hid_field *field = report->field[fieldnum]; - printk("found field at fieldnum %i\n", fieldnum); - - if (field->maxusage <= 0) - continue; - - switch (field->usage[0].hid) { - case 0xff00000a: - case THRUSTMASTER_USAGE_FF: - if (field->report_count < 2) { - hid_warn(hid, "ignoring FF field with report_count < 2\n"); - continue; - } - - if (field->logical_maximum == - field->logical_minimum) { - hid_warn(hid, "ignoring FF field with logical_maximum == logical_minimum\n"); - continue; - } - - if (tmff->report && tmff->report != report) { - hid_warn(hid, "ignoring FF field in other report\n"); - continue; - } - - if (tmff->ff_field && tmff->ff_field != field) { - hid_warn(hid, "ignoring duplicate FF field\n"); - continue; - } - - tmff->report = report; - tmff->ff_field = field; - - for (i = 0; ff_bits[i] >= 0; i++) - set_bit(ff_bits[i], input_dev->ffbit); - - break; - - default: - hid_warn(hid, "ignoring unknown output usage %08x\n", - field->usage[0].hid); - continue; - } - } - } - - if (!tmff->report) { - hid_err(hid, "can't find FF field in output reports\n"); - error = -ENODEV; - goto fail; - } - - error = input_ff_create_memless(input_dev, tmff, tmff_play); - if (error) - goto fail; - - ff = input_dev->ff; - ff->set_gain = tmff_set_gain; - - hid_info(hid, "force feedback for ThrustMaster devices by Zinx Verituse \n"); - return 0; - -fail: - hid_err(hid, "We have failed creating a force feedback memless device!!!\n"); - kfree(tmff); - return error; -} -#else -static inline int tmff_init(struct hid_device *hid, const signed short *ff_bits) -{ - return 0; -} -#endif -static int tmff_afterthought_t300rs(struct hid_device *hid){ - int trans, b_ep, bb_ep, i, err; - u8 *send_buf, *rq_buf; - struct device *dev = &hid->dev; - struct usb_interface *usbif = to_usb_interface(dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - struct usb_host_endpoint *ep; - - ep = &usbif->cur_altsetting->endpoint[0]; - bb_ep = ep->desc.bEndpointAddress; - - ep = &usbif->cur_altsetting->endpoint[1]; - b_ep = ep->desc.bEndpointAddress; - - send_buf = kmalloc(256, GFP_ATOMIC); /* overkill but whatever */ - rq_buf = kmalloc(256, GFP_ATOMIC); - - for(i = 0; i < ARRAY_SIZE(t300rs_fin_sizes); ++i){ - memcpy(send_buf, t300rs_fin_arr[i], t300rs_fin_sizes[i]); - - err = usb_interrupt_msg(usbdev, - usb_sndintpipe(usbdev, b_ep), - send_buf, - t300rs_fin_sizes[i], - &trans, - USB_CTRL_SET_TIMEOUT); - hid_info(hid, "sent %i:th message", i); - if(err){ - hid_err(hid, "T300RS setup data at index %i couldn't be sent, ERRNO: %i\n", i, err); - goto error; - } - } - - -error: - kfree(send_buf); - kfree(rq_buf); - return err; -} - - -static int tm_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; - } - - if(hdev->product == 0xb66e){ - ret = tmff_init_t300rs(hdev); - - if(ret){ - hid_err(hdev, "t300rs init failed\n"); - goto err; - } - } - - printk("woot\n"); - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); - if (ret) { - hid_err(hdev, "hw start failed\n"); - goto err; - } - printk("waat\n"); - - ret = tmff_init(hdev, (void *)id->driver_data); - - if(ret){ - hid_err(hdev, "what the fuck is going on?\n"); - if(ret == -32){ - //hid_hw_stop(hdev); - return 0; - } - goto err; - } - - if(hdev->product == 0xb66e){ - ret = tmff_afterthought_t300rs(hdev); - - if(ret){ - hid_err(hdev, "t300rs afterinit failed\n"); - goto err; - } - } - return 0; -err: - return ret; -} - -static void tm_remove(struct hid_device *hdev){ - hid_hw_stop(hdev); -} - -static __u8 t300rs_rdesc_fixed[] = {0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x85, 0x07, 0x09, 0x30, 0x15, 0x00, 0x27, 0xff, 0xff, 0x00, 0x00, 0x35, 0x00, 0x47, 0xff, 0xff, 0x00, 0x00, 0x75, 0x10, 0x95, 0x01, 0x81, 0x02, 0x09, 0x31, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x81, 0x02, 0x09, 0x35, 0x81, 0x02, 0x09, 0x36, 0x81, 0x02, 0x81, 0x03, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0d, 0x25, 0x01, 0x45, 0x01, 0x75, 0x01, 0x95, 0x0d, 0x81, 0x02, 0x75, 0x0b, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01, 0x09, 0x39, 0x25, 0x07, 0x46, 0x3b, 0x01, 0x55, 0x00, 0x65, 0x14, 0x75, 0x04, 0x81, 0x42, 0x65, 0x00, 0x81, 0x03, 0x85, 0x0a, 0x06, 0x00, 0xff, 0x09, 0x0a, 0x75, 0x08, 0x95, 0x3f, - 0x26, 0xff, 0x7f, - 0x16, 0x00, 0x80, - 0x46, 0xff, 0x7f, - 0x36, 0x00, 0x80, - 0x91, 0x02, 0x85, 0x02, 0x09, 0x02, 0x81, 0x02, 0x09, 0x14, 0x85, 0x14, 0x81, 0x02, 0xc0, 0xc0,}; - -static __u8 *tmff_t300rs_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize){ - if(hdev->product != 0xb66e){ - return rdesc; - } - printk("wahey"); - rdesc = t300rs_rdesc_fixed; - *rsize = sizeof(t300rs_rdesc_fixed); - return rdesc; -}; - -static const struct hid_device_id tm_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65d), - .driver_data = (unsigned long)ff_constant }, /* die */ - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb66e), - .driver_data = (unsigned long)ff_constant }, - { } -}; -MODULE_DEVICE_TABLE(hid, tm_devices); - -static struct hid_driver tm_driver = { - .name = "thrustmaster", - .id_table = tm_devices, - .probe = tm_probe, - .remove = tm_remove, - .report_fixup = tmff_t300rs_report_fixup, -}; -module_hid_driver(tm_driver); - -MODULE_LICENSE("GPL"); -- cgit v1.3 From e6e4ed227ec39cf07bd0e8d77f8e1be8e181080c Mon Sep 17 00:00:00 2001 From: kimi Date: Wed, 8 Jul 2020 14:28:32 -0400 Subject: added files --- compile_commands.json | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ hid-tmt300rs.c | 1 + 2 files changed, 115 insertions(+) create mode 100644 compile_commands.json create mode 100644 hid-tmt300rs.c diff --git a/compile_commands.json b/compile_commands.json new file mode 100644 index 0000000..ea1a16a --- /dev/null +++ b/compile_commands.json @@ -0,0 +1,114 @@ +[ + { + "arguments": [ + "gcc", + "-c", + "-Wp,-MD,/home/kimi/Documents/tmff2/.hid-tminit.o.d", + "-nostdinc", + "-isystem", + "/usr/lib/gcc/x86_64-linux-gnu/9/include", + "-I./arch/x86/include", + "-I./arch/x86/include/generated", + "-I./include", + "-I./arch/x86/include/uapi", + "-I./arch/x86/include/generated/uapi", + "-I./include/uapi", + "-I./include/generated/uapi", + "-include", + "./include/linux/kconfig.h", + "-Iubuntu/include", + "-include", + "./include/linux/compiler_types.h", + "-D__KERNEL__", + "-Wall", + "-Wundef", + "-Werror=strict-prototypes", + "-Wno-trigraphs", + "-fno-strict-aliasing", + "-fno-common", + "-fshort-wchar", + "-fno-PIE", + "-Werror=implicit-function-declaration", + "-Werror=implicit-int", + "-Wno-format-security", + "-std=gnu89", + "-mno-sse", + "-mno-mmx", + "-mno-sse2", + "-mno-3dnow", + "-mno-avx", + "-m64", + "-falign-jumps=1", + "-falign-loops=1", + "-mno-80387", + "-mno-fp-ret-in-387", + "-mpreferred-stack-boundary=3", + "-mskip-rax-setup", + "-mtune=generic", + "-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", + "-mindirect-branch-register", + "-fno-jump-tables", + "-fno-delete-null-pointer-checks", + "-Wno-frame-address", + "-Wno-format-truncation", + "-Wno-format-overflow", + "-Wno-address-of-packed-member", + "-O2", + "--param=allow-store-data-races=0", + "-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", + "-pg", + "-mrecord-mcount", + "-mfentry", + "-DCC_USING_FENTRY", + "-flive-patching=inline-clone", + "-Wdeclaration-after-statement", + "-Wvla", + "-Wno-pointer-sign", + "-Wno-stringop-truncation", + "-Wno-array-bounds", + "-Wno-stringop-overflow", + "-Wno-restrict", + "-Wno-maybe-uninitialized", + "-fno-strict-overflow", + "-fno-merge-all-constants", + "-fmerge-constants", + "-fno-stack-check", + "-fconserve-stack", + "-Werror=date-time", + "-Werror=incompatible-pointer-types", + "-Werror=designated-init", + "-fmacro-prefix-map=./=", + "-fcf-protection=none", + "-Wno-packed-not-aligned", + "-DMODULE", + "-DKBUILD_BASENAME=\"hid_tminit\"", + "-DKBUILD_MODNAME=\"hid_tminit\"", + "-o", + "/home/kimi/Documents/tmff2/hid-tminit.o", + "../../../home/kimi/Documents/tmff2/hid-tminit.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-tmt300rs.c b/hid-tmt300rs.c new file mode 100644 index 0000000..3c3684c --- /dev/null +++ b/hid-tmt300rs.c @@ -0,0 +1 @@ +/* empty for now */ -- cgit v1.3 From bec11109dd3d5792b54044e04eba044048484dba Mon Sep 17 00:00:00 2001 From: kimi Date: Thu, 9 Jul 2020 06:49:27 -0400 Subject: big changes --- Makefile | 1 + hid-tminit.c | 4 +- hid-tmt300rs.c | 385 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- hid-tmt300rs.h | 50 ++++++++ 4 files changed, 438 insertions(+), 2 deletions(-) create mode 100644 hid-tmt300rs.h diff --git a/Makefile b/Makefile index d666a97..6675c23 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ obj-m += hid-tminit.o +obj-m += hid-tmt300rs.o all: make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules diff --git a/hid-tminit.c b/hid-tminit.c index e48b419..e20126b 100644 --- a/hid-tminit.c +++ b/hid-tminit.c @@ -1,5 +1,7 @@ #include "hid-tminit.h" + + static void tminit_callback(struct urb *urb){ ctx.status = urb->status; hid_info(urb->dev, "urb status %d received\n", urb->status); @@ -26,7 +28,7 @@ int tminit(struct hid_device *hdev){ usb_sndctrlpipe(usbdev, 0), setup_packet, transfer_buffer, - 0, + 8, tminit_callback, hdev); diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c index 3c3684c..1368a62 100644 --- a/hid-tmt300rs.c +++ b/hid-tmt300rs.c @@ -1 +1,384 @@ -/* empty for now */ +#include "hid-tmt300rs.h" + +static struct t300rs_device_entry *t300rs_get_device(struct hid_device *hdev){ + struct t300rs_data *drv_data; + struct t300rs_device_entry *t300rs; + + spin_lock_irqsave(&lock, lock_flags); + drv_data = hid_get_drvdata(hdev); + if(!drv_data){ + hid_err(hdev, "private data not found\n"); + return NULL; + } + + t300rs = drv_data->device_props; + if(!t300rs){ + hid_err(hdev, "device properties not found\n"); + return NULL; + } + spin_unlock_irqrestore(&lock, lock_flags); + + return t300rs; +} + +static int t300rs_send_int(struct input_dev *dev, u8 *send_buffer, int *trans){ + struct hid_device *hdev = input_get_drvdata(dev); + struct t300rs_device_entry *t300rs; + struct usb_device *usbdev; + struct usb_interface *usbif; + struct usb_host_endpoint *ep; + int b_ep; + + t300rs = t300rs_get_device(hdev); + + usbdev = t300rs->usbdev; + usbif = t300rs->usbif; + ep = &usbif->cur_altsetting->endpoint[1]; + b_ep = ep->desc.bEndpointAddress; + + return usb_interrupt_msg(usbdev, + usb_sndintpipe(usbdev, b_ep), + send_buffer, + T300RS_BUFFER_LENGTH, + trans, + USB_CTRL_SET_TIMEOUT); +} + +static int t300rs_upload(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old){ + /* temp */ + return 0; +} + +static int t300rs_play(struct input_dev *dev, int effect_id, int value){ + /* temp */ + return 0; +} + +static ssize_t t300rs_range_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count){ + struct hid_device *hdev = to_hid_device(dev); + struct t300rs_device_entry *t300rs; + u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + u16 range = simple_strtoul(buf, NULL, 10); + int ret, trans; + + t300rs = t300rs_get_device(hdev); + + if(range < 0x097b){ + range = 0x097b; + } + + send_buffer[0] = 0x60; + send_buffer[1] = 0x08; + send_buffer[2] = 0x11; + send_buffer[3] = range & 0xff; + send_buffer[4] = range >> 8; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed sending interrupts\n"); + return -1; + } + + t300rs->range = range; + kfree(send_buffer); + return count; +} + +static ssize_t t300rs_range_show(struct device *dev, struct device_attribute *attr, + char *buf){ + struct hid_device *hdev = to_hid_device(dev); + struct t300rs_device_entry *t300rs; + + t300rs = t300rs_get_device(hdev); + + return t300rs->range; +} + +static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, t300rs_range_show, t300rs_range_store); + +static void t300rs_set_gain(struct input_dev *dev, u16 gain){ + struct hid_device *hdev = input_get_drvdata(dev); + u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + int ret, trans; + + send_buffer[0] = 0x60; + send_buffer[1] = 0x02; + send_buffer[2] = SCALE_VALUE_U16(gain, sizeof(char)); + + ret = t300rs_send_int(dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed sending interrupts\n"); + } +} + +static void t300rs_destroy(struct ff_device *ff){ + /* maybe not temp? */ + return; +} + + +static int t300rs_open(struct input_dev *dev){ + struct hid_device *hdev = input_get_drvdata(dev); + u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + int ret, trans; + + send_buffer[0] = 0x60; + send_buffer[1] = 0x01; + send_buffer[2] = 0x04; + + ret = t300rs_send_int(dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed sending interrupts\n"); + goto err; + } + memset(send_buffer, 0, T300RS_BUFFER_LENGTH); + + send_buffer[0] = 0x60; + send_buffer[1] = 0x12; + send_buffer[2] = 0xbf; + send_buffer[3] = 0x04; + send_buffer[6] = 0x03; + send_buffer[7] = 0xb7; + send_buffer[8] = 0x1e; + + ret = t300rs_send_int(dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed sending interrupts\n"); + goto err; + } + memset(send_buffer, 0, T300RS_BUFFER_LENGTH); + + send_buffer[0] = 0x60; + send_buffer[1] = 0x01; + send_buffer[2] = 0x05; + + ret = t300rs_send_int(dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed sending interrupts\n"); + goto err; + } + +err: + kfree(send_buffer); + return ret; +} + +static void t300rs_close(struct input_dev *dev){ + int ret, trans; + struct hid_device *hdev = input_get_drvdata(dev); + u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + + send_buffer[0] = 0x60; + send_buffer[1] = 0x01; + + ret = t300rs_send_int(dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed sending interrupts\n"); + goto err; + } +err: + kfree(send_buffer); + return; +} + +int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ + struct t300rs_device_entry *t300rs; + struct t300rs_data *drv_data; + struct list_head *report_list; + struct hid_input *hidinput = list_entry(hdev->inputs.next, + struct hid_input, list); + struct input_dev *input_dev = hidinput->input; + struct device *dev = &hdev->dev; + struct usb_interface *usbif = to_usb_interface(dev->parent); + struct usb_device *usbdev = interface_to_usbdev(usbif); + struct hid_report *report; + struct ff_device *ff; + int i, ret; + + drv_data = hid_get_drvdata(hdev); + if(!drv_data){ + hid_err(hdev, "private driver data not allocated\n"); + ret = -ENOMEM; + goto err; + } + + t300rs = kzalloc(sizeof(struct t300rs_device_entry), GFP_ATOMIC); + if(!t300rs){ + return -ENOMEM; + } + + t300rs->input_dev = input_dev; + t300rs->hdev = hdev; + t300rs->usbdev = usbdev; + t300rs->usbif = usbif; + spin_lock_init(&t300rs->lock); + + drv_data->device_props = t300rs; + + + report_list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list; + list_for_each_entry(report, report_list, list){ + int fieldnum; + + for(fieldnum = 0; fieldnum < report->maxfield; ++fieldnum){ + struct hid_field *field = report->field[fieldnum]; + + if(field->maxusage <= 0){ + continue; + } + + switch(field->usage[0].hid){ + case 0xff00000a: + if(field->report_count < 2){ + hid_warn(hdev, "ignoring FF field with report_count < 2\n"); + continue; + } + + if(field->logical_maximum == field->logical_minimum){ + hid_warn(hdev, "ignoring FF field with l_max == l_min"); + continue; + } + + if(t300rs->report && t300rs->report != report){ + hid_warn(hdev, "ignoring FF field in other report\n"); + continue; + } + + if(t300rs->ff_field && t300rs->ff_field != field){ + hid_warn(hdev, "ignoring duplicate FF field\n"); + continue; + } + + t300rs->report = report; + t300rs->ff_field = field; + + for(i = 0; ff_bits[i] >= 0; ++i){ + set_bit(ff_bits[i], input_dev->ffbit); + } + + break; + + default: + hid_warn(hdev, "ignoring unknown output usage\n"); + continue; + } + } + } + + if(!t300rs->report){ + hid_err(hdev, "can't find FF field in output reports\n"); + ret = -ENODEV; + goto err; + } + + ret = input_ff_create(input_dev, T300RS_MAX_EFFECTS); + if(ret){ + hid_err(hdev, "could not create input_ff\n"); + goto err; + } + + ff = input_dev->ff; + ff->upload = t300rs_upload; + ff->playback = t300rs_play; + ff->set_gain = t300rs_set_gain; + ff->destroy = t300rs_destroy; + + input_dev->open = t300rs_open; + input_dev->close = t300rs_close; + + ret = device_create_file(&hdev->dev, &dev_attr_range); + if(ret){ + hid_warn(hdev, "unable to create sysfs interface for range\n"); + } + + hid_info(hdev, "force feedback for T300RS\n"); + return 0; +err: + kfree(t300rs); + hid_err(hdev, "failed creating force feedback device\n"); + return ret; + +} + +static int t300rs_probe(struct hid_device *hdev, const struct hid_device_id *id){ + int ret; + struct t300rs_data *drv_data; + + spin_lock_init(&lock); + spin_lock_irqsave(&lock, lock_flags); + + drv_data = kzalloc(sizeof(struct t300rs_data), GFP_ATOMIC); + if(!drv_data){ + hid_err(hdev, "out of memory\n"); + ret = -ENOMEM; + goto err; + } + + drv_data->quirks = id->driver_data; + hid_set_drvdata(hdev, (void*)drv_data); + + 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 = t300rs_init(hdev, (void*)id->driver_data); + if(ret){ + hid_err(hdev, "t300rs_init failed\n"); + goto err; + } + + spin_unlock_irqrestore(&lock, lock_flags); + return 0; +err: + kfree(drv_data); + spin_unlock_irqrestore(&lock, lock_flags); + return ret; +} + +static void t300rs_remove(struct hid_device *hdev){ + struct t300rs_device_entry *t300rs; + struct t300rs_data *drv_data; + + device_remove_file(&hdev->dev, &dev_attr_range); + + drv_data = hid_get_drvdata(hdev); + t300rs = t300rs_get_device(hdev); + + kfree(drv_data); + kfree(t300rs); + hid_hw_stop(hdev); + return; +} + +static __u8 *t300rs_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize){ + rdesc = t300rs_rdesc_fixed; + *rsize = sizeof(t300rs_rdesc_fixed); + return rdesc; +} + +static const struct hid_device_id t300rs_devices[] = { + {HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb66e), + .driver_data = (unsigned long)t300rs_ff_effects}, + {} +}; +MODULE_DEVICE_TABLE(hid, t300rs_devices); + +static struct hid_driver t300rs_driver = { + .name = "t300rs", + .id_table = t300rs_devices, + .probe = t300rs_probe, + .remove = t300rs_remove, + .report_fixup = t300rs_report_fixup, +}; +module_hid_driver(t300rs_driver); + +MODULE_LICENSE("GPL"); diff --git a/hid-tmt300rs.h b/hid-tmt300rs.h new file mode 100644 index 0000000..876f778 --- /dev/null +++ b/hid-tmt300rs.h @@ -0,0 +1,50 @@ +#include "hid-tm.h" + +#define T300RS_MAX_EFFECTS FF_MAX_EFFECTS +#define T300RS_BUFFER_LENGTH 64 + +#define CLAMP_VALUE_U16(x) ((unsigned short)((x) > 0xffff ? 0xffff : (x))) +#define SCALE_VALUE_U16(x, bits) (CLAMP_VALUE_U16(x) >> (16 - bits)) + +spinlock_t lock; +unsigned long lock_flags; + +static const signed short t300rs_ff_effects[] = { + FF_CONSTANT, + FF_RAMP, + FF_SPRING, + FF_DAMPER, + FF_FRICTION, + FF_INERTIA, + FF_PERIODIC, + FF_SINE, + FF_TRIANGLE, + FF_SQUARE, + FF_SAW_UP, + FF_SAW_DOWN, + FF_AUTOCENTER, + FF_GAIN, + -1 +}; + +struct t300rs_device_entry { + struct hid_device *hdev; + struct input_dev *input_dev; + struct hid_report *report; + struct hid_field *ff_field; + struct usb_device *usbdev; + struct usb_interface *usbif; + + spinlock_t lock; + unsigned long lock_flags; + + u16 range; +}; + +struct t300rs_data{ + unsigned long quirks; + void *device_props; +}; + +static __u8 t300rs_rdesc_fixed[] = {0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x85, 0x07, 0x09, 0x30, 0x15, 0x00, 0x27, 0xff, 0xff, 0x00, 0x00, 0x35, 0x00, 0x47, 0xff, 0xff, 0x00, 0x00, 0x75, 0x10, 0x95, 0x01, 0x81, 0x02, 0x09, 0x31, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x81, 0x02, 0x09, 0x35, 0x81, 0x02, 0x09, 0x36, 0x81, 0x02, 0x81, 0x03, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0d, 0x25, 0x01, 0x45, 0x01, 0x75, 0x01, 0x95, 0x0d, 0x81, 0x02, 0x75, 0x0b, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01, 0x09, 0x39, 0x25, 0x07, 0x46, 0x3b, 0x01, 0x55, 0x00, 0x65, 0x14, 0x75, 0x04, 0x81, 0x42, 0x65, 0x00, 0x81, 0x03, 0x85, 0x0a, 0x06, 0x00, 0xff, 0x09, 0x0a, 0x75, 0x08, 0x95, 0x3f, 0x26, 0xff, 0x7f, 0x16, 0x00, 0x80, 0x46, 0xff, 0x7f, 0x36, 0x00, 0x80, 0x91, 0x02, 0x85, 0x02, 0x09, 0x02, 0x81, 0x02, 0x09, 0x14, 0x85, 0x14, 0x81, 0x02, 0xc0, 0xc0,}; + -- cgit v1.3 From ae3ea9cc09ade406886156091f4acf1d04091277 Mon Sep 17 00:00:00 2001 From: kimi Date: Thu, 9 Jul 2020 13:38:06 -0400 Subject: v.0.01 --- hid-tmt300rs.c | 601 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- hid-tmt300rs.h | 33 ++++ usbhid.h | 95 +++++++++ 3 files changed, 711 insertions(+), 18 deletions(-) create mode 100644 usbhid.h diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c index 1368a62..c2540c0 100644 --- a/hid-tmt300rs.c +++ b/hid-tmt300rs.c @@ -1,5 +1,13 @@ #include "hid-tmt300rs.h" +static void t300rs_int_callback(struct urb *urb){ + if(urb->status){ + hid_warn(urb->dev, "urb status %i received\n", urb->status); + } + + usb_free_urb(urb); +} + static struct t300rs_device_entry *t300rs_get_device(struct hid_device *hdev){ struct t300rs_data *drv_data; struct t300rs_device_entry *t300rs; @@ -27,30 +35,561 @@ static int t300rs_send_int(struct input_dev *dev, u8 *send_buffer, int *trans){ struct usb_device *usbdev; struct usb_interface *usbif; struct usb_host_endpoint *ep; - int b_ep; + struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC); t300rs = t300rs_get_device(hdev); usbdev = t300rs->usbdev; usbif = t300rs->usbif; ep = &usbif->cur_altsetting->endpoint[1]; - b_ep = ep->desc.bEndpointAddress; - return usb_interrupt_msg(usbdev, - usb_sndintpipe(usbdev, b_ep), + usb_fill_int_urb( + urb, + usbdev, + usb_sndintpipe(usbdev, 1), send_buffer, T300RS_BUFFER_LENGTH, - trans, - USB_CTRL_SET_TIMEOUT); + t300rs_int_callback, + hdev, + ep->desc.bInterval + ); + + return usb_submit_urb(urb, GFP_ATOMIC); +} + +static int t300rs_play_effect(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ + u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + int ret, trans; + + send_buffer[0] = 0x60; + send_buffer[2] = state->effect.id + 1; + send_buffer[3] = 0x89; + send_buffer[4] = 0x01; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed starting effect play\n"); + } + + hid_info(t300rs->hdev, "sent play\n"); + kfree(send_buffer); + return ret; +} + +static int t300rs_stop_effect(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ + u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + int ret, trans; + + send_buffer[0] = 0x60; + send_buffer[2] = state->effect.id + 1; + send_buffer[3] = 0x89; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed stopping effect play\n"); + } + + hid_info(t300rs->hdev, "stopping effect\n"); + return ret; +} + +static void t300rs_fill_envelope(u8 *send_buffer, int i, s16 level, u16 duration, struct ff_envelope *envelope){ + u16 attack_length = (duration * envelope->attack_length) / 0x7fff; + u16 attack_level = (level * envelope->attack_level) / 0x7fff; + u16 fade_length = (duration * envelope->fade_length) / 0x7fff; + u16 fade_level = (level * envelope->fade_level) / 0x7fff; + + attack_length = cpu_to_le16(attack_length); + attack_level = cpu_to_le16(attack_level); + fade_length = cpu_to_le16(fade_length); + fade_level = cpu_to_le16(fade_level); + + send_buffer[i ] = attack_length & 0xff; + send_buffer[i + 1] = attack_length >> 8; + send_buffer[i + 2] = attack_level & 0xff; + send_buffer[i + 3] = attack_level >> 8; + send_buffer[i + 4] = fade_length & 0xff; + send_buffer[i + 5] = fade_length >> 8; + send_buffer[i + 6] = fade_level & 0xff; + send_buffer[i + 7] = fade_level >> 8; +} + +static int t300rs_upload_constant(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ + u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + struct ff_effect effect = state->effect; + struct ff_constant_effect constant = state->effect.u.constant; + s16 level, le_level; + u16 duration, le_offset, le_duration; + + int ret, trans; + + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + t300rs_stop_effect(t300rs, state); + __clear_bit(FF_EFFECT_PLAYING, &state->flags); + } + + level = (constant.level * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; + duration = effect.replay.length; + + le_level = cpu_to_le16(level); + le_offset = cpu_to_le16(effect.replay.delay); + le_duration = cpu_to_le16(duration); + + send_buffer[0] = 0x60; + send_buffer[2] = effect.id + 1; + send_buffer[3] = 0x6a; + + send_buffer[4] = le_level & 0xff; + send_buffer[5] = le_level >> 8; + + t300rs_fill_envelope(send_buffer, 6, level, + duration, &constant.envelope); + + send_buffer[15] = 0x4f; + + send_buffer[16] = le_duration & 0xff; + send_buffer[17] = le_duration >> 8; + + send_buffer[20] = le_offset & 0xff; + send_buffer[21] = le_offset >> 8; + + send_buffer[23] = 0xff; + send_buffer[24] = 0xff; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed uploading constant effect\n"); + } + hid_info(t300rs->hdev, "uploading constant"); + kfree(send_buffer); + return ret; +} + +static int t300rs_upload_ramp(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ + u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + struct ff_effect effect = state->effect; + struct ff_ramp_effect ramp = state->effect.u.ramp; + int ret, trans; + u16 difference, le_difference, top, bottom, le_duration, le_offset; + s16 level, le_level; + + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + t300rs_stop_effect(t300rs, state); + __clear_bit(FF_EFFECT_PLAYING, &state->flags); + } + + top = ramp.end_level > ramp.start_level ? ramp.end_level : ramp.start_level; + bottom = ramp.end_level > ramp.start_level ? ramp.start_level : ramp.end_level; + + + difference = ((top - bottom) * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; + level = (top * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; + + le_difference = cpu_to_le16(difference); + le_level = cpu_to_le16(level); + le_duration = cpu_to_le16(effect.replay.length); + le_offset = cpu_to_le16(effect.replay.delay); + + send_buffer[0] = 0x60; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x6b; + + send_buffer[3] = le_difference & 0xff; + send_buffer[4] = le_difference >> 8; + + send_buffer[5] = le_level & 0xff; + send_buffer[6] = le_level >> 8; + + send_buffer[9] = le_duration & 0xff; + send_buffer[10] = le_duration >> 8; + + send_buffer[12] = 0x80; + + t300rs_fill_envelope(send_buffer, 14, level, + effect.replay.length, &ramp.envelope); + + send_buffer[22] = ramp.end_level > ramp.start_level ? 0x04 : 0x05; + send_buffer[23] = 0x4f; + + send_buffer[24] = le_duration & 0xff; + send_buffer[25] = le_duration >> 8; + + send_buffer[28] = le_offset & 0xff; + send_buffer[29] = le_offset >> 8; + + send_buffer[31] = 0xff; + send_buffer[32] = 0xff; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed uploading ramp"); + } + kfree(send_buffer); + hid_info(t300rs->hdev, "uploading ramp"); + return ret; +} + +static int t300rs_upload_spring(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ + u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + struct ff_effect effect = state->effect; + /* we only care about the first axis */ + struct ff_condition_effect spring = state->effect.u.condition[0]; + int ret, trans; + u16 le_right_coeff, le_left_coeff, le_deadband_right, le_deadband_left, + le_duration, le_offset; + + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + t300rs_stop_effect(t300rs, state); + __clear_bit(FF_EFFECT_PLAYING, &state->flags); + } + + send_buffer[0] = 0x60; + send_buffer[2] = effect.id + 1; + send_buffer[3] = 0x64; + + le_right_coeff = cpu_to_le16(spring.right_coeff); + le_left_coeff = cpu_to_le16(spring.left_coeff); + + le_deadband_right = cpu_to_le16(0xfffe - spring.deadband - spring.center); + le_deadband_left = cpu_to_le16(0xfffe - spring.deadband + spring.center); + + le_duration = cpu_to_le16(effect.replay.length); + le_offset = cpu_to_le16(effect.replay.delay); + + hid_info(t300rs->hdev, "coeffs: %x vs %x\n", le_right_coeff, spring.right_coeff); + + send_buffer[4] = le_right_coeff & 0xff; + send_buffer[5] = le_right_coeff >> 8; + + send_buffer[6] = le_left_coeff & 0xff; + send_buffer[7] = le_left_coeff >> 8; + + send_buffer[8] = le_deadband_right & 0xff; + send_buffer[9] = le_deadband_right >> 8; + + send_buffer[10] = le_deadband_left & 0xff; + send_buffer[11] = le_deadband_left >> 8; + + memcpy(&send_buffer[12], spring_values, ARRAY_SIZE(spring_values)); + send_buffer[29] = 0x4f; + + send_buffer[30] = le_duration & 0xff; + send_buffer[31] = le_duration >> 8; + + send_buffer[34] = le_offset & 0xff; + send_buffer[35] = le_offset >> 8; + + send_buffer[37] = 0xff; + send_buffer[38] = 0xff; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed uploading spring\n"); + } + kfree(send_buffer); + hid_info(t300rs->hdev, "uploading spring"); + return ret; +} + +static int t300rs_upload_damper(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ + u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + struct ff_effect effect = state->effect; + /* we only care about the first axis */ + struct ff_condition_effect spring = state->effect.u.condition[0]; + int ret, trans; + u16 le_right_coeff, le_left_coeff, le_deadband_right, le_deadband_left, + le_duration, le_offset; + + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + t300rs_stop_effect(t300rs, state); + __clear_bit(FF_EFFECT_PLAYING, &state->flags); + } + + send_buffer[0] = 0x60; + send_buffer[2] = effect.id + 1; + send_buffer[3] = 0x64; + + le_right_coeff = cpu_to_le16(spring.right_coeff); + le_left_coeff = cpu_to_le16(spring.left_coeff); + + le_deadband_right = cpu_to_le16(0xfffe - spring.deadband - spring.center); + le_deadband_left = cpu_to_le16(0xfffe - spring.deadband + spring.center); + + le_duration = cpu_to_le16(effect.replay.length); + le_offset = cpu_to_le16(effect.replay.delay); + + hid_info(t300rs->hdev, "coeffs: %x vs %x\n", le_right_coeff, spring.right_coeff); + + send_buffer[4] = le_right_coeff & 0xff; + send_buffer[5] = le_right_coeff >> 8; + + send_buffer[6] = le_left_coeff & 0xff; + send_buffer[7] = le_left_coeff >> 8; + + send_buffer[8] = le_deadband_right & 0xff; + send_buffer[9] = le_deadband_right >> 8; + + send_buffer[10] = le_deadband_left & 0xff; + send_buffer[11] = le_deadband_left >> 8; + + memcpy(&send_buffer[12], damper_values, ARRAY_SIZE(damper_values)); + send_buffer[29] = 0x4f; + + send_buffer[30] = le_duration & 0xff; + send_buffer[31] = le_duration >> 8; + + send_buffer[34] = le_offset & 0xff; + send_buffer[35] = le_offset >> 8; + + send_buffer[37] = 0xff; + send_buffer[38] = 0xff; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed uploading spring\n"); + } + + hid_info(t300rs->hdev, "uploading spring"); + return ret; + return 0; +} + +static int t300rs_upload_periodic(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ + u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + struct ff_effect effect = state->effect; + struct ff_periodic_effect periodic = state->effect.u.periodic; + int ret, trans; + u16 magnitude, le_magnitude, le_phase, le_period, le_offset, le_duration; + s16 le_periodic_offset; + + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + t300rs_stop_effect(t300rs, state); + __clear_bit(FF_EFFECT_PLAYING, &state->flags); + } + + + magnitude = (periodic.magnitude * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; + + hid_warn(t300rs->hdev, "magnitude %i vs %i\n", periodic.magnitude, magnitude); + le_magnitude = cpu_to_le16(magnitude); + le_phase = cpu_to_le16(periodic.phase); + le_periodic_offset = cpu_to_le16(periodic.offset); + le_period = cpu_to_le16(periodic.period); + le_offset = cpu_to_le16(effect.replay.delay); + le_duration = cpu_to_le16(effect.replay.length); + + send_buffer[0] = 0x60; + send_buffer[2] = effect.id + 1; + send_buffer[3] = 0x6b; + + send_buffer[4] = le_magnitude & 0xff; + send_buffer[5] = le_magnitude >> 8; + + send_buffer[6] = le_phase & 0xff; + send_buffer[7] = le_phase >> 8; + + send_buffer[8] = le_periodic_offset & 0xff; + send_buffer[9] = le_periodic_offset >> 8; + + send_buffer[10] = le_period & 0xff; + send_buffer[11] = le_period >> 8; + + send_buffer[13] = 0x80; + + t300rs_fill_envelope(send_buffer, 14, magnitude, + effect.replay.length, &periodic.envelope); + + send_buffer[22] = periodic.waveform - 0x57; + send_buffer[23] = 0x4f; + + send_buffer[24] = le_duration & 0xff; + send_buffer[25] = le_duration >> 8; + + send_buffer[27] = le_offset & 0xff; + send_buffer[28] = le_offset >> 8; + + send_buffer[30] = 0xff; + send_buffer[31] = 0xff; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed uploading periodic effect"); + } + kfree(send_buffer); + hid_info(t300rs->hdev, "uploaded periodic effect"); + return ret; } +static int t300rs_upload_effect(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ + switch(state->effect.type){ + case FF_CONSTANT: + return t300rs_upload_constant(t300rs, state); + case FF_RAMP: + return t300rs_upload_ramp(t300rs, state); + case FF_SPRING: + return t300rs_upload_spring(t300rs, state); + case FF_DAMPER: + case FF_FRICTION: + case FF_INERTIA: + return t300rs_upload_damper(t300rs, state); + case FF_PERIODIC: + return t300rs_upload_periodic(t300rs, state); + default: + hid_err(t300rs->hdev, "invalid effect type"); + return -1; + } +} + +static int t300rs_timer_helper(struct t300rs_device_entry *t300rs){ + struct usbhid_device *usbhid = t300rs->hdev->driver_data; + struct t300rs_effect_state *state; + int current_period, effect_id, ret; + + if(usbhid->outhead != usbhid->outtail){ + current_period = timer_msecs; + timer_msecs *= 2; + hid_info(t300rs->hdev, "commands stacking up, increasing timer period\n"); + return current_period; + } + + for(effect_id = 0; effect_id < t300rs->max_id; ++effect_id){ + + state = &t300rs->states[effect_id]; + + if(!test_bit(FF_EFFECT_QUEUE_START, &state->flags) && + !test_bit(FF_EFFECT_QUEUE_STOP, &state->flags)){ + continue; + } + + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + if(JIFFIES2MS(jiffies) - state->start_time >= state->effect.replay.length){ + __clear_bit(FF_EFFECT_PLAYING, &state->flags); + + if(state->count){ + __set_bit(FF_EFFECT_QUEUE_START, &state->flags); + state->count--; + } + } + } + + if(test_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags)){ + __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); + + ret = t300rs_upload_effect(t300rs, state); + if(ret){ + hid_err(t300rs->hdev, "failed uploading effects"); + return ret; + } + } + + if(test_bit(FF_EFFECT_QUEUE_START, &state->flags)){ + __clear_bit(FF_EFFECT_QUEUE_START, &state->flags); + __set_bit(FF_EFFECT_PLAYING, &state->flags); + + state->start_time = JIFFIES2MS(jiffies); + + ret = t300rs_play_effect(t300rs, state); + if(ret){ + hid_err(t300rs->hdev, "failed starting effects\n"); + return ret; + } + } + + if(test_bit(FF_EFFECT_QUEUE_STOP, &state->flags)){ + __clear_bit(FF_EFFECT_QUEUE_STOP, &state->flags); + __clear_bit(FF_EFFECT_PLAYING, &state->flags); + + ret = t300rs_stop_effect(t300rs, state); + if(ret){ + hid_err(t300rs->hdev, "failed stopping effect\n"); + return ret; + } + } + } + + return 0; +} + +static enum hrtimer_restart t300rs_timer(struct hrtimer *t){ + struct t300rs_device_entry *t300rs = container_of(t, struct t300rs_device_entry, hrtimer); + int overruns, delay_timer; + + delay_timer = t300rs_timer_helper(t300rs); + + if(delay_timer){ + hrtimer_forward_now(&t300rs->hrtimer, ms_to_ktime(delay_timer)); + return HRTIMER_RESTART; + } + + if(t300rs->effects_used){ + overruns = hrtimer_forward_now(&t300rs->hrtimer, ms_to_ktime(timer_msecs)); + overruns--; + return HRTIMER_RESTART; + } else { + return HRTIMER_NORESTART; + } +} + + static int t300rs_upload(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old){ - /* temp */ + struct hid_device *hdev = input_get_drvdata(dev); + struct t300rs_device_entry *t300rs; + struct t300rs_effect_state *state; + + t300rs = t300rs_get_device(hdev); + + if(effect->type == FF_PERIODIC && effect->u.periodic.period == 0){ + return -EINVAL; + } + + if(effect->id > t300rs->max_id){ + t300rs->max_id = effect->id; + } + + state = &t300rs->states[effect->id]; + + spin_lock_irqsave(&t300rs->lock, t300rs->lock_flags); + + state->effect = *effect; + __set_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); + + spin_unlock_irqrestore(&t300rs->lock, t300rs->lock_flags); + return 0; } static int t300rs_play(struct input_dev *dev, int effect_id, int value){ - /* temp */ + struct hid_device *hdev = input_get_drvdata(dev); + struct t300rs_device_entry *t300rs; + struct t300rs_effect_state *state; + + t300rs = t300rs_get_device(hdev); + + state = &t300rs->states[effect_id]; + + spin_lock_irqsave(&t300rs->lock, t300rs->lock_flags); + + if(value > 0){ + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + __set_bit(FF_EFFECT_QUEUE_STOP, &state->flags); + } else { + t300rs->effects_used++; + + if(!hrtimer_active(&t300rs->hrtimer)){ + hrtimer_start(&t300rs->hrtimer, ms_to_ktime(timer_msecs), HRTIMER_MODE_REL); + } + } + + state->count = value; + + __set_bit(FF_EFFECT_QUEUE_START, &state->flags); + } else { + __set_bit(FF_EFFECT_QUEUE_STOP, &state->flags); + t300rs->effects_used--; + + } + + spin_unlock_irqrestore(&t300rs->lock, t300rs->lock_flags); return 0; } @@ -67,7 +606,9 @@ static ssize_t t300rs_range_store(struct device *dev, struct device_attribute *a if(range < 0x097b){ range = 0x097b; } - + + range = cpu_to_le16(range); + send_buffer[0] = 0x60; send_buffer[1] = 0x08; send_buffer[2] = 0x11; @@ -79,7 +620,7 @@ static ssize_t t300rs_range_store(struct device *dev, struct device_attribute *a hid_err(hdev, "failed sending interrupts\n"); return -1; } - + t300rs->range = range; kfree(send_buffer); return count; @@ -89,7 +630,7 @@ static ssize_t t300rs_range_show(struct device *dev, struct device_attribute *at char *buf){ struct hid_device *hdev = to_hid_device(dev); struct t300rs_device_entry *t300rs; - + t300rs = t300rs_get_device(hdev); return t300rs->range; @@ -104,8 +645,8 @@ static void t300rs_set_gain(struct input_dev *dev, u16 gain){ send_buffer[0] = 0x60; send_buffer[1] = 0x02; - send_buffer[2] = SCALE_VALUE_U16(gain, sizeof(char)); - + send_buffer[2] = SCALE_VALUE_U16(gain, 8); + ret = t300rs_send_int(dev, send_buffer, &trans); if(ret){ hid_err(hdev, "failed sending interrupts\n"); @@ -205,13 +746,24 @@ int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ t300rs = kzalloc(sizeof(struct t300rs_device_entry), GFP_ATOMIC); if(!t300rs){ - return -ENOMEM; + hid_err(hdev, "device entry could not be created\n"); + ret = -ENOMEM; + goto t300rs_err; } - + t300rs->input_dev = input_dev; t300rs->hdev = hdev; t300rs->usbdev = usbdev; t300rs->usbif = usbif; + t300rs->max_id = 0; + t300rs->states = kmalloc(sizeof(struct t300rs_effect_state) * 0x60, GFP_ATOMIC); + + if(!t300rs->states){ + hid_err(hdev, "effect states could not be created\n"); + ret = -ENOMEM; + goto states_err; + } + spin_lock_init(&t300rs->lock); drv_data->device_props = t300rs; @@ -269,13 +821,13 @@ int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ if(!t300rs->report){ hid_err(hdev, "can't find FF field in output reports\n"); ret = -ENODEV; - goto err; + goto out; } ret = input_ff_create(input_dev, T300RS_MAX_EFFECTS); if(ret){ hid_err(hdev, "could not create input_ff\n"); - goto err; + goto out; } ff = input_dev->ff; @@ -290,12 +842,22 @@ int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ ret = device_create_file(&hdev->dev, &dev_attr_range); if(ret){ hid_warn(hdev, "unable to create sysfs interface for range\n"); + goto out; } + hrtimer_init(&t300rs->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + t300rs->hrtimer.function = t300rs_timer; + hid_info(hdev, "force feedback for T300RS\n"); return 0; -err: + +out: + kfree(t300rs->states); +states_err: kfree(t300rs); +t300rs_err: + kfree(drv_data); +err: hid_err(hdev, "failed creating force feedback device\n"); return ret; @@ -353,6 +915,9 @@ static void t300rs_remove(struct hid_device *hdev){ drv_data = hid_get_drvdata(hdev); t300rs = t300rs_get_device(hdev); + hrtimer_cancel(&t300rs->hrtimer); + + kfree(t300rs->states); kfree(drv_data); kfree(t300rs); hid_hw_stop(hdev); diff --git a/hid-tmt300rs.h b/hid-tmt300rs.h index 876f778..3ac4336 100644 --- a/hid-tmt300rs.h +++ b/hid-tmt300rs.h @@ -1,14 +1,28 @@ #include "hid-tm.h" +#include "usbhid.h" +#include +#include +#include #define T300RS_MAX_EFFECTS FF_MAX_EFFECTS #define T300RS_BUFFER_LENGTH 64 +#define DEFAULT_TIMER_PERIOD 2 + +#define FF_EFFECT_QUEUE_UPLOAD 0 +#define FF_EFFECT_QUEUE_START 1 +#define FF_EFFECT_QUEUE_STOP 2 +#define FF_EFFECT_PLAYING 3 + #define CLAMP_VALUE_U16(x) ((unsigned short)((x) > 0xffff ? 0xffff : (x))) #define SCALE_VALUE_U16(x, bits) (CLAMP_VALUE_U16(x) >> (16 - bits)) +#define JIFFIES2MS(jiffies) ((jiffies) * 1000 / HZ) spinlock_t lock; unsigned long lock_flags; +static int timer_msecs = DEFAULT_TIMER_PERIOD; + static const signed short t300rs_ff_effects[] = { FF_CONSTANT, FF_RAMP, @@ -27,6 +41,13 @@ static const signed short t300rs_ff_effects[] = { -1 }; +struct t300rs_effect_state { + struct ff_effect effect; + unsigned long flags; + unsigned int start_time; + unsigned long count; +}; + struct t300rs_device_entry { struct hid_device *hdev; struct input_dev *input_dev; @@ -34,13 +55,18 @@ struct t300rs_device_entry { struct hid_field *ff_field; struct usb_device *usbdev; struct usb_interface *usbif; + struct t300rs_effect_state *states; + struct hrtimer hrtimer; spinlock_t lock; unsigned long lock_flags; + int max_id; u16 range; + u8 effects_used; }; + struct t300rs_data{ unsigned long quirks; void *device_props; @@ -48,3 +74,10 @@ struct t300rs_data{ static __u8 t300rs_rdesc_fixed[] = {0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x85, 0x07, 0x09, 0x30, 0x15, 0x00, 0x27, 0xff, 0xff, 0x00, 0x00, 0x35, 0x00, 0x47, 0xff, 0xff, 0x00, 0x00, 0x75, 0x10, 0x95, 0x01, 0x81, 0x02, 0x09, 0x31, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x81, 0x02, 0x09, 0x35, 0x81, 0x02, 0x09, 0x36, 0x81, 0x02, 0x81, 0x03, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0d, 0x25, 0x01, 0x45, 0x01, 0x75, 0x01, 0x95, 0x0d, 0x81, 0x02, 0x75, 0x0b, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01, 0x09, 0x39, 0x25, 0x07, 0x46, 0x3b, 0x01, 0x55, 0x00, 0x65, 0x14, 0x75, 0x04, 0x81, 0x42, 0x65, 0x00, 0x81, 0x03, 0x85, 0x0a, 0x06, 0x00, 0xff, 0x09, 0x0a, 0x75, 0x08, 0x95, 0x3f, 0x26, 0xff, 0x7f, 0x16, 0x00, 0x80, 0x46, 0xff, 0x7f, 0x36, 0x00, 0x80, 0x91, 0x02, 0x85, 0x02, 0x09, 0x02, 0x81, 0x02, 0x09, 0x14, 0x85, 0x14, 0x81, 0x02, 0xc0, 0xc0,}; +static u8 spring_values[] = { + 0xa6, 0x6a, 0xa6, 0x6a, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xdf, 0x58, 0xa6, 0x6a, 0x06 +}; + +static u8 damper_values[] = { + 0xfc, 0x7f, 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0xfc, 0x7f, 0x07 +}; diff --git a/usbhid.h b/usbhid.h new file mode 100644 index 0000000..8ab2917 --- /dev/null +++ b/usbhid.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef __USBHID_H +#define __USBHID_H + +/* + * Copyright (c) 1999 Andreas Gal + * Copyright (c) 2000-2001 Vojtech Pavlik + * Copyright (c) 2006 Jiri Kosina + */ + +/* + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* API provided by hid-core.c for USB HID drivers */ +void usbhid_init_reports(struct hid_device *hid); +struct usb_interface *usbhid_find_interface(int minor); + +/* iofl flags */ +#define HID_CTRL_RUNNING 1 +#define HID_OUT_RUNNING 2 +#define HID_IN_RUNNING 3 +#define HID_RESET_PENDING 4 +#define HID_SUSPENDED 5 +#define HID_CLEAR_HALT 6 +#define HID_DISCONNECTED 7 +#define HID_STARTED 8 +#define HID_KEYS_PRESSED 10 +#define HID_NO_BANDWIDTH 11 +#define HID_RESUME_RUNNING 12 +/* + * The device is opened, meaning there is a client that is interested + * in data coming from the device. + */ +#define HID_OPENED 13 +/* + * We are polling input endpoint by [re]submitting IN URB, because + * either HID device is opened or ALWAYS POLL quirk is set for the + * device. + */ +#define HID_IN_POLLING 14 + +/* + * USB-specific HID struct, to be pointed to + * from struct hid_device->driver_data + */ + +struct usbhid_device { + struct hid_device *hid; /* pointer to corresponding HID dev */ + + struct usb_interface *intf; /* USB interface */ + int ifnum; /* USB interface number */ + + unsigned int bufsize; /* URB buffer size */ + + struct urb *urbin; /* Input URB */ + char *inbuf; /* Input buffer */ + dma_addr_t inbuf_dma; /* Input buffer dma */ + + struct urb *urbctrl; /* Control URB */ + struct usb_ctrlrequest *cr; /* Control request struct */ + struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE]; /* Control fifo */ + unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */ + char *ctrlbuf; /* Control buffer */ + dma_addr_t ctrlbuf_dma; /* Control buffer dma */ + unsigned long last_ctrl; /* record of last output for timeouts */ + + struct urb *urbout; /* Output URB */ + struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */ + unsigned char outhead, outtail; /* Output pipe fifo head & tail */ + char *outbuf; /* Output buffer */ + dma_addr_t outbuf_dma; /* Output buffer dma */ + unsigned long last_out; /* record of last output for timeouts */ + + spinlock_t lock; /* fifo spinlock */ + unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ + struct timer_list io_retry; /* Retry timer */ + unsigned long stop_retry; /* Time to give up, in jiffies */ + unsigned int retry_delay; /* Delay length in ms */ + struct work_struct reset_work; /* Task context for resets */ + wait_queue_head_t wait; /* For sleeping */ +}; + +#define hid_to_usb_dev(hid_dev) \ + to_usb_device(hid_dev->dev.parent->parent) + +#endif -- cgit v1.3 From 64038b9d5fcc7d76191cbf77424bb779ad88390c Mon Sep 17 00:00:00 2001 From: kimi Date: Thu, 9 Jul 2020 14:07:52 -0400 Subject: fixed weird issue that crashed the kernel --- hid-tm.h | 1 - hid-tminit.c | 43 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/hid-tm.h b/hid-tm.h index 17cc741..e0117ae 100644 --- a/hid-tm.h +++ b/hid-tm.h @@ -15,7 +15,6 @@ struct api_context ctx; int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) { - unsigned long expire; int retval; diff --git a/hid-tminit.c b/hid-tminit.c index e20126b..9b894f5 100644 --- a/hid-tminit.c +++ b/hid-tminit.c @@ -1,12 +1,41 @@ #include "hid-tminit.h" - - static void tminit_callback(struct urb *urb){ - ctx.status = urb->status; hid_info(urb->dev, "urb status %d received\n", urb->status); } +/* for some godawful reason these interrupts are absolutely necessary, otherwise + * the whole kernel crashes. I have no idea why. + * */ +static void tminit_interrupts(struct hid_device *hdev){ + int ret, trans, i, b_ep; + u8 *send_buf = kmalloc(256, GFP_KERNEL); + + struct usb_host_endpoint *ep; + struct device *dev = &hdev->dev; + struct usb_interface *usbif = to_usb_interface(dev->parent); + struct usb_device *usbdev = interface_to_usbdev(usbif); + + ep = &usbif->cur_altsetting->endpoint[1]; + b_ep = ep->desc.bEndpointAddress; + + for(i = 0; i < ARRAY_SIZE(setup_arr); ++i){ + memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]); + + ret = usb_interrupt_msg(usbdev, + usb_sndintpipe(usbdev, b_ep), + send_buf, + setup_arr_sizes[i], + &trans, + USB_CTRL_SET_TIMEOUT); + + if(ret){ + hid_err(hdev, "setup data couldn't be sent\n"); + return; + } + } +} + int tminit(struct hid_device *hdev){ struct urb *urb; u8 *setup_packet, *transfer_buffer; @@ -14,7 +43,9 @@ int tminit(struct hid_device *hdev){ struct usb_interface *usbif = to_usb_interface(dev->parent); struct usb_device *usbdev = interface_to_usbdev(usbif); int ret; - + + tminit_interrupts(hdev); + setup_packet = kmalloc(8, GFP_ATOMIC); transfer_buffer = kmalloc(8, GFP_ATOMIC); @@ -34,9 +65,9 @@ int tminit(struct hid_device *hdev){ /* we sort of have to go on faith that the message is sent, because the * wheel usually completely dies as soon as it receives the message. + * No need to even check the return value. */ - ret = usb_start_wait_urb(urb, 5, NULL); - + ret = usb_submit_urb(urb, GFP_ATOMIC); kfree(setup_packet); kfree(transfer_buffer); return ret; -- cgit v1.3 From 014c79bc4966b40c2b4e18c0a2407b6af53908a1 Mon Sep 17 00:00:00 2001 From: kimi Date: Thu, 9 Jul 2020 14:19:37 -0400 Subject: hopefully fixed autocentering issue --- hid-tmt300rs.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c index c2540c0..4173601 100644 --- a/hid-tmt300rs.c +++ b/hid-tmt300rs.c @@ -638,6 +638,27 @@ static ssize_t t300rs_range_show(struct device *dev, struct device_attribute *at static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, t300rs_range_show, t300rs_range_store); +static void t300rs_set_autocenter(struct input_dev *dev, u16 value){ + struct hid_device *hdev = input_get_drvdata(dev); + u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + u16 le_value = cpu_to_le16(value); + int ret, trans; + + send_buffer[0] = 0x60; + send_buffer[1] = 0x08; + send_buffer[2] = 0x03; + + send_buffer[3] = le_value & 0xff; + send_buffer[4] = le_value >> 8; + + ret = t300rs_send_int(dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed setting autocenter"); + } + + kfree(send_buffer); +} + static void t300rs_set_gain(struct input_dev *dev, u16 gain){ struct hid_device *hdev = input_get_drvdata(dev); u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); @@ -649,8 +670,10 @@ static void t300rs_set_gain(struct input_dev *dev, u16 gain){ ret = t300rs_send_int(dev, send_buffer, &trans); if(ret){ - hid_err(hdev, "failed sending interrupts\n"); + hid_err(hdev, "failed setting gain\n"); } + + kfree(send_buffer); } static void t300rs_destroy(struct ff_device *ff){ @@ -834,6 +857,7 @@ int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ ff->upload = t300rs_upload; ff->playback = t300rs_play; ff->set_gain = t300rs_set_gain; + ff->set_autocenter = t300rs_set_autocenter; ff->destroy = t300rs_destroy; input_dev->open = t300rs_open; -- cgit v1.3 From ab71fe85ea80dc912c5f5871b7036e8da6df33b5 Mon Sep 17 00:00:00 2001 From: kimi Date: Thu, 9 Jul 2020 14:58:12 -0400 Subject: I borked the buttons, hopefully fixed --- hid-tmt300rs.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ hid-tmt300rs.h | 2 ++ 2 files changed, 48 insertions(+) diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c index 4173601..3d678c8 100644 --- a/hid-tmt300rs.c +++ b/hid-tmt300rs.c @@ -869,6 +869,7 @@ int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ goto out; } + hrtimer_init(&t300rs->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); t300rs->hrtimer.function = t300rs_timer; @@ -887,6 +888,48 @@ err: } +/* for some reason this specific command must be sent before hid_hw_start. Odd. + * */ +static int t300rs_preinit(struct hid_device *hdev){ + int ret; + u8 *setup_packet; + + /* this is sort of unnecessary, as later on I compile the interfaces etc + * into one struct, but for now this will do + * */ + struct device *dev = &hdev->dev; + struct usb_interface *usbif = to_usb_interface(dev->parent); + struct usb_device *usbdev = interface_to_usbdev(usbif); + struct urb *urb; + + setup_packet = kmalloc(8, GFP_ATOMIC); + + memcpy(setup_packet, t300rs_ctrl_out, ARRAY_SIZE(t300rs_ctrl_out)); + urb = usb_alloc_urb(0, GFP_ATOMIC); + + usb_fill_control_urb(urb, + usbdev, + usb_sndctrlpipe(usbdev, 0), + setup_packet, + NULL, + 0, + /* technically speaking this isn't an interrupt usb, but hey, this + * works. + * */ + t300rs_int_callback, + hdev); + + ret = usb_submit_urb(urb, GFP_ATOMIC); + if(ret != 0){ + hid_err(hdev, "Failed sending ctrl out with ERRNO: %i", ret); + goto error; + } + +error: + kfree(setup_packet); + return ret; +} + static int t300rs_probe(struct hid_device *hdev, const struct hid_device_id *id){ int ret; struct t300rs_data *drv_data; @@ -910,6 +953,9 @@ static int t300rs_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err; } + /* lord have mercy */ + t300rs_preinit(hdev); + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if(ret){ hid_err(hdev, "hw start failed\n"); diff --git a/hid-tmt300rs.h b/hid-tmt300rs.h index 3ac4336..bec73eb 100644 --- a/hid-tmt300rs.h +++ b/hid-tmt300rs.h @@ -81,3 +81,5 @@ static u8 spring_values[] = { static u8 damper_values[] = { 0xfc, 0x7f, 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0xfc, 0x7f, 0x07 }; + +static u8 t300rs_ctrl_out[] = { 0x41, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, }; -- cgit v1.3 From 6ab0a7ce8601e1b3ae24516d91e26ca116e8fce4 Mon Sep 17 00:00:00 2001 From: kimi Date: Thu, 9 Jul 2020 15:44:22 -0400 Subject: small progress --- hid-tmt300rs.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c index 3d678c8..2e2609a 100644 --- a/hid-tmt300rs.c +++ b/hid-tmt300rs.c @@ -892,7 +892,7 @@ err: * */ static int t300rs_preinit(struct hid_device *hdev){ int ret; - u8 *setup_packet; + u8 *setup_packet, *send_buffer; /* this is sort of unnecessary, as later on I compile the interfaces etc * into one struct, but for now this will do @@ -900,9 +900,10 @@ static int t300rs_preinit(struct hid_device *hdev){ struct device *dev = &hdev->dev; struct usb_interface *usbif = to_usb_interface(dev->parent); struct usb_device *usbdev = interface_to_usbdev(usbif); - struct urb *urb; + struct urb *urb; setup_packet = kmalloc(8, GFP_ATOMIC); + send_buffer = kzalloc(8, GFP_ATOMIC); memcpy(setup_packet, t300rs_ctrl_out, ARRAY_SIZE(t300rs_ctrl_out)); urb = usb_alloc_urb(0, GFP_ATOMIC); @@ -911,7 +912,10 @@ static int t300rs_preinit(struct hid_device *hdev){ usbdev, usb_sndctrlpipe(usbdev, 0), setup_packet, - NULL, + /* why is it important we have a pointer, when we send out 0 bytes? + * No clue. + * */ + send_buffer, 0, /* technically speaking this isn't an interrupt usb, but hey, this * works. @@ -926,6 +930,7 @@ static int t300rs_preinit(struct hid_device *hdev){ } error: + kfree(send_buffer); kfree(setup_packet); return ret; } -- cgit v1.3 From 2031f19d346e5abcfaa1feb35103fba52dd5c55c Mon Sep 17 00:00:00 2001 From: Kimplul Date: Fri, 10 Jul 2020 00:40:09 +0300 Subject: incremental additions --- Module.symvers | 0 compile_commands.json | 44 +++++++++++++-------------------- hid-tminit.ko | Bin 0 -> 419984 bytes hid-tminit.mod | 2 ++ hid-tminit.mod.c | 55 +++++++++++++++++++++++++++++++++++++++++ hid-tminit.mod.o | Bin 0 -> 143264 bytes hid-tminit.o | Bin 0 -> 278312 bytes hid-tmt300rs.c | 36 +++++++++++++-------------- hid-tmt300rs.h | 2 +- hid-tmt300rs.ko | Bin 0 -> 537752 bytes hid-tmt300rs.mod | 2 ++ hid-tmt300rs.mod.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ hid-tmt300rs.mod.o | Bin 0 -> 144040 bytes hid-tmt300rs.o | Bin 0 -> 395304 bytes modules.order | 2 ++ todo.txt | 3 +++ 16 files changed, 166 insertions(+), 47 deletions(-) create mode 100644 Module.symvers create mode 100644 hid-tminit.ko create mode 100644 hid-tminit.mod create mode 100644 hid-tminit.mod.c create mode 100644 hid-tminit.mod.o create mode 100644 hid-tminit.o create mode 100644 hid-tmt300rs.ko create mode 100644 hid-tmt300rs.mod create mode 100644 hid-tmt300rs.mod.c create mode 100644 hid-tmt300rs.mod.o create mode 100644 hid-tmt300rs.o create mode 100644 modules.order create mode 100644 todo.txt diff --git a/Module.symvers b/Module.symvers new file mode 100644 index 0000000..e69de29 diff --git a/compile_commands.json b/compile_commands.json index ea1a16a..a75ead3 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -1,24 +1,24 @@ [ { "arguments": [ - "gcc", + "gcc-9", "-c", - "-Wp,-MD,/home/kimi/Documents/tmff2/.hid-tminit.o.d", + "-Wp,-MD,/home/kimi/Documents/Projects/hid-tmff2/.hid-tmt300rs.o.d", "-nostdinc", "-isystem", "/usr/lib/gcc/x86_64-linux-gnu/9/include", - "-I./arch/x86/include", + "-I/usr/src/linux-headers-5.7.0-1-common/arch/x86/include", "-I./arch/x86/include/generated", + "-I/usr/src/linux-headers-5.7.0-1-common/include", "-I./include", - "-I./arch/x86/include/uapi", + "-I/usr/src/linux-headers-5.7.0-1-common/arch/x86/include/uapi", "-I./arch/x86/include/generated/uapi", - "-I./include/uapi", + "-I/usr/src/linux-headers-5.7.0-1-common/include/uapi", "-I./include/generated/uapi", "-include", - "./include/linux/kconfig.h", - "-Iubuntu/include", + "/usr/src/linux-headers-5.7.0-1-common/include/linux/kconfig.h", "-include", - "./include/linux/compiler_types.h", + "/usr/src/linux-headers-5.7.0-1-common/include/linux/compiler_types.h", "-D__KERNEL__", "-Wall", "-Wundef", @@ -48,15 +48,6 @@ "-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", @@ -69,14 +60,13 @@ "-Wno-address-of-packed-member", "-O2", "--param=allow-store-data-races=0", - "-Wframe-larger-than=1024", + "-Wframe-larger-than=2048", "-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", @@ -98,17 +88,17 @@ "-Werror=date-time", "-Werror=incompatible-pointer-types", "-Werror=designated-init", - "-fmacro-prefix-map=./=", + "-fmacro-prefix-map=/usr/src/linux-headers-5.7.0-1-common/=", "-fcf-protection=none", "-Wno-packed-not-aligned", "-DMODULE", - "-DKBUILD_BASENAME=\"hid_tminit\"", - "-DKBUILD_MODNAME=\"hid_tminit\"", + "-DKBUILD_BASENAME=\"hid_tmt300rs\"", + "-DKBUILD_MODNAME=\"hid_tmt300rs\"", "-o", - "/home/kimi/Documents/tmff2/hid-tminit.o", - "../../../home/kimi/Documents/tmff2/hid-tminit.c" + "/home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.o", + "../../../home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.c" ], - "directory": "/usr/src/linux-headers-5.4.0-40-generic", - "file": "../../../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-tmt300rs.c" } ] \ No newline at end of file diff --git a/hid-tminit.ko b/hid-tminit.ko new file mode 100644 index 0000000..f7a0f97 Binary files /dev/null and b/hid-tminit.ko differ diff --git a/hid-tminit.mod b/hid-tminit.mod new file mode 100644 index 0000000..821c012 --- /dev/null +++ b/hid-tminit.mod @@ -0,0 +1,2 @@ +/home/kimi/Documents/Projects/hid-tmff2/hid-tminit.o + diff --git a/hid-tminit.mod.c b/hid-tminit.mod.c new file mode 100644 index 0000000..7029581 --- /dev/null +++ b/hid-tminit.mod.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +BUILD_SALT; + +MODULE_INFO(vermagic, VERMAGIC_STRING); +MODULE_INFO(name, KBUILD_MODNAME); + +__visible struct module __this_module +__section(.gnu.linkonce.this_module) = { + .name = KBUILD_MODNAME, + .init = init_module, +#ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module, +#endif + .arch = MODULE_ARCH_INIT, +}; + +#ifdef CONFIG_RETPOLINE +MODULE_INFO(retpoline, "Y"); +#endif + +static const struct modversion_info ____versions[] +__used __section(__versions) = { + { 0x7ca88ad8, "module_layout" }, + { 0x817489f6, "hid_unregister_driver" }, + { 0xb7aa9422, "__hid_register_driver" }, + { 0x414fc2a1, "hid_hw_start" }, + { 0xcd9e657d, "hid_open_report" }, + { 0x316d1bda, "_dev_err" }, + { 0xdecd0b29, "__stack_chk_fail" }, + { 0x37a0cba, "kfree" }, + { 0x82fea2ff, "usb_alloc_urb" }, + { 0xc30561e7, "usb_interrupt_msg" }, + { 0x69acdf38, "memcpy" }, + { 0xc27f683d, "kmem_cache_alloc_trace" }, + { 0x46a9479b, "kmalloc_caches" }, + { 0x70bce9a, "__dynamic_dev_dbg" }, + { 0xfeba7354, "current_task" }, + { 0x648538a5, "usb_kill_urb" }, + { 0x7f02188f, "__msecs_to_jiffies" }, + { 0xadd72fe9, "usb_free_urb" }, + { 0x4a3ad70e, "wait_for_completion_timeout" }, + { 0xedb8a9, "usb_submit_urb" }, + { 0x608741b5, "__init_swait_queue_head" }, + { 0x4a0c79b0, "hid_hw_stop" }, + { 0x59e59766, "_dev_info" }, + { 0xbdfb6dbb, "__fentry__" }, +}; + +MODULE_INFO(depends, "hid,usbcore"); + +MODULE_ALIAS("hid:b0003g*v0000044Fp0000B65D"); diff --git a/hid-tminit.mod.o b/hid-tminit.mod.o new file mode 100644 index 0000000..ae7e374 Binary files /dev/null and b/hid-tminit.mod.o differ diff --git a/hid-tminit.o b/hid-tminit.o new file mode 100644 index 0000000..ae3404b Binary files /dev/null and b/hid-tminit.o differ diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c index 2e2609a..b8f0a30 100644 --- a/hid-tmt300rs.c +++ b/hid-tmt300rs.c @@ -451,18 +451,16 @@ static int t300rs_timer_helper(struct t300rs_device_entry *t300rs){ hid_info(t300rs->hdev, "commands stacking up, increasing timer period\n"); return current_period; } - - for(effect_id = 0; effect_id < t300rs->max_id; ++effect_id){ + + for(effect_id = 0; effect_id < T300RS_MAX_EFFECTS; ++effect_id){ state = &t300rs->states[effect_id]; - if(!test_bit(FF_EFFECT_QUEUE_START, &state->flags) && - !test_bit(FF_EFFECT_QUEUE_STOP, &state->flags)){ - continue; - } - - if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + /* + * alright, for now no count support + * if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ if(JIFFIES2MS(jiffies) - state->start_time >= state->effect.replay.length){ + hid_info(t300rs->hdev, "maybe dangerous?"); __clear_bit(FF_EFFECT_PLAYING, &state->flags); if(state->count){ @@ -470,7 +468,7 @@ static int t300rs_timer_helper(struct t300rs_device_entry *t300rs){ state->count--; } } - } + }*/ if(test_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags)){ __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); @@ -537,7 +535,7 @@ static int t300rs_upload(struct input_dev *dev, struct ff_effect *effect, struct struct t300rs_effect_state *state; t300rs = t300rs_get_device(hdev); - + if(effect->type == FF_PERIODIC && effect->u.periodic.period == 0){ return -EINVAL; } @@ -566,11 +564,11 @@ static int t300rs_play(struct input_dev *dev, int effect_id, int value){ t300rs = t300rs_get_device(hdev); state = &t300rs->states[effect_id]; - + spin_lock_irqsave(&t300rs->lock, t300rs->lock_flags); if(value > 0){ - if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + if(test_bit(FF_EFFECT_QUEUE_START, &state->flags)){ __set_bit(FF_EFFECT_QUEUE_STOP, &state->flags); } else { t300rs->effects_used++; @@ -593,6 +591,7 @@ static int t300rs_play(struct input_dev *dev, int effect_id, int value){ return 0; } +/* we should set a default range */ static ssize_t t300rs_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct hid_device *hdev = to_hid_device(dev); @@ -728,7 +727,7 @@ err: return ret; } -static void t300rs_close(struct input_dev *dev){ +/*static void t300rs_close(struct input_dev *dev){ int ret, trans; struct hid_device *hdev = input_get_drvdata(dev); u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); @@ -744,7 +743,7 @@ static void t300rs_close(struct input_dev *dev){ err: kfree(send_buffer); return; -} +}*/ int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ struct t300rs_device_entry *t300rs; @@ -860,19 +859,20 @@ int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ ff->set_autocenter = t300rs_set_autocenter; ff->destroy = t300rs_destroy; - input_dev->open = t300rs_open; - input_dev->close = t300rs_close; + /* input_dev->open = t300rs_open; + input_dev->close = t300rs_close; */ ret = device_create_file(&hdev->dev, &dev_attr_range); if(ret){ hid_warn(hdev, "unable to create sysfs interface for range\n"); goto out; } - + hrtimer_init(&t300rs->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); t300rs->hrtimer.function = t300rs_timer; + t300rs_open(input_dev); hid_info(hdev, "force feedback for T300RS\n"); return 0; @@ -940,7 +940,6 @@ static int t300rs_probe(struct hid_device *hdev, const struct hid_device_id *id) struct t300rs_data *drv_data; spin_lock_init(&lock); - spin_lock_irqsave(&lock, lock_flags); drv_data = kzalloc(sizeof(struct t300rs_data), GFP_ATOMIC); if(!drv_data){ @@ -973,7 +972,6 @@ static int t300rs_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err; } - spin_unlock_irqrestore(&lock, lock_flags); return 0; err: kfree(drv_data); diff --git a/hid-tmt300rs.h b/hid-tmt300rs.h index bec73eb..1cc3424 100644 --- a/hid-tmt300rs.h +++ b/hid-tmt300rs.h @@ -7,7 +7,7 @@ #define T300RS_MAX_EFFECTS FF_MAX_EFFECTS #define T300RS_BUFFER_LENGTH 64 -#define DEFAULT_TIMER_PERIOD 2 +#define DEFAULT_TIMER_PERIOD 16 /* the wheel seems to be bad at stuff*/ #define FF_EFFECT_QUEUE_UPLOAD 0 #define FF_EFFECT_QUEUE_START 1 diff --git a/hid-tmt300rs.ko b/hid-tmt300rs.ko new file mode 100644 index 0000000..7ec9bb8 Binary files /dev/null and b/hid-tmt300rs.ko differ diff --git a/hid-tmt300rs.mod b/hid-tmt300rs.mod new file mode 100644 index 0000000..8a429e9 --- /dev/null +++ b/hid-tmt300rs.mod @@ -0,0 +1,2 @@ +/home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.o + diff --git a/hid-tmt300rs.mod.c b/hid-tmt300rs.mod.c new file mode 100644 index 0000000..d10c5bb --- /dev/null +++ b/hid-tmt300rs.mod.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include + +BUILD_SALT; + +MODULE_INFO(vermagic, VERMAGIC_STRING); +MODULE_INFO(name, KBUILD_MODNAME); + +__visible struct module __this_module +__section(.gnu.linkonce.this_module) = { + .name = KBUILD_MODNAME, + .init = init_module, +#ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module, +#endif + .arch = MODULE_ARCH_INIT, +}; + +#ifdef CONFIG_RETPOLINE +MODULE_INFO(retpoline, "Y"); +#endif + +static const struct modversion_info ____versions[] +__used __section(__versions) = { + { 0x7ca88ad8, "module_layout" }, + { 0x817489f6, "hid_unregister_driver" }, + { 0xb7aa9422, "__hid_register_driver" }, + { 0x414fc2a1, "hid_hw_start" }, + { 0xcd9e657d, "hid_open_report" }, + { 0x1ee7d3cd, "hrtimer_init" }, + { 0x7d42edf, "device_create_file" }, + { 0xb3e1146a, "input_ff_create" }, + { 0x70bce9a, "__dynamic_dev_dbg" }, + { 0xfeba7354, "current_task" }, + { 0x648538a5, "usb_kill_urb" }, + { 0x7f02188f, "__msecs_to_jiffies" }, + { 0x4a3ad70e, "wait_for_completion_timeout" }, + { 0x608741b5, "__init_swait_queue_head" }, + { 0xdecd0b29, "__stack_chk_fail" }, + { 0x15ba50a6, "jiffies" }, + { 0xdc21e866, "hrtimer_forward" }, + { 0x2ea2c95c, "__x86_indirect_thunk_rax" }, + { 0x59e59766, "_dev_info" }, + { 0x20000329, "simple_strtoul" }, + { 0xc27f683d, "kmem_cache_alloc_trace" }, + { 0x46a9479b, "kmalloc_caches" }, + { 0xedb8a9, "usb_submit_urb" }, + { 0x82fea2ff, "usb_alloc_urb" }, + { 0x4a0c79b0, "hid_hw_stop" }, + { 0x37a0cba, "kfree" }, + { 0xa0c6befa, "hrtimer_cancel" }, + { 0x9c59e5d5, "device_remove_file" }, + { 0xfbdfc558, "hrtimer_start_range_ns" }, + { 0xb4ff6bb6, "hrtimer_active" }, + { 0xc85d768e, "_dev_warn" }, + { 0xadd72fe9, "usb_free_urb" }, + { 0x316d1bda, "_dev_err" }, + { 0x3812050a, "_raw_spin_unlock_irqrestore" }, + { 0x51760917, "_raw_spin_lock_irqsave" }, + { 0xbdfb6dbb, "__fentry__" }, +}; + +MODULE_INFO(depends, "hid,usbcore"); + +MODULE_ALIAS("hid:b0003g*v0000044Fp0000B66E"); diff --git a/hid-tmt300rs.mod.o b/hid-tmt300rs.mod.o new file mode 100644 index 0000000..95b6880 Binary files /dev/null and b/hid-tmt300rs.mod.o differ diff --git a/hid-tmt300rs.o b/hid-tmt300rs.o new file mode 100644 index 0000000..743d20b Binary files /dev/null and b/hid-tmt300rs.o differ diff --git a/modules.order b/modules.order new file mode 100644 index 0000000..a0e2376 --- /dev/null +++ b/modules.order @@ -0,0 +1,2 @@ +/home/kimi/Documents/Projects/hid-tmff2/hid-tminit.ko +/home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.ko diff --git a/todo.txt b/todo.txt new file mode 100644 index 0000000..ea2310d --- /dev/null +++ b/todo.txt @@ -0,0 +1,3 @@ +1. set a default range for the wheel so that it syncs up correctly +2. figure out the bug where the effects suddenly stop being sent (happens in +dirt rally at least) -- cgit v1.3 From 11c7bb0526d1ddd20d86b9cb2981b3a213d40404 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Fri, 10 Jul 2020 18:42:11 +0300 Subject: incorrect usage of git --- hid-tmt300rs.c | 92 ++++++++++++++++++++++++----------------------------- hid-tmt300rs.h | 6 ++-- hid-tmt300rs.ko | Bin 537752 -> 527336 bytes hid-tmt300rs.mod.c | 4 +-- hid-tmt300rs.mod.o | Bin 144040 -> 144040 bytes hid-tmt300rs.o | Bin 395304 -> 384888 bytes 6 files changed, 46 insertions(+), 56 deletions(-) diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c index b8f0a30..bab04ec 100644 --- a/hid-tmt300rs.c +++ b/hid-tmt300rs.c @@ -71,7 +71,6 @@ static int t300rs_play_effect(struct t300rs_device_entry *t300rs, struct t300rs_ hid_err(t300rs->hdev, "failed starting effect play\n"); } - hid_info(t300rs->hdev, "sent play\n"); kfree(send_buffer); return ret; } @@ -89,7 +88,7 @@ static int t300rs_stop_effect(struct t300rs_device_entry *t300rs, struct t300rs_ hid_err(t300rs->hdev, "failed stopping effect play\n"); } - hid_info(t300rs->hdev, "stopping effect\n"); + kfree(send_buffer); return ret; } @@ -160,7 +159,6 @@ static int t300rs_upload_constant(struct t300rs_device_entry *t300rs, struct t30 if(ret){ hid_err(t300rs->hdev, "failed uploading constant effect\n"); } - hid_info(t300rs->hdev, "uploading constant"); kfree(send_buffer); return ret; } @@ -225,7 +223,6 @@ static int t300rs_upload_ramp(struct t300rs_device_entry *t300rs, struct t300rs_ hid_err(t300rs->hdev, "failed uploading ramp"); } kfree(send_buffer); - hid_info(t300rs->hdev, "uploading ramp"); return ret; } @@ -256,8 +253,6 @@ static int t300rs_upload_spring(struct t300rs_device_entry *t300rs, struct t300r le_duration = cpu_to_le16(effect.replay.length); le_offset = cpu_to_le16(effect.replay.delay); - hid_info(t300rs->hdev, "coeffs: %x vs %x\n", le_right_coeff, spring.right_coeff); - send_buffer[4] = le_right_coeff & 0xff; send_buffer[5] = le_right_coeff >> 8; @@ -287,7 +282,6 @@ static int t300rs_upload_spring(struct t300rs_device_entry *t300rs, struct t300r hid_err(t300rs->hdev, "failed uploading spring\n"); } kfree(send_buffer); - hid_info(t300rs->hdev, "uploading spring"); return ret; } @@ -318,8 +312,6 @@ static int t300rs_upload_damper(struct t300rs_device_entry *t300rs, struct t300r le_duration = cpu_to_le16(effect.replay.length); le_offset = cpu_to_le16(effect.replay.delay); - hid_info(t300rs->hdev, "coeffs: %x vs %x\n", le_right_coeff, spring.right_coeff); - send_buffer[4] = le_right_coeff & 0xff; send_buffer[5] = le_right_coeff >> 8; @@ -348,10 +340,8 @@ static int t300rs_upload_damper(struct t300rs_device_entry *t300rs, struct t300r if(ret){ hid_err(t300rs->hdev, "failed uploading spring\n"); } - - hid_info(t300rs->hdev, "uploading spring"); + kfree(send_buffer); return ret; - return 0; } static int t300rs_upload_periodic(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ @@ -367,10 +357,8 @@ static int t300rs_upload_periodic(struct t300rs_device_entry *t300rs, struct t30 __clear_bit(FF_EFFECT_PLAYING, &state->flags); } - magnitude = (periodic.magnitude * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; - hid_warn(t300rs->hdev, "magnitude %i vs %i\n", periodic.magnitude, magnitude); le_magnitude = cpu_to_le16(magnitude); le_phase = cpu_to_le16(periodic.phase); le_periodic_offset = cpu_to_le16(periodic.offset); @@ -415,8 +403,8 @@ static int t300rs_upload_periodic(struct t300rs_device_entry *t300rs, struct t30 if(ret){ hid_err(t300rs->hdev, "failed uploading periodic effect"); } + kfree(send_buffer); - hid_info(t300rs->hdev, "uploaded periodic effect"); return ret; } @@ -441,34 +429,23 @@ static int t300rs_upload_effect(struct t300rs_device_entry *t300rs, struct t300r } static int t300rs_timer_helper(struct t300rs_device_entry *t300rs){ - struct usbhid_device *usbhid = t300rs->hdev->driver_data; struct t300rs_effect_state *state; - int current_period, effect_id, ret; - - if(usbhid->outhead != usbhid->outtail){ - current_period = timer_msecs; - timer_msecs *= 2; - hid_info(t300rs->hdev, "commands stacking up, increasing timer period\n"); - return current_period; - } - + unsigned long jiffies_now = JIFFIES2MS(jiffies); + int max_count = 0, effect_id, ret; + for(effect_id = 0; effect_id < T300RS_MAX_EFFECTS; ++effect_id){ state = &t300rs->states[effect_id]; - /* - * alright, for now no count support - * if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ - if(JIFFIES2MS(jiffies) - state->start_time >= state->effect.replay.length){ - hid_info(t300rs->hdev, "maybe dangerous?"); + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + if((jiffies_now - state->start_time) >= state->effect.replay.length){ __clear_bit(FF_EFFECT_PLAYING, &state->flags); if(state->count){ __set_bit(FF_EFFECT_QUEUE_START, &state->flags); - state->count--; } } - }*/ + } if(test_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags)){ __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); @@ -484,13 +461,15 @@ static int t300rs_timer_helper(struct t300rs_device_entry *t300rs){ __clear_bit(FF_EFFECT_QUEUE_START, &state->flags); __set_bit(FF_EFFECT_PLAYING, &state->flags); - state->start_time = JIFFIES2MS(jiffies); - ret = t300rs_play_effect(t300rs, state); if(ret){ hid_err(t300rs->hdev, "failed starting effects\n"); return ret; } + + if(state->count){ + state->count--; + } } if(test_bit(FF_EFFECT_QUEUE_STOP, &state->flags)){ @@ -503,29 +482,31 @@ static int t300rs_timer_helper(struct t300rs_device_entry *t300rs){ return ret; } } + + if(state->count > max_count){ + max_count = state->count; + } } - return 0; + return max_count; } static enum hrtimer_restart t300rs_timer(struct hrtimer *t){ struct t300rs_device_entry *t300rs = container_of(t, struct t300rs_device_entry, hrtimer); - int overruns, delay_timer; + int max_count; - delay_timer = t300rs_timer_helper(t300rs); + spin_lock_irqsave(&t300rs->lock, t300rs->lock_flags); - if(delay_timer){ - hrtimer_forward_now(&t300rs->hrtimer, ms_to_ktime(delay_timer)); - return HRTIMER_RESTART; - } + max_count = t300rs_timer_helper(t300rs); + + spin_unlock_irqrestore(&t300rs->lock, t300rs->lock_flags); - if(t300rs->effects_used){ - overruns = hrtimer_forward_now(&t300rs->hrtimer, ms_to_ktime(timer_msecs)); - overruns--; + if(max_count > 0){ + hrtimer_forward_now(&t300rs->hrtimer, ms_to_ktime(timer_msecs)); return HRTIMER_RESTART; } else { return HRTIMER_NORESTART; - } + } } @@ -572,19 +553,19 @@ static int t300rs_play(struct input_dev *dev, int effect_id, int value){ __set_bit(FF_EFFECT_QUEUE_STOP, &state->flags); } else { t300rs->effects_used++; - - if(!hrtimer_active(&t300rs->hrtimer)){ - hrtimer_start(&t300rs->hrtimer, ms_to_ktime(timer_msecs), HRTIMER_MODE_REL); - } } state->count = value; - + state->start_time = JIFFIES2MS(jiffies); __set_bit(FF_EFFECT_QUEUE_START, &state->flags); + } else { __set_bit(FF_EFFECT_QUEUE_STOP, &state->flags); t300rs->effects_used--; + } + if(!hrtimer_active(&t300rs->hrtimer)){ + hrtimer_start(&t300rs->hrtimer, ms_to_ktime(timer_msecs), HRTIMER_MODE_REL); } spin_unlock_irqrestore(&t300rs->lock, t300rs->lock_flags); @@ -757,6 +738,7 @@ int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ struct usb_device *usbdev = interface_to_usbdev(usbif); struct hid_report *report; struct ff_device *ff; + char range[10] = "54000"; /* approx 900 degress */ int i, ret; drv_data = hid_get_drvdata(hdev); @@ -872,6 +854,10 @@ int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ hrtimer_init(&t300rs->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); t300rs->hrtimer.function = t300rs_timer; + + t300rs_range_store(dev, &dev_attr_range, range, 10); + t300rs_set_gain(input_dev, 0xffff); + t300rs_open(input_dev); hid_info(hdev, "force feedback for T300RS\n"); return 0; @@ -958,7 +944,7 @@ static int t300rs_probe(struct hid_device *hdev, const struct hid_device_id *id) } /* lord have mercy */ - t300rs_preinit(hdev); + //t300rs_preinit(hdev); ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if(ret){ @@ -983,6 +969,7 @@ static void t300rs_remove(struct hid_device *hdev){ struct t300rs_device_entry *t300rs; struct t300rs_data *drv_data; + spin_lock_irqsave(&lock, lock_flags); device_remove_file(&hdev->dev, &dev_attr_range); drv_data = hid_get_drvdata(hdev); @@ -994,6 +981,9 @@ static void t300rs_remove(struct hid_device *hdev){ kfree(drv_data); kfree(t300rs); hid_hw_stop(hdev); + + spin_unlock_irqrestore(&lock, lock_flags); + return; } diff --git a/hid-tmt300rs.h b/hid-tmt300rs.h index 1cc3424..b308627 100644 --- a/hid-tmt300rs.h +++ b/hid-tmt300rs.h @@ -4,10 +4,10 @@ #include #include -#define T300RS_MAX_EFFECTS FF_MAX_EFFECTS +#define T300RS_MAX_EFFECTS 16 #define T300RS_BUFFER_LENGTH 64 -#define DEFAULT_TIMER_PERIOD 16 /* the wheel seems to be bad at stuff*/ +#define DEFAULT_TIMER_PERIOD 4 /* the wheel seems to be bad at stuff*/ #define FF_EFFECT_QUEUE_UPLOAD 0 #define FF_EFFECT_QUEUE_START 1 @@ -44,7 +44,7 @@ static const signed short t300rs_ff_effects[] = { struct t300rs_effect_state { struct ff_effect effect; unsigned long flags; - unsigned int start_time; + unsigned long start_time; unsigned long count; }; diff --git a/hid-tmt300rs.ko b/hid-tmt300rs.ko index 7ec9bb8..07d01f3 100644 Binary files a/hid-tmt300rs.ko and b/hid-tmt300rs.ko differ diff --git a/hid-tmt300rs.mod.c b/hid-tmt300rs.mod.c index d10c5bb..a114b1d 100644 --- a/hid-tmt300rs.mod.c +++ b/hid-tmt300rs.mod.c @@ -29,6 +29,7 @@ __used __section(__versions) = { { 0xb7aa9422, "__hid_register_driver" }, { 0x414fc2a1, "hid_hw_start" }, { 0xcd9e657d, "hid_open_report" }, + { 0x59e59766, "_dev_info" }, { 0x1ee7d3cd, "hrtimer_init" }, { 0x7d42edf, "device_create_file" }, { 0xb3e1146a, "input_ff_create" }, @@ -39,10 +40,8 @@ __used __section(__versions) = { { 0x4a3ad70e, "wait_for_completion_timeout" }, { 0x608741b5, "__init_swait_queue_head" }, { 0xdecd0b29, "__stack_chk_fail" }, - { 0x15ba50a6, "jiffies" }, { 0xdc21e866, "hrtimer_forward" }, { 0x2ea2c95c, "__x86_indirect_thunk_rax" }, - { 0x59e59766, "_dev_info" }, { 0x20000329, "simple_strtoul" }, { 0xc27f683d, "kmem_cache_alloc_trace" }, { 0x46a9479b, "kmalloc_caches" }, @@ -54,6 +53,7 @@ __used __section(__versions) = { { 0x9c59e5d5, "device_remove_file" }, { 0xfbdfc558, "hrtimer_start_range_ns" }, { 0xb4ff6bb6, "hrtimer_active" }, + { 0x15ba50a6, "jiffies" }, { 0xc85d768e, "_dev_warn" }, { 0xadd72fe9, "usb_free_urb" }, { 0x316d1bda, "_dev_err" }, diff --git a/hid-tmt300rs.mod.o b/hid-tmt300rs.mod.o index 95b6880..5ab5b8c 100644 Binary files a/hid-tmt300rs.mod.o and b/hid-tmt300rs.mod.o differ diff --git a/hid-tmt300rs.o b/hid-tmt300rs.o index 743d20b..a01b321 100644 Binary files a/hid-tmt300rs.o and b/hid-tmt300rs.o differ -- cgit v1.3 From ead4ca3e9726eea7456064682c739aee74416fba Mon Sep 17 00:00:00 2001 From: kimi Date: Fri, 10 Jul 2020 12:16:08 -0400 Subject: wow? --- compile_commands.json | 40 +++++++++++++++--------- hid-tminit.ko | Bin 419984 -> 280264 bytes hid-tminit.mod | 2 +- hid-tminit.mod.c | 34 +++----------------- hid-tminit.mod.o | Bin 143264 -> 2904 bytes hid-tmt300rs.c | 85 +++++++++++++++----------------------------------- hid-tmt300rs.h | 6 ++++ hid-tmt300rs.ko | Bin 527336 -> 26560 bytes hid-tmt300rs.mod | 2 +- hid-tmt300rs.mod.c | 46 +++------------------------ hid-tmt300rs.mod.o | Bin 144040 -> 2912 bytes hid-tmt300rs.o | Bin 384888 -> 24568 bytes modules.order | 4 +-- 13 files changed, 68 insertions(+), 151 deletions(-) diff --git a/compile_commands.json b/compile_commands.json index a75ead3..56b8bee 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-tmt300rs.o.d", + "-Wp,-MD,/home/kimi/Documents/tmff2/.hid-tmt300rs.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_tmt300rs\"", "-DKBUILD_MODNAME=\"hid_tmt300rs\"", "-o", - "/home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.o", - "../../../home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.c" + "/home/kimi/Documents/tmff2/hid-tmt300rs.o", + "../../../home/kimi/Documents/tmff2/hid-tmt300rs.c" ], - "directory": "/usr/src/linux-headers-5.7.0-1-amd64", - "file": "../../../home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.c" + "directory": "/usr/src/linux-headers-5.4.0-40-generic", + "file": "../../../home/kimi/Documents/tmff2/hid-tmt300rs.c" } ] \ No newline at end of file diff --git a/hid-tminit.ko b/hid-tminit.ko index f7a0f97..763336c 100644 Binary files a/hid-tminit.ko and b/hid-tminit.ko differ diff --git a/hid-tminit.mod b/hid-tminit.mod index 821c012..858ad57 100644 --- a/hid-tminit.mod +++ b/hid-tminit.mod @@ -1,2 +1,2 @@ -/home/kimi/Documents/Projects/hid-tmff2/hid-tminit.o +/home/kimi/Documents/tmff2/hid-tminit.o diff --git a/hid-tminit.mod.c b/hid-tminit.mod.c index 7029581..dbd2e54 100644 --- a/hid-tminit.mod.c +++ b/hid-tminit.mod.c @@ -1,5 +1,5 @@ -#include #include +#include #include #include @@ -22,34 +22,8 @@ __section(.gnu.linkonce.this_module) = { MODULE_INFO(retpoline, "Y"); #endif -static const struct modversion_info ____versions[] -__used __section(__versions) = { - { 0x7ca88ad8, "module_layout" }, - { 0x817489f6, "hid_unregister_driver" }, - { 0xb7aa9422, "__hid_register_driver" }, - { 0x414fc2a1, "hid_hw_start" }, - { 0xcd9e657d, "hid_open_report" }, - { 0x316d1bda, "_dev_err" }, - { 0xdecd0b29, "__stack_chk_fail" }, - { 0x37a0cba, "kfree" }, - { 0x82fea2ff, "usb_alloc_urb" }, - { 0xc30561e7, "usb_interrupt_msg" }, - { 0x69acdf38, "memcpy" }, - { 0xc27f683d, "kmem_cache_alloc_trace" }, - { 0x46a9479b, "kmalloc_caches" }, - { 0x70bce9a, "__dynamic_dev_dbg" }, - { 0xfeba7354, "current_task" }, - { 0x648538a5, "usb_kill_urb" }, - { 0x7f02188f, "__msecs_to_jiffies" }, - { 0xadd72fe9, "usb_free_urb" }, - { 0x4a3ad70e, "wait_for_completion_timeout" }, - { 0xedb8a9, "usb_submit_urb" }, - { 0x608741b5, "__init_swait_queue_head" }, - { 0x4a0c79b0, "hid_hw_stop" }, - { 0x59e59766, "_dev_info" }, - { 0xbdfb6dbb, "__fentry__" }, -}; - -MODULE_INFO(depends, "hid,usbcore"); +MODULE_INFO(depends, "hid"); MODULE_ALIAS("hid:b0003g*v0000044Fp0000B65D"); + +MODULE_INFO(srcversion, "49C62A898823BBE8124B035"); diff --git a/hid-tminit.mod.o b/hid-tminit.mod.o index ae7e374..ce3c467 100644 Binary files a/hid-tminit.mod.o and b/hid-tminit.mod.o differ diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c index bab04ec..8b002c7 100644 --- a/hid-tmt300rs.c +++ b/hid-tmt300rs.c @@ -38,6 +38,9 @@ static int t300rs_send_int(struct input_dev *dev, u8 *send_buffer, int *trans){ struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC); t300rs = t300rs_get_device(hdev); + if(!t300rs){ + hid_err(hdev, "could not get device\n"); + } usbdev = t300rs->usbdev; usbif = t300rs->usbif; @@ -495,11 +498,11 @@ static enum hrtimer_restart t300rs_timer(struct hrtimer *t){ struct t300rs_device_entry *t300rs = container_of(t, struct t300rs_device_entry, hrtimer); int max_count; - spin_lock_irqsave(&t300rs->lock, t300rs->lock_flags); + spin_lock_irqsave(&data_lock, data_flags); max_count = t300rs_timer_helper(t300rs); - spin_unlock_irqrestore(&t300rs->lock, t300rs->lock_flags); + spin_unlock_irqrestore(&data_lock, data_flags); if(max_count > 0){ hrtimer_forward_now(&t300rs->hrtimer, ms_to_ktime(timer_msecs)); @@ -663,10 +666,13 @@ static void t300rs_destroy(struct ff_device *ff){ static int t300rs_open(struct input_dev *dev){ + struct t300rs_device_entry *t300rs; struct hid_device *hdev = input_get_drvdata(dev); u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); int ret, trans; + t300rs = t300rs_get_device(hdev); + send_buffer[0] = 0x60; send_buffer[1] = 0x01; send_buffer[2] = 0x04; @@ -705,14 +711,17 @@ static int t300rs_open(struct input_dev *dev){ err: kfree(send_buffer); - return ret; + return t300rs->open(dev); } -/*static void t300rs_close(struct input_dev *dev){ +static void t300rs_close(struct input_dev *dev){ int ret, trans; struct hid_device *hdev = input_get_drvdata(dev); + struct t300rs_device_entry *t300rs; u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); + t300rs = t300rs_get_device(hdev); + send_buffer[0] = 0x60; send_buffer[1] = 0x01; @@ -723,8 +732,10 @@ err: } err: kfree(send_buffer); + + t300rs->close(dev); return; -}*/ +} int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ struct t300rs_device_entry *t300rs; @@ -841,8 +852,11 @@ int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ ff->set_autocenter = t300rs_set_autocenter; ff->destroy = t300rs_destroy; - /* input_dev->open = t300rs_open; - input_dev->close = t300rs_close; */ + t300rs->open = input_dev->open; + t300rs->close = input_dev->close; + + input_dev->open = t300rs_open; + input_dev->close = t300rs_close; ret = device_create_file(&hdev->dev, &dev_attr_range); if(ret){ @@ -874,53 +888,6 @@ err: } -/* for some reason this specific command must be sent before hid_hw_start. Odd. - * */ -static int t300rs_preinit(struct hid_device *hdev){ - int ret; - u8 *setup_packet, *send_buffer; - - /* this is sort of unnecessary, as later on I compile the interfaces etc - * into one struct, but for now this will do - * */ - struct device *dev = &hdev->dev; - struct usb_interface *usbif = to_usb_interface(dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - struct urb *urb; - - setup_packet = kmalloc(8, GFP_ATOMIC); - send_buffer = kzalloc(8, GFP_ATOMIC); - - memcpy(setup_packet, t300rs_ctrl_out, ARRAY_SIZE(t300rs_ctrl_out)); - urb = usb_alloc_urb(0, GFP_ATOMIC); - - usb_fill_control_urb(urb, - usbdev, - usb_sndctrlpipe(usbdev, 0), - setup_packet, - /* why is it important we have a pointer, when we send out 0 bytes? - * No clue. - * */ - send_buffer, - 0, - /* technically speaking this isn't an interrupt usb, but hey, this - * works. - * */ - t300rs_int_callback, - hdev); - - ret = usb_submit_urb(urb, GFP_ATOMIC); - if(ret != 0){ - hid_err(hdev, "Failed sending ctrl out with ERRNO: %i", ret); - goto error; - } - -error: - kfree(send_buffer); - kfree(setup_packet); - return ret; -} - static int t300rs_probe(struct hid_device *hdev, const struct hid_device_id *id){ int ret; struct t300rs_data *drv_data; @@ -943,9 +910,6 @@ static int t300rs_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err; } - /* lord have mercy */ - //t300rs_preinit(hdev); - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if(ret){ hid_err(hdev, "hw start failed\n"); @@ -969,20 +933,21 @@ static void t300rs_remove(struct hid_device *hdev){ struct t300rs_device_entry *t300rs; struct t300rs_data *drv_data; - spin_lock_irqsave(&lock, lock_flags); device_remove_file(&hdev->dev, &dev_attr_range); drv_data = hid_get_drvdata(hdev); t300rs = t300rs_get_device(hdev); + spin_lock_irqsave(&data_lock, data_flags); + hrtimer_cancel(&t300rs->hrtimer); + hid_hw_stop(hdev); kfree(t300rs->states); kfree(drv_data); kfree(t300rs); - hid_hw_stop(hdev); - spin_unlock_irqrestore(&lock, lock_flags); + spin_unlock_irqrestore(&data_lock, data_flags); return; } diff --git a/hid-tmt300rs.h b/hid-tmt300rs.h index b308627..f3c8d97 100644 --- a/hid-tmt300rs.h +++ b/hid-tmt300rs.h @@ -21,6 +21,9 @@ spinlock_t lock; unsigned long lock_flags; +spinlock_t data_lock; +unsigned long data_flags; + static int timer_msecs = DEFAULT_TIMER_PERIOD; static const signed short t300rs_ff_effects[] = { @@ -58,6 +61,9 @@ struct t300rs_device_entry { struct t300rs_effect_state *states; struct hrtimer hrtimer; + int (*open)(struct input_dev *dev); + void (*close)(struct input_dev *dev); + spinlock_t lock; unsigned long lock_flags; diff --git a/hid-tmt300rs.ko b/hid-tmt300rs.ko index 07d01f3..4a7c06a 100644 Binary files a/hid-tmt300rs.ko and b/hid-tmt300rs.ko differ diff --git a/hid-tmt300rs.mod b/hid-tmt300rs.mod index 8a429e9..92bd18f 100644 --- a/hid-tmt300rs.mod +++ b/hid-tmt300rs.mod @@ -1,2 +1,2 @@ -/home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.o +/home/kimi/Documents/tmff2/hid-tmt300rs.o diff --git a/hid-tmt300rs.mod.c b/hid-tmt300rs.mod.c index a114b1d..7d03495 100644 --- a/hid-tmt300rs.mod.c +++ b/hid-tmt300rs.mod.c @@ -1,5 +1,5 @@ -#include #include +#include #include #include @@ -22,46 +22,8 @@ __section(.gnu.linkonce.this_module) = { MODULE_INFO(retpoline, "Y"); #endif -static const struct modversion_info ____versions[] -__used __section(__versions) = { - { 0x7ca88ad8, "module_layout" }, - { 0x817489f6, "hid_unregister_driver" }, - { 0xb7aa9422, "__hid_register_driver" }, - { 0x414fc2a1, "hid_hw_start" }, - { 0xcd9e657d, "hid_open_report" }, - { 0x59e59766, "_dev_info" }, - { 0x1ee7d3cd, "hrtimer_init" }, - { 0x7d42edf, "device_create_file" }, - { 0xb3e1146a, "input_ff_create" }, - { 0x70bce9a, "__dynamic_dev_dbg" }, - { 0xfeba7354, "current_task" }, - { 0x648538a5, "usb_kill_urb" }, - { 0x7f02188f, "__msecs_to_jiffies" }, - { 0x4a3ad70e, "wait_for_completion_timeout" }, - { 0x608741b5, "__init_swait_queue_head" }, - { 0xdecd0b29, "__stack_chk_fail" }, - { 0xdc21e866, "hrtimer_forward" }, - { 0x2ea2c95c, "__x86_indirect_thunk_rax" }, - { 0x20000329, "simple_strtoul" }, - { 0xc27f683d, "kmem_cache_alloc_trace" }, - { 0x46a9479b, "kmalloc_caches" }, - { 0xedb8a9, "usb_submit_urb" }, - { 0x82fea2ff, "usb_alloc_urb" }, - { 0x4a0c79b0, "hid_hw_stop" }, - { 0x37a0cba, "kfree" }, - { 0xa0c6befa, "hrtimer_cancel" }, - { 0x9c59e5d5, "device_remove_file" }, - { 0xfbdfc558, "hrtimer_start_range_ns" }, - { 0xb4ff6bb6, "hrtimer_active" }, - { 0x15ba50a6, "jiffies" }, - { 0xc85d768e, "_dev_warn" }, - { 0xadd72fe9, "usb_free_urb" }, - { 0x316d1bda, "_dev_err" }, - { 0x3812050a, "_raw_spin_unlock_irqrestore" }, - { 0x51760917, "_raw_spin_lock_irqsave" }, - { 0xbdfb6dbb, "__fentry__" }, -}; - -MODULE_INFO(depends, "hid,usbcore"); +MODULE_INFO(depends, "hid"); MODULE_ALIAS("hid:b0003g*v0000044Fp0000B66E"); + +MODULE_INFO(srcversion, "8A85E6A9A9E4442C81CA1CE"); diff --git a/hid-tmt300rs.mod.o b/hid-tmt300rs.mod.o index 5ab5b8c..f761a52 100644 Binary files a/hid-tmt300rs.mod.o and b/hid-tmt300rs.mod.o differ diff --git a/hid-tmt300rs.o b/hid-tmt300rs.o index a01b321..bc2808c 100644 Binary files a/hid-tmt300rs.o and b/hid-tmt300rs.o differ diff --git a/modules.order b/modules.order index a0e2376..0be5217 100644 --- a/modules.order +++ b/modules.order @@ -1,2 +1,2 @@ -/home/kimi/Documents/Projects/hid-tmff2/hid-tminit.ko -/home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.ko +/home/kimi/Documents/tmff2/hid-tminit.ko +/home/kimi/Documents/tmff2/hid-tmt300rs.ko -- cgit v1.3 From ad6e7105b52363912618084f8268606eaad89ed3 Mon Sep 17 00:00:00 2001 From: kimi Date: Fri, 10 Jul 2020 12:49:02 -0400 Subject: removed unneccessary files, I don't know how they got there --- hid-tminit.ko | Bin 280264 -> 0 bytes hid-tminit.mod | 2 -- hid-tminit.mod.c | 29 ----------------------------- hid-tminit.mod.o | Bin 2904 -> 0 bytes hid-tminit.o | Bin 278312 -> 0 bytes hid-tmt300rs.c | 18 ++++-------------- hid-tmt300rs.h | 5 ----- hid-tmt300rs.ko | Bin 26560 -> 0 bytes hid-tmt300rs.mod | 2 -- hid-tmt300rs.mod.c | 29 ----------------------------- hid-tmt300rs.mod.o | Bin 2912 -> 0 bytes hid-tmt300rs.o | Bin 24568 -> 0 bytes 12 files changed, 4 insertions(+), 81 deletions(-) delete mode 100644 hid-tminit.ko delete mode 100644 hid-tminit.mod delete mode 100644 hid-tminit.mod.c delete mode 100644 hid-tminit.mod.o delete mode 100644 hid-tminit.o delete mode 100644 hid-tmt300rs.ko delete mode 100644 hid-tmt300rs.mod delete mode 100644 hid-tmt300rs.mod.c delete mode 100644 hid-tmt300rs.mod.o delete mode 100644 hid-tmt300rs.o diff --git a/hid-tminit.ko b/hid-tminit.ko deleted file mode 100644 index 763336c..0000000 Binary files a/hid-tminit.ko and /dev/null differ diff --git a/hid-tminit.mod b/hid-tminit.mod deleted file mode 100644 index 858ad57..0000000 --- a/hid-tminit.mod +++ /dev/null @@ -1,2 +0,0 @@ -/home/kimi/Documents/tmff2/hid-tminit.o - diff --git a/hid-tminit.mod.c b/hid-tminit.mod.c deleted file mode 100644 index dbd2e54..0000000 --- a/hid-tminit.mod.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include -#include - -BUILD_SALT; - -MODULE_INFO(vermagic, VERMAGIC_STRING); -MODULE_INFO(name, KBUILD_MODNAME); - -__visible struct module __this_module -__section(.gnu.linkonce.this_module) = { - .name = KBUILD_MODNAME, - .init = init_module, -#ifdef CONFIG_MODULE_UNLOAD - .exit = cleanup_module, -#endif - .arch = MODULE_ARCH_INIT, -}; - -#ifdef CONFIG_RETPOLINE -MODULE_INFO(retpoline, "Y"); -#endif - -MODULE_INFO(depends, "hid"); - -MODULE_ALIAS("hid:b0003g*v0000044Fp0000B65D"); - -MODULE_INFO(srcversion, "49C62A898823BBE8124B035"); diff --git a/hid-tminit.mod.o b/hid-tminit.mod.o deleted file mode 100644 index ce3c467..0000000 Binary files a/hid-tminit.mod.o and /dev/null differ diff --git a/hid-tminit.o b/hid-tminit.o deleted file mode 100644 index ae3404b..0000000 Binary files a/hid-tminit.o and /dev/null differ diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c index 8b002c7..e29ede8 100644 --- a/hid-tmt300rs.c +++ b/hid-tmt300rs.c @@ -498,12 +498,8 @@ static enum hrtimer_restart t300rs_timer(struct hrtimer *t){ struct t300rs_device_entry *t300rs = container_of(t, struct t300rs_device_entry, hrtimer); int max_count; - spin_lock_irqsave(&data_lock, data_flags); - max_count = t300rs_timer_helper(t300rs); - spin_unlock_irqrestore(&data_lock, data_flags); - if(max_count > 0){ hrtimer_forward_now(&t300rs->hrtimer, ms_to_ktime(timer_msecs)); return HRTIMER_RESTART; @@ -719,7 +715,7 @@ static void t300rs_close(struct input_dev *dev){ struct hid_device *hdev = input_get_drvdata(dev); struct t300rs_device_entry *t300rs; u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - + t300rs = t300rs_get_device(hdev); send_buffer[0] = 0x60; @@ -732,7 +728,6 @@ static void t300rs_close(struct input_dev *dev){ } err: kfree(send_buffer); - t300rs->close(dev); return; } @@ -783,7 +778,6 @@ int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ drv_data->device_props = t300rs; - report_list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list; list_for_each_entry(report, report_list, list){ int fieldnum; @@ -867,12 +861,12 @@ int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ hrtimer_init(&t300rs->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); t300rs->hrtimer.function = t300rs_timer; - + + spin_unlock_irqrestore(&lock, lock_flags); t300rs_range_store(dev, &dev_attr_range, range, 10); t300rs_set_gain(input_dev, 0xffff); - t300rs_open(input_dev); hid_info(hdev, "force feedback for T300RS\n"); return 0; @@ -893,6 +887,7 @@ static int t300rs_probe(struct hid_device *hdev, const struct hid_device_id *id) struct t300rs_data *drv_data; spin_lock_init(&lock); + spin_lock_irqsave(&lock, lock_flags); drv_data = kzalloc(sizeof(struct t300rs_data), GFP_ATOMIC); if(!drv_data){ @@ -921,7 +916,6 @@ static int t300rs_probe(struct hid_device *hdev, const struct hid_device_id *id) hid_err(hdev, "t300rs_init failed\n"); goto err; } - return 0; err: kfree(drv_data); @@ -938,8 +932,6 @@ static void t300rs_remove(struct hid_device *hdev){ drv_data = hid_get_drvdata(hdev); t300rs = t300rs_get_device(hdev); - spin_lock_irqsave(&data_lock, data_flags); - hrtimer_cancel(&t300rs->hrtimer); hid_hw_stop(hdev); @@ -947,8 +939,6 @@ static void t300rs_remove(struct hid_device *hdev){ kfree(drv_data); kfree(t300rs); - spin_unlock_irqrestore(&data_lock, data_flags); - return; } diff --git a/hid-tmt300rs.h b/hid-tmt300rs.h index f3c8d97..ccdea78 100644 --- a/hid-tmt300rs.h +++ b/hid-tmt300rs.h @@ -21,9 +21,6 @@ spinlock_t lock; unsigned long lock_flags; -spinlock_t data_lock; -unsigned long data_flags; - static int timer_msecs = DEFAULT_TIMER_PERIOD; static const signed short t300rs_ff_effects[] = { @@ -87,5 +84,3 @@ static u8 spring_values[] = { static u8 damper_values[] = { 0xfc, 0x7f, 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0xfc, 0x7f, 0x07 }; - -static u8 t300rs_ctrl_out[] = { 0x41, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, }; diff --git a/hid-tmt300rs.ko b/hid-tmt300rs.ko deleted file mode 100644 index 4a7c06a..0000000 Binary files a/hid-tmt300rs.ko and /dev/null differ diff --git a/hid-tmt300rs.mod b/hid-tmt300rs.mod deleted file mode 100644 index 92bd18f..0000000 --- a/hid-tmt300rs.mod +++ /dev/null @@ -1,2 +0,0 @@ -/home/kimi/Documents/tmff2/hid-tmt300rs.o - diff --git a/hid-tmt300rs.mod.c b/hid-tmt300rs.mod.c deleted file mode 100644 index 7d03495..0000000 --- a/hid-tmt300rs.mod.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include -#include - -BUILD_SALT; - -MODULE_INFO(vermagic, VERMAGIC_STRING); -MODULE_INFO(name, KBUILD_MODNAME); - -__visible struct module __this_module -__section(.gnu.linkonce.this_module) = { - .name = KBUILD_MODNAME, - .init = init_module, -#ifdef CONFIG_MODULE_UNLOAD - .exit = cleanup_module, -#endif - .arch = MODULE_ARCH_INIT, -}; - -#ifdef CONFIG_RETPOLINE -MODULE_INFO(retpoline, "Y"); -#endif - -MODULE_INFO(depends, "hid"); - -MODULE_ALIAS("hid:b0003g*v0000044Fp0000B66E"); - -MODULE_INFO(srcversion, "8A85E6A9A9E4442C81CA1CE"); diff --git a/hid-tmt300rs.mod.o b/hid-tmt300rs.mod.o deleted file mode 100644 index f761a52..0000000 Binary files a/hid-tmt300rs.mod.o and /dev/null differ diff --git a/hid-tmt300rs.o b/hid-tmt300rs.o deleted file mode 100644 index bc2808c..0000000 Binary files a/hid-tmt300rs.o and /dev/null differ -- cgit v1.3 From 5ae25b0620e2601244114ac795598df1392f2f38 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Fri, 10 Jul 2020 20:24:23 +0300 Subject: usable state --- compile_commands.json | 40 +++++++++++------------------- hid-tminit.ko | Bin 0 -> 419984 bytes hid-tminit.mod | 2 ++ hid-tminit.mod.c | 55 +++++++++++++++++++++++++++++++++++++++++ hid-tminit.mod.o | Bin 0 -> 143264 bytes hid-tminit.o | Bin 0 -> 278312 bytes hid-tmt300rs.c | 41 ++++++++++++++++++++++++------ hid-tmt300rs.ko | Bin 0 -> 533720 bytes hid-tmt300rs.mod | 2 ++ hid-tmt300rs.mod.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ hid-tmt300rs.mod.o | Bin 0 -> 144040 bytes hid-tmt300rs.o | Bin 0 -> 391280 bytes modules.order | 4 +-- 13 files changed, 176 insertions(+), 35 deletions(-) create mode 100644 hid-tminit.ko create mode 100644 hid-tminit.mod create mode 100644 hid-tminit.mod.c create mode 100644 hid-tminit.mod.o create mode 100644 hid-tminit.o create mode 100644 hid-tmt300rs.ko create mode 100644 hid-tmt300rs.mod create mode 100644 hid-tmt300rs.mod.c create mode 100644 hid-tmt300rs.mod.o create mode 100644 hid-tmt300rs.o diff --git a/compile_commands.json b/compile_commands.json index 56b8bee..a75ead3 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -1,24 +1,24 @@ [ { "arguments": [ - "gcc", + "gcc-9", "-c", - "-Wp,-MD,/home/kimi/Documents/tmff2/.hid-tmt300rs.o.d", + "-Wp,-MD,/home/kimi/Documents/Projects/hid-tmff2/.hid-tmt300rs.o.d", "-nostdinc", "-isystem", "/usr/lib/gcc/x86_64-linux-gnu/9/include", - "-I./arch/x86/include", + "-I/usr/src/linux-headers-5.7.0-1-common/arch/x86/include", "-I./arch/x86/include/generated", + "-I/usr/src/linux-headers-5.7.0-1-common/include", "-I./include", - "-I./arch/x86/include/uapi", + "-I/usr/src/linux-headers-5.7.0-1-common/arch/x86/include/uapi", "-I./arch/x86/include/generated/uapi", - "-I./include/uapi", + "-I/usr/src/linux-headers-5.7.0-1-common/include/uapi", "-I./include/generated/uapi", "-include", - "./include/linux/kconfig.h", - "-Iubuntu/include", + "/usr/src/linux-headers-5.7.0-1-common/include/linux/kconfig.h", "-include", - "./include/linux/compiler_types.h", + "/usr/src/linux-headers-5.7.0-1-common/include/linux/compiler_types.h", "-D__KERNEL__", "-Wall", "-Wundef", @@ -48,15 +48,6 @@ "-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", @@ -69,14 +60,13 @@ "-Wno-address-of-packed-member", "-O2", "--param=allow-store-data-races=0", - "-Wframe-larger-than=1024", + "-Wframe-larger-than=2048", "-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", @@ -98,17 +88,17 @@ "-Werror=date-time", "-Werror=incompatible-pointer-types", "-Werror=designated-init", - "-fmacro-prefix-map=./=", + "-fmacro-prefix-map=/usr/src/linux-headers-5.7.0-1-common/=", "-fcf-protection=none", "-Wno-packed-not-aligned", "-DMODULE", "-DKBUILD_BASENAME=\"hid_tmt300rs\"", "-DKBUILD_MODNAME=\"hid_tmt300rs\"", "-o", - "/home/kimi/Documents/tmff2/hid-tmt300rs.o", - "../../../home/kimi/Documents/tmff2/hid-tmt300rs.c" + "/home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.o", + "../../../home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.c" ], - "directory": "/usr/src/linux-headers-5.4.0-40-generic", - "file": "../../../home/kimi/Documents/tmff2/hid-tmt300rs.c" + "directory": "/usr/src/linux-headers-5.7.0-1-amd64", + "file": "../../../home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.c" } ] \ No newline at end of file diff --git a/hid-tminit.ko b/hid-tminit.ko new file mode 100644 index 0000000..f7a0f97 Binary files /dev/null and b/hid-tminit.ko differ diff --git a/hid-tminit.mod b/hid-tminit.mod new file mode 100644 index 0000000..821c012 --- /dev/null +++ b/hid-tminit.mod @@ -0,0 +1,2 @@ +/home/kimi/Documents/Projects/hid-tmff2/hid-tminit.o + diff --git a/hid-tminit.mod.c b/hid-tminit.mod.c new file mode 100644 index 0000000..7029581 --- /dev/null +++ b/hid-tminit.mod.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +BUILD_SALT; + +MODULE_INFO(vermagic, VERMAGIC_STRING); +MODULE_INFO(name, KBUILD_MODNAME); + +__visible struct module __this_module +__section(.gnu.linkonce.this_module) = { + .name = KBUILD_MODNAME, + .init = init_module, +#ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module, +#endif + .arch = MODULE_ARCH_INIT, +}; + +#ifdef CONFIG_RETPOLINE +MODULE_INFO(retpoline, "Y"); +#endif + +static const struct modversion_info ____versions[] +__used __section(__versions) = { + { 0x7ca88ad8, "module_layout" }, + { 0x817489f6, "hid_unregister_driver" }, + { 0xb7aa9422, "__hid_register_driver" }, + { 0x414fc2a1, "hid_hw_start" }, + { 0xcd9e657d, "hid_open_report" }, + { 0x316d1bda, "_dev_err" }, + { 0xdecd0b29, "__stack_chk_fail" }, + { 0x37a0cba, "kfree" }, + { 0x82fea2ff, "usb_alloc_urb" }, + { 0xc30561e7, "usb_interrupt_msg" }, + { 0x69acdf38, "memcpy" }, + { 0xc27f683d, "kmem_cache_alloc_trace" }, + { 0x46a9479b, "kmalloc_caches" }, + { 0x70bce9a, "__dynamic_dev_dbg" }, + { 0xfeba7354, "current_task" }, + { 0x648538a5, "usb_kill_urb" }, + { 0x7f02188f, "__msecs_to_jiffies" }, + { 0xadd72fe9, "usb_free_urb" }, + { 0x4a3ad70e, "wait_for_completion_timeout" }, + { 0xedb8a9, "usb_submit_urb" }, + { 0x608741b5, "__init_swait_queue_head" }, + { 0x4a0c79b0, "hid_hw_stop" }, + { 0x59e59766, "_dev_info" }, + { 0xbdfb6dbb, "__fentry__" }, +}; + +MODULE_INFO(depends, "hid,usbcore"); + +MODULE_ALIAS("hid:b0003g*v0000044Fp0000B65D"); diff --git a/hid-tminit.mod.o b/hid-tminit.mod.o new file mode 100644 index 0000000..ae7e374 Binary files /dev/null and b/hid-tminit.mod.o differ diff --git a/hid-tminit.o b/hid-tminit.o new file mode 100644 index 0000000..ae3404b Binary files /dev/null and b/hid-tminit.o differ diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c index e29ede8..39747cd 100644 --- a/hid-tmt300rs.c +++ b/hid-tmt300rs.c @@ -124,10 +124,15 @@ static int t300rs_upload_constant(struct t300rs_device_entry *t300rs, struct t30 u16 duration, le_offset, le_duration; int ret, trans; - + + /* currently this driver doesn't support dynamic effect updating quite like + * many games would assume. There's not a huge drawback to this method, the + * wheel maybe feels a bit more jittery because of this but it's not a + * massive downside. At some point in the future I'd like to improve the + * dynamic updating, but this will do for now. + * */ if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ t300rs_stop_effect(t300rs, state); - __clear_bit(FF_EFFECT_PLAYING, &state->flags); } level = (constant.level * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; @@ -162,6 +167,11 @@ static int t300rs_upload_constant(struct t300rs_device_entry *t300rs, struct t30 if(ret){ hid_err(t300rs->hdev, "failed uploading constant effect\n"); } + + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + t300rs_play_effect(t300rs, state); + } + kfree(send_buffer); return ret; } @@ -176,7 +186,6 @@ static int t300rs_upload_ramp(struct t300rs_device_entry *t300rs, struct t300rs_ if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ t300rs_stop_effect(t300rs, state); - __clear_bit(FF_EFFECT_PLAYING, &state->flags); } top = ramp.end_level > ramp.start_level ? ramp.end_level : ramp.start_level; @@ -225,6 +234,11 @@ static int t300rs_upload_ramp(struct t300rs_device_entry *t300rs, struct t300rs_ if(ret){ hid_err(t300rs->hdev, "failed uploading ramp"); } + + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + t300rs_play_effect(t300rs, state); + } + kfree(send_buffer); return ret; } @@ -240,7 +254,6 @@ static int t300rs_upload_spring(struct t300rs_device_entry *t300rs, struct t300r if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ t300rs_stop_effect(t300rs, state); - __clear_bit(FF_EFFECT_PLAYING, &state->flags); } send_buffer[0] = 0x60; @@ -284,6 +297,11 @@ static int t300rs_upload_spring(struct t300rs_device_entry *t300rs, struct t300r if(ret){ hid_err(t300rs->hdev, "failed uploading spring\n"); } + + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + t300rs_play_effect(t300rs, state); + } + kfree(send_buffer); return ret; } @@ -299,7 +317,6 @@ static int t300rs_upload_damper(struct t300rs_device_entry *t300rs, struct t300r if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ t300rs_stop_effect(t300rs, state); - __clear_bit(FF_EFFECT_PLAYING, &state->flags); } send_buffer[0] = 0x60; @@ -343,6 +360,11 @@ static int t300rs_upload_damper(struct t300rs_device_entry *t300rs, struct t300r if(ret){ hid_err(t300rs->hdev, "failed uploading spring\n"); } + + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + t300rs_play_effect(t300rs, state); + } + kfree(send_buffer); return ret; } @@ -357,7 +379,6 @@ static int t300rs_upload_periodic(struct t300rs_device_entry *t300rs, struct t30 if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ t300rs_stop_effect(t300rs, state); - __clear_bit(FF_EFFECT_PLAYING, &state->flags); } magnitude = (periodic.magnitude * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; @@ -406,7 +427,11 @@ static int t300rs_upload_periodic(struct t300rs_device_entry *t300rs, struct t30 if(ret){ hid_err(t300rs->hdev, "failed uploading periodic effect"); } - + + if(test_bit(FF_EFFECT_PLAYING, &state->flags)){ + t300rs_play_effect(t300rs, state); + } + kfree(send_buffer); return ret; } @@ -426,7 +451,7 @@ static int t300rs_upload_effect(struct t300rs_device_entry *t300rs, struct t300r case FF_PERIODIC: return t300rs_upload_periodic(t300rs, state); default: - hid_err(t300rs->hdev, "invalid effect type"); + hid_err(t300rs->hdev, "invalid effect type: %x", state->effect.type); return -1; } } diff --git a/hid-tmt300rs.ko b/hid-tmt300rs.ko new file mode 100644 index 0000000..39f2a45 Binary files /dev/null and b/hid-tmt300rs.ko differ diff --git a/hid-tmt300rs.mod b/hid-tmt300rs.mod new file mode 100644 index 0000000..8a429e9 --- /dev/null +++ b/hid-tmt300rs.mod @@ -0,0 +1,2 @@ +/home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.o + diff --git a/hid-tmt300rs.mod.c b/hid-tmt300rs.mod.c new file mode 100644 index 0000000..25ad51d --- /dev/null +++ b/hid-tmt300rs.mod.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include + +BUILD_SALT; + +MODULE_INFO(vermagic, VERMAGIC_STRING); +MODULE_INFO(name, KBUILD_MODNAME); + +__visible struct module __this_module +__section(.gnu.linkonce.this_module) = { + .name = KBUILD_MODNAME, + .init = init_module, +#ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module, +#endif + .arch = MODULE_ARCH_INIT, +}; + +#ifdef CONFIG_RETPOLINE +MODULE_INFO(retpoline, "Y"); +#endif + +static const struct modversion_info ____versions[] +__used __section(__versions) = { + { 0x7ca88ad8, "module_layout" }, + { 0x817489f6, "hid_unregister_driver" }, + { 0xb7aa9422, "__hid_register_driver" }, + { 0x414fc2a1, "hid_hw_start" }, + { 0xcd9e657d, "hid_open_report" }, + { 0x59e59766, "_dev_info" }, + { 0x1ee7d3cd, "hrtimer_init" }, + { 0x7d42edf, "device_create_file" }, + { 0xb3e1146a, "input_ff_create" }, + { 0x70bce9a, "__dynamic_dev_dbg" }, + { 0xfeba7354, "current_task" }, + { 0x648538a5, "usb_kill_urb" }, + { 0x7f02188f, "__msecs_to_jiffies" }, + { 0x4a3ad70e, "wait_for_completion_timeout" }, + { 0x608741b5, "__init_swait_queue_head" }, + { 0xdecd0b29, "__stack_chk_fail" }, + { 0xdc21e866, "hrtimer_forward" }, + { 0x20000329, "simple_strtoul" }, + { 0x2ea2c95c, "__x86_indirect_thunk_rax" }, + { 0xc27f683d, "kmem_cache_alloc_trace" }, + { 0x46a9479b, "kmalloc_caches" }, + { 0xedb8a9, "usb_submit_urb" }, + { 0x82fea2ff, "usb_alloc_urb" }, + { 0x37a0cba, "kfree" }, + { 0x4a0c79b0, "hid_hw_stop" }, + { 0xa0c6befa, "hrtimer_cancel" }, + { 0x9c59e5d5, "device_remove_file" }, + { 0xfbdfc558, "hrtimer_start_range_ns" }, + { 0xb4ff6bb6, "hrtimer_active" }, + { 0x15ba50a6, "jiffies" }, + { 0xc85d768e, "_dev_warn" }, + { 0xadd72fe9, "usb_free_urb" }, + { 0x316d1bda, "_dev_err" }, + { 0x3812050a, "_raw_spin_unlock_irqrestore" }, + { 0x51760917, "_raw_spin_lock_irqsave" }, + { 0xbdfb6dbb, "__fentry__" }, +}; + +MODULE_INFO(depends, "hid,usbcore"); + +MODULE_ALIAS("hid:b0003g*v0000044Fp0000B66E"); diff --git a/hid-tmt300rs.mod.o b/hid-tmt300rs.mod.o new file mode 100644 index 0000000..6f6c16d Binary files /dev/null and b/hid-tmt300rs.mod.o differ diff --git a/hid-tmt300rs.o b/hid-tmt300rs.o new file mode 100644 index 0000000..7cf277f Binary files /dev/null and b/hid-tmt300rs.o differ diff --git a/modules.order b/modules.order index 0be5217..a0e2376 100644 --- a/modules.order +++ b/modules.order @@ -1,2 +1,2 @@ -/home/kimi/Documents/tmff2/hid-tminit.ko -/home/kimi/Documents/tmff2/hid-tmt300rs.ko +/home/kimi/Documents/Projects/hid-tmff2/hid-tminit.ko +/home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.ko -- cgit v1.3 From 5a5eea18a530d2b931761992d3a27925843a75e5 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Fri, 10 Jul 2020 20:25:55 +0300 Subject: fixup! usable state usable state --- Module.symvers | 0 hid-tminit.ko | Bin 419984 -> 0 bytes hid-tminit.mod | 2 -- hid-tminit.mod.c | 55 ------------------------------------------- hid-tminit.mod.o | Bin 143264 -> 0 bytes hid-tminit.o | Bin 278312 -> 0 bytes hid-tmt300rs.ko | Bin 533720 -> 0 bytes hid-tmt300rs.mod | 2 -- hid-tmt300rs.mod.c | 67 ----------------------------------------------------- hid-tmt300rs.mod.o | Bin 144040 -> 0 bytes hid-tmt300rs.o | Bin 391280 -> 0 bytes modules.order | 2 -- 12 files changed, 128 deletions(-) delete mode 100644 Module.symvers delete mode 100644 hid-tminit.ko delete mode 100644 hid-tminit.mod delete mode 100644 hid-tminit.mod.c delete mode 100644 hid-tminit.mod.o delete mode 100644 hid-tminit.o delete mode 100644 hid-tmt300rs.ko delete mode 100644 hid-tmt300rs.mod delete mode 100644 hid-tmt300rs.mod.c delete mode 100644 hid-tmt300rs.mod.o delete mode 100644 hid-tmt300rs.o delete mode 100644 modules.order diff --git a/Module.symvers b/Module.symvers deleted file mode 100644 index e69de29..0000000 diff --git a/hid-tminit.ko b/hid-tminit.ko deleted file mode 100644 index f7a0f97..0000000 Binary files a/hid-tminit.ko and /dev/null differ diff --git a/hid-tminit.mod b/hid-tminit.mod deleted file mode 100644 index 821c012..0000000 --- a/hid-tminit.mod +++ /dev/null @@ -1,2 +0,0 @@ -/home/kimi/Documents/Projects/hid-tmff2/hid-tminit.o - diff --git a/hid-tminit.mod.c b/hid-tminit.mod.c deleted file mode 100644 index 7029581..0000000 --- a/hid-tminit.mod.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include -#include - -BUILD_SALT; - -MODULE_INFO(vermagic, VERMAGIC_STRING); -MODULE_INFO(name, KBUILD_MODNAME); - -__visible struct module __this_module -__section(.gnu.linkonce.this_module) = { - .name = KBUILD_MODNAME, - .init = init_module, -#ifdef CONFIG_MODULE_UNLOAD - .exit = cleanup_module, -#endif - .arch = MODULE_ARCH_INIT, -}; - -#ifdef CONFIG_RETPOLINE -MODULE_INFO(retpoline, "Y"); -#endif - -static const struct modversion_info ____versions[] -__used __section(__versions) = { - { 0x7ca88ad8, "module_layout" }, - { 0x817489f6, "hid_unregister_driver" }, - { 0xb7aa9422, "__hid_register_driver" }, - { 0x414fc2a1, "hid_hw_start" }, - { 0xcd9e657d, "hid_open_report" }, - { 0x316d1bda, "_dev_err" }, - { 0xdecd0b29, "__stack_chk_fail" }, - { 0x37a0cba, "kfree" }, - { 0x82fea2ff, "usb_alloc_urb" }, - { 0xc30561e7, "usb_interrupt_msg" }, - { 0x69acdf38, "memcpy" }, - { 0xc27f683d, "kmem_cache_alloc_trace" }, - { 0x46a9479b, "kmalloc_caches" }, - { 0x70bce9a, "__dynamic_dev_dbg" }, - { 0xfeba7354, "current_task" }, - { 0x648538a5, "usb_kill_urb" }, - { 0x7f02188f, "__msecs_to_jiffies" }, - { 0xadd72fe9, "usb_free_urb" }, - { 0x4a3ad70e, "wait_for_completion_timeout" }, - { 0xedb8a9, "usb_submit_urb" }, - { 0x608741b5, "__init_swait_queue_head" }, - { 0x4a0c79b0, "hid_hw_stop" }, - { 0x59e59766, "_dev_info" }, - { 0xbdfb6dbb, "__fentry__" }, -}; - -MODULE_INFO(depends, "hid,usbcore"); - -MODULE_ALIAS("hid:b0003g*v0000044Fp0000B65D"); diff --git a/hid-tminit.mod.o b/hid-tminit.mod.o deleted file mode 100644 index ae7e374..0000000 Binary files a/hid-tminit.mod.o and /dev/null differ diff --git a/hid-tminit.o b/hid-tminit.o deleted file mode 100644 index ae3404b..0000000 Binary files a/hid-tminit.o and /dev/null differ diff --git a/hid-tmt300rs.ko b/hid-tmt300rs.ko deleted file mode 100644 index 39f2a45..0000000 Binary files a/hid-tmt300rs.ko and /dev/null differ diff --git a/hid-tmt300rs.mod b/hid-tmt300rs.mod deleted file mode 100644 index 8a429e9..0000000 --- a/hid-tmt300rs.mod +++ /dev/null @@ -1,2 +0,0 @@ -/home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.o - diff --git a/hid-tmt300rs.mod.c b/hid-tmt300rs.mod.c deleted file mode 100644 index 25ad51d..0000000 --- a/hid-tmt300rs.mod.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include -#include - -BUILD_SALT; - -MODULE_INFO(vermagic, VERMAGIC_STRING); -MODULE_INFO(name, KBUILD_MODNAME); - -__visible struct module __this_module -__section(.gnu.linkonce.this_module) = { - .name = KBUILD_MODNAME, - .init = init_module, -#ifdef CONFIG_MODULE_UNLOAD - .exit = cleanup_module, -#endif - .arch = MODULE_ARCH_INIT, -}; - -#ifdef CONFIG_RETPOLINE -MODULE_INFO(retpoline, "Y"); -#endif - -static const struct modversion_info ____versions[] -__used __section(__versions) = { - { 0x7ca88ad8, "module_layout" }, - { 0x817489f6, "hid_unregister_driver" }, - { 0xb7aa9422, "__hid_register_driver" }, - { 0x414fc2a1, "hid_hw_start" }, - { 0xcd9e657d, "hid_open_report" }, - { 0x59e59766, "_dev_info" }, - { 0x1ee7d3cd, "hrtimer_init" }, - { 0x7d42edf, "device_create_file" }, - { 0xb3e1146a, "input_ff_create" }, - { 0x70bce9a, "__dynamic_dev_dbg" }, - { 0xfeba7354, "current_task" }, - { 0x648538a5, "usb_kill_urb" }, - { 0x7f02188f, "__msecs_to_jiffies" }, - { 0x4a3ad70e, "wait_for_completion_timeout" }, - { 0x608741b5, "__init_swait_queue_head" }, - { 0xdecd0b29, "__stack_chk_fail" }, - { 0xdc21e866, "hrtimer_forward" }, - { 0x20000329, "simple_strtoul" }, - { 0x2ea2c95c, "__x86_indirect_thunk_rax" }, - { 0xc27f683d, "kmem_cache_alloc_trace" }, - { 0x46a9479b, "kmalloc_caches" }, - { 0xedb8a9, "usb_submit_urb" }, - { 0x82fea2ff, "usb_alloc_urb" }, - { 0x37a0cba, "kfree" }, - { 0x4a0c79b0, "hid_hw_stop" }, - { 0xa0c6befa, "hrtimer_cancel" }, - { 0x9c59e5d5, "device_remove_file" }, - { 0xfbdfc558, "hrtimer_start_range_ns" }, - { 0xb4ff6bb6, "hrtimer_active" }, - { 0x15ba50a6, "jiffies" }, - { 0xc85d768e, "_dev_warn" }, - { 0xadd72fe9, "usb_free_urb" }, - { 0x316d1bda, "_dev_err" }, - { 0x3812050a, "_raw_spin_unlock_irqrestore" }, - { 0x51760917, "_raw_spin_lock_irqsave" }, - { 0xbdfb6dbb, "__fentry__" }, -}; - -MODULE_INFO(depends, "hid,usbcore"); - -MODULE_ALIAS("hid:b0003g*v0000044Fp0000B66E"); diff --git a/hid-tmt300rs.mod.o b/hid-tmt300rs.mod.o deleted file mode 100644 index 6f6c16d..0000000 Binary files a/hid-tmt300rs.mod.o and /dev/null differ diff --git a/hid-tmt300rs.o b/hid-tmt300rs.o deleted file mode 100644 index 7cf277f..0000000 Binary files a/hid-tmt300rs.o and /dev/null differ diff --git a/modules.order b/modules.order deleted file mode 100644 index a0e2376..0000000 --- a/modules.order +++ /dev/null @@ -1,2 +0,0 @@ -/home/kimi/Documents/Projects/hid-tmff2/hid-tminit.ko -/home/kimi/Documents/Projects/hid-tmff2/hid-tmt300rs.ko -- cgit v1.3 From 4d82a0fdfb95cdea2fd904c3ee33c1c6f603d153 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Fri, 10 Jul 2020 22:02:50 +0300 Subject: updated readme --- README.md | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 589a59f..8de3d4e 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,45 @@ # Linux kernel module for the Thrustmaster T300RS wheel -## General information for the curious: -* This driver is heavily under development, and is currently missing some major features, such as force feedback among many other things. +## Current state -* I try to only push to Github whenever I'm relatively sure the driver won't freeze up the kernel, but I absolutely do not recommend running this driver on your main computer. Set up a virtual machine if you want to test this out. I personally recommend QEMU/libvirt: https://www.qemu.org/download/ + Playable. Dynamic updating of effects isn't baked into the wheel quite as + well as I'd hoped, and so the driver in its current state doesn't really + support it. At some point in the future I'd like to add it to the feature + list, but it will need a lot more research and might take a while. -* In case you want to try installing this driver, it should be fairly simple: - ``` - make - sudo make install - ``` - And possibly some ```sudo depmod -a && sudo modprobe hid-tmff2``` - To see if the driver is being loaded, run ```dmesg```. The feed should be filled with debugging messages that honestly probably should be improved. A lot. + One other issue is that if you have the T3PA pedals, the clutch doesn't seem + to be registered by most(all?) games. It is registered and works as expected + in jstest and jstest-gtk, no clue what that is about. -Update as of 27.06.2020 21:21 + Anycase, *this version is usable in most force feedback games, supports + rangesetting as well as gain and autocentering along with most force feedback effects.** +## Small note + + While I haven't personally come across any crashes or lockups with this + version, I can't promise that they won't occur under any circumstances. -I managed to somewhat successfully play DiRT Rally. The force feedback works, but isn't anywhere near as high quality as on windows. I've experiences some odd cases where the wheel decides to lock up, but it doesn't seem to affect the host computer in any way. No clue why it happens, but they seem to be relatively rare and reseating the USB plug has so far always returned the wheel to a usable state. + With that in mind, -NOTE: I still don't necessarily recommend using this driver, unless you're really desperate for some ffb. I can't promise that this driver won't freeze up your kernel, corrupt all your data and kick your dog. +## Installation + + + Unplug wheel from computer + + `git clone this-repo` + + `make` + + `sudo make install` + + Plug wheel back in + + reboot (not strictly necessary, but recommended) + + Done! + +## Additional tidbits + + + Change range: + + Write a value between 0 and 65535 to + /sys/bus/devices/XXXX:044F:B66E.XXX/range + + + Change autocenter and gain: + + Use the default evdev ways, i.e. https://www.kernel.org/doc/html/v5.1/input/ff.html + + + Currently there is no support for this driver in oversteer(https://github.com/berarma/oversteer), but ffbwrap(https://github.com/berarma/ffbtools) should, at least in theory, work. Although I have to say that I haven't got it to work so far. -- cgit v1.3