aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/hcd.c207
-rw-r--r--drivers/usb/core/hcd.h15
-rw-r--r--drivers/usb/core/hub.c5
3 files changed, 140 insertions, 87 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 0da23732e807..1180c157b717 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -519,119 +519,120 @@ error:
519/*-------------------------------------------------------------------------*/ 519/*-------------------------------------------------------------------------*/
520 520
521/* 521/*
522 * Root Hub interrupt transfers are synthesized with a timer. 522 * Root Hub interrupt transfers are polled using a timer if the
523 * Completions are called in_interrupt() but not in_irq(). 523 * driver requests it; otherwise the driver is responsible for
524 * calling usb_hcd_poll_rh_status() when an event occurs.
524 * 525 *
525 * Note: some root hubs (including common UHCI based designs) can't 526 * Completions are called in_interrupt(), but they may or may not
526 * correctly issue port change IRQs. They're the ones that _need_ a 527 * be in_irq().
527 * timer; most other root hubs don't. Some systems could save a
528 * lot of battery power by eliminating these root hub timer IRQs.
529 */ 528 */
529void usb_hcd_poll_rh_status(struct usb_hcd *hcd)
530{
531 struct urb *urb;
532 int length;
533 unsigned long flags;
534 char buffer[4]; /* Any root hubs with > 31 ports? */
530 535
531static void rh_report_status (unsigned long ptr); 536 if (!hcd->uses_new_polling && !hcd->status_urb)
537 return;
532 538
533static int rh_status_urb (struct usb_hcd *hcd, struct urb *urb) 539 length = hcd->driver->hub_status_data(hcd, buffer);
534{ 540 if (length > 0) {
535 int len = 1 + (urb->dev->maxchild / 8);
536 541
537 /* rh_timer protected by hcd_data_lock */ 542 /* try to complete the status urb */
538 if (hcd->rh_timer.data || urb->transfer_buffer_length < len) { 543 local_irq_save (flags);
539 dev_dbg (hcd->self.controller, 544 spin_lock(&hcd_root_hub_lock);
540 "not queuing rh status urb, stat %d\n", 545 urb = hcd->status_urb;
541 urb->status); 546 if (urb) {
542 return -EINVAL; 547 spin_lock(&urb->lock);
548 if (urb->status == -EINPROGRESS) {
549 hcd->poll_pending = 0;
550 hcd->status_urb = NULL;
551 urb->status = 0;
552 urb->hcpriv = NULL;
553 urb->actual_length = length;
554 memcpy(urb->transfer_buffer, buffer, length);
555 } else /* urb has been unlinked */
556 length = 0;
557 spin_unlock(&urb->lock);
558 } else
559 length = 0;
560 spin_unlock(&hcd_root_hub_lock);
561
562 /* local irqs are always blocked in completions */
563 if (length > 0)
564 usb_hcd_giveback_urb (hcd, urb, NULL);
565 else
566 hcd->poll_pending = 1;
567 local_irq_restore (flags);
543 } 568 }
544 569
545 init_timer (&hcd->rh_timer); 570 /* The USB 2.0 spec says 256 ms. This is close enough and won't
546 hcd->rh_timer.function = rh_report_status; 571 * exceed that limit if HZ is 100. */
547 hcd->rh_timer.data = (unsigned long) urb; 572 if (hcd->uses_new_polling ? hcd->poll_rh :
548 /* USB 2.0 spec says 256msec; this is close enough */ 573 (length == 0 && hcd->status_urb != NULL))
549 hcd->rh_timer.expires = jiffies + HZ/4; 574 mod_timer (&hcd->rh_timer, jiffies + msecs_to_jiffies(250));
550 add_timer (&hcd->rh_timer);
551 urb->hcpriv = hcd; /* nonzero to indicate it's queued */
552 return 0;
553} 575}
576EXPORT_SYMBOL_GPL(usb_hcd_poll_rh_status);
554 577
555/* timer callback */ 578/* timer callback */
579static void rh_timer_func (unsigned long _hcd)
580{
581 usb_hcd_poll_rh_status((struct usb_hcd *) _hcd);
582}
583
584/*-------------------------------------------------------------------------*/
556 585
557static void rh_report_status (unsigned long ptr) 586static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb)
558{ 587{
559 struct urb *urb; 588 int retval;
560 struct usb_hcd *hcd;
561 int length = 0;
562 unsigned long flags; 589 unsigned long flags;
590 int len = 1 + (urb->dev->maxchild / 8);
563 591
564 urb = (struct urb *) ptr; 592 spin_lock_irqsave (&hcd_root_hub_lock, flags);
565 local_irq_save (flags); 593 if (urb->status != -EINPROGRESS) /* already unlinked */
566 spin_lock (&urb->lock); 594 retval = urb->status;
595 else if (hcd->status_urb || urb->transfer_buffer_length < len) {
596 dev_dbg (hcd->self.controller, "not queuing rh status urb\n");
597 retval = -EINVAL;
598 } else {
599 hcd->status_urb = urb;
600 urb->hcpriv = hcd; /* indicate it's queued */
567 601
568 /* do nothing if the urb's been unlinked */ 602 if (!hcd->uses_new_polling)
569 if (!urb->dev 603 mod_timer (&hcd->rh_timer, jiffies +
570 || urb->status != -EINPROGRESS 604 msecs_to_jiffies(250));
571 || (hcd = urb->dev->bus->hcpriv) == NULL) {
572 spin_unlock (&urb->lock);
573 local_irq_restore (flags);
574 return;
575 }
576 605
577 /* complete the status urb, or retrigger the timer */ 606 /* If a status change has already occurred, report it ASAP */
578 spin_lock (&hcd_data_lock); 607 else if (hcd->poll_pending)
579 if (urb->dev->state == USB_STATE_CONFIGURED) { 608 mod_timer (&hcd->rh_timer, jiffies);
580 length = hcd->driver->hub_status_data ( 609 retval = 0;
581 hcd, urb->transfer_buffer);
582 if (length > 0) {
583 hcd->rh_timer.data = 0;
584 urb->actual_length = length;
585 urb->status = 0;
586 urb->hcpriv = NULL;
587 } else
588 mod_timer (&hcd->rh_timer, jiffies + HZ/4);
589 } 610 }
590 spin_unlock (&hcd_data_lock); 611 spin_unlock_irqrestore (&hcd_root_hub_lock, flags);
591 spin_unlock (&urb->lock); 612 return retval;
592
593 /* local irqs are always blocked in completions */
594 if (length > 0)
595 usb_hcd_giveback_urb (hcd, urb, NULL);
596 local_irq_restore (flags);
597} 613}
598 614
599/*-------------------------------------------------------------------------*/
600
601static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb) 615static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb)
602{ 616{
603 if (usb_pipeint (urb->pipe)) { 617 if (usb_pipeint (urb->pipe))
604 int retval; 618 return rh_queue_status (hcd, urb);
605 unsigned long flags;
606
607 spin_lock_irqsave (&hcd_data_lock, flags);
608 retval = rh_status_urb (hcd, urb);
609 spin_unlock_irqrestore (&hcd_data_lock, flags);
610 return retval;
611 }
612 if (usb_pipecontrol (urb->pipe)) 619 if (usb_pipecontrol (urb->pipe))
613 return rh_call_control (hcd, urb); 620 return rh_call_control (hcd, urb);
614 else 621 return -EINVAL;
615 return -EINVAL;
616} 622}
617 623
618/*-------------------------------------------------------------------------*/ 624/*-------------------------------------------------------------------------*/
619 625
626/* Asynchronous unlinks of root-hub control URBs are legal, but they
627 * don't do anything. Status URB unlinks must be made in process context
628 * with interrupts enabled.
629 */
620static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) 630static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
621{ 631{
622 unsigned long flags; 632 if (usb_pipeendpoint(urb->pipe) == 0) { /* Control URB */
623 633 if (in_interrupt())
624 /* note: always a synchronous unlink */ 634 return 0; /* nothing to do */
625 if ((unsigned long) urb == hcd->rh_timer.data) {
626 del_timer_sync (&hcd->rh_timer);
627 hcd->rh_timer.data = 0;
628
629 local_irq_save (flags);
630 urb->hcpriv = NULL;
631 usb_hcd_giveback_urb (hcd, urb, NULL);
632 local_irq_restore (flags);
633 635
634 } else if (usb_pipeendpoint(urb->pipe) == 0) {
635 spin_lock_irq(&urb->lock); /* from usb_kill_urb */ 636 spin_lock_irq(&urb->lock); /* from usb_kill_urb */
636 ++urb->reject; 637 ++urb->reject;
637 spin_unlock_irq(&urb->lock); 638 spin_unlock_irq(&urb->lock);
@@ -642,8 +643,22 @@ static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
642 spin_lock_irq(&urb->lock); 643 spin_lock_irq(&urb->lock);
643 --urb->reject; 644 --urb->reject;
644 spin_unlock_irq(&urb->lock); 645 spin_unlock_irq(&urb->lock);
645 } else 646
646 return -EINVAL; 647 } else { /* Status URB */
648 if (!hcd->uses_new_polling)
649 del_timer_sync (&hcd->rh_timer);
650 local_irq_disable ();
651 spin_lock (&hcd_root_hub_lock);
652 if (urb == hcd->status_urb) {
653 hcd->status_urb = NULL;
654 urb->hcpriv = NULL;
655 } else
656 urb = NULL; /* wasn't fully queued */
657 spin_unlock (&hcd_root_hub_lock);
658 if (urb)
659 usb_hcd_giveback_urb (hcd, urb, NULL);
660 local_irq_enable ();
661 }
647 662
648 return 0; 663 return 0;
649} 664}
@@ -885,6 +900,16 @@ int usb_hcd_register_root_hub (struct usb_device *usb_dev, struct usb_hcd *hcd)
885} 900}
886EXPORT_SYMBOL_GPL(usb_hcd_register_root_hub); 901EXPORT_SYMBOL_GPL(usb_hcd_register_root_hub);
887 902
903void usb_enable_root_hub_irq (struct usb_bus *bus)
904{
905 struct usb_hcd *hcd;
906
907 hcd = container_of (bus, struct usb_hcd, self);
908 if (hcd->driver->hub_irq_enable && !hcd->poll_rh &&
909 hcd->state != HC_STATE_HALT)
910 hcd->driver->hub_irq_enable (hcd);
911}
912
888 913
889/*-------------------------------------------------------------------------*/ 914/*-------------------------------------------------------------------------*/
890 915
@@ -1348,7 +1373,8 @@ hcd_endpoint_disable (struct usb_device *udev, struct usb_host_endpoint *ep)
1348 1373
1349 hcd = udev->bus->hcpriv; 1374 hcd = udev->bus->hcpriv;
1350 1375
1351 WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT); 1376 WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT &&
1377 udev->state != USB_STATE_NOTATTACHED);
1352 1378
1353 local_irq_disable (); 1379 local_irq_disable ();
1354 1380
@@ -1612,6 +1638,8 @@ void usb_hc_died (struct usb_hcd *hcd)
1612 1638
1613 spin_lock_irqsave (&hcd_root_hub_lock, flags); 1639 spin_lock_irqsave (&hcd_root_hub_lock, flags);
1614 if (hcd->rh_registered) { 1640 if (hcd->rh_registered) {
1641 hcd->poll_rh = 0;
1642 del_timer(&hcd->rh_timer);
1615 1643
1616 /* make khubd clean up old urbs and devices */ 1644 /* make khubd clean up old urbs and devices */
1617 usb_set_device_state (hcd->self.root_hub, 1645 usb_set_device_state (hcd->self.root_hub,
@@ -1665,6 +1693,8 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,
1665 hcd->self.bus_name = bus_name; 1693 hcd->self.bus_name = bus_name;
1666 1694
1667 init_timer(&hcd->rh_timer); 1695 init_timer(&hcd->rh_timer);
1696 hcd->rh_timer.function = rh_timer_func;
1697 hcd->rh_timer.data = (unsigned long) hcd;
1668 1698
1669 hcd->driver = driver; 1699 hcd->driver = driver;
1670 hcd->product_desc = (driver->product_desc) ? driver->product_desc : 1700 hcd->product_desc = (driver->product_desc) ? driver->product_desc :
@@ -1748,6 +1778,8 @@ int usb_add_hcd(struct usb_hcd *hcd,
1748 goto err3; 1778 goto err3;
1749 } 1779 }
1750 1780
1781 if (hcd->uses_new_polling && hcd->poll_rh)
1782 usb_hcd_poll_rh_status(hcd);
1751 return retval; 1783 return retval;
1752 1784
1753 err3: 1785 err3:
@@ -1782,6 +1814,9 @@ void usb_remove_hcd(struct usb_hcd *hcd)
1782 spin_unlock_irq (&hcd_root_hub_lock); 1814 spin_unlock_irq (&hcd_root_hub_lock);
1783 usb_disconnect(&hcd->self.root_hub); 1815 usb_disconnect(&hcd->self.root_hub);
1784 1816
1817 hcd->poll_rh = 0;
1818 del_timer_sync(&hcd->rh_timer);
1819
1785 hcd->driver->stop(hcd); 1820 hcd->driver->stop(hcd);
1786 hcd->state = HC_STATE_HALT; 1821 hcd->state = HC_STATE_HALT;
1787 1822
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 325a51656c3f..ac5752778e39 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -65,7 +65,8 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */
65 const char *product_desc; /* product/vendor string */ 65 const char *product_desc; /* product/vendor string */
66 char irq_descr[24]; /* driver + bus # */ 66 char irq_descr[24]; /* driver + bus # */
67 67
68 struct timer_list rh_timer; /* drives root hub */ 68 struct timer_list rh_timer; /* drives root-hub polling */
69 struct urb *status_urb; /* the current status urb */
69 70
70 /* 71 /*
71 * hardware info/state 72 * hardware info/state
@@ -76,6 +77,12 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */
76 unsigned remote_wakeup:1;/* sw should use wakeup? */ 77 unsigned remote_wakeup:1;/* sw should use wakeup? */
77 unsigned rh_registered:1;/* is root hub registered? */ 78 unsigned rh_registered:1;/* is root hub registered? */
78 79
80 /* The next flag is a stopgap, to be removed when all the HCDs
81 * support the new root-hub polling mechanism. */
82 unsigned uses_new_polling:1;
83 unsigned poll_rh:1; /* poll for rh status? */
84 unsigned poll_pending:1; /* status has changed? */
85
79 int irq; /* irq allocated */ 86 int irq; /* irq allocated */
80 void __iomem *regs; /* device memory/io */ 87 void __iomem *regs; /* device memory/io */
81 u64 rsrc_start; /* memory/io resource start */ 88 u64 rsrc_start; /* memory/io resource start */
@@ -207,6 +214,8 @@ struct hc_driver {
207 int (*hub_suspend)(struct usb_hcd *); 214 int (*hub_suspend)(struct usb_hcd *);
208 int (*hub_resume)(struct usb_hcd *); 215 int (*hub_resume)(struct usb_hcd *);
209 int (*start_port_reset)(struct usb_hcd *, unsigned port_num); 216 int (*start_port_reset)(struct usb_hcd *, unsigned port_num);
217 void (*hub_irq_enable)(struct usb_hcd *);
218 /* Needed only if port-change IRQs are level-triggered */
210}; 219};
211 220
212extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs); 221extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs);
@@ -243,7 +252,9 @@ void hcd_buffer_free (struct usb_bus *bus, size_t size,
243 252
244/* generic bus glue, needed for host controllers that don't use PCI */ 253/* generic bus glue, needed for host controllers that don't use PCI */
245extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r); 254extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
255
246extern void usb_hc_died (struct usb_hcd *hcd); 256extern void usb_hc_died (struct usb_hcd *hcd);
257extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
247 258
248/* -------------------------------------------------------------------------- */ 259/* -------------------------------------------------------------------------- */
249 260
@@ -360,6 +371,8 @@ extern wait_queue_head_t usb_kill_urb_queue;
360extern struct usb_bus *usb_bus_get (struct usb_bus *bus); 371extern struct usb_bus *usb_bus_get (struct usb_bus *bus);
361extern void usb_bus_put (struct usb_bus *bus); 372extern void usb_bus_put (struct usb_bus *bus);
362 373
374extern void usb_enable_root_hub_irq (struct usb_bus *bus);
375
363extern int usb_find_interface_driver (struct usb_device *dev, 376extern int usb_find_interface_driver (struct usb_device *dev,
364 struct usb_interface *interface); 377 struct usb_interface *interface);
365 378
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a8d879a85d04..6d1a330d577b 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2787,6 +2787,11 @@ static void hub_events(void)
2787 2787
2788 hub->activating = 0; 2788 hub->activating = 0;
2789 2789
2790 /* If this is a root hub, tell the HCD it's okay to
2791 * re-enable port-change interrupts now. */
2792 if (!hdev->parent)
2793 usb_enable_root_hub_irq(hdev->bus);
2794
2790loop: 2795loop:
2791 usb_unlock_device(hdev); 2796 usb_unlock_device(hdev);
2792 usb_put_intf(intf); 2797 usb_put_intf(intf);