Linux 2.6.17.7
[linux/fpc-iii.git] / drivers / usb / host / ehci-hub.c
blobd03e3cad5ca8a90a2cf7319a2f92891b481a1784
1 /*
2 * Copyright (C) 2001-2004 by David Brownell
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* this file is part of ehci-hcd.c */
21 /*-------------------------------------------------------------------------*/
24 * EHCI Root Hub ... the nonsharable stuff
26 * Registers don't need cpu_to_le32, that happens transparently
29 /*-------------------------------------------------------------------------*/
31 #ifdef CONFIG_PM
33 static int ehci_bus_suspend (struct usb_hcd *hcd)
35 struct ehci_hcd *ehci = hcd_to_ehci (hcd);
36 int port;
38 if (time_before (jiffies, ehci->next_statechange))
39 msleep(5);
41 port = HCS_N_PORTS (ehci->hcs_params);
42 spin_lock_irq (&ehci->lock);
44 /* stop schedules, clean any completed work */
45 if (HC_IS_RUNNING(hcd->state)) {
46 ehci_quiesce (ehci);
47 hcd->state = HC_STATE_QUIESCING;
49 ehci->command = readl (&ehci->regs->command);
50 if (ehci->reclaim)
51 ehci->reclaim_ready = 1;
52 ehci_work(ehci, NULL);
54 /* suspend any active/unsuspended ports, maybe allow wakeup */
55 while (port--) {
56 u32 __iomem *reg = &ehci->regs->port_status [port];
57 u32 t1 = readl (reg) & ~PORT_RWC_BITS;
58 u32 t2 = t1;
60 if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
61 t2 |= PORT_SUSPEND;
62 if (device_may_wakeup(&hcd->self.root_hub->dev))
63 t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
64 else
65 t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
67 if (t1 != t2) {
68 ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
69 port + 1, t1, t2);
70 writel (t2, reg);
74 /* turn off now-idle HC */
75 del_timer_sync (&ehci->watchdog);
76 ehci_halt (ehci);
77 hcd->state = HC_STATE_SUSPENDED;
79 ehci->next_statechange = jiffies + msecs_to_jiffies(10);
80 spin_unlock_irq (&ehci->lock);
81 return 0;
85 /* caller has locked the root hub, and should reset/reinit on error */
86 static int ehci_bus_resume (struct usb_hcd *hcd)
88 struct ehci_hcd *ehci = hcd_to_ehci (hcd);
89 u32 temp;
90 int i;
91 int intr_enable;
93 if (time_before (jiffies, ehci->next_statechange))
94 msleep(5);
95 spin_lock_irq (&ehci->lock);
97 /* Ideally and we've got a real resume here, and no port's power
98 * was lost. (For PCI, that means Vaux was maintained.) But we
99 * could instead be restoring a swsusp snapshot -- so that BIOS was
100 * the last user of the controller, not reset/pm hardware keeping
101 * state we gave to it.
104 /* re-init operational registers in case we lost power */
105 if (readl (&ehci->regs->intr_enable) == 0) {
106 /* at least some APM implementations will try to deliver
107 * IRQs right away, so delay them until we're ready.
109 intr_enable = 1;
110 writel (0, &ehci->regs->segment);
111 writel (ehci->periodic_dma, &ehci->regs->frame_list);
112 writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next);
113 } else
114 intr_enable = 0;
115 ehci_dbg(ehci, "resume root hub%s\n",
116 intr_enable ? " after power loss" : "");
118 /* restore CMD_RUN, framelist size, and irq threshold */
119 writel (ehci->command, &ehci->regs->command);
121 /* take ports out of suspend */
122 i = HCS_N_PORTS (ehci->hcs_params);
123 while (i--) {
124 temp = readl (&ehci->regs->port_status [i]);
125 temp &= ~(PORT_RWC_BITS
126 | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E);
127 if (temp & PORT_SUSPEND) {
128 ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
129 temp |= PORT_RESUME;
131 writel (temp, &ehci->regs->port_status [i]);
133 i = HCS_N_PORTS (ehci->hcs_params);
134 mdelay (20);
135 while (i--) {
136 temp = readl (&ehci->regs->port_status [i]);
137 if ((temp & PORT_SUSPEND) == 0)
138 continue;
139 temp &= ~(PORT_RWC_BITS | PORT_RESUME);
140 writel (temp, &ehci->regs->port_status [i]);
141 ehci_vdbg (ehci, "resumed port %d\n", i + 1);
143 (void) readl (&ehci->regs->command);
145 /* maybe re-activate the schedule(s) */
146 temp = 0;
147 if (ehci->async->qh_next.qh)
148 temp |= CMD_ASE;
149 if (ehci->periodic_sched)
150 temp |= CMD_PSE;
151 if (temp) {
152 ehci->command |= temp;
153 writel (ehci->command, &ehci->regs->command);
156 ehci->next_statechange = jiffies + msecs_to_jiffies(5);
157 hcd->state = HC_STATE_RUNNING;
159 /* Now we can safely re-enable irqs */
160 if (intr_enable)
161 writel (INTR_MASK, &ehci->regs->intr_enable);
163 spin_unlock_irq (&ehci->lock);
164 return 0;
167 #else
169 #define ehci_bus_suspend NULL
170 #define ehci_bus_resume NULL
172 #endif /* CONFIG_PM */
174 /*-------------------------------------------------------------------------*/
176 static int check_reset_complete (
177 struct ehci_hcd *ehci,
178 int index,
179 int port_status
181 if (!(port_status & PORT_CONNECT)) {
182 ehci->reset_done [index] = 0;
183 return port_status;
186 /* if reset finished and it's still not enabled -- handoff */
187 if (!(port_status & PORT_PE)) {
189 /* with integrated TT, there's nobody to hand it to! */
190 if (ehci_is_TDI(ehci)) {
191 ehci_dbg (ehci,
192 "Failed to enable port %d on root hub TT\n",
193 index+1);
194 return port_status;
197 ehci_dbg (ehci, "port %d full speed --> companion\n",
198 index + 1);
200 // what happens if HCS_N_CC(params) == 0 ?
201 port_status |= PORT_OWNER;
202 port_status &= ~PORT_RWC_BITS;
203 writel (port_status, &ehci->regs->port_status [index]);
205 } else
206 ehci_dbg (ehci, "port %d high speed\n", index + 1);
208 return port_status;
211 /*-------------------------------------------------------------------------*/
214 /* build "status change" packet (one or two bytes) from HC registers */
216 static int
217 ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
219 struct ehci_hcd *ehci = hcd_to_ehci (hcd);
220 u32 temp, status = 0;
221 int ports, i, retval = 1;
222 unsigned long flags;
224 /* if !USB_SUSPEND, root hub timers won't get shut down ... */
225 if (!HC_IS_RUNNING(hcd->state))
226 return 0;
228 /* init status to no-changes */
229 buf [0] = 0;
230 ports = HCS_N_PORTS (ehci->hcs_params);
231 if (ports > 7) {
232 buf [1] = 0;
233 retval++;
236 /* no hub change reports (bit 0) for now (power, ...) */
238 /* port N changes (bit N)? */
239 spin_lock_irqsave (&ehci->lock, flags);
240 for (i = 0; i < ports; i++) {
241 temp = readl (&ehci->regs->port_status [i]);
242 if (temp & PORT_OWNER) {
243 /* don't report this in GetPortStatus */
244 if (temp & PORT_CSC) {
245 temp &= ~PORT_RWC_BITS;
246 temp |= PORT_CSC;
247 writel (temp, &ehci->regs->port_status [i]);
249 continue;
251 if (!(temp & PORT_CONNECT))
252 ehci->reset_done [i] = 0;
253 if ((temp & (PORT_CSC | PORT_PEC | PORT_OCC)) != 0
254 // PORT_STAT_C_SUSPEND?
255 || ((temp & PORT_RESUME) != 0
256 && time_after (jiffies,
257 ehci->reset_done [i]))) {
258 if (i < 7)
259 buf [0] |= 1 << (i + 1);
260 else
261 buf [1] |= 1 << (i - 7);
262 status = STS_PCD;
265 /* FIXME autosuspend idle root hubs */
266 spin_unlock_irqrestore (&ehci->lock, flags);
267 return status ? retval : 0;
270 /*-------------------------------------------------------------------------*/
272 static void
273 ehci_hub_descriptor (
274 struct ehci_hcd *ehci,
275 struct usb_hub_descriptor *desc
277 int ports = HCS_N_PORTS (ehci->hcs_params);
278 u16 temp;
280 desc->bDescriptorType = 0x29;
281 desc->bPwrOn2PwrGood = 10; /* ehci 1.0, 2.3.9 says 20ms max */
282 desc->bHubContrCurrent = 0;
284 desc->bNbrPorts = ports;
285 temp = 1 + (ports / 8);
286 desc->bDescLength = 7 + 2 * temp;
288 /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */
289 memset (&desc->bitmap [0], 0, temp);
290 memset (&desc->bitmap [temp], 0xff, temp);
292 temp = 0x0008; /* per-port overcurrent reporting */
293 if (HCS_PPC (ehci->hcs_params))
294 temp |= 0x0001; /* per-port power control */
295 else
296 temp |= 0x0002; /* no power switching */
297 #if 0
298 // re-enable when we support USB_PORT_FEAT_INDICATOR below.
299 if (HCS_INDICATOR (ehci->hcs_params))
300 temp |= 0x0080; /* per-port indicators (LEDs) */
301 #endif
302 desc->wHubCharacteristics = (__force __u16)cpu_to_le16 (temp);
305 /*-------------------------------------------------------------------------*/
307 #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
309 static int ehci_hub_control (
310 struct usb_hcd *hcd,
311 u16 typeReq,
312 u16 wValue,
313 u16 wIndex,
314 char *buf,
315 u16 wLength
317 struct ehci_hcd *ehci = hcd_to_ehci (hcd);
318 int ports = HCS_N_PORTS (ehci->hcs_params);
319 u32 temp, status;
320 unsigned long flags;
321 int retval = 0;
324 * FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR.
325 * HCS_INDICATOR may say we can change LEDs to off/amber/green.
326 * (track current state ourselves) ... blink for diagnostics,
327 * power, "this is the one", etc. EHCI spec supports this.
330 spin_lock_irqsave (&ehci->lock, flags);
331 switch (typeReq) {
332 case ClearHubFeature:
333 switch (wValue) {
334 case C_HUB_LOCAL_POWER:
335 case C_HUB_OVER_CURRENT:
336 /* no hub-wide feature/status flags */
337 break;
338 default:
339 goto error;
341 break;
342 case ClearPortFeature:
343 if (!wIndex || wIndex > ports)
344 goto error;
345 wIndex--;
346 temp = readl (&ehci->regs->port_status [wIndex]);
347 if (temp & PORT_OWNER)
348 break;
350 switch (wValue) {
351 case USB_PORT_FEAT_ENABLE:
352 writel (temp & ~PORT_PE,
353 &ehci->regs->port_status [wIndex]);
354 break;
355 case USB_PORT_FEAT_C_ENABLE:
356 writel((temp & ~PORT_RWC_BITS) | PORT_PEC,
357 &ehci->regs->port_status [wIndex]);
358 break;
359 case USB_PORT_FEAT_SUSPEND:
360 if (temp & PORT_RESET)
361 goto error;
362 if (ehci->no_selective_suspend)
363 break;
364 if (temp & PORT_SUSPEND) {
365 if ((temp & PORT_PE) == 0)
366 goto error;
367 /* resume signaling for 20 msec */
368 temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
369 writel (temp | PORT_RESUME,
370 &ehci->regs->port_status [wIndex]);
371 ehci->reset_done [wIndex] = jiffies
372 + msecs_to_jiffies (20);
374 break;
375 case USB_PORT_FEAT_C_SUSPEND:
376 /* we auto-clear this feature */
377 break;
378 case USB_PORT_FEAT_POWER:
379 if (HCS_PPC (ehci->hcs_params))
380 writel (temp & ~(PORT_RWC_BITS | PORT_POWER),
381 &ehci->regs->port_status [wIndex]);
382 break;
383 case USB_PORT_FEAT_C_CONNECTION:
384 writel((temp & ~PORT_RWC_BITS) | PORT_CSC,
385 &ehci->regs->port_status [wIndex]);
386 break;
387 case USB_PORT_FEAT_C_OVER_CURRENT:
388 writel((temp & ~PORT_RWC_BITS) | PORT_OCC,
389 &ehci->regs->port_status [wIndex]);
390 break;
391 case USB_PORT_FEAT_C_RESET:
392 /* GetPortStatus clears reset */
393 break;
394 default:
395 goto error;
397 readl (&ehci->regs->command); /* unblock posted write */
398 break;
399 case GetHubDescriptor:
400 ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *)
401 buf);
402 break;
403 case GetHubStatus:
404 /* no hub-wide feature/status flags */
405 memset (buf, 0, 4);
406 //cpu_to_le32s ((u32 *) buf);
407 break;
408 case GetPortStatus:
409 if (!wIndex || wIndex > ports)
410 goto error;
411 wIndex--;
412 status = 0;
413 temp = readl (&ehci->regs->port_status [wIndex]);
415 // wPortChange bits
416 if (temp & PORT_CSC)
417 status |= 1 << USB_PORT_FEAT_C_CONNECTION;
418 if (temp & PORT_PEC)
419 status |= 1 << USB_PORT_FEAT_C_ENABLE;
420 if (temp & PORT_OCC)
421 status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT;
423 /* whoever resumes must GetPortStatus to complete it!! */
424 if ((temp & PORT_RESUME)
425 && time_after (jiffies,
426 ehci->reset_done [wIndex])) {
427 status |= 1 << USB_PORT_FEAT_C_SUSPEND;
428 ehci->reset_done [wIndex] = 0;
430 /* stop resume signaling */
431 temp = readl (&ehci->regs->port_status [wIndex]);
432 writel (temp & ~(PORT_RWC_BITS | PORT_RESUME),
433 &ehci->regs->port_status [wIndex]);
434 retval = handshake (
435 &ehci->regs->port_status [wIndex],
436 PORT_RESUME, 0, 2000 /* 2msec */);
437 if (retval != 0) {
438 ehci_err (ehci, "port %d resume error %d\n",
439 wIndex + 1, retval);
440 goto error;
442 temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
445 /* whoever resets must GetPortStatus to complete it!! */
446 if ((temp & PORT_RESET)
447 && time_after (jiffies,
448 ehci->reset_done [wIndex])) {
449 status |= 1 << USB_PORT_FEAT_C_RESET;
450 ehci->reset_done [wIndex] = 0;
452 /* force reset to complete */
453 writel (temp & ~(PORT_RWC_BITS | PORT_RESET),
454 &ehci->regs->port_status [wIndex]);
455 /* REVISIT: some hardware needs 550+ usec to clear
456 * this bit; seems too long to spin routinely...
458 retval = handshake (
459 &ehci->regs->port_status [wIndex],
460 PORT_RESET, 0, 750);
461 if (retval != 0) {
462 ehci_err (ehci, "port %d reset error %d\n",
463 wIndex + 1, retval);
464 goto error;
467 /* see what we found out */
468 temp = check_reset_complete (ehci, wIndex,
469 readl (&ehci->regs->port_status [wIndex]));
472 // don't show wPortStatus if it's owned by a companion hc
473 if (!(temp & PORT_OWNER)) {
474 if (temp & PORT_CONNECT) {
475 status |= 1 << USB_PORT_FEAT_CONNECTION;
476 // status may be from integrated TT
477 status |= ehci_port_speed(ehci, temp);
479 if (temp & PORT_PE)
480 status |= 1 << USB_PORT_FEAT_ENABLE;
481 if (temp & (PORT_SUSPEND|PORT_RESUME))
482 status |= 1 << USB_PORT_FEAT_SUSPEND;
483 if (temp & PORT_OC)
484 status |= 1 << USB_PORT_FEAT_OVER_CURRENT;
485 if (temp & PORT_RESET)
486 status |= 1 << USB_PORT_FEAT_RESET;
487 if (temp & PORT_POWER)
488 status |= 1 << USB_PORT_FEAT_POWER;
491 #ifndef EHCI_VERBOSE_DEBUG
492 if (status & ~0xffff) /* only if wPortChange is interesting */
493 #endif
494 dbg_port (ehci, "GetStatus", wIndex + 1, temp);
495 // we "know" this alignment is good, caller used kmalloc()...
496 *((__le32 *) buf) = cpu_to_le32 (status);
497 break;
498 case SetHubFeature:
499 switch (wValue) {
500 case C_HUB_LOCAL_POWER:
501 case C_HUB_OVER_CURRENT:
502 /* no hub-wide feature/status flags */
503 break;
504 default:
505 goto error;
507 break;
508 case SetPortFeature:
509 if (!wIndex || wIndex > ports)
510 goto error;
511 wIndex--;
512 temp = readl (&ehci->regs->port_status [wIndex]);
513 if (temp & PORT_OWNER)
514 break;
516 temp &= ~PORT_RWC_BITS;
517 switch (wValue) {
518 case USB_PORT_FEAT_SUSPEND:
519 if (ehci->no_selective_suspend)
520 break;
521 if ((temp & PORT_PE) == 0
522 || (temp & PORT_RESET) != 0)
523 goto error;
524 if (device_may_wakeup(&hcd->self.root_hub->dev))
525 temp |= PORT_WAKE_BITS;
526 writel (temp | PORT_SUSPEND,
527 &ehci->regs->port_status [wIndex]);
528 break;
529 case USB_PORT_FEAT_POWER:
530 if (HCS_PPC (ehci->hcs_params))
531 writel (temp | PORT_POWER,
532 &ehci->regs->port_status [wIndex]);
533 break;
534 case USB_PORT_FEAT_RESET:
535 if (temp & PORT_RESUME)
536 goto error;
537 /* line status bits may report this as low speed,
538 * which can be fine if this root hub has a
539 * transaction translator built in.
541 if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT
542 && !ehci_is_TDI(ehci)
543 && PORT_USB11 (temp)) {
544 ehci_dbg (ehci,
545 "port %d low speed --> companion\n",
546 wIndex + 1);
547 temp |= PORT_OWNER;
548 } else {
549 ehci_vdbg (ehci, "port %d reset\n", wIndex + 1);
550 temp |= PORT_RESET;
551 temp &= ~PORT_PE;
554 * caller must wait, then call GetPortStatus
555 * usb 2.0 spec says 50 ms resets on root
557 ehci->reset_done [wIndex] = jiffies
558 + msecs_to_jiffies (50);
560 writel (temp, &ehci->regs->port_status [wIndex]);
561 break;
562 default:
563 goto error;
565 readl (&ehci->regs->command); /* unblock posted writes */
566 break;
568 default:
569 error:
570 /* "stall" on error */
571 retval = -EPIPE;
573 spin_unlock_irqrestore (&ehci->lock, flags);
574 return retval;