aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/uhci-hcd.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-04-09 17:24:42 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-06-27 17:43:42 -0400
commit014e73c99aa408f3766afe8d11a1caa3a708b736 (patch)
treede7080493008eff560003364e6d88ad242014471 /drivers/usb/host/uhci-hcd.c
parent72ebddb59a644732ff0240cdf5d216952a2b0c6b (diff)
[PATCH] USB UHCI: subroutine reordering
This patch moves a few subroutines around in the uhci-hcd source file. Nothing else is changed. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/uhci-hcd.c')
-rw-r--r--drivers/usb/host/uhci-hcd.c287
1 files changed, 143 insertions, 144 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 49bd83ee0c75..8b6c87ef486b 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -90,7 +90,6 @@ static char *errbuf;
90static kmem_cache_t *uhci_up_cachep; /* urb_priv */ 90static kmem_cache_t *uhci_up_cachep; /* urb_priv */
91 91
92static void uhci_get_current_frame_number(struct uhci_hcd *uhci); 92static void uhci_get_current_frame_number(struct uhci_hcd *uhci);
93static void hc_state_transitions(struct uhci_hcd *uhci);
94 93
95/* If a transfer is still active after this much time, turn off FSBR */ 94/* If a transfer is still active after this much time, turn off FSBR */
96#define IDLE_TIMEOUT msecs_to_jiffies(50) 95#define IDLE_TIMEOUT msecs_to_jiffies(50)
@@ -105,96 +104,43 @@ static void hc_state_transitions(struct uhci_hcd *uhci);
105#include "uhci-debug.c" 104#include "uhci-debug.c"
106#include "uhci-q.c" 105#include "uhci-q.c"
107 106
108static int init_stall_timer(struct usb_hcd *hcd); 107static int ports_active(struct uhci_hcd *uhci)
109
110static void stall_callback(unsigned long ptr)
111{
112 struct usb_hcd *hcd = (struct usb_hcd *)ptr;
113 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
114 struct urb_priv *up;
115 unsigned long flags;
116
117 spin_lock_irqsave(&uhci->lock, flags);
118 uhci_scan_schedule(uhci, NULL);
119
120 list_for_each_entry(up, &uhci->urb_list, urb_list) {
121 struct urb *u = up->urb;
122
123 spin_lock(&u->lock);
124
125 /* Check if the FSBR timed out */
126 if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, up->fsbrtime + IDLE_TIMEOUT))
127 uhci_fsbr_timeout(uhci, u);
128
129 spin_unlock(&u->lock);
130 }
131
132 /* Really disable FSBR */
133 if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) {
134 uhci->fsbrtimeout = 0;
135 uhci->skel_term_qh->link = UHCI_PTR_TERM;
136 }
137
138 /* Poll for and perform state transitions */
139 hc_state_transitions(uhci);
140 if (unlikely(uhci->suspended_ports && uhci->state != UHCI_SUSPENDED))
141 uhci_check_ports(uhci);
142
143 init_stall_timer(hcd);
144 spin_unlock_irqrestore(&uhci->lock, flags);
145}
146
147static int init_stall_timer(struct usb_hcd *hcd)
148{ 108{
149 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 109 unsigned long io_addr = uhci->io_addr;
110 int connection = 0;
111 int i;
150 112
151 init_timer(&uhci->stall_timer); 113 for (i = 0; i < uhci->rh_numports; i++)
152 uhci->stall_timer.function = stall_callback; 114 connection |= (inw(io_addr + USBPORTSC1 + i * 2) & USBPORTSC_CCS);
153 uhci->stall_timer.data = (unsigned long)hcd;
154 uhci->stall_timer.expires = jiffies + msecs_to_jiffies(100);
155 add_timer(&uhci->stall_timer);
156 115
157 return 0; 116 return connection;
158} 117}
159 118
160static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) 119static int suspend_allowed(struct uhci_hcd *uhci)
161{ 120{
162 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
163 unsigned long io_addr = uhci->io_addr; 121 unsigned long io_addr = uhci->io_addr;
164 unsigned short status; 122 int i;
165 123
166 /* 124 if (to_pci_dev(uhci_dev(uhci))->vendor != PCI_VENDOR_ID_INTEL)
167 * Read the interrupt status, and write it back to clear the 125 return 1;
168 * interrupt cause. Contrary to the UHCI specification, the 126
169 * "HC Halted" status bit is persistent: it is RO, not R/WC. 127 /* Some of Intel's USB controllers have a bug that causes false
128 * resume indications if any port has an over current condition.
129 * To prevent problems, we will not allow a global suspend if
130 * any ports are OC.
131 *
132 * Some motherboards using Intel's chipsets (but not using all
133 * the USB ports) appear to hardwire the over current inputs active
134 * to disable the USB ports.
170 */ 135 */
171 status = inw(io_addr + USBSTS);
172 if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */
173 return IRQ_NONE;
174 outw(status, io_addr + USBSTS); /* Clear it */
175 136
176 if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { 137 /* check for over current condition on any port */
177 if (status & USBSTS_HSE) 138 for (i = 0; i < uhci->rh_numports; i++) {
178 dev_err(uhci_dev(uhci), "host system error, " 139 if (inw(io_addr + USBPORTSC1 + i * 2) & USBPORTSC_OC)
179 "PCI problems?\n"); 140 return 0;
180 if (status & USBSTS_HCPE)
181 dev_err(uhci_dev(uhci), "host controller process "
182 "error, something bad happened!\n");
183 if ((status & USBSTS_HCH) && uhci->state > 0) {
184 dev_err(uhci_dev(uhci), "host controller halted, "
185 "very bad!\n");
186 /* FIXME: Reset the controller, fix the offending TD */
187 }
188 } 141 }
189 142
190 if (status & USBSTS_RD) 143 return 1;
191 uhci->resume_detect = 1;
192
193 spin_lock(&uhci->lock);
194 uhci_scan_schedule(uhci, regs);
195 spin_unlock(&uhci->lock);
196
197 return IRQ_HANDLED;
198} 144}
199 145
200static void reset_hc(struct uhci_hcd *uhci) 146static void reset_hc(struct uhci_hcd *uhci)
@@ -276,43 +222,46 @@ static void wakeup_hc(struct uhci_hcd *uhci)
276 } 222 }
277} 223}
278 224
279static int ports_active(struct uhci_hcd *uhci) 225static int start_hc(struct uhci_hcd *uhci)
280{ 226{
281 unsigned long io_addr = uhci->io_addr; 227 unsigned long io_addr = uhci->io_addr;
282 int connection = 0; 228 int timeout = 10;
283 int i;
284
285 for (i = 0; i < uhci->rh_numports; i++)
286 connection |= (inw(io_addr + USBPORTSC1 + i * 2) & USBPORTSC_CCS);
287 229
288 return connection; 230 /*
289} 231 * Reset the HC - this will force us to get a
232 * new notification of any already connected
233 * ports due to the virtual disconnect that it
234 * implies.
235 */
236 outw(USBCMD_HCRESET, io_addr + USBCMD);
237 while (inw(io_addr + USBCMD) & USBCMD_HCRESET) {
238 if (--timeout < 0) {
239 dev_err(uhci_dev(uhci), "USBCMD_HCRESET timed out!\n");
240 return -ETIMEDOUT;
241 }
242 msleep(1);
243 }
290 244
291static int suspend_allowed(struct uhci_hcd *uhci) 245 /* Mark controller as running before we enable interrupts */
292{ 246 uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;
293 unsigned long io_addr = uhci->io_addr;
294 int i;
295 247
296 if (to_pci_dev(uhci_dev(uhci))->vendor != PCI_VENDOR_ID_INTEL) 248 /* Turn on PIRQ and all interrupts */
297 return 1; 249 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
250 USBLEGSUP_DEFAULT);
251 outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
252 io_addr + USBINTR);
298 253
299 /* Some of Intel's USB controllers have a bug that causes false 254 /* Start at frame 0 */
300 * resume indications if any port has an over current condition. 255 outw(0, io_addr + USBFRNUM);
301 * To prevent problems, we will not allow a global suspend if 256 outl(uhci->fl->dma_handle, io_addr + USBFLBASEADD);
302 * any ports are OC.
303 *
304 * Some motherboards using Intel's chipsets (but not using all
305 * the USB ports) appear to hardwire the over current inputs active
306 * to disable the USB ports.
307 */
308 257
309 /* check for over current condition on any port */ 258 /* Run and mark it configured with a 64-byte max packet */
310 for (i = 0; i < uhci->rh_numports; i++) { 259 uhci->state = UHCI_RUNNING_GRACE;
311 if (inw(io_addr + USBPORTSC1 + i * 2) & USBPORTSC_OC) 260 uhci->state_end = jiffies + HZ;
312 return 0; 261 outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD);
313 } 262 uhci->is_stopped = 0;
314 263
315 return 1; 264 return 0;
316} 265}
317 266
318static void hc_state_transitions(struct uhci_hcd *uhci) 267static void hc_state_transitions(struct uhci_hcd *uhci)
@@ -353,56 +302,106 @@ static void hc_state_transitions(struct uhci_hcd *uhci)
353 } 302 }
354} 303}
355 304
356/* 305static int init_stall_timer(struct usb_hcd *hcd);
357 * Store the current frame number in uhci->frame_number if the controller 306
358 * is runnning 307static void stall_callback(unsigned long ptr)
359 */
360static void uhci_get_current_frame_number(struct uhci_hcd *uhci)
361{ 308{
362 if (!uhci->is_stopped) 309 struct usb_hcd *hcd = (struct usb_hcd *)ptr;
363 uhci->frame_number = inw(uhci->io_addr + USBFRNUM); 310 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
311 struct urb_priv *up;
312 unsigned long flags;
313
314 spin_lock_irqsave(&uhci->lock, flags);
315 uhci_scan_schedule(uhci, NULL);
316
317 list_for_each_entry(up, &uhci->urb_list, urb_list) {
318 struct urb *u = up->urb;
319
320 spin_lock(&u->lock);
321
322 /* Check if the FSBR timed out */
323 if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, up->fsbrtime + IDLE_TIMEOUT))
324 uhci_fsbr_timeout(uhci, u);
325
326 spin_unlock(&u->lock);
327 }
328
329 /* Really disable FSBR */
330 if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) {
331 uhci->fsbrtimeout = 0;
332 uhci->skel_term_qh->link = UHCI_PTR_TERM;
333 }
334
335 /* Poll for and perform state transitions */
336 hc_state_transitions(uhci);
337 if (unlikely(uhci->suspended_ports && uhci->state != UHCI_SUSPENDED))
338 uhci_check_ports(uhci);
339
340 init_stall_timer(hcd);
341 spin_unlock_irqrestore(&uhci->lock, flags);
364} 342}
365 343
366static int start_hc(struct uhci_hcd *uhci) 344static int init_stall_timer(struct usb_hcd *hcd)
367{ 345{
346 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
347
348 init_timer(&uhci->stall_timer);
349 uhci->stall_timer.function = stall_callback;
350 uhci->stall_timer.data = (unsigned long)hcd;
351 uhci->stall_timer.expires = jiffies + msecs_to_jiffies(100);
352 add_timer(&uhci->stall_timer);
353
354 return 0;
355}
356
357static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
358{
359 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
368 unsigned long io_addr = uhci->io_addr; 360 unsigned long io_addr = uhci->io_addr;
369 int timeout = 10; 361 unsigned short status;
370 362
371 /* 363 /*
372 * Reset the HC - this will force us to get a 364 * Read the interrupt status, and write it back to clear the
373 * new notification of any already connected 365 * interrupt cause. Contrary to the UHCI specification, the
374 * ports due to the virtual disconnect that it 366 * "HC Halted" status bit is persistent: it is RO, not R/WC.
375 * implies.
376 */ 367 */
377 outw(USBCMD_HCRESET, io_addr + USBCMD); 368 status = inw(io_addr + USBSTS);
378 while (inw(io_addr + USBCMD) & USBCMD_HCRESET) { 369 if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */
379 if (--timeout < 0) { 370 return IRQ_NONE;
380 dev_err(uhci_dev(uhci), "USBCMD_HCRESET timed out!\n"); 371 outw(status, io_addr + USBSTS); /* Clear it */
381 return -ETIMEDOUT; 372
373 if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
374 if (status & USBSTS_HSE)
375 dev_err(uhci_dev(uhci), "host system error, "
376 "PCI problems?\n");
377 if (status & USBSTS_HCPE)
378 dev_err(uhci_dev(uhci), "host controller process "
379 "error, something bad happened!\n");
380 if ((status & USBSTS_HCH) && uhci->state > 0) {
381 dev_err(uhci_dev(uhci), "host controller halted, "
382 "very bad!\n");
383 /* FIXME: Reset the controller, fix the offending TD */
382 } 384 }
383 msleep(1);
384 } 385 }
385 386
386 /* Mark controller as running before we enable interrupts */ 387 if (status & USBSTS_RD)
387 uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; 388 uhci->resume_detect = 1;
388
389 /* Turn on PIRQ and all interrupts */
390 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
391 USBLEGSUP_DEFAULT);
392 outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
393 io_addr + USBINTR);
394 389
395 /* Start at frame 0 */ 390 spin_lock(&uhci->lock);
396 outw(0, io_addr + USBFRNUM); 391 uhci_scan_schedule(uhci, regs);
397 outl(uhci->fl->dma_handle, io_addr + USBFLBASEADD); 392 spin_unlock(&uhci->lock);
398 393
399 /* Run and mark it configured with a 64-byte max packet */ 394 return IRQ_HANDLED;
400 uhci->state = UHCI_RUNNING_GRACE; 395}
401 uhci->state_end = jiffies + HZ;
402 outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD);
403 uhci->is_stopped = 0;
404 396
405 return 0; 397/*
398 * Store the current frame number in uhci->frame_number if the controller
399 * is runnning
400 */
401static void uhci_get_current_frame_number(struct uhci_hcd *uhci)
402{
403 if (!uhci->is_stopped)
404 uhci->frame_number = inw(uhci->io_addr + USBFRNUM);
406} 405}
407 406
408/* 407/*