ehci-hub.c (9cdf083f981b8d37b3212400a359368661385099) ehci-hub.c (083522d76662cda71328df1f3d75e5a9057c7c9f)
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.
8 *

--- 33 unchanged lines hidden (view full) ---

42 port = HCS_N_PORTS (ehci->hcs_params);
43 spin_lock_irq (&ehci->lock);
44
45 /* stop schedules, clean any completed work */
46 if (HC_IS_RUNNING(hcd->state)) {
47 ehci_quiesce (ehci);
48 hcd->state = HC_STATE_QUIESCING;
49 }
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.
8 *

--- 33 unchanged lines hidden (view full) ---

42 port = HCS_N_PORTS (ehci->hcs_params);
43 spin_lock_irq (&ehci->lock);
44
45 /* stop schedules, clean any completed work */
46 if (HC_IS_RUNNING(hcd->state)) {
47 ehci_quiesce (ehci);
48 hcd->state = HC_STATE_QUIESCING;
49 }
50 ehci->command = readl (&ehci->regs->command);
50 ehci->command = ehci_readl(ehci, &ehci->regs->command);
51 if (ehci->reclaim)
52 ehci->reclaim_ready = 1;
53 ehci_work(ehci);
54
55 /* Unlike other USB host controller types, EHCI doesn't have
56 * any notion of "global" or bus-wide suspend. The driver has
57 * to manually suspend all the active unsuspended ports, and
58 * then manually resume them in the bus_resume() routine.
59 */
60 ehci->bus_suspended = 0;
61 while (port--) {
62 u32 __iomem *reg = &ehci->regs->port_status [port];
51 if (ehci->reclaim)
52 ehci->reclaim_ready = 1;
53 ehci_work(ehci);
54
55 /* Unlike other USB host controller types, EHCI doesn't have
56 * any notion of "global" or bus-wide suspend. The driver has
57 * to manually suspend all the active unsuspended ports, and
58 * then manually resume them in the bus_resume() routine.
59 */
60 ehci->bus_suspended = 0;
61 while (port--) {
62 u32 __iomem *reg = &ehci->regs->port_status [port];
63 u32 t1 = readl (reg) & ~PORT_RWC_BITS;
63 u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
64 u32 t2 = t1;
65
66 /* keep track of which ports we suspend */
67 if ((t1 & PORT_PE) && !(t1 & PORT_OWNER) &&
68 !(t1 & PORT_SUSPEND)) {
69 t2 |= PORT_SUSPEND;
70 set_bit(port, &ehci->bus_suspended);
71 }
72
73 /* enable remote wakeup on all ports */
74 if (device_may_wakeup(&hcd->self.root_hub->dev))
75 t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
76 else
77 t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
78
79 if (t1 != t2) {
80 ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
81 port + 1, t1, t2);
64 u32 t2 = t1;
65
66 /* keep track of which ports we suspend */
67 if ((t1 & PORT_PE) && !(t1 & PORT_OWNER) &&
68 !(t1 & PORT_SUSPEND)) {
69 t2 |= PORT_SUSPEND;
70 set_bit(port, &ehci->bus_suspended);
71 }
72
73 /* enable remote wakeup on all ports */
74 if (device_may_wakeup(&hcd->self.root_hub->dev))
75 t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
76 else
77 t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
78
79 if (t1 != t2) {
80 ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
81 port + 1, t1, t2);
82 writel (t2, reg);
82 ehci_writel(ehci, t2, reg);
83 }
84 }
85
86 /* turn off now-idle HC */
87 del_timer_sync (&ehci->watchdog);
88 ehci_halt (ehci);
89 hcd->state = HC_STATE_SUSPENDED;
90
91 /* allow remote wakeup */
92 mask = INTR_MASK;
93 if (!device_may_wakeup(&hcd->self.root_hub->dev))
94 mask &= ~STS_PCD;
83 }
84 }
85
86 /* turn off now-idle HC */
87 del_timer_sync (&ehci->watchdog);
88 ehci_halt (ehci);
89 hcd->state = HC_STATE_SUSPENDED;
90
91 /* allow remote wakeup */
92 mask = INTR_MASK;
93 if (!device_may_wakeup(&hcd->self.root_hub->dev))
94 mask &= ~STS_PCD;
95 writel(mask, &ehci->regs->intr_enable);
96 readl(&ehci->regs->intr_enable);
95 ehci_writel(ehci, mask, &ehci->regs->intr_enable);
96 ehci_readl(ehci, &ehci->regs->intr_enable);
97
98 ehci->next_statechange = jiffies + msecs_to_jiffies(10);
99 spin_unlock_irq (&ehci->lock);
100 return 0;
101}
102
103
104/* caller has locked the root hub, and should reset/reinit on error */

