diff options
Diffstat (limited to 'drivers/hid/usbhid')
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 65 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbmouse.c | 7 |
2 files changed, 61 insertions, 11 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 | ||
402 | static 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 | |||
402 | static void hid_irq_out(struct urb *urb) | 412 | static 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 | */ |
456 | static 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 | ||
447 | static void hid_ctrl(struct urb *urb) | 466 | static 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 | ||
diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c index 0f6be45d43d..bf16d72dc37 100644 --- a/drivers/hid/usbhid/usbmouse.c +++ b/drivers/hid/usbhid/usbmouse.c | |||
@@ -92,9 +92,10 @@ static void usb_mouse_irq(struct urb *urb) | |||
92 | resubmit: | 92 | resubmit: |
93 | status = usb_submit_urb (urb, GFP_ATOMIC); | 93 | status = usb_submit_urb (urb, GFP_ATOMIC); |
94 | if (status) | 94 | if (status) |
95 | err ("can't resubmit intr, %s-%s/input0, status %d", | 95 | dev_err(&mouse->usbdev->dev, |
96 | mouse->usbdev->bus->bus_name, | 96 | "can't resubmit intr, %s-%s/input0, status %d\n", |
97 | mouse->usbdev->devpath, status); | 97 | mouse->usbdev->bus->bus_name, |
98 | mouse->usbdev->devpath, status); | ||
98 | } | 99 | } |
99 | 100 | ||
100 | static int usb_mouse_open(struct input_dev *dev) | 101 | static int usb_mouse_open(struct input_dev *dev) |