diff options
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c637207a1c80..2b72473544d3 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -1024,6 +1024,51 @@ done: | |||
1024 | return; | 1024 | return; |
1025 | } | 1025 | } |
1026 | 1026 | ||
1027 | static void | ||
1028 | ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) | ||
1029 | { | ||
1030 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
1031 | struct ehci_qh *qh; | ||
1032 | int eptype = usb_endpoint_type(&ep->desc); | ||
1033 | |||
1034 | if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT) | ||
1035 | return; | ||
1036 | |||
1037 | rescan: | ||
1038 | spin_lock_irq(&ehci->lock); | ||
1039 | qh = ep->hcpriv; | ||
1040 | |||
1041 | /* For Bulk and Interrupt endpoints we maintain the toggle state | ||
1042 | * in the hardware; the toggle bits in udev aren't used at all. | ||
1043 | * When an endpoint is reset by usb_clear_halt() we must reset | ||
1044 | * the toggle bit in the QH. | ||
1045 | */ | ||
1046 | if (qh) { | ||
1047 | if (!list_empty(&qh->qtd_list)) { | ||
1048 | WARN_ONCE(1, "clear_halt for a busy endpoint\n"); | ||
1049 | } else if (qh->qh_state == QH_STATE_IDLE) { | ||
1050 | qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); | ||
1051 | } else { | ||
1052 | /* It's not safe to write into the overlay area | ||
1053 | * while the QH is active. Unlink it first and | ||
1054 | * wait for the unlink to complete. | ||
1055 | */ | ||
1056 | if (qh->qh_state == QH_STATE_LINKED) { | ||
1057 | if (eptype == USB_ENDPOINT_XFER_BULK) { | ||
1058 | unlink_async(ehci, qh); | ||
1059 | } else { | ||
1060 | intr_deschedule(ehci, qh); | ||
1061 | (void) qh_schedule(ehci, qh); | ||
1062 | } | ||
1063 | } | ||
1064 | spin_unlock_irq(&ehci->lock); | ||
1065 | schedule_timeout_uninterruptible(1); | ||
1066 | goto rescan; | ||
1067 | } | ||
1068 | } | ||
1069 | spin_unlock_irq(&ehci->lock); | ||
1070 | } | ||
1071 | |||
1027 | static int ehci_get_frame (struct usb_hcd *hcd) | 1072 | static int ehci_get_frame (struct usb_hcd *hcd) |
1028 | { | 1073 | { |
1029 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 1074 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
@@ -1097,7 +1142,7 @@ static int __init ehci_hcd_init(void) | |||
1097 | sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); | 1142 | sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); |
1098 | 1143 | ||
1099 | #ifdef DEBUG | 1144 | #ifdef DEBUG |
1100 | ehci_debug_root = debugfs_create_dir("ehci", NULL); | 1145 | ehci_debug_root = debugfs_create_dir("ehci", usb_debug_root); |
1101 | if (!ehci_debug_root) { | 1146 | if (!ehci_debug_root) { |
1102 | retval = -ENOENT; | 1147 | retval = -ENOENT; |
1103 | goto err_debug; | 1148 | goto err_debug; |