diff options
| -rw-r--r-- | hid-tminit.c | 46 | ||||
| -rw-r--r-- | hid-tminit.h | 17 |
2 files changed, 62 insertions, 1 deletions
diff --git a/hid-tminit.c b/hid-tminit.c index 219d78c..7adabd1 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), diff --git a/hid-tminit.h b/hid-tminit.h index 820ca86..c8b664e 100644 --- a/hid-tminit.h +++ b/hid-tminit.h @@ -1,4 +1,21 @@ /** + * These interrupts are used to prevent a nasty crash when initializing the + * T300RS. Used in tminit_interrupts(). + */ +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) +}; +/** * This struct contains for each type of * Thrustmaster wheel * |
