aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/usbhid/hid-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/usbhid/hid-core.c')
-rw-r--r--drivers/hid/usbhid/hid-core.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index e2997a8d5e1b..56d06cd8075b 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -5,7 +5,7 @@
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> 5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc 6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7 * Copyright (c) 2007-2008 Oliver Neukum 7 * Copyright (c) 2007-2008 Oliver Neukum
8 * Copyright (c) 2006-2009 Jiri Kosina 8 * Copyright (c) 2006-2010 Jiri Kosina
9 */ 9 */
10 10
11/* 11/*
@@ -316,6 +316,7 @@ static int hid_submit_out(struct hid_device *hid)
316 err_hid("usb_submit_urb(out) failed"); 316 err_hid("usb_submit_urb(out) failed");
317 return -1; 317 return -1;
318 } 318 }
319 usbhid->last_out = jiffies;
319 } else { 320 } else {
320 /* 321 /*
321 * queue work to wake up the device. 322 * queue work to wake up the device.
@@ -377,6 +378,7 @@ static int hid_submit_ctrl(struct hid_device *hid)
377 err_hid("usb_submit_urb(ctrl) failed"); 378 err_hid("usb_submit_urb(ctrl) failed");
378 return -1; 379 return -1;
379 } 380 }
381 usbhid->last_ctrl = jiffies;
380 } else { 382 } else {
381 /* 383 /*
382 * queue work to wake up the device. 384 * queue work to wake up the device.
@@ -512,9 +514,20 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
512 usbhid->out[usbhid->outhead].report = report; 514 usbhid->out[usbhid->outhead].report = report;
513 usbhid->outhead = head; 515 usbhid->outhead = head;
514 516
515 if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) 517 if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) {
516 if (hid_submit_out(hid)) 518 if (hid_submit_out(hid))
517 clear_bit(HID_OUT_RUNNING, &usbhid->iofl); 519 clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
520 } else {
521 /*
522 * the queue is known to run
523 * but an earlier request may be stuck
524 * we may need to time out
525 * no race because this is called under
526 * spinlock
527 */
528 if (time_after(jiffies, usbhid->last_out + HZ * 5))
529 usb_unlink_urb(usbhid->urbout);
530 }
518 return; 531 return;
519 } 532 }
520 533
@@ -535,9 +548,20 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
535 usbhid->ctrl[usbhid->ctrlhead].dir = dir; 548 usbhid->ctrl[usbhid->ctrlhead].dir = dir;
536 usbhid->ctrlhead = head; 549 usbhid->ctrlhead = head;
537 550
538 if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) 551 if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) {
539 if (hid_submit_ctrl(hid)) 552 if (hid_submit_ctrl(hid))
540 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); 553 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
554 } else {
555 /*
556 * the queue is known to run
557 * but an earlier request may be stuck
558 * we may need to time out
559 * no race because this is called under
560 * spinlock
561 */
562 if (time_after(jiffies, usbhid->last_ctrl + HZ * 5))
563 usb_unlink_urb(usbhid->urbctrl);
564 }
541} 565}
542 566
543void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) 567void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
@@ -774,7 +798,8 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
774 return 0; 798 return 0;
775} 799}
776 800
777static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count) 801static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count,
802 unsigned char report_type)
778{ 803{
779 struct usbhid_device *usbhid = hid->driver_data; 804 struct usbhid_device *usbhid = hid->driver_data;
780 struct usb_device *dev = hid_to_usb_dev(hid); 805 struct usb_device *dev = hid_to_usb_dev(hid);
@@ -785,7 +810,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
785 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 810 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
786 HID_REQ_SET_REPORT, 811 HID_REQ_SET_REPORT,
787 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 812 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
788 ((HID_OUTPUT_REPORT + 1) << 8) | *buf, 813 ((report_type + 1) << 8) | *buf,
789 interface->desc.bInterfaceNumber, buf + 1, count - 1, 814 interface->desc.bInterfaceNumber, buf + 1, count - 1,
790 USB_CTRL_SET_TIMEOUT); 815 USB_CTRL_SET_TIMEOUT);
791 816
@@ -981,9 +1006,6 @@ static int usbhid_start(struct hid_device *hid)
981 1006
982 spin_lock_init(&usbhid->lock); 1007 spin_lock_init(&usbhid->lock);
983 1008
984 usbhid->intf = intf;
985 usbhid->ifnum = interface->desc.bInterfaceNumber;
986
987 usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); 1009 usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
988 if (!usbhid->urbctrl) { 1010 if (!usbhid->urbctrl) {
989 ret = -ENOMEM; 1011 ret = -ENOMEM;
@@ -1154,6 +1176,8 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
1154 1176
1155 hid->driver_data = usbhid; 1177 hid->driver_data = usbhid;
1156 usbhid->hid = hid; 1178 usbhid->hid = hid;
1179 usbhid->intf = intf;
1180 usbhid->ifnum = interface->desc.bInterfaceNumber;
1157 1181
1158 ret = hid_add_device(hid); 1182 ret = hid_add_device(hid);
1159 if (ret) { 1183 if (ret) {
@@ -1342,7 +1366,7 @@ static int hid_reset_resume(struct usb_interface *intf)
1342 1366
1343#endif /* CONFIG_PM */ 1367#endif /* CONFIG_PM */
1344 1368
1345static struct usb_device_id hid_usb_ids [] = { 1369static const struct usb_device_id hid_usb_ids[] = {
1346 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, 1370 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
1347 .bInterfaceClass = USB_INTERFACE_CLASS_HID }, 1371 .bInterfaceClass = USB_INTERFACE_CLASS_HID },
1348 { } /* Terminating entry */ 1372 { } /* Terminating entry */