aboutsummaryrefslogtreecommitdiff
path: root/hid-tminit.c
diff options
context:
space:
mode:
Diffstat (limited to 'hid-tminit.c')
-rw-r--r--hid-tminit.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/hid-tminit.c b/hid-tminit.c
index 0719a83..8219ab1 100644
--- a/hid-tminit.c
+++ b/hid-tminit.c
@@ -17,6 +17,46 @@
#include <linux/module.h>
#include "hid-tminit.h"
+/**
+ * On some setups initializing the T300RS crashes the kernel,
+ * these interrupts fix that particular issue. So far they haven't caused any
+ * adverse effects in other wheels.
+ */
+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);
+
+ if(!send_buf){
+ hid_err(hdev, "failed allocating send buffer\n");
+ return;
+ }
+
+ 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;
+ }
+ }
+
+ kzfree(send_buf);
+}
+
static void tminit_change_handler(struct urb *urb)
{
struct hid_device *hdev = urb->context;
@@ -28,6 +68,8 @@ static void tminit_change_handler(struct urb *urb)
hid_err(hdev, "URB to change wheel mode failed with error %d\n", urb->status);
}
+
+
/**
* Called by the USB subsystem when the wheel respons to our request
* to get [what it seems to be] the wheel's model.
@@ -166,10 +208,12 @@ static int tminit_probe(struct hid_device *hdev, const struct hid_device_id *id)
tm_wheel->usb_dev = interface_to_usbdev(to_usb_interface(hdev->dev.parent));
hid_set_drvdata(hdev, tm_wheel);
+ tminit_interrupts(hdev);
+
usb_fill_control_urb(
tm_wheel->urb,
tm_wheel->usb_dev,
- usb_sndctrlpipe(tm_wheel->usb_dev, 0),
+ usb_rcvctrlpipe(tm_wheel->usb_dev, 0),
(char*)tm_wheel->model_request,
tm_wheel->response,
sizeof(struct tm_wheel_response),