diff options
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 22 |
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 | */ |
720 | static int ehci_urb_enqueue ( | 728 | static 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 | ||
780 | static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | 787 | static 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 | } |
839 | done: | 851 | done: |
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 | /*-------------------------------------------------------------------------*/ |