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