summaryrefslogtreecommitdiff
path: root/drivers/usb/host/ohci-hub.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2014-07-18 16:25:59 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-18 16:30:46 -0700
commitc6fcb85ea22889527ee44aba42c3e3b479fd2d92 (patch)
tree37ef7947b0b0aa53aa49bf6c5cbc7fca3204b1ea /drivers/usb/host/ohci-hub.c
parent8b3ab0edaf6acd281243bf974fac7e01c9574d08 (diff)
USB: OHCI: redesign the TD done list
This patch changes the way ohci-hcd handles the TD done list. In addition to relying on the TD pointers stored by the controller hardware, we need to handle TDs that the hardware has forgotten about. This means the list has to exist even while the dl_done_list() routine isn't running. That function essentially gets split in two: update_done_list() reads the TD pointers stored by the hardware and adds the TDs to the done list, and process_done_list() scans through the list to handle URB completions. When we detect a TD that the hardware forgot about, we will be able to add it to the done list manually and then process it normally. Since the list is really a queue, and because there can be a lot of TDs, keep the existing singly linked implementation. To insure that URBs are given back in order of submission, whenever a TD is added to the done list, all the preceding TDs for the same endpoint must be added as well (going back to the first one that isn't already on the done list). The done list manipulations must all be protected by the private lock. The scope of the lock is expanded in preparation for the watchdog routine to be added in a later patch. We have to be more careful about giving back unlinked URBs. Since TDs may be added to the done list by the watchdog routine and not in response to a controller interrupt, we have to check explicitly to make sure all the URB's TDs that were added to the done list have been processed before giving back the URB. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ohci-hub.c')
-rw-r--r--drivers/usb/host/ohci-hub.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index b4940de1eba3..dccb90edd66e 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -39,7 +39,8 @@
#define OHCI_SCHED_ENABLES \
(OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE)
-static void dl_done_list (struct ohci_hcd *);
+static void update_done_list(struct ohci_hcd *);
+static void process_done_list(struct ohci_hcd *);
static void finish_unlinks (struct ohci_hcd *, u16);
#ifdef CONFIG_PM
@@ -87,7 +88,8 @@ __acquires(ohci->lock)
msleep (8);
spin_lock_irq (&ohci->lock);
}
- dl_done_list (ohci);
+ update_done_list(ohci);
+ process_done_list(ohci);
finish_unlinks (ohci, ohci_frame_no(ohci));
/*