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 --- hid-tm.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 hid-tm.h (limited to 'hid-tm.h') 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; +} -- 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(-) (limited to 'hid-tm.h') 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