--- 8 unchanged lines hidden (view full) ---

113 spin_lock_irq (&ehci->lock);
114
115 /* Ideally and we've got a real resume here, and no port's power
116 * was lost. (For PCI, that means Vaux was maintained.) But we
117 * could instead be restoring a swsusp snapshot -- so that BIOS was
118 * the last user of the controller, not reset/pm hardware keeping
119 * state we gave to it.
120 */
97
98 ehci->next_statechange = jiffies + msecs_to_jiffies(10);
99 spin_unlock_irq (&ehci->lock);
100 return 0;
101}
102
103
104/* caller has locked the root hub, and should reset/reinit on error */

--- 8 unchanged lines hidden (view full) ---

113 spin_lock_irq (&ehci->lock);
114
115 /* Ideally and we've got a real resume here, and no port's power
116 * was lost. (For PCI, that means Vaux was maintained.) But we
117 * could instead be restoring a swsusp snapshot -- so that BIOS was
118 * the last user of the controller, not reset/pm hardware keeping
119 * state we gave to it.
120 */
121 temp = readl(&ehci->regs->intr_enable);
121 temp = ehci_readl(ehci, &ehci->regs->intr_enable);
122 ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss");
123
124 /* at least some APM implementations will try to deliver
125 * IRQs right away, so delay them until we're ready.
126 */
122 ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss");
123
124 /* at least some APM implementations will try to deliver
125 * IRQs right away, so delay them until we're ready.
126 */
127 writel(0, &ehci->regs->intr_enable);
127 ehci_writel(ehci, 0, &ehci->regs->intr_enable);
128
129 /* re-init operational registers */
128
129 /* re-init operational registers */
130 writel(0, &ehci->regs->segment);
131 writel(ehci->periodic_dma, &ehci->regs->frame_list);
132 writel((u32) ehci->async->qh_dma, &ehci->regs->async_next);
130 ehci_writel(ehci, 0, &ehci->regs->segment);
131 ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
132 ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next);
133
134 /* restore CMD_RUN, framelist size, and irq threshold */
133
134 /* restore CMD_RUN, framelist size, and irq threshold */
135 writel (ehci->command, &ehci->regs->command);
135 ehci_writel(ehci, ehci->command, &ehci->regs->command);
136
137 /* manually resume the ports we suspended during bus_suspend() */
138 i = HCS_N_PORTS (ehci->hcs_params);
139 while (i--) {
136
137 /* manually resume the ports we suspended during bus_suspend() */
138 i = HCS_N_PORTS (ehci->hcs_params);
139 while (i--) {
140 temp = readl (&ehci->regs->port_status [i]);
140 temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
141 temp &= ~(PORT_RWC_BITS
142 | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E);
143 if (test_bit(i, &ehci->bus_suspended) &&
144 (temp & PORT_SUSPEND)) {
145 ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
146 temp |= PORT_RESUME;
147 }
141 temp &= ~(PORT_RWC_BITS
142 | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E);
143 if (test_bit(i, &ehci->bus_suspended) &&
144 (temp & PORT_SUSPEND)) {
145 ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
146 temp |= PORT_RESUME;
147 }
148 writel (temp, &ehci->regs->port_status [i]);
148 ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
149 }
150 i = HCS_N_PORTS (ehci->hcs_params);
151 mdelay (20);
152 while (i--) {
149 }
150 i = HCS_N_PORTS (ehci->hcs_params);
151 mdelay (20);
152 while (i--) {
153 temp = readl (&ehci->regs->port_status [i]);
153 temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
154 if (test_bit(i, &ehci->bus_suspended) &&
155 (temp & PORT_SUSPEND)) {
156 temp &= ~(PORT_RWC_BITS | PORT_RESUME);
154 if (test_bit(i, &ehci->bus_suspended) &&
155 (temp & PORT_SUSPEND)) {
156 temp &= ~(PORT_RWC_BITS | PORT_RESUME);
157 writel (temp, &ehci->regs->port_status [i]);
157 ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
158 ehci_vdbg (ehci, "resumed port %d\n", i + 1);
159 }
160 }
158 ehci_vdbg (ehci, "resumed port %d\n", i + 1);
159 }
160 }
161 (void) readl (&ehci->regs->command);
161 (void) ehci_readl(ehci, &ehci->regs->command);
162
163 /* maybe re-activate the schedule(s) */
164 temp = 0;
165 if (ehci->async->qh_next.qh)
166 temp |= CMD_ASE;
167 if (ehci->periodic_sched)
168 temp |= CMD_PSE;
169 if (temp) {
170 ehci->command |= temp;
162
163 /* maybe re-activate the schedule(s) */
164 temp = 0;
165 if (ehci->async->qh_next.qh)
166 temp |= CMD_ASE;
167 if (ehci->periodic_sched)
168 temp |= CMD_PSE;
169 if (temp) {
170 ehci->command |= temp;
171 writel (ehci->command, &ehci->regs->command);
171 ehci_writel(ehci, ehci->command, &ehci->regs->command);
172 }
173
174 ehci->next_statechange = jiffies + msecs_to_jiffies(5);
175 hcd->state = HC_STATE_RUNNING;
176
177 /* Now we can safely re-enable irqs */
172 }
173
174 ehci->next_statechange = jiffies + msecs_to_jiffies(5);
175 hcd->state = HC_STATE_RUNNING;
176
177 /* Now we can safely re-enable irqs */
178 writel(INTR_MASK, &ehci->regs->intr_enable);
178 ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
179
180 spin_unlock_irq (&ehci->lock);
181 return 0;
182}
183
184#else
185
186#define ehci_bus_suspend NULL

