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