xref: /linux/drivers/usb/host/ehci-hub.c (revision d67b569f5f620c0fb95d5212642746b7ba9d29e4)
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  *
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.
13  *
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.
17  */
18 
19 /* this file is part of ehci-hcd.c */
20 
21 /*-------------------------------------------------------------------------*/
22 
23 /*
24  * EHCI Root Hub ... the nonsharable stuff
25  *
26  * Registers don't need cpu_to_le32, that happens transparently
27  */
28 
29 /*-------------------------------------------------------------------------*/
30 
31 #ifdef	CONFIG_PM
32 
33 static int ehci_hub_suspend (struct usb_hcd *hcd)
34 {
35 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
36 	int			port;
37 
38 	if (time_before (jiffies, ehci->next_statechange))
39 		msleep(5);
40 
41 	port = HCS_N_PORTS (ehci->hcs_params);
42 	spin_lock_irq (&ehci->lock);
43 
44 	/* stop schedules, clean any completed work */
45 	if (HC_IS_RUNNING(hcd->state)) {
46 		ehci_quiesce (ehci);
47 		hcd->state = HC_STATE_QUIESCING;
48 	}
49 	ehci->command = readl (&ehci->regs->command);
50 	if (ehci->reclaim)
51 		ehci->reclaim_ready = 1;
52 	ehci_work(ehci, NULL);
53 
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);
58 		u32		t2 = t1;
59 
60 		if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
61 			t2 |= PORT_SUSPEND;
62 		if (hcd->remote_wakeup)
63 			t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
64 		else
65 			t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
66 
67 		if (t1 != t2) {
68 			ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
69 				port + 1, t1, t2);
70 			writel (t2, reg);
71 		}
72 	}
73 
74 	/* turn off now-idle HC */
75 	del_timer_sync (&ehci->watchdog);
76 	ehci_halt (ehci);
77 	hcd->state = HC_STATE_SUSPENDED;
78 
79 	ehci->next_statechange = jiffies + msecs_to_jiffies(10);
80 	spin_unlock_irq (&ehci->lock);
81 	return 0;
82 }
83 
84 
85 /* caller has locked the root hub, and should reset/reinit on error */
86 static int ehci_hub_resume (struct usb_hcd *hcd)
87 {
88 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
89 	u32			temp;
90 	int			i;
91 	int			intr_enable;
92 
93 	if (time_before (jiffies, ehci->next_statechange))
94 		msleep(5);
95 	spin_lock_irq (&ehci->lock);
96 
97 	/* re-init operational registers in case we lost power */
98 	if (readl (&ehci->regs->intr_enable) == 0) {
99  		/* at least some APM implementations will try to deliver
100 		 * IRQs right away, so delay them until we're ready.
101  		 */
102  		intr_enable = 1;
103 		writel (0, &ehci->regs->segment);
104 		writel (ehci->periodic_dma, &ehci->regs->frame_list);
105 		writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next);
106 	} else
107 		intr_enable = 0;
108 	ehci_dbg(ehci, "resume root hub%s\n",
109 			intr_enable ? " after power loss" : "");
110 
111 	/* restore CMD_RUN, framelist size, and irq threshold */
112 	writel (ehci->command, &ehci->regs->command);
113 
114 	/* take ports out of suspend */
115 	i = HCS_N_PORTS (ehci->hcs_params);
116 	while (i--) {
117 		temp = readl (&ehci->regs->port_status [i]);
118 		temp &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
119 		if (temp & PORT_SUSPEND) {
120 			ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
121 			temp |= PORT_RESUME;
122 		}
123 		writel (temp, &ehci->regs->port_status [i]);
124 	}
125 	i = HCS_N_PORTS (ehci->hcs_params);
126 	mdelay (20);
127 	while (i--) {
128 		temp = readl (&ehci->regs->port_status [i]);
129 		if ((temp & PORT_SUSPEND) == 0)
130 			continue;
131 		temp &= ~PORT_RESUME;
132 		writel (temp, &ehci->regs->port_status [i]);
133 		ehci_vdbg (ehci, "resumed port %d\n", i + 1);
134 	}
135 	(void) readl (&ehci->regs->command);
136 
137 	/* maybe re-activate the schedule(s) */
138 	temp = 0;
139 	if (ehci->async->qh_next.qh)
140 		temp |= CMD_ASE;
141 	if (ehci->periodic_sched)
142 		temp |= CMD_PSE;
143 	if (temp) {
144 		ehci->command |= temp;
145 		writel (ehci->command, &ehci->regs->command);
146 	}
147 
148 	ehci->next_statechange = jiffies + msecs_to_jiffies(5);
149 	hcd->state = HC_STATE_RUNNING;
150 
151 	/* Now we can safely re-enable irqs */
152 	if (intr_enable)
153 		writel (INTR_MASK, &ehci->regs->intr_enable);
154 
155 	spin_unlock_irq (&ehci->lock);
156 	return 0;
157 }
158 
159 #else
160 
161 #define ehci_hub_suspend	NULL
162 #define ehci_hub_resume		NULL
163 
164 #endif	/* CONFIG_PM */
165 
166 /*-------------------------------------------------------------------------*/
167 
168 static int check_reset_complete (
169 	struct ehci_hcd	*ehci,
170 	int		index,
171 	int		port_status
172 ) {
173 	if (!(port_status & PORT_CONNECT)) {
174 		ehci->reset_done [index] = 0;
175 		return port_status;
176 	}
177 
178 	/* if reset finished and it's still not enabled -- handoff */
179 	if (!(port_status & PORT_PE)) {
180 
181 		/* with integrated TT, there's nobody to hand it to! */
182 		if (ehci_is_TDI(ehci)) {
183 			ehci_dbg (ehci,
184 				"Failed to enable port %d on root hub TT\n",
185 				index+1);
186 			return port_status;
187 		}
188 
189 		ehci_dbg (ehci, "port %d full speed --> companion\n",
190 			index + 1);
191 
192 		// what happens if HCS_N_CC(params) == 0 ?
193 		port_status |= PORT_OWNER;
194 		writel (port_status, &ehci->regs->port_status [index]);
195 
196 	} else
197 		ehci_dbg (ehci, "port %d high speed\n", index + 1);
198 
199 	return port_status;
200 }
201 
202 /*-------------------------------------------------------------------------*/
203 
204 
205 /* build "status change" packet (one or two bytes) from HC registers */
206 
207 static int
208 ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
209 {
210 	struct ehci_hcd	*ehci = hcd_to_ehci (hcd);
211 	u32		temp, status = 0;
212 	int		ports, i, retval = 1;
213 	unsigned long	flags;
214 
215 	/* if !USB_SUSPEND, root hub timers won't get shut down ... */
216 	if (!HC_IS_RUNNING(hcd->state))
217 		return 0;
218 
219 	/* init status to no-changes */
220 	buf [0] = 0;
221 	ports = HCS_N_PORTS (ehci->hcs_params);
222 	if (ports > 7) {
223 		buf [1] = 0;
224 		retval++;
225 	}
226 
227 	/* no hub change reports (bit 0) for now (power, ...) */
228 
229 	/* port N changes (bit N)? */
230 	spin_lock_irqsave (&ehci->lock, flags);
231 	for (i = 0; i < ports; i++) {
232 		temp = readl (&ehci->regs->port_status [i]);
233 		if (temp & PORT_OWNER) {
234 			/* don't report this in GetPortStatus */
235 			if (temp & PORT_CSC) {
236 				temp &= ~PORT_CSC;
237 				writel (temp, &ehci->regs->port_status [i]);
238 			}
239 			continue;
240 		}
241 		if (!(temp & PORT_CONNECT))
242 			ehci->reset_done [i] = 0;
243 		if ((temp & (PORT_CSC | PORT_PEC | PORT_OCC)) != 0
244 				// PORT_STAT_C_SUSPEND?
245 				|| ((temp & PORT_RESUME) != 0
246 					&& time_after (jiffies,
247 						ehci->reset_done [i]))) {
248 			if (i < 7)
249 			    buf [0] |= 1 << (i + 1);
250 			else
251 			    buf [1] |= 1 << (i - 7);
252 			status = STS_PCD;
253 		}
254 	}
255 	/* FIXME autosuspend idle root hubs */
256 	spin_unlock_irqrestore (&ehci->lock, flags);
257 	return status ? retval : 0;
258 }
259 
260 /*-------------------------------------------------------------------------*/
261 
262 static void
263 ehci_hub_descriptor (
264 	struct ehci_hcd			*ehci,
265 	struct usb_hub_descriptor	*desc
266 ) {
267 	int		ports = HCS_N_PORTS (ehci->hcs_params);
268 	u16		temp;
269 
270 	desc->bDescriptorType = 0x29;
271 	desc->bPwrOn2PwrGood = 10;	/* ehci 1.0, 2.3.9 says 20ms max */
272 	desc->bHubContrCurrent = 0;
273 
274 	desc->bNbrPorts = ports;
275 	temp = 1 + (ports / 8);
276 	desc->bDescLength = 7 + 2 * temp;
277 
278 	/* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
279 	memset (&desc->bitmap [0], 0, temp);
280 	memset (&desc->bitmap [temp], 0xff, temp);
281 
282 	temp = 0x0008;			/* per-port overcurrent reporting */
283 	if (HCS_PPC (ehci->hcs_params))
284 		temp |= 0x0001;		/* per-port power control */
285 	else
286 		temp |= 0x0002;		/* no power switching */
287 #if 0
288 // re-enable when we support USB_PORT_FEAT_INDICATOR below.
289 	if (HCS_INDICATOR (ehci->hcs_params))
290 		temp |= 0x0080;		/* per-port indicators (LEDs) */
291 #endif
292 	desc->wHubCharacteristics = (__force __u16)cpu_to_le16 (temp);
293 }
294 
295 /*-------------------------------------------------------------------------*/
296 
297 #define	PORT_WAKE_BITS 	(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
298 
299 static int ehci_hub_control (
300 	struct usb_hcd	*hcd,
301 	u16		typeReq,
302 	u16		wValue,
303 	u16		wIndex,
304 	char		*buf,
305 	u16		wLength
306 ) {
307 	struct ehci_hcd	*ehci = hcd_to_ehci (hcd);
308 	int		ports = HCS_N_PORTS (ehci->hcs_params);
309 	u32		temp, status;
310 	unsigned long	flags;
311 	int		retval = 0;
312 
313 	/*
314 	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
315 	 * HCS_INDICATOR may say we can change LEDs to off/amber/green.
316 	 * (track current state ourselves) ... blink for diagnostics,
317 	 * power, "this is the one", etc.  EHCI spec supports this.
318 	 */
319 
320 	spin_lock_irqsave (&ehci->lock, flags);
321 	switch (typeReq) {
322 	case ClearHubFeature:
323 		switch (wValue) {
324 		case C_HUB_LOCAL_POWER:
325 		case C_HUB_OVER_CURRENT:
326 			/* no hub-wide feature/status flags */
327 			break;
328 		default:
329 			goto error;
330 		}
331 		break;
332 	case ClearPortFeature:
333 		if (!wIndex || wIndex > ports)
334 			goto error;
335 		wIndex--;
336 		temp = readl (&ehci->regs->port_status [wIndex]);
337 		if (temp & PORT_OWNER)
338 			break;
339 
340 		switch (wValue) {
341 		case USB_PORT_FEAT_ENABLE:
342 			writel (temp & ~PORT_PE,
343 				&ehci->regs->port_status [wIndex]);
344 			break;
345 		case USB_PORT_FEAT_C_ENABLE:
346 			writel (temp | PORT_PEC,
347 				&ehci->regs->port_status [wIndex]);
348 			break;
349 		case USB_PORT_FEAT_SUSPEND:
350 			if (temp & PORT_RESET)
351 				goto error;
352 			if (temp & PORT_SUSPEND) {
353 				if ((temp & PORT_PE) == 0)
354 					goto error;
355 				/* resume signaling for 20 msec */
356 				writel ((temp & ~PORT_WAKE_BITS) | PORT_RESUME,
357 					&ehci->regs->port_status [wIndex]);
358 				ehci->reset_done [wIndex] = jiffies
359 						+ msecs_to_jiffies (20);
360 			}
361 			break;
362 		case USB_PORT_FEAT_C_SUSPEND:
363 			/* we auto-clear this feature */
364 			break;
365 		case USB_PORT_FEAT_POWER:
366 			if (HCS_PPC (ehci->hcs_params))
367 				writel (temp & ~PORT_POWER,
368 					&ehci->regs->port_status [wIndex]);
369 			break;
370 		case USB_PORT_FEAT_C_CONNECTION:
371 			writel (temp | PORT_CSC,
372 				&ehci->regs->port_status [wIndex]);
373 			break;
374 		case USB_PORT_FEAT_C_OVER_CURRENT:
375 			writel (temp | PORT_OCC,
376 				&ehci->regs->port_status [wIndex]);
377 			break;
378 		case USB_PORT_FEAT_C_RESET:
379 			/* GetPortStatus clears reset */
380 			break;
381 		default:
382 			goto error;
383 		}
384 		readl (&ehci->regs->command);	/* unblock posted write */
385 		break;
386 	case GetHubDescriptor:
387 		ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *)
388 			buf);
389 		break;
390 	case GetHubStatus:
391 		/* no hub-wide feature/status flags */
392 		memset (buf, 0, 4);
393 		//cpu_to_le32s ((u32 *) buf);
394 		break;
395 	case GetPortStatus:
396 		if (!wIndex || wIndex > ports)
397 			goto error;
398 		wIndex--;
399 		status = 0;
400 		temp = readl (&ehci->regs->port_status [wIndex]);
401 
402 		// wPortChange bits
403 		if (temp & PORT_CSC)
404 			status |= 1 << USB_PORT_FEAT_C_CONNECTION;
405 		if (temp & PORT_PEC)
406 			status |= 1 << USB_PORT_FEAT_C_ENABLE;
407 		if (temp & PORT_OCC)
408 			status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT;
409 
410 		/* whoever resumes must GetPortStatus to complete it!! */
411 		if ((temp & PORT_RESUME)
412 				&& time_after (jiffies,
413 					ehci->reset_done [wIndex])) {
414 			status |= 1 << USB_PORT_FEAT_C_SUSPEND;
415 			ehci->reset_done [wIndex] = 0;
416 
417 			/* stop resume signaling */
418 			temp = readl (&ehci->regs->port_status [wIndex]);
419 			writel (temp & ~PORT_RESUME,
420 				&ehci->regs->port_status [wIndex]);
421 			retval = handshake (
422 					&ehci->regs->port_status [wIndex],
423 					PORT_RESUME, 0, 2000 /* 2msec */);
424 			if (retval != 0) {
425 				ehci_err (ehci, "port %d resume error %d\n",
426 					wIndex + 1, retval);
427 				goto error;
428 			}
429 			temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
430 		}
431 
432 		/* whoever resets must GetPortStatus to complete it!! */
433 		if ((temp & PORT_RESET)
434 				&& time_after (jiffies,
435 					ehci->reset_done [wIndex])) {
436 			status |= 1 << USB_PORT_FEAT_C_RESET;
437 			ehci->reset_done [wIndex] = 0;
438 
439 			/* force reset to complete */
440 			writel (temp & ~PORT_RESET,
441 					&ehci->regs->port_status [wIndex]);
442 			/* REVISIT:  some hardware needs 550+ usec to clear
443 			 * this bit; seems too long to spin routinely...
444 			 */
445 			retval = handshake (
446 					&ehci->regs->port_status [wIndex],
447 					PORT_RESET, 0, 750);
448 			if (retval != 0) {
449 				ehci_err (ehci, "port %d reset error %d\n",
450 					wIndex + 1, retval);
451 				goto error;
452 			}
453 
454 			/* see what we found out */
455 			temp = check_reset_complete (ehci, wIndex,
456 				readl (&ehci->regs->port_status [wIndex]));
457 		}
458 
459 		// don't show wPortStatus if it's owned by a companion hc
460 		if (!(temp & PORT_OWNER)) {
461 			if (temp & PORT_CONNECT) {
462 				status |= 1 << USB_PORT_FEAT_CONNECTION;
463 				// status may be from integrated TT
464 				status |= ehci_port_speed(ehci, temp);
465 			}
466 			if (temp & PORT_PE)
467 				status |= 1 << USB_PORT_FEAT_ENABLE;
468 			if (temp & (PORT_SUSPEND|PORT_RESUME))
469 				status |= 1 << USB_PORT_FEAT_SUSPEND;
470 			if (temp & PORT_OC)
471 				status |= 1 << USB_PORT_FEAT_OVER_CURRENT;
472 			if (temp & PORT_RESET)
473 				status |= 1 << USB_PORT_FEAT_RESET;
474 			if (temp & PORT_POWER)
475 				status |= 1 << USB_PORT_FEAT_POWER;
476 		}
477 
478 #ifndef	EHCI_VERBOSE_DEBUG
479 	if (status & ~0xffff)	/* only if wPortChange is interesting */
480 #endif
481 		dbg_port (ehci, "GetStatus", wIndex + 1, temp);
482 		// we "know" this alignment is good, caller used kmalloc()...
483 		*((__le32 *) buf) = cpu_to_le32 (status);
484 		break;
485 	case SetHubFeature:
486 		switch (wValue) {
487 		case C_HUB_LOCAL_POWER:
488 		case C_HUB_OVER_CURRENT:
489 			/* no hub-wide feature/status flags */
490 			break;
491 		default:
492 			goto error;
493 		}
494 		break;
495 	case SetPortFeature:
496 		if (!wIndex || wIndex > ports)
497 			goto error;
498 		wIndex--;
499 		temp = readl (&ehci->regs->port_status [wIndex]);
500 		if (temp & PORT_OWNER)
501 			break;
502 
503 		switch (wValue) {
504 		case USB_PORT_FEAT_SUSPEND:
505 			if ((temp & PORT_PE) == 0
506 					|| (temp & PORT_RESET) != 0)
507 				goto error;
508 			if (hcd->remote_wakeup)
509 				temp |= PORT_WAKE_BITS;
510 			writel (temp | PORT_SUSPEND,
511 				&ehci->regs->port_status [wIndex]);
512 			break;
513 		case USB_PORT_FEAT_POWER:
514 			if (HCS_PPC (ehci->hcs_params))
515 				writel (temp | PORT_POWER,
516 					&ehci->regs->port_status [wIndex]);
517 			break;
518 		case USB_PORT_FEAT_RESET:
519 			if (temp & PORT_RESUME)
520 				goto error;
521 			/* line status bits may report this as low speed,
522 			 * which can be fine if this root hub has a
523 			 * transaction translator built in.
524 			 */
525 			if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT
526 					&& !ehci_is_TDI(ehci)
527 					&& PORT_USB11 (temp)) {
528 				ehci_dbg (ehci,
529 					"port %d low speed --> companion\n",
530 					wIndex + 1);
531 				temp |= PORT_OWNER;
532 			} else {
533 				ehci_vdbg (ehci, "port %d reset\n", wIndex + 1);
534 				temp |= PORT_RESET;
535 				temp &= ~PORT_PE;
536 
537 				/*
538 				 * caller must wait, then call GetPortStatus
539 				 * usb 2.0 spec says 50 ms resets on root
540 				 */
541 				ehci->reset_done [wIndex] = jiffies
542 						+ msecs_to_jiffies (50);
543 			}
544 			writel (temp, &ehci->regs->port_status [wIndex]);
545 			break;
546 		default:
547 			goto error;
548 		}
549 		readl (&ehci->regs->command);	/* unblock posted writes */
550 		break;
551 
552 	default:
553 error:
554 		/* "stall" on error */
555 		retval = -EPIPE;
556 	}
557 	spin_unlock_irqrestore (&ehci->lock, flags);
558 	return retval;
559 }
560