musb_procfs.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  1. /*
  2. * MUSB OTG driver debug support
  3. *
  4. * Copyright 2005 Mentor Graphics Corporation
  5. * Copyright (C) 2005-2006 by Texas Instruments
  6. * Copyright (C) 2006-2007 Nokia Corporation
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * version 2 as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA
  21. *
  22. * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
  23. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  24. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
  25. * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  27. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  28. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  29. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  31. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. *
  33. */
  34. #include <linux/kernel.h>
  35. #include <linux/proc_fs.h>
  36. #include <linux/seq_file.h>
  37. #include <linux/uaccess.h> /* FIXME remove procfs writes */
  38. #include <asm/arch/hardware.h>
  39. #include "musb_core.h"
  40. #include "davinci.h"
  41. #ifdef CONFIG_USB_MUSB_HDRC_HCD
  42. static int dump_qh(struct musb_qh *qh, char *buf, unsigned max)
  43. {
  44. int count;
  45. int tmp;
  46. struct usb_host_endpoint *hep = qh->hep;
  47. struct urb *urb;
  48. count = snprintf(buf, max, " qh %p dev%d ep%d%s max%d\n",
  49. qh, qh->dev->devnum, qh->epnum,
  50. ({ char *s; switch (qh->type) {
  51. case USB_ENDPOINT_XFER_BULK:
  52. s = "-bulk"; break;
  53. case USB_ENDPOINT_XFER_INT:
  54. s = "-int"; break;
  55. case USB_ENDPOINT_XFER_CONTROL:
  56. s = ""; break;
  57. default:
  58. s = "iso"; break;
  59. }; s; }),
  60. qh->maxpacket);
  61. if (count <= 0)
  62. return 0;
  63. buf += count;
  64. max -= count;
  65. list_for_each_entry(urb, &hep->urb_list, urb_list) {
  66. tmp = snprintf(buf, max, "\t%s urb %p %d/%d\n",
  67. usb_pipein(urb->pipe) ? "in" : "out",
  68. urb, urb->actual_length,
  69. urb->transfer_buffer_length);
  70. if (tmp <= 0)
  71. break;
  72. tmp = min(tmp, (int)max);
  73. count += tmp;
  74. buf += tmp;
  75. max -= tmp;
  76. }
  77. return count;
  78. }
  79. static int
  80. dump_queue(struct list_head *q, char *buf, unsigned max)
  81. {
  82. int count = 0;
  83. struct musb_qh *qh;
  84. list_for_each_entry(qh, q, ring) {
  85. int tmp;
  86. tmp = dump_qh(qh, buf, max);
  87. if (tmp <= 0)
  88. break;
  89. tmp = min(tmp, (int)max);
  90. count += tmp;
  91. buf += tmp;
  92. max -= tmp;
  93. }
  94. return count;
  95. }
  96. #endif /* HCD */
  97. #ifdef CONFIG_USB_GADGET_MUSB_HDRC
  98. static int dump_ep(struct musb_ep *ep, char *buffer, unsigned max)
  99. {
  100. char *buf = buffer;
  101. int code = 0;
  102. void __iomem *regs = ep->hw_ep->regs;
  103. char *mode = "1buf";
  104. if (ep->is_in) {
  105. if (ep->hw_ep->tx_double_buffered)
  106. mode = "2buf";
  107. } else {
  108. if (ep->hw_ep->rx_double_buffered)
  109. mode = "2buf";
  110. }
  111. do {
  112. struct usb_request *req;
  113. code = snprintf(buf, max,
  114. "\n%s (hw%d): %s%s, csr %04x maxp %04x\n",
  115. ep->name, ep->current_epnum,
  116. mode, ep->dma ? " dma" : "",
  117. musb_readw(regs,
  118. (ep->is_in || !ep->current_epnum)
  119. ? MUSB_TXCSR
  120. : MUSB_RXCSR),
  121. musb_readw(regs, ep->is_in
  122. ? MUSB_TXMAXP
  123. : MUSB_RXMAXP)
  124. );
  125. if (code <= 0)
  126. break;
  127. code = min(code, (int) max);
  128. buf += code;
  129. max -= code;
  130. if (is_cppi_enabled() && ep->current_epnum) {
  131. unsigned cppi = ep->current_epnum - 1;
  132. void __iomem *base = ep->musb->ctrl_base;
  133. unsigned off1 = cppi << 2;
  134. void __iomem *ram = base;
  135. char tmp[16];
  136. if (ep->is_in) {
  137. ram += DAVINCI_TXCPPI_STATERAM_OFFSET(cppi);
  138. tmp[0] = 0;
  139. } else {
  140. ram += DAVINCI_RXCPPI_STATERAM_OFFSET(cppi);
  141. snprintf(tmp, sizeof tmp, "%d left, ",
  142. musb_readl(base,
  143. DAVINCI_RXCPPI_BUFCNT0_REG + off1));
  144. }
  145. code = snprintf(buf, max, "%cX DMA%d: %s"
  146. "%08x %08x, %08x %08x; "
  147. "%08x %08x %08x .. %08x\n",
  148. ep->is_in ? 'T' : 'R',
  149. ep->current_epnum - 1, tmp,
  150. musb_readl(ram, 0 * 4),
  151. musb_readl(ram, 1 * 4),
  152. musb_readl(ram, 2 * 4),
  153. musb_readl(ram, 3 * 4),
  154. musb_readl(ram, 4 * 4),
  155. musb_readl(ram, 5 * 4),
  156. musb_readl(ram, 6 * 4),
  157. musb_readl(ram, 7 * 4));
  158. if (code <= 0)
  159. break;
  160. code = min(code, (int) max);
  161. buf += code;
  162. max -= code;
  163. }
  164. if (list_empty(&ep->req_list)) {
  165. code = snprintf(buf, max, "\t(queue empty)\n");
  166. if (code <= 0)
  167. break;
  168. code = min(code, (int) max);
  169. buf += code;
  170. max -= code;
  171. break;
  172. }
  173. list_for_each_entry(req, &ep->req_list, list) {
  174. code = snprintf(buf, max, "\treq %p, %s%s%d/%d\n",
  175. req,
  176. req->zero ? "zero, " : "",
  177. req->short_not_ok ? "!short, " : "",
  178. req->actual, req->length);
  179. if (code <= 0)
  180. break;
  181. code = min(code, (int) max);
  182. buf += code;
  183. max -= code;
  184. }
  185. } while (0);
  186. return buf - buffer;
  187. }
  188. #endif
  189. static int
  190. dump_end_info(struct musb *musb, u8 epnum, char *aBuffer, unsigned max)
  191. {
  192. int code = 0;
  193. char *buf = aBuffer;
  194. struct musb_hw_ep *hw_ep = &musb->endpoints[epnum];
  195. do {
  196. musb_ep_select(musb->mregs, epnum);
  197. #ifdef CONFIG_USB_MUSB_HDRC_HCD
  198. if (is_host_active(musb)) {
  199. int dump_rx, dump_tx;
  200. void __iomem *regs = hw_ep->regs;
  201. /* TEMPORARY (!) until we have a real periodic
  202. * schedule tree ...
  203. */
  204. if (!epnum) {
  205. /* control is shared, uses RX queue
  206. * but (mostly) shadowed tx registers
  207. */
  208. dump_tx = !list_empty(&musb->control);
  209. dump_rx = 0;
  210. } else if (hw_ep == musb->bulk_ep) {
  211. dump_tx = !list_empty(&musb->out_bulk);
  212. dump_rx = !list_empty(&musb->in_bulk);
  213. } else if (musb->periodic[epnum]) {
  214. struct usb_host_endpoint *hep;
  215. hep = musb->periodic[epnum]->hep;
  216. dump_rx = hep->desc.bEndpointAddress
  217. & USB_ENDPOINT_DIR_MASK;
  218. dump_tx = !dump_rx;
  219. } else
  220. break;
  221. /* END TEMPORARY */
  222. if (dump_rx) {
  223. code = snprintf(buf, max,
  224. "\nRX%d: %s rxcsr %04x interval %02x "
  225. "max %04x type %02x; "
  226. "dev %d hub %d port %d"
  227. "\n",
  228. epnum,
  229. hw_ep->rx_double_buffered
  230. ? "2buf" : "1buf",
  231. musb_readw(regs, MUSB_RXCSR),
  232. musb_readb(regs, MUSB_RXINTERVAL),
  233. musb_readw(regs, MUSB_RXMAXP),
  234. musb_readb(regs, MUSB_RXTYPE),
  235. /* FIXME: assumes multipoint */
  236. musb_readb(musb->mregs,
  237. MUSB_BUSCTL_OFFSET(epnum,
  238. MUSB_RXFUNCADDR)),
  239. musb_readb(musb->mregs,
  240. MUSB_BUSCTL_OFFSET(epnum,
  241. MUSB_RXHUBADDR)),
  242. musb_readb(musb->mregs,
  243. MUSB_BUSCTL_OFFSET(epnum,
  244. MUSB_RXHUBPORT))
  245. );
  246. if (code <= 0)
  247. break;
  248. code = min(code, (int) max);
  249. buf += code;
  250. max -= code;
  251. if (is_cppi_enabled()
  252. && epnum
  253. && hw_ep->rx_channel) {
  254. unsigned cppi = epnum - 1;
  255. unsigned off1 = cppi << 2;
  256. void __iomem *base;
  257. void __iomem *ram;
  258. char tmp[16];
  259. base = musb->ctrl_base;
  260. ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
  261. cppi) + base;
  262. snprintf(tmp, sizeof tmp, "%d left, ",
  263. musb_readl(base,
  264. DAVINCI_RXCPPI_BUFCNT0_REG
  265. + off1));
  266. code = snprintf(buf, max,
  267. " rx dma%d: %s"
  268. "%08x %08x, %08x %08x; "
  269. "%08x %08x %08x .. %08x\n",
  270. cppi, tmp,
  271. musb_readl(ram, 0 * 4),
  272. musb_readl(ram, 1 * 4),
  273. musb_readl(ram, 2 * 4),
  274. musb_readl(ram, 3 * 4),
  275. musb_readl(ram, 4 * 4),
  276. musb_readl(ram, 5 * 4),
  277. musb_readl(ram, 6 * 4),
  278. musb_readl(ram, 7 * 4));
  279. if (code <= 0)
  280. break;
  281. code = min(code, (int) max);
  282. buf += code;
  283. max -= code;
  284. }
  285. if (hw_ep == musb->bulk_ep
  286. && !list_empty(
  287. &musb->in_bulk)) {
  288. code = dump_queue(&musb->in_bulk,
  289. buf, max);
  290. if (code <= 0)
  291. break;
  292. code = min(code, (int) max);
  293. buf += code;
  294. max -= code;
  295. } else if (musb->periodic[epnum]) {
  296. code = dump_qh(musb->periodic[epnum],
  297. buf, max);
  298. if (code <= 0)
  299. break;
  300. code = min(code, (int) max);
  301. buf += code;
  302. max -= code;
  303. }
  304. }
  305. if (dump_tx) {
  306. code = snprintf(buf, max,
  307. "\nTX%d: %s txcsr %04x interval %02x "
  308. "max %04x type %02x; "
  309. "dev %d hub %d port %d"
  310. "\n",
  311. epnum,
  312. hw_ep->tx_double_buffered
  313. ? "2buf" : "1buf",
  314. musb_readw(regs, MUSB_TXCSR),
  315. musb_readb(regs, MUSB_TXINTERVAL),
  316. musb_readw(regs, MUSB_TXMAXP),
  317. musb_readb(regs, MUSB_TXTYPE),
  318. /* FIXME: assumes multipoint */
  319. musb_readb(musb->mregs,
  320. MUSB_BUSCTL_OFFSET(epnum,
  321. MUSB_TXFUNCADDR)),
  322. musb_readb(musb->mregs,
  323. MUSB_BUSCTL_OFFSET(epnum,
  324. MUSB_TXHUBADDR)),
  325. musb_readb(musb->mregs,
  326. MUSB_BUSCTL_OFFSET(epnum,
  327. MUSB_TXHUBPORT))
  328. );
  329. if (code <= 0)
  330. break;
  331. code = min(code, (int) max);
  332. buf += code;
  333. max -= code;
  334. if (is_cppi_enabled()
  335. && epnum
  336. && hw_ep->tx_channel) {
  337. unsigned cppi = epnum - 1;
  338. void __iomem *base;
  339. void __iomem *ram;
  340. base = musb->ctrl_base;
  341. ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
  342. cppi) + base;
  343. code = snprintf(buf, max,
  344. " tx dma%d: "
  345. "%08x %08x, %08x %08x; "
  346. "%08x %08x %08x .. %08x\n",
  347. cppi,
  348. musb_readl(ram, 0 * 4),
  349. musb_readl(ram, 1 * 4),
  350. musb_readl(ram, 2 * 4),
  351. musb_readl(ram, 3 * 4),
  352. musb_readl(ram, 4 * 4),
  353. musb_readl(ram, 5 * 4),
  354. musb_readl(ram, 6 * 4),
  355. musb_readl(ram, 7 * 4));
  356. if (code <= 0)
  357. break;
  358. code = min(code, (int) max);
  359. buf += code;
  360. max -= code;
  361. }
  362. if (hw_ep == musb->control_ep
  363. && !list_empty(
  364. &musb->control)) {
  365. code = dump_queue(&musb->control,
  366. buf, max);
  367. if (code <= 0)
  368. break;
  369. code = min(code, (int) max);
  370. buf += code;
  371. max -= code;
  372. } else if (hw_ep == musb->bulk_ep
  373. && !list_empty(
  374. &musb->out_bulk)) {
  375. code = dump_queue(&musb->out_bulk,
  376. buf, max);
  377. if (code <= 0)
  378. break;
  379. code = min(code, (int) max);
  380. buf += code;
  381. max -= code;
  382. } else if (musb->periodic[epnum]) {
  383. code = dump_qh(musb->periodic[epnum],
  384. buf, max);
  385. if (code <= 0)
  386. break;
  387. code = min(code, (int) max);
  388. buf += code;
  389. max -= code;
  390. }
  391. }
  392. }
  393. #endif
  394. #ifdef CONFIG_USB_GADGET_MUSB_HDRC
  395. if (is_peripheral_active(musb)) {
  396. code = 0;
  397. if (hw_ep->ep_in.desc || !epnum) {
  398. code = dump_ep(&hw_ep->ep_in, buf, max);
  399. if (code <= 0)
  400. break;
  401. code = min(code, (int) max);
  402. buf += code;
  403. max -= code;
  404. }
  405. if (hw_ep->ep_out.desc) {
  406. code = dump_ep(&hw_ep->ep_out, buf, max);
  407. if (code <= 0)
  408. break;
  409. code = min(code, (int) max);
  410. buf += code;
  411. max -= code;
  412. }
  413. }
  414. #endif
  415. } while (0);
  416. return buf - aBuffer;
  417. }
  418. /* Dump the current status and compile options.
  419. * @param musb the device driver instance
  420. * @param buffer where to dump the status; it must be big enough to hold the
  421. * result otherwise "BAD THINGS HAPPENS(TM)".
  422. */
  423. static int dump_header_stats(struct musb *musb, char *buffer)
  424. {
  425. int code, count = 0;
  426. const void __iomem *mbase = musb->mregs;
  427. *buffer = 0;
  428. count = sprintf(buffer, "Status: %sHDRC, Mode=%s "
  429. "(Power=%02x, DevCtl=%02x)\n",
  430. (musb->is_multipoint ? "M" : ""), MUSB_MODE(musb),
  431. musb_readb(mbase, MUSB_POWER),
  432. musb_readb(mbase, MUSB_DEVCTL));
  433. if (count <= 0)
  434. return 0;
  435. buffer += count;
  436. code = sprintf(buffer, "OTG state: %s; %sactive\n",
  437. otg_state_string(musb),
  438. musb->is_active ? "" : "in");
  439. if (code <= 0)
  440. goto done;
  441. buffer += code;
  442. count += code;
  443. code = sprintf(buffer,
  444. "Options: "
  445. #ifdef CONFIG_MUSB_PIO_ONLY
  446. "pio"
  447. #elif defined(CONFIG_USB_TI_CPPI_DMA)
  448. "cppi-dma"
  449. #elif defined(CONFIG_USB_INVENTRA_DMA)
  450. "musb-dma"
  451. #elif defined(CONFIG_USB_TUSB_OMAP_DMA)
  452. "tusb-omap-dma"
  453. #else
  454. "?dma?"
  455. #endif
  456. ", "
  457. #ifdef CONFIG_USB_MUSB_OTG
  458. "otg (peripheral+host)"
  459. #elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
  460. "peripheral"
  461. #elif defined(CONFIG_USB_MUSB_HDRC_HCD)
  462. "host"
  463. #endif
  464. ", debug=%d [eps=%d]\n",
  465. debug,
  466. musb->nr_endpoints);
  467. if (code <= 0)
  468. goto done;
  469. count += code;
  470. buffer += code;
  471. #ifdef CONFIG_USB_GADGET_MUSB_HDRC
  472. code = sprintf(buffer, "Peripheral address: %02x\n",
  473. musb_readb(musb->ctrl_base, MUSB_FADDR));
  474. if (code <= 0)
  475. goto done;
  476. buffer += code;
  477. count += code;
  478. #endif
  479. #ifdef CONFIG_USB_MUSB_HDRC_HCD
  480. code = sprintf(buffer, "Root port status: %08x\n",
  481. musb->port1_status);
  482. if (code <= 0)
  483. goto done;
  484. buffer += code;
  485. count += code;
  486. #endif
  487. #ifdef CONFIG_ARCH_DAVINCI
  488. code = sprintf(buffer,
  489. "DaVinci: ctrl=%02x stat=%1x phy=%03x\n"
  490. "\trndis=%05x auto=%04x intsrc=%08x intmsk=%08x"
  491. "\n",
  492. musb_readl(musb->ctrl_base, DAVINCI_USB_CTRL_REG),
  493. musb_readl(musb->ctrl_base, DAVINCI_USB_STAT_REG),
  494. __raw_readl((void __force __iomem *)
  495. IO_ADDRESS(USBPHY_CTL_PADDR)),
  496. musb_readl(musb->ctrl_base, DAVINCI_RNDIS_REG),
  497. musb_readl(musb->ctrl_base, DAVINCI_AUTOREQ_REG),
  498. musb_readl(musb->ctrl_base,
  499. DAVINCI_USB_INT_SOURCE_REG),
  500. musb_readl(musb->ctrl_base,
  501. DAVINCI_USB_INT_MASK_REG));
  502. if (code <= 0)
  503. goto done;
  504. count += code;
  505. buffer += code;
  506. #endif /* DAVINCI */
  507. #ifdef CONFIG_USB_TUSB6010
  508. code = sprintf(buffer,
  509. "TUSB6010: devconf %08x, phy enable %08x drive %08x"
  510. "\n\totg %03x timer %08x"
  511. "\n\tprcm conf %08x mgmt %08x; int src %08x mask %08x"
  512. "\n",
  513. musb_readl(musb->ctrl_base, TUSB_DEV_CONF),
  514. musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
  515. musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL),
  516. musb_readl(musb->ctrl_base, TUSB_DEV_OTG_STAT),
  517. musb_readl(musb->ctrl_base, TUSB_DEV_OTG_TIMER),
  518. musb_readl(musb->ctrl_base, TUSB_PRCM_CONF),
  519. musb_readl(musb->ctrl_base, TUSB_PRCM_MNGMT),
  520. musb_readl(musb->ctrl_base, TUSB_INT_SRC),
  521. musb_readl(musb->ctrl_base, TUSB_INT_MASK));
  522. if (code <= 0)
  523. goto done;
  524. count += code;
  525. buffer += code;
  526. #endif /* DAVINCI */
  527. if (is_cppi_enabled() && musb->dma_controller) {
  528. code = sprintf(buffer,
  529. "CPPI: txcr=%d txsrc=%01x txena=%01x; "
  530. "rxcr=%d rxsrc=%01x rxena=%01x "
  531. "\n",
  532. musb_readl(musb->ctrl_base,
  533. DAVINCI_TXCPPI_CTRL_REG),
  534. musb_readl(musb->ctrl_base,
  535. DAVINCI_TXCPPI_RAW_REG),
  536. musb_readl(musb->ctrl_base,
  537. DAVINCI_TXCPPI_INTENAB_REG),
  538. musb_readl(musb->ctrl_base,
  539. DAVINCI_RXCPPI_CTRL_REG),
  540. musb_readl(musb->ctrl_base,
  541. DAVINCI_RXCPPI_RAW_REG),
  542. musb_readl(musb->ctrl_base,
  543. DAVINCI_RXCPPI_INTENAB_REG));
  544. if (code <= 0)
  545. goto done;
  546. count += code;
  547. buffer += code;
  548. }
  549. #ifdef CONFIG_USB_GADGET_MUSB_HDRC
  550. if (is_peripheral_enabled(musb)) {
  551. code = sprintf(buffer, "Gadget driver: %s\n",
  552. musb->gadget_driver
  553. ? musb->gadget_driver->driver.name
  554. : "(none)");
  555. if (code <= 0)
  556. goto done;
  557. count += code;
  558. buffer += code;
  559. }
  560. #endif
  561. done:
  562. return count;
  563. }
  564. /* Write to ProcFS
  565. *
  566. * C soft-connect
  567. * c soft-disconnect
  568. * I enable HS
  569. * i disable HS
  570. * s stop session
  571. * F force session (OTG-unfriendly)
  572. * E rElinquish bus (OTG)
  573. * H request host mode
  574. * h cancel host request
  575. * T start sending TEST_PACKET
  576. * D<num> set/query the debug level
  577. */
  578. static int musb_proc_write(struct file *file, const char __user *buffer,
  579. unsigned long count, void *data)
  580. {
  581. char cmd;
  582. u8 reg;
  583. struct musb *musb = (struct musb *)data;
  584. void __iomem *mbase = musb->mregs;
  585. /* MOD_INC_USE_COUNT; */
  586. if (unlikely(copy_from_user(&cmd, buffer, 1)))
  587. return -EFAULT;
  588. switch (cmd) {
  589. case 'C':
  590. if (mbase) {
  591. reg = musb_readb(mbase, MUSB_POWER)
  592. | MUSB_POWER_SOFTCONN;
  593. musb_writeb(mbase, MUSB_POWER, reg);
  594. }
  595. break;
  596. case 'c':
  597. if (mbase) {
  598. reg = musb_readb(mbase, MUSB_POWER)
  599. & ~MUSB_POWER_SOFTCONN;
  600. musb_writeb(mbase, MUSB_POWER, reg);
  601. }
  602. break;
  603. case 'I':
  604. if (mbase) {
  605. reg = musb_readb(mbase, MUSB_POWER)
  606. | MUSB_POWER_HSENAB;
  607. musb_writeb(mbase, MUSB_POWER, reg);
  608. }
  609. break;
  610. case 'i':
  611. if (mbase) {
  612. reg = musb_readb(mbase, MUSB_POWER)
  613. & ~MUSB_POWER_HSENAB;
  614. musb_writeb(mbase, MUSB_POWER, reg);
  615. }
  616. break;
  617. case 'F':
  618. reg = musb_readb(mbase, MUSB_DEVCTL);
  619. reg |= MUSB_DEVCTL_SESSION;
  620. musb_writeb(mbase, MUSB_DEVCTL, reg);
  621. break;
  622. case 'H':
  623. if (mbase) {
  624. reg = musb_readb(mbase, MUSB_DEVCTL);
  625. reg |= MUSB_DEVCTL_HR;
  626. musb_writeb(mbase, MUSB_DEVCTL, reg);
  627. /* MUSB_HST_MODE( ((struct musb*)data) ); */
  628. /* WARNING("Host Mode\n"); */
  629. }
  630. break;
  631. case 'h':
  632. if (mbase) {
  633. reg = musb_readb(mbase, MUSB_DEVCTL);
  634. reg &= ~MUSB_DEVCTL_HR;
  635. musb_writeb(mbase, MUSB_DEVCTL, reg);
  636. }
  637. break;
  638. case 'T':
  639. if (mbase) {
  640. musb_load_testpacket(musb);
  641. musb_writeb(mbase, MUSB_TESTMODE,
  642. MUSB_TEST_PACKET);
  643. }
  644. break;
  645. #if (MUSB_DEBUG > 0)
  646. /* set/read debug level */
  647. case 'D':{
  648. if (count > 1) {
  649. char digits[8], *p = digits;
  650. int i = 0, level = 0, sign = 1;
  651. int len = min(count - 1, (unsigned long)8);
  652. if (copy_from_user(&digits, &buffer[1], len))
  653. return -EFAULT;
  654. /* optional sign */
  655. if (*p == '-') {
  656. len -= 1;
  657. sign = -sign;
  658. p++;
  659. }
  660. /* read it */
  661. while (i++ < len && *p > '0' && *p < '9') {
  662. level = level * 10 + (*p - '0');
  663. p++;
  664. }
  665. level *= sign;
  666. DBG(1, "debug level %d\n", level);
  667. debug = level;
  668. }
  669. }
  670. break;
  671. case '?':
  672. INFO("?: you are seeing it\n");
  673. INFO("C/c: soft connect enable/disable\n");
  674. INFO("I/i: hispeed enable/disable\n");
  675. INFO("F: force session start\n");
  676. INFO("H: host mode\n");
  677. INFO("T: start sending TEST_PACKET\n");
  678. INFO("D: set/read dbug level\n");
  679. break;
  680. #endif
  681. default:
  682. ERR("Command %c not implemented\n", cmd);
  683. break;
  684. }
  685. musb_platform_try_idle(musb, 0);
  686. return count;
  687. }
  688. static int musb_proc_read(char *page, char **start,
  689. off_t off, int count, int *eof, void *data)
  690. {
  691. char *buffer = page;
  692. int code = 0;
  693. unsigned long flags;
  694. struct musb *musb = data;
  695. unsigned epnum;
  696. count -= off;
  697. count -= 1; /* for NUL at end */
  698. if (count <= 0)
  699. return -EINVAL;
  700. spin_lock_irqsave(&musb->lock, flags);
  701. code = dump_header_stats(musb, buffer);
  702. if (code > 0) {
  703. buffer += code;
  704. count -= code;
  705. }
  706. /* generate the report for the end points */
  707. /* REVISIT ... not unless something's connected! */
  708. for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints;
  709. epnum++) {
  710. code = dump_end_info(musb, epnum, buffer, count);
  711. if (code > 0) {
  712. buffer += code;
  713. count -= code;
  714. }
  715. }
  716. musb_platform_try_idle(musb, 0);
  717. spin_unlock_irqrestore(&musb->lock, flags);
  718. *eof = 1;
  719. return buffer - page;
  720. }
  721. void __devexit musb_debug_delete(char *name, struct musb *musb)
  722. {
  723. if (musb->proc_entry)
  724. remove_proc_entry(name, NULL);
  725. }
  726. struct proc_dir_entry *__init
  727. musb_debug_create(char *name, struct musb *data)
  728. {
  729. struct proc_dir_entry *pde;
  730. /* FIXME convert everything to seq_file; then later, debugfs */
  731. if (!name)
  732. return NULL;
  733. pde = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, NULL);
  734. data->proc_entry = pde;
  735. if (pde) {
  736. pde->data = data;
  737. /* pde->owner = THIS_MODULE; */
  738. pde->read_proc = musb_proc_read;
  739. pde->write_proc = musb_proc_write;
  740. pde->size = 0;
  741. pr_debug("Registered /proc/%s\n", name);
  742. } else {
  743. pr_debug("Cannot create a valid proc file entry");
  744. }
  745. return pde;
  746. }