ehci-hub.c 16 KB

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