aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r--drivers/usb/host/ehci-hcd.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 35cdba10411b..c1514442883e 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -570,10 +570,18 @@ static int ehci_run (struct usb_hcd *hcd)
570 * are explicitly handed to companion controller(s), so no TT is 570 * are explicitly handed to companion controller(s), so no TT is
571 * involved with the root hub. (Except where one is integrated, 571 * involved with the root hub. (Except where one is integrated,
572 * and there's no companion controller unless maybe for USB OTG.) 572 * and there's no companion controller unless maybe for USB OTG.)
573 *
574 * Turning on the CF flag will transfer ownership of all ports
575 * from the companions to the EHCI controller. If any of the
576 * companions are in the middle of a port reset at the time, it
577 * could cause trouble. Write-locking ehci_cf_port_reset_rwsem
578 * guarantees that no resets are in progress.
573 */ 579 */
580 down_write(&ehci_cf_port_reset_rwsem);
574 hcd->state = HC_STATE_RUNNING; 581 hcd->state = HC_STATE_RUNNING;
575 ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); 582 ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
576 ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ 583 ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
584 up_write(&ehci_cf_port_reset_rwsem);
577 585
578 temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); 586 temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
579 ehci_info (ehci, 587 ehci_info (ehci,
@@ -719,7 +727,6 @@ dead:
719 */ 727 */
720static int ehci_urb_enqueue ( 728static int ehci_urb_enqueue (
721 struct usb_hcd *hcd, 729 struct usb_hcd *hcd,
722 struct usb_host_endpoint *ep,
723 struct urb *urb, 730 struct urb *urb,
724 gfp_t mem_flags 731 gfp_t mem_flags
725) { 732) {
@@ -734,12 +741,12 @@ static int ehci_urb_enqueue (
734 default: 741 default:
735 if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) 742 if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
736 return -ENOMEM; 743 return -ENOMEM;
737 return submit_async (ehci, ep, urb, &qtd_list, mem_flags); 744 return submit_async(ehci, urb, &qtd_list, mem_flags);
738 745
739 case PIPE_INTERRUPT: 746 case PIPE_INTERRUPT:
740 if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) 747 if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
741 return -ENOMEM; 748 return -ENOMEM;
742 return intr_submit (ehci, ep, urb, &qtd_list, mem_flags); 749 return intr_submit(ehci, urb, &qtd_list, mem_flags);
743 750
744 case PIPE_ISOCHRONOUS: 751 case PIPE_ISOCHRONOUS:
745 if (urb->dev->speed == USB_SPEED_HIGH) 752 if (urb->dev->speed == USB_SPEED_HIGH)
@@ -777,13 +784,18 @@ static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
777 * completions normally happen asynchronously 784 * completions normally happen asynchronously
778 */ 785 */
779 786
780static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) 787static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
781{ 788{
782 struct ehci_hcd *ehci = hcd_to_ehci (hcd); 789 struct ehci_hcd *ehci = hcd_to_ehci (hcd);
783 struct ehci_qh *qh; 790 struct ehci_qh *qh;
784 unsigned long flags; 791 unsigned long flags;
792 int rc;
785 793
786 spin_lock_irqsave (&ehci->lock, flags); 794 spin_lock_irqsave (&ehci->lock, flags);
795 rc = usb_hcd_check_unlink_urb(hcd, urb, status);
796 if (rc)
797 goto done;
798
787 switch (usb_pipetype (urb->pipe)) { 799 switch (usb_pipetype (urb->pipe)) {
788 // case PIPE_CONTROL: 800 // case PIPE_CONTROL:
789 // case PIPE_BULK: 801 // case PIPE_BULK:
@@ -838,7 +850,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
838 } 850 }
839done: 851done:
840 spin_unlock_irqrestore (&ehci->lock, flags); 852 spin_unlock_irqrestore (&ehci->lock, flags);
841 return 0; 853 return rc;
842} 854}
843 855
844/*-------------------------------------------------------------------------*/ 856/*-------------------------------------------------------------------------*/