aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci.h
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-12-11 16:05:30 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-02-01 17:34:55 -0500
commit07d29b63ef6b39963ab37818653284d861cf55af (patch)
tree10460d9d13ad7284b644181af66ecdbf416cc5ba /drivers/usb/host/ehci.h
parent2e2eb83ffd1aeb92bf8793eea892b5bc05a993ea (diff)
USB: EHCI: add separate IAA watchdog timer
This patch (as1028) was mostly written by David Brownell; I made only a few changes (extra log info and a small bug fix -- which might account for why David's version had to be reverted). It adds a new watchdog timer to the ehci-hcd driver to be used exclusively for detecting lost or missing IAA notifications. Previously a shared timer had been used, which may have led to some problems as reported by Christian Hoffmann. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci.h')
-rw-r--r--drivers/usb/host/ehci.h22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 10e71417c352..eeda4c88ebae 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -74,7 +74,6 @@ struct ehci_hcd { /* one per controller */
74 /* async schedule support */ 74 /* async schedule support */
75 struct ehci_qh *async; 75 struct ehci_qh *async;
76 struct ehci_qh *reclaim; 76 struct ehci_qh *reclaim;
77 unsigned reclaim_ready : 1;
78 unsigned scanning : 1; 77 unsigned scanning : 1;
79 78
80 /* periodic schedule support */ 79 /* periodic schedule support */
@@ -105,6 +104,7 @@ struct ehci_hcd { /* one per controller */
105 struct dma_pool *itd_pool; /* itd per iso urb */ 104 struct dma_pool *itd_pool; /* itd per iso urb */
106 struct dma_pool *sitd_pool; /* sitd per split iso urb */ 105 struct dma_pool *sitd_pool; /* sitd per split iso urb */
107 106
107 struct timer_list iaa_watchdog;
108 struct timer_list watchdog; 108 struct timer_list watchdog;
109 unsigned long actions; 109 unsigned long actions;
110 unsigned stamp; 110 unsigned stamp;
@@ -148,9 +148,21 @@ static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci)
148} 148}
149 149
150 150
151static inline void
152iaa_watchdog_start(struct ehci_hcd *ehci)
153{
154 WARN_ON(timer_pending(&ehci->iaa_watchdog));
155 mod_timer(&ehci->iaa_watchdog,
156 jiffies + msecs_to_jiffies(EHCI_IAA_MSECS));
157}
158
159static inline void iaa_watchdog_done(struct ehci_hcd *ehci)
160{
161 del_timer(&ehci->iaa_watchdog);
162}
163
151enum ehci_timer_action { 164enum ehci_timer_action {
152 TIMER_IO_WATCHDOG, 165 TIMER_IO_WATCHDOG,
153 TIMER_IAA_WATCHDOG,
154 TIMER_ASYNC_SHRINK, 166 TIMER_ASYNC_SHRINK,
155 TIMER_ASYNC_OFF, 167 TIMER_ASYNC_OFF,
156}; 168};
@@ -168,9 +180,6 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
168 unsigned long t; 180 unsigned long t;
169 181
170 switch (action) { 182 switch (action) {
171 case TIMER_IAA_WATCHDOG:
172 t = EHCI_IAA_JIFFIES;
173 break;
174 case TIMER_IO_WATCHDOG: 183 case TIMER_IO_WATCHDOG:
175 t = EHCI_IO_JIFFIES; 184 t = EHCI_IO_JIFFIES;
176 break; 185 break;
@@ -187,8 +196,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
187 // async queue SHRINK often precedes IAA. while it's ready 196 // async queue SHRINK often precedes IAA. while it's ready
188 // to go OFF neither can matter, and afterwards the IO 197 // to go OFF neither can matter, and afterwards the IO
189 // watchdog stops unless there's still periodic traffic. 198 // watchdog stops unless there's still periodic traffic.
190 if (action != TIMER_IAA_WATCHDOG 199 if (time_before_eq(t, ehci->watchdog.expires)
191 && t > ehci->watchdog.expires
192 && timer_pending (&ehci->watchdog)) 200 && timer_pending (&ehci->watchdog))
193 return; 201 return;
194 mod_timer (&ehci->watchdog, t); 202 mod_timer (&ehci->watchdog, t);