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.c65
1 files changed, 57 insertions, 8 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 5bf91dbad59..340d6ae646e 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -203,7 +203,7 @@ static int usbhid_restart_out_queue(struct usbhid_device *usbhid)
203 return 0; 203 return 0;
204 204
205 if ((kicked = (usbhid->outhead != usbhid->outtail))) { 205 if ((kicked = (usbhid->outhead != usbhid->outtail))) {
206 dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail); 206 hid_dbg(hid, "Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
207 207
208 r = usb_autopm_get_interface_async(usbhid->intf); 208 r = usb_autopm_get_interface_async(usbhid->intf);
209 if (r < 0) 209 if (r < 0)
@@ -230,7 +230,7 @@ static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
230 return 0; 230 return 0;
231 231
232 if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) { 232 if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) {
233 dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail); 233 hid_dbg(hid, "Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
234 234
235 r = usb_autopm_get_interface_async(usbhid->intf); 235 r = usb_autopm_get_interface_async(usbhid->intf);
236 if (r < 0) 236 if (r < 0)
@@ -399,6 +399,16 @@ static int hid_submit_ctrl(struct hid_device *hid)
399 * Output interrupt completion handler. 399 * Output interrupt completion handler.
400 */ 400 */
401 401
402static int irq_out_pump_restart(struct hid_device *hid)
403{
404 struct usbhid_device *usbhid = hid->driver_data;
405
406 if (usbhid->outhead != usbhid->outtail)
407 return hid_submit_out(hid);
408 else
409 return -1;
410}
411
402static void hid_irq_out(struct urb *urb) 412static void hid_irq_out(struct urb *urb)
403{ 413{
404 struct hid_device *hid = urb->context; 414 struct hid_device *hid = urb->context;
@@ -428,7 +438,7 @@ static void hid_irq_out(struct urb *urb)
428 else 438 else
429 usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); 439 usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
430 440
431 if (usbhid->outhead != usbhid->outtail && !hid_submit_out(hid)) { 441 if (!irq_out_pump_restart(hid)) {
432 /* Successfully submitted next urb in queue */ 442 /* Successfully submitted next urb in queue */
433 spin_unlock_irqrestore(&usbhid->lock, flags); 443 spin_unlock_irqrestore(&usbhid->lock, flags);
434 return; 444 return;
@@ -443,6 +453,15 @@ static void hid_irq_out(struct urb *urb)
443/* 453/*
444 * Control pipe completion handler. 454 * Control pipe completion handler.
445 */ 455 */
456static int ctrl_pump_restart(struct hid_device *hid)
457{
458 struct usbhid_device *usbhid = hid->driver_data;
459
460 if (usbhid->ctrlhead != usbhid->ctrltail)
461 return hid_submit_ctrl(hid);
462 else
463 return -1;
464}
446 465
447static void hid_ctrl(struct urb *urb) 466static void hid_ctrl(struct urb *urb)
448{ 467{
@@ -476,7 +495,7 @@ static void hid_ctrl(struct urb *urb)
476 else 495 else
477 usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); 496 usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
478 497
479 if (usbhid->ctrlhead != usbhid->ctrltail && !hid_submit_ctrl(hid)) { 498 if (!ctrl_pump_restart(hid)) {
480 /* Successfully submitted next urb in queue */ 499 /* Successfully submitted next urb in queue */
481 spin_unlock(&usbhid->lock); 500 spin_unlock(&usbhid->lock);
482 return; 501 return;
@@ -535,11 +554,27 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
535 * the queue is known to run 554 * the queue is known to run
536 * but an earlier request may be stuck 555 * but an earlier request may be stuck
537 * we may need to time out 556 * we may need to time out
538 * no race because this is called under 557 * no race because the URB is blocked under
539 * spinlock 558 * spinlock
540 */ 559 */
541 if (time_after(jiffies, usbhid->last_out + HZ * 5)) 560 if (time_after(jiffies, usbhid->last_out + HZ * 5)) {
561 usb_block_urb(usbhid->urbout);
562 /* drop lock to not deadlock if the callback is called */
563 spin_unlock(&usbhid->lock);
542 usb_unlink_urb(usbhid->urbout); 564 usb_unlink_urb(usbhid->urbout);
565 spin_lock(&usbhid->lock);
566 usb_unblock_urb(usbhid->urbout);
567 /*
568 * if the unlinking has already completed
569 * the pump will have been stopped
570 * it must be restarted now
571 */
572 if (!test_bit(HID_OUT_RUNNING, &usbhid->iofl))
573 if (!irq_out_pump_restart(hid))
574 set_bit(HID_OUT_RUNNING, &usbhid->iofl);
575
576
577 }
543 } 578 }
544 return; 579 return;
545 } 580 }
@@ -583,11 +618,25 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
583 * the queue is known to run 618 * the queue is known to run
584 * but an earlier request may be stuck 619 * but an earlier request may be stuck
585 * we may need to time out 620 * we may need to time out
586 * no race because this is called under 621 * no race because the URB is blocked under
587 * spinlock 622 * spinlock
588 */ 623 */
589 if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) 624 if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) {
625 usb_block_urb(usbhid->urbctrl);
626 /* drop lock to not deadlock if the callback is called */
627 spin_unlock(&usbhid->lock);
590 usb_unlink_urb(usbhid->urbctrl); 628 usb_unlink_urb(usbhid->urbctrl);
629 spin_lock(&usbhid->lock);
630 usb_unblock_urb(usbhid->urbctrl);
631 /*
632 * if the unlinking has already completed
633 * the pump will have been stopped
634 * it must be restarted now
635 */
636 if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
637 if (!ctrl_pump_restart(hid))
638 set_bit(HID_CTRL_RUNNING, &usbhid->iofl);
639 }
591 } 640 }
592} 641}
593 642