--- 25 unchanged lines hidden (view full) ---

212 }
213
214 ehci_dbg (ehci, "port %d full speed --> companion\n",
215 index + 1);
216
217 // what happens if HCS_N_CC(params) == 0 ?
218 port_status |= PORT_OWNER;
219 port_status &= ~PORT_RWC_BITS;
179
180 spin_unlock_irq (&ehci->lock);
181 return 0;
182}
183
184#else
185
186#define ehci_bus_suspend NULL

--- 25 unchanged lines hidden (view full) ---

212 }
213
214 ehci_dbg (ehci, "port %d full speed --> companion\n",
215 index + 1);
216
217 // what happens if HCS_N_CC(params) == 0 ?
218 port_status |= PORT_OWNER;
219 port_status &= ~PORT_RWC_BITS;
220 writel (port_status, &ehci->regs->port_status [index]);
220 ehci_writel(ehci, port_status,
221 &ehci->regs->port_status [index]);
221
222 } else
223 ehci_dbg (ehci, "port %d high speed\n", index + 1);
224
225 return port_status;
226}
227
228/*-------------------------------------------------------------------------*/

--- 34 unchanged lines hidden (view full) ---

263 mask = PORT_CSC | PORT_PEC;
264 // PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND
265
266 /* no hub change reports (bit 0) for now (power, ...) */
267
268 /* port N changes (bit N)? */
269 spin_lock_irqsave (&ehci->lock, flags);
270 for (i = 0; i < ports; i++) {
222
223 } else
224 ehci_dbg (ehci, "port %d high speed\n", index + 1);
225
226 return port_status;
227}
228
229/*-------------------------------------------------------------------------*/

--- 34 unchanged lines hidden (view full) ---

