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