From a34e6498f0f606210ed56d5ad53f00602c52be40 Mon Sep 17 00:00:00 2001 From: kimi Date: Sat, 15 Aug 2020 08:47:00 -0400 Subject: fix for kernel panic when initializing T300RS on some setups --- hid-tminit.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'hid-tminit.c') diff --git a/hid-tminit.c b/hid-tminit.c index 219d78c..f0c96e8 100644 --- a/hid-tminit.c +++ b/hid-tminit.c @@ -17,6 +17,46 @@ #include #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), -- cgit v1.3 From d1835027f64168b78e126944c1b84ce846084d99 Mon Sep 17 00:00:00 2001 From: Dario Pagani Date: Sun, 16 Aug 2020 12:04:51 +0200 Subject: Formatting --- hid-tminit.c | 66 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'hid-tminit.c') diff --git a/hid-tminit.c b/hid-tminit.c index f0c96e8..7adabd1 100644 --- a/hid-tminit.c +++ b/hid-tminit.c @@ -23,38 +23,38 @@ * 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); + 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) @@ -208,7 +208,7 @@ 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); + tminit_interrupts(hdev); usb_fill_control_urb( tm_wheel->urb, -- cgit v1.3