264 mask = PORT_CSC | PORT_PEC;
265 // PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND
266
267 /* no hub change reports (bit 0) for now (power, ...) */
268
269 /* port N changes (bit N)? */
270 spin_lock_irqsave (&ehci->lock, flags);
271 for (i = 0; i < ports; i++) {
271 temp = readl (&ehci->regs->port_status [i]);
272 temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
272 if (temp & PORT_OWNER) {
273 /* don't report this in GetPortStatus */
274 if (temp & PORT_CSC) {
275 temp &= ~PORT_RWC_BITS;
276 temp |= PORT_CSC;
273 if (temp & PORT_OWNER) {
274 /* don't report this in GetPortStatus */
275 if (temp & PORT_CSC) {
276 temp &= ~PORT_RWC_BITS;
277 temp |= PORT_CSC;
277 writel (temp, &ehci->regs->port_status [i]);
278 ehci_writel(ehci, temp,
279 &ehci->regs->port_status [i]);
278 }
279 continue;
280 }
281 if (!(temp & PORT_CONNECT))
282 ehci->reset_done [i] = 0;
283 if ((temp & mask) != 0
284 || ((temp & PORT_RESUME) != 0
285 && time_after (jiffies,

--- 82 unchanged lines hidden (view full) ---

368 default:
369 goto error;
370 }
371 break;
372 case ClearPortFeature:
373 if (!wIndex || wIndex > ports)
374 goto error;
375 wIndex--;
280 }
281 continue;
282 }
283 if (!(temp & PORT_CONNECT))
284 ehci->reset_done [i] = 0;
285 if ((temp & mask) != 0
286 || ((temp & PORT_RESUME) != 0
287 && time_after (jiffies,

--- 82 unchanged lines hidden (view full) ---

370 default:
371 goto error;
372 }
373 break;
374 case ClearPortFeature:
375 if (!wIndex || wIndex > ports)
376 goto error;
377 wIndex--;
376 temp = readl (&ehci->regs->port_status [wIndex]);
378 temp = ehci_readl(ehci, &ehci->regs->port_status [wIndex]);
377 if (temp & PORT_OWNER)
378 break;
379
380 switch (wValue) {
381 case USB_PORT_FEAT_ENABLE:
379 if (temp & PORT_OWNER)
380 break;
381
382 switch (wValue) {
383 case USB_PORT_FEAT_ENABLE:
382 writel (temp & ~PORT_PE,
383 &ehci->regs->port_status [wIndex]);
384 ehci_writel(ehci, temp & ~PORT_PE,
385 &ehci->regs->port_status [wIndex]);
384 break;
385 case USB_PORT_FEAT_C_ENABLE:
386 break;
387 case USB_PORT_FEAT_C_ENABLE:
386 writel((temp & ~PORT_RWC_BITS) | PORT_PEC,
387 &ehci->regs->port_status [wIndex]);
388 ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC,
389 &ehci->regs->port_status [wIndex]);
388 break;
389 case USB_PORT_FEAT_SUSPEND:
390 if (temp & PORT_RESET)
391 goto error;
392 if (ehci->no_selective_suspend)
393 break;
394 if (temp & PORT_SUSPEND) {
395 if ((temp & PORT_PE) == 0)
396 goto error;
397 /* resume signaling for 20 msec */
398 temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
390 break;
391 case USB_PORT_FEAT_SUSPEND:
392 if (temp & PORT_RESET)
393 goto error;
394 if (ehci->no_selective_suspend)
395 break;
396 if (temp & PORT_SUSPEND) {
397 if ((temp & PORT_PE) == 0)
398 goto error;
399 /* resume signaling for 20 msec */
400 temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
399 writel (temp | PORT_RESUME,
400 &ehci->regs->port_status [wIndex]);
401 ehci_writel(ehci, temp | PORT_RESUME,
402 &ehci->regs->port_status [wIndex]);
401 ehci->reset_done [wIndex] = jiffies
402 + msecs_to_jiffies (20);
403 }
404 break;
405 case USB_PORT_FEAT_C_SUSPEND:
406 /* we auto-clear this feature */
407 break;
408 case USB_PORT_FEAT_POWER:
409 if (HCS_PPC (ehci->hcs_params))
403 ehci->reset_done [wIndex] = jiffies
404 + msecs_to_jiffies (20);
405 }
406 break;
407 case USB_PORT_FEAT_C_SUSPEND:
408 /* we auto-clear this feature */
409 break;
410 case USB_PORT_FEAT_POWER:
411 if (HCS_PPC (ehci->hcs_params))
410 writel (temp & ~(PORT_RWC_BITS | PORT_POWER),
411 &ehci->regs->port_status [wIndex]);
412 ehci_writel(ehci,
413 temp & ~(PORT_RWC_BITS | PORT_POWER),
414 &ehci->regs->port_status [wIndex]);
412 break;
413 case USB_PORT_FEAT_C_CONNECTION:
415 break;
416 case USB_PORT_FEAT_C_CONNECTION:
414 writel((temp & ~PORT_RWC_BITS) | PORT_CSC,
415 &ehci->regs->port_status [wIndex]);
417 ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC,
418 &ehci->regs->port_status [wIndex]);
416 break;
417 case USB_PORT_FEAT_C_OVER_CURRENT:
419 break;
420 case USB_PORT_FEAT_C_OVER_CURRENT:
418 writel((temp & ~PORT_RWC_BITS) | PORT_OCC,
419 &ehci->regs->port_status [wIndex]);
421 ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC,
422 &ehci->regs->port_status [wIndex]);
420 break;
421 case USB_PORT_FEAT_C_RESET:
422 /* GetPortStatus clears reset */
423 break;
424 default:
425 goto error;
426 }
423 break;
424 case USB_PORT_FEAT_C_RESET:
425 /* GetPortStatus clears reset */
426 break;
427 default:
428 goto error;
429 }
427 readl (&ehci->regs->command); /* unblock posted write */
430 ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */
428 break;
429 case GetHubDescriptor:
430 ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *)
431 buf);
432 break;
433 case GetHubStatus:
434 /* no hub-wide feature/status flags */
435 memset (buf, 0, 4);
436 //cpu_to_le32s ((u32 *) buf);
437 break;
438 case GetPortStatus:
439 if (!wIndex || wIndex > ports)
440 goto error;
441 wIndex--;
442 status = 0;
431 break;
432 case GetHubDescriptor:
433 ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *)
434 buf);
435 break;
436 case GetHubStatus:
437 /* no hub-wide feature/status flags */
438 memset (buf, 0, 4);
439 //cpu_to_le32s ((u32 *) buf);
440 break;
441 case GetPortStatus:
442 if (!wIndex || wIndex > ports)
443 goto error;
444 wIndex--;
445 status = 0;
443 temp = readl (&ehci->regs->port_status [wIndex]);
446 temp = ehci_readl(ehci, &ehci->regs->port_status [wIndex]);
444
445 // wPortChange bits
446 if (temp & PORT_CSC)
447 status |= 1 << USB_PORT_FEAT_C_CONNECTION;
448 if (temp & PORT_PEC)
449 status |= 1 << USB_PORT_FEAT_C_ENABLE;
450 if ((temp & PORT_OCC) && !ignore_oc)
451 status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT;
452
453 /* whoever resumes must GetPortStatus to complete it!! */
454 if ((temp & PORT_RESUME)
455 && time_after (jiffies,
456 ehci->reset_done [wIndex])) {
457 status |= 1 << USB_PORT_FEAT_C_SUSPEND;
458 ehci->reset_done [wIndex] = 0;
459
460 /* stop resume signaling */
447
448 // wPortChange bits
449 if (temp & PORT_CSC)
450 status |= 1 << USB_PORT_FEAT_C_CONNECTION;
451 if (temp & PORT_PEC)
452 status |= 1 << USB_PORT_FEAT_C_ENABLE;
453 if ((temp & PORT_OCC) && !ignore_oc)
454 status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT;
455
456 /* whoever resumes must GetPortStatus to complete it!! */
457 if ((temp & PORT_RESUME)
458 && time_after (jiffies,
459 ehci->reset_done [wIndex])) {
460 status |= 1 << USB_PORT_FEAT_C_SUSPEND;
461 ehci->reset_done [wIndex] = 0;
462
463 /* stop resume signaling */
461 temp = readl (&ehci->regs->port_status [wIndex]);
462 writel (temp & ~(PORT_RWC_BITS | PORT_RESUME),
463 &ehci->regs->port_status [wIndex]);
464 retval = handshake (
465 &ehci->regs->port_status [wIndex],
466 PORT_RESUME, 0, 2000 /* 2msec */);
464 temp = ehci_readl(ehci,
465 &ehci->regs->port_status [wIndex]);
466 ehci_writel(ehci,
467 temp & ~(PORT_RWC_BITS | PORT_RESUME),
468 &ehci->regs->port_status [wIndex]);
469 retval = handshake(ehci,
470 &ehci->regs->port_status [wIndex],
471 PORT_RESUME, 0, 2000 /* 2msec */);
467 if (retval != 0) {
468 ehci_err (ehci, "port %d resume error %d\n",
469 wIndex + 1, retval);
470 goto error;
471 }
472 temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
473 }
474
475 /* whoever resets must GetPortStatus to complete it!! */
476 if ((temp & PORT_RESET)
477 && time_after (jiffies,
478 ehci->reset_done [wIndex])) {
479 status |= 1 << USB_PORT_FEAT_C_RESET;
480 ehci->reset_done [wIndex] = 0;
481
482 /* force reset to complete */
472 if (retval != 0) {
473 ehci_err (ehci, "port %d resume error %d\n",
474 wIndex + 1, retval);
475 goto error;
476 }
477 temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
478 }
479
480 /* whoever resets must GetPortStatus to complete it!! */
481 if ((temp & PORT_RESET)
482 && time_after (jiffies,
483 ehci->reset_done [wIndex])) {
484 status |= 1 << USB_PORT_FEAT_C_RESET;
485 ehci->reset_done [wIndex] = 0;
486
487 /* force reset to complete */
483 writel (temp & ~(PORT_RWC_BITS | PORT_RESET),
484 &ehci->regs->port_status [wIndex]);
488 ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
489 &ehci->regs->port_status [wIndex]);
485 /* REVISIT: some hardware needs 550+ usec to clear
486 * this bit; seems too long to spin routinely...
487 */
490 /* REVISIT: some hardware needs 550+ usec to clear
491 * this bit; seems too long to spin routinely...
492 */
488 retval = handshake (
489 &ehci->regs->port_status [wIndex],
493 retval = handshake(ehci,
494 &ehci->regs->port_status [wIndex],
490 PORT_RESET, 0, 750);
491 if (retval != 0) {
492 ehci_err (ehci, "port %d reset error %d\n",
493 wIndex + 1, retval);
494 goto error;
495 }
496
497 /* see what we found out */
498 temp = check_reset_complete (ehci, wIndex,
495 PORT_RESET, 0, 750);
496 if (retval != 0) {
497 ehci_err (ehci, "port %d reset error %d\n",
498 wIndex + 1, retval);
499 goto error;
500 }
501
502 /* see what we found out */
503 temp = check_reset_complete (ehci, wIndex,
499 readl (&ehci->regs->port_status [wIndex]));
504 ehci_readl(ehci,
505 &ehci->regs->port_status [wIndex]));
500 }
501
502 // don't show wPortStatus if it's owned by a companion hc
503 if (!(temp & PORT_OWNER)) {
504 if (temp & PORT_CONNECT) {
505 status |= 1 << USB_PORT_FEAT_CONNECTION;
506 // status may be from integrated TT
507 status |= ehci_port_speed(ehci, temp);

--- 28 unchanged lines hidden (view full) ---

536 }
537 break;
538 case SetPortFeature:
539 selector = wIndex >> 8;
540 wIndex &= 0xff;
541 if (!wIndex || wIndex > ports)
542 goto error;
543 wIndex--;
506 }
507
508 // don't show wPortStatus if it's owned by a companion hc
509 if (!(temp & PORT_OWNER)) {
510 if (temp & PORT_CONNECT) {
511 status |= 1 << USB_PORT_FEAT_CONNECTION;
512 // status may be from integrated TT
513 status |= ehci_port_speed(ehci, temp);

--- 28 unchanged lines hidden (view full) ---

542 }
543 break;
544 case SetPortFeature:
545 selector = wIndex >> 8;
546 wIndex &= 0xff;
547 if (!wIndex || wIndex > ports)
548 goto error;
549 wIndex--;
544 temp = readl (&ehci->regs->port_status [wIndex]);
550 temp = ehci_readl(ehci, &ehci->regs->port_status [wIndex]);
545 if (temp & PORT_OWNER)
546 break;
547
548 temp &= ~PORT_RWC_BITS;
549 switch (wValue) {
550 case USB_PORT_FEAT_SUSPEND:
551 if (ehci->no_selective_suspend)
552 break;
553 if ((temp & PORT_PE) == 0
554 || (temp & PORT_RESET) != 0)
555 goto error;
556 if (device_may_wakeup(&hcd->self.root_hub->dev))
557 temp |= PORT_WAKE_BITS;
551 if (temp & PORT_OWNER)
552 break;
553
554 temp &= ~PORT_RWC_BITS;
555 switch (wValue) {
556 case USB_PORT_FEAT_SUSPEND:
557 if (ehci->no_selective_suspend)
558 break;
559 if ((temp & PORT_PE) == 0
560 || (temp & PORT_RESET) != 0)
561 goto error;
562 if (device_may_wakeup(&hcd->self.root_hub->dev))
563 temp |= PORT_WAKE_BITS;
558 writel (temp | PORT_SUSPEND,
559 &ehci->regs->port_status [wIndex]);
564 ehci_writel(ehci, temp | PORT_SUSPEND,
565 &ehci->regs->port_status [wIndex]);
560 break;
561 case USB_PORT_FEAT_POWER:
562 if (HCS_PPC (ehci->hcs_params))
566 break;
567 case USB_PORT_FEAT_POWER:
568 if (HCS_PPC (ehci->hcs_params))
563 writel (temp | PORT_POWER,
564 &ehci->regs->port_status [wIndex]);
569 ehci_writel(ehci, temp | PORT_POWER,
570 &ehci->regs->port_status [wIndex]);
565 break;
566 case USB_PORT_FEAT_RESET:
567 if (temp & PORT_RESUME)
568 goto error;
569 /* line status bits may report this as low speed,
570 * which can be fine if this root hub has a
571 * transaction translator built in.
572 */

--- 11 unchanged lines hidden (view full) ---

584
585 /*
586 * caller must wait, then call GetPortStatus
587 * usb 2.0 spec says 50 ms resets on root
588 */
589 ehci->reset_done [wIndex] = jiffies
590 + msecs_to_jiffies (50);
591 }
571 break;
572 case USB_PORT_FEAT_RESET:
573 if (temp & PORT_RESUME)
574 goto error;
575 /* line status bits may report this as low speed,
576 * which can be fine if this root hub has a
577 * transaction translator built in.
578 */

--- 11 unchanged lines hidden (view full) ---

590
591 /*
592 * caller must wait, then call GetPortStatus
593 * usb 2.0 spec says 50 ms resets on root
594 */
595 ehci->reset_done [wIndex] = jiffies
596 + msecs_to_jiffies (50);
597 }
592 writel (temp, &ehci->regs->port_status [wIndex]);
598 ehci_writel(ehci, temp,
599 &ehci->regs->port_status [wIndex]);
593 break;
594
595 /* For downstream facing ports (these): one hub port is put
596 * into test mode according to USB2 11.24.2.13, then the hub
597 * must be reset (which for root hub now means rmmod+modprobe,
598 * or else system reboot). See EHCI 2.3.9 and 4.14 for info
599 * about the EHCI-specific stuff.
600 */
601 case USB_PORT_FEAT_TEST:
602 if (!selector || selector > 5)
603 goto error;
604 ehci_quiesce(ehci);
605 ehci_halt(ehci);
606 temp |= selector << 16;
600 break;
601
602 /* For downstream facing ports (these): one hub port is put
603 * into test mode according to USB2 11.24.2.13, then the hub
604 * must be reset (which for root hub now means rmmod+modprobe,
605 * or else system reboot). See EHCI 2.3.9 and 4.14 for info
606 * about the EHCI-specific stuff.
607 */
608 case USB_PORT_FEAT_TEST:
609 if (!selector || selector > 5)
610 goto error;
611 ehci_quiesce(ehci);
612 ehci_halt(ehci);
613 temp |= selector << 16;
607 writel (temp, &ehci->regs->port_status [wIndex]);
614 ehci_writel(ehci, temp,
615 &ehci->regs->port_status [wIndex]);
608 break;
609
610 default:
611 goto error;
612 }
616 break;
617
618 default:
619 goto error;
620 }
613 readl (&ehci->regs->command); /* unblock posted writes */
621 ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
614 break;
615
616 default:
617error:
618 /* "stall" on error */
619 retval = -EPIPE;
620 }
621 spin_unlock_irqrestore (&ehci->lock, flags);
622 return retval;
623}
622 break;
623
624 default:
625error:
626 /* "stall" on error */
627 retval = -EPIPE;
628 }
629 spin_unlock_irqrestore (&ehci->lock, flags);
630 return retval;
631}