diff options
Diffstat (limited to 'hid-tminit.c')
| -rw-r--r-- | hid-tminit.c | 79 |
1 files changed, 76 insertions, 3 deletions
diff --git a/hid-tminit.c b/hid-tminit.c index 7f1c657..be62ee8 100644 --- a/hid-tminit.c +++ b/hid-tminit.c @@ -1,9 +1,52 @@ #include "hid-tminit.h" static void tminit_callback(struct urb *urb){ - hid_info(urb->dev, "urb status %d received\n", urb->status); + if(urb->status){ + hid_info(urb->dev, "urb status %d received\n", urb->status); + } + + usb_free_urb(urb); +} + +static int tminit_send_int(struct hid_device *hdev, struct usb_device *usbdev, struct usb_interface *usbif, u8 *send_buffer, int *trans){ + struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC); + struct usb_host_endpoint *ep; + + ep = &usbif->cur_altsetting->endpoint[1]; + + usb_fill_int_urb( + urb, + usbdev, + usb_sndintpipe(usbdev, 1), + send_buffer, + 9, + tminit_callback, + hdev, + ep->desc.bInterval + ); + + return usb_submit_urb(urb, GFP_ATOMIC); } +static int tminit_send_int_in(struct hid_device *hdev, struct usb_device *usbdev, struct usb_interface *usbif, u8 *send_buffer, int *trans){ + struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC); + struct usb_host_endpoint *ep; + + ep = &usbif->cur_altsetting->endpoint[1]; + + usb_fill_int_urb( + urb, + usbdev, + usb_rcvintpipe(usbdev, 2), + send_buffer, + 27, + tminit_callback, + hdev, + ep->desc.bInterval + ); + + return usb_submit_urb(urb, GFP_ATOMIC); +} /* for some godawful reason these interrupts are absolutely necessary, otherwise * the whole kernel crashes. I have no idea why. * */ @@ -19,7 +62,30 @@ static void tminit_interrupts(struct hid_device *hdev){ 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[0], setup_arr_sizes[0]); + ret = usb_interrupt_msg(usbdev, + usb_sndintpipe(usbdev, b_ep), + send_buf, + setup_arr_sizes[0], + &trans, + USB_CTRL_SET_TIMEOUT + ); + + if(ret){ + hid_err(hdev, "setup int couldn't be sent: %i\n", ret); + } + + for(i = 0; i < 4; ++i){ + ret = tminit_send_int_in(hdev, usbdev, usbif, send_buf, trans); + + if(ret){ + hid_err(hdev, "setup int in couldn't be sent: %i\n", ret); + } + } + + msleep(100); + + for(i = 1; i < ARRAY_SIZE(setup_arr); ++i){ memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]); ret = usb_interrupt_msg(usbdev, @@ -27,12 +93,15 @@ static void tminit_interrupts(struct hid_device *hdev){ send_buf, setup_arr_sizes[i], &trans, - USB_CTRL_SET_TIMEOUT); + USB_CTRL_SET_TIMEOUT + ); if(ret){ hid_err(hdev, "setup data couldn't be sent\n"); return; } + + msleep(10); } @@ -140,6 +209,9 @@ int tminit(struct hid_device *hdev){ memcpy(setup_packet, hw_rq_out, 8); memcpy(transfer_buffer, hw_rq_in, 8); + // this is really ugly but it'll work for now I suppose + msleep(200); + ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 73, @@ -154,6 +226,7 @@ int tminit(struct hid_device *hdev){ hid_err(hdev, "failed retrieving 73 after interrupts: %i", ret); } + urb = usb_alloc_urb(0, GFP_ATOMIC); usb_fill_control_urb(urb, |
