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 (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); 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 /* 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. 102 */ 103 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. 108 */ 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" : ""); 117 118 /* restore CMD_RUN, framelist size, and irq threshold */ 119 writel (ehci->command, &ehci->regs->command); 120 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; 130 } 131 writel (temp, &ehci->regs->port_status [i]); 132 } 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); 142 } 143 (void) readl (&ehci->regs->command); 144 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); 154 } 155 156 ehci->next_statechange = jiffies + msecs_to_jiffies(5); 157 hcd->state = HC_STATE_RUNNING; 158 159 /* Now we can safely re-enable irqs */ 160 if (intr_enable) 161 writel (INTR_MASK, &ehci->regs->intr_enable); 162 163 spin_unlock_irq (&ehci->lock); 164 return 0; 165 } 166 167 #else 168 169 #define ehci_bus_suspend NULL 170 #define ehci_bus_resume NULL 171 172 #endif /* CONFIG_PM */ 173 174 /*-------------------------------------------------------------------------*/ 175 176 static int check_reset_complete ( 177 struct ehci_hcd *ehci, 178 int index, 179 int port_status 180 ) { 181 if (!(port_status & PORT_CONNECT)) { 182 ehci->reset_done [index] = 0; 183 return port_status; 184 } 185 186 /* if reset finished and it's still not enabled -- handoff */ 187 if (!(port_status & PORT_PE)) { 188 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; 195 } 196 197 ehci_dbg (ehci, "port %d full speed --> companion\n", 198 index + 1); 199 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]); 204 205 } else 206 ehci_dbg (ehci, "port %d high speed\n", index + 1); 207 208 return port_status; 209 } 210 211 /*-------------------------------------------------------------------------*/ 212 213 214 /* build "status change" packet (one or two bytes) from HC registers */ 215 216 static int 217 ehci_hub_status_data (struct usb_hcd *hcd, char *buf) 218 { 219 struct ehci_hcd *ehci = hcd_to_ehci (hcd); 220 u32 temp, status = 0; 221 int ports, i, retval = 1; 222 unsigned long flags; 223 224 /* if !USB_SUSPEND, root hub timers won't get shut down ... */ 225 if (!HC_IS_RUNNING(hcd->state)) 226 return 0; 227 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++; 234 } 235 236 /* no hub change reports (bit 0) for now (power, ...) */ 237 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]); 248 } 249 continue; 250 } 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; 263 } 264 } 265 /* FIXME autosuspend idle root hubs */ 266 spin_unlock_irqrestore (&ehci->lock, flags); 267 return status ? retval : 0; 268 } 269 270 /*-------------------------------------------------------------------------*/ 271 272 static void 273 ehci_hub_descriptor ( 274 struct ehci_hcd *ehci, 275 struct usb_hub_descriptor *desc 276 ) { 277 int ports = HCS_N_PORTS (ehci->hcs_params); 278 u16 temp; 279 280 desc->bDescriptorType = 0x29; 281 desc->bPwrOn2PwrGood = 10; /* ehci 1.0, 2.3.9 says 20ms max */ 282 desc->bHubContrCurrent = 0; 283 284 desc->bNbrPorts = ports; 285 temp = 1 + (ports / 8); 286 desc->bDescLength = 7 + 2 * temp; 287 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); 291 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); 303 } 304 305 /*-------------------------------------------------------------------------*/ 306 307 #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) 308 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 316 ) { 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; 322 323 /* 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. 328 */ 329 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; 340 } 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; 349 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 (temp & PORT_SUSPEND) { 363 if ((temp & PORT_PE) == 0) 364 goto error; 365 /* resume signaling for 20 msec */ 366 temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); 367 writel (temp | PORT_RESUME, 368 &ehci->regs->port_status [wIndex]); 369 ehci->reset_done [wIndex] = jiffies 370 + msecs_to_jiffies (20); 371 } 372 break; 373 case USB_PORT_FEAT_C_SUSPEND: 374 /* we auto-clear this feature */ 375 break; 376 case USB_PORT_FEAT_POWER: 377 if (HCS_PPC (ehci->hcs_params)) 378 writel (temp & ~(PORT_RWC_BITS | PORT_POWER), 379 &ehci->regs->port_status [wIndex]); 380 break; 381 case USB_PORT_FEAT_C_CONNECTION: 382 writel((temp & ~PORT_RWC_BITS) | PORT_CSC, 383 &ehci->regs->port_status [wIndex]); 384 break; 385 case USB_PORT_FEAT_C_OVER_CURRENT: 386 writel((temp & ~PORT_RWC_BITS) | PORT_OCC, 387 &ehci->regs->port_status [wIndex]); 388 break; 389 case USB_PORT_FEAT_C_RESET: 390 /* GetPortStatus clears reset */ 391 break; 392 default: 393 goto error; 394 } 395 readl (&ehci->regs->command); /* unblock posted write */ 396 break; 397 case GetHubDescriptor: 398 ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *) 399 buf); 400 break; 401 case GetHubStatus: 402 /* no hub-wide feature/status flags */ 403 memset (buf, 0, 4); 404 //cpu_to_le32s ((u32 *) buf); 405 break; 406 case GetPortStatus: 407 if (!wIndex || wIndex > ports) 408 goto error; 409 wIndex--; 410 status = 0; 411 temp = readl (&ehci->regs->port_status [wIndex]); 412 413 // wPortChange bits 414 if (temp & PORT_CSC) 415 status |= 1 << USB_PORT_FEAT_C_CONNECTION; 416 if (temp & PORT_PEC) 417 status |= 1 << USB_PORT_FEAT_C_ENABLE; 418 if (temp & PORT_OCC) 419 status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; 420 421 /* whoever resumes must GetPortStatus to complete it!! */ 422 if ((temp & PORT_RESUME) 423 && time_after (jiffies, 424 ehci->reset_done [wIndex])) { 425 status |= 1 << USB_PORT_FEAT_C_SUSPEND; 426 ehci->reset_done [wIndex] = 0; 427 428 /* stop resume signaling */ 429 temp = readl (&ehci->regs->port_status [wIndex]); 430 writel (temp & ~(PORT_RWC_BITS | PORT_RESUME), 431 &ehci->regs->port_status [wIndex]); 432 retval = handshake ( 433 &ehci->regs->port_status [wIndex], 434 PORT_RESUME, 0, 2000 /* 2msec */); 435 if (retval != 0) { 436 ehci_err (ehci, "port %d resume error %d\n", 437 wIndex + 1, retval); 438 goto error; 439 } 440 temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); 441 } 442 443 /* whoever resets must GetPortStatus to complete it!! */ 444 if ((temp & PORT_RESET) 445 && time_after (jiffies, 446 ehci->reset_done [wIndex])) { 447 status |= 1 << USB_PORT_FEAT_C_RESET; 448 ehci->reset_done [wIndex] = 0; 449 450 /* force reset to complete */ 451 writel (temp & ~(PORT_RWC_BITS | PORT_RESET), 452 &ehci->regs->port_status [wIndex]); 453 /* REVISIT: some hardware needs 550+ usec to clear 454 * this bit; seems too long to spin routinely... 455 */ 456 retval = handshake ( 457 &ehci->regs->port_status [wIndex], 458 PORT_RESET, 0, 750); 459 if (retval != 0) { 460 ehci_err (ehci, "port %d reset error %d\n", 461 wIndex + 1, retval); 462 goto error; 463 } 464 465 /* see what we found out */ 466 temp = check_reset_complete (ehci, wIndex, 467 readl (&ehci->regs->port_status [wIndex])); 468 } 469 470 // don't show wPortStatus if it's owned by a companion hc 471 if (!(temp & PORT_OWNER)) { 472 if (temp & PORT_CONNECT) { 473 status |= 1 << USB_PORT_FEAT_CONNECTION; 474 // status may be from integrated TT 475 status |= ehci_port_speed(ehci, temp); 476 } 477 if (temp & PORT_PE) 478 status |= 1 << USB_PORT_FEAT_ENABLE; 479 if (temp & (PORT_SUSPEND|PORT_RESUME)) 480 status |= 1 << USB_PORT_FEAT_SUSPEND; 481 if (temp & PORT_OC) 482 status |= 1 << USB_PORT_FEAT_OVER_CURRENT; 483 if (temp & PORT_RESET) 484 status |= 1 << USB_PORT_FEAT_RESET; 485 if (temp & PORT_POWER) 486 status |= 1 << USB_PORT_FEAT_POWER; 487 } 488 489 #ifndef EHCI_VERBOSE_DEBUG 490 if (status & ~0xffff) /* only if wPortChange is interesting */ 491 #endif 492 dbg_port (ehci, "GetStatus", wIndex + 1, temp); 493 // we "know" this alignment is good, caller used kmalloc()... 494 *((__le32 *) buf) = cpu_to_le32 (status); 495 break; 496 case SetHubFeature: 497 switch (wValue) { 498 case C_HUB_LOCAL_POWER: 499 case C_HUB_OVER_CURRENT: 500 /* no hub-wide feature/status flags */ 501 break; 502 default: 503 goto error; 504 } 505 break; 506 case SetPortFeature: 507 if (!wIndex || wIndex > ports) 508 goto error; 509 wIndex--; 510 temp = readl (&ehci->regs->port_status [wIndex]); 511 if (temp & PORT_OWNER) 512 break; 513 514 temp &= ~PORT_RWC_BITS; 515 switch (wValue) { 516 case USB_PORT_FEAT_SUSPEND: 517 if ((temp & PORT_PE) == 0 518 || (temp & PORT_RESET) != 0) 519 goto error; 520 if (device_may_wakeup(&hcd->self.root_hub->dev)) 521 temp |= PORT_WAKE_BITS; 522 writel (temp | PORT_SUSPEND, 523 &ehci->regs->port_status [wIndex]); 524 break; 525 case USB_PORT_FEAT_POWER: 526 if (HCS_PPC (ehci->hcs_params)) 527 writel (temp | PORT_POWER, 528 &ehci->regs->port_status [wIndex]); 529 break; 530 case USB_PORT_FEAT_RESET: 531 if (temp & PORT_RESUME) 532 goto error; 533 /* line status bits may report this as low speed, 534 * which can be fine if this root hub has a 535 * transaction translator built in. 536 */ 537 if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT 538 && !ehci_is_TDI(ehci) 539 && PORT_USB11 (temp)) { 540 ehci_dbg (ehci, 541 "port %d low speed --> companion\n", 542 wIndex + 1); 543 temp |= PORT_OWNER; 544 } else { 545 ehci_vdbg (ehci, "port %d reset\n", wIndex + 1); 546 temp |= PORT_RESET; 547 temp &= ~PORT_PE; 548 549 /* 550 * caller must wait, then call GetPortStatus 551 * usb 2.0 spec says 50 ms resets on root 552 */ 553 ehci->reset_done [wIndex] = jiffies 554 + msecs_to_jiffies (50); 555 } 556 writel (temp, &ehci->regs->port_status [wIndex]); 557 break; 558 default: 559 goto error; 560 } 561 readl (&ehci->regs->command); /* unblock posted writes */ 562 break; 563 564 default: 565 error: 566 /* "stall" on error */ 567 retval = -EPIPE; 568 } 569 spin_unlock_irqrestore (&ehci->lock, flags); 570 return retval; 571 } 572