Full support for Ginger Console
[linux-ginger.git] / drivers / usb / musb / musb_procfs.c
blob8b6b1fe5bdd3b84b03c700d8c43c75ab5cab748b
1 /*
2 * MUSB OTG driver debug support
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
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.
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.
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
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.
35 #include <linux/kernel.h>
36 #include <linux/proc_fs.h>
37 #include <linux/seq_file.h>
38 #include <linux/uaccess.h> /* FIXME remove procfs writes */
39 #include <mach/hardware.h>
41 #include "musb_core.h"
43 #include "davinci.h"
45 #ifdef CONFIG_USB_MUSB_HDRC_HCD
47 static int dump_qh(struct musb_qh *qh, char *buf, unsigned max)
49 int count;
50 int tmp;
51 struct usb_host_endpoint *hep = qh->hep;
52 struct urb *urb;
54 count = snprintf(buf, max, " qh %p dev%d ep%d%s max%d\n",
55 qh, qh->dev->devnum, qh->epnum,
56 ({ char *s; switch (qh->type) {
57 case USB_ENDPOINT_XFER_BULK:
58 s = "-bulk"; break;
59 case USB_ENDPOINT_XFER_INT:
60 s = "-int"; break;
61 case USB_ENDPOINT_XFER_CONTROL:
62 s = ""; break;
63 default:
64 s = "iso"; break;
65 }; s; }),
66 qh->maxpacket);
67 if (count <= 0)
68 return 0;
69 buf += count;
70 max -= count;
72 list_for_each_entry(urb, &hep->urb_list, urb_list) {
73 tmp = snprintf(buf, max, "\t%s urb %p %d/%d\n",
74 usb_pipein(urb->pipe) ? "in" : "out",
75 urb, urb->actual_length,
76 urb->transfer_buffer_length);
77 if (tmp <= 0)
78 break;
79 tmp = min(tmp, (int)max);
80 count += tmp;
81 buf += tmp;
82 max -= tmp;
84 return count;
87 static int
88 dump_queue(struct list_head *q, char *buf, unsigned max)
90 int count = 0;
91 struct musb_qh *qh;
93 list_for_each_entry(qh, q, ring) {
94 int tmp;
96 tmp = dump_qh(qh, buf, max);
97 if (tmp <= 0)
98 break;
99 tmp = min(tmp, (int)max);
100 count += tmp;
101 buf += tmp;
102 max -= tmp;
104 return count;
107 #endif /* HCD */
109 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
110 static int dump_ep(struct musb_ep *ep, char *buffer, unsigned max)
112 char *buf = buffer;
113 int code = 0;
114 void __iomem *regs = ep->hw_ep->regs;
115 char *mode = "1buf";
117 if (ep->is_in) {
118 if (ep->hw_ep->tx_double_buffered)
119 mode = "2buf";
120 } else {
121 if (ep->hw_ep->rx_double_buffered)
122 mode = "2buf";
125 do {
126 struct usb_request *req;
128 code = snprintf(buf, max,
129 "\n%s (hw%d): %s%s, csr %04x maxp %04x\n",
130 ep->name, ep->current_epnum,
131 mode, ep->dma ? " dma" : "",
132 musb_readw(regs,
133 (ep->is_in || !ep->current_epnum)
134 ? MUSB_TXCSR
135 : MUSB_RXCSR),
136 musb_readw(regs, ep->is_in
137 ? MUSB_TXMAXP
138 : MUSB_RXMAXP)
140 if (code <= 0)
141 break;
142 code = min(code, (int) max);
143 buf += code;
144 max -= code;
146 if ((is_cppi_enabled() || is_cppi41_enabled())
147 && ep->current_epnum) {
148 unsigned cppi = ep->current_epnum - 1;
149 void __iomem *base = ep->musb->ctrl_base;
150 unsigned off1 = cppi << 2;
151 void __iomem *ram = base;
152 char tmp[16];
154 if (ep->is_in) {
155 ram += DAVINCI_TXCPPI_STATERAM_OFFSET(cppi);
156 tmp[0] = 0;
157 } else {
158 ram += DAVINCI_RXCPPI_STATERAM_OFFSET(cppi);
159 snprintf(tmp, sizeof tmp, "%d left, ",
160 musb_readl(base,
161 DAVINCI_RXCPPI_BUFCNT0_REG + off1));
164 code = snprintf(buf, max, "%cX DMA%d: %s"
165 "%08x %08x, %08x %08x; "
166 "%08x %08x %08x .. %08x\n",
167 ep->is_in ? 'T' : 'R',
168 ep->current_epnum - 1, tmp,
169 musb_readl(ram, 0 * 4),
170 musb_readl(ram, 1 * 4),
171 musb_readl(ram, 2 * 4),
172 musb_readl(ram, 3 * 4),
173 musb_readl(ram, 4 * 4),
174 musb_readl(ram, 5 * 4),
175 musb_readl(ram, 6 * 4),
176 musb_readl(ram, 7 * 4));
177 if (code <= 0)
178 break;
179 code = min(code, (int) max);
180 buf += code;
181 max -= code;
184 if (list_empty(&ep->req_list)) {
185 code = snprintf(buf, max, "\t(queue empty)\n");
186 if (code <= 0)
187 break;
188 code = min(code, (int) max);
189 buf += code;
190 max -= code;
191 break;
193 list_for_each_entry(req, &ep->req_list, list) {
194 code = snprintf(buf, max, "\treq %p, %s%s%d/%d\n",
195 req,
196 req->zero ? "zero, " : "",
197 req->short_not_ok ? "!short, " : "",
198 req->actual, req->length);
199 if (code <= 0)
200 break;
201 code = min(code, (int) max);
202 buf += code;
203 max -= code;
205 } while (0);
206 return buf - buffer;
208 #endif
210 static int
211 dump_end_info(struct musb *musb, u8 epnum, char *aBuffer, unsigned max)
213 int code = 0;
214 char *buf = aBuffer;
215 struct musb_hw_ep *hw_ep = &musb->endpoints[epnum];
217 do {
218 musb_ep_select(musb->mregs, epnum);
219 #ifdef CONFIG_USB_MUSB_HDRC_HCD
220 if (is_host_active(musb)) {
221 int dump_rx, dump_tx;
222 void __iomem *regs = hw_ep->regs;
224 /* TEMPORARY (!) until we have a real periodic
225 * schedule tree ...
227 if (!epnum) {
228 /* control is shared, uses RX queue
229 * but (mostly) shadowed tx registers
231 dump_tx = !list_empty(&musb->control);
232 dump_rx = 0;
233 } else if (hw_ep == musb->bulk_ep) {
234 dump_tx = !list_empty(&musb->out_bulk);
235 dump_rx = !list_empty(&musb->in_bulk);
236 } else if (hw_ep->in_qh || hw_ep->out_qh) {
237 if (hw_ep->in_qh)
238 dump_rx = 1;
239 else
240 dump_rx = 0;
241 dump_tx = !dump_rx;
242 } else
243 break;
244 /* END TEMPORARY */
247 if (dump_rx) {
248 code = snprintf(buf, max,
249 "\nRX%d: %s rxcsr %04x interval %02x "
250 "max %04x type %02x; "
251 "dev %d hub %d port %d"
252 "\n",
253 epnum,
254 hw_ep->rx_double_buffered
255 ? "2buf" : "1buf",
256 musb_readw(regs, MUSB_RXCSR),
257 musb_readb(regs, MUSB_RXINTERVAL),
258 musb_readw(regs, MUSB_RXMAXP),
259 musb_readb(regs, MUSB_RXTYPE),
260 /* FIXME: assumes multipoint */
261 musb_readb(musb->mregs,
262 MUSB_BUSCTL_OFFSET(epnum,
263 MUSB_RXFUNCADDR)),
264 musb_readb(musb->mregs,
265 MUSB_BUSCTL_OFFSET(epnum,
266 MUSB_RXHUBADDR)),
267 musb_readb(musb->mregs,
268 MUSB_BUSCTL_OFFSET(epnum,
269 MUSB_RXHUBPORT))
271 if (code <= 0)
272 break;
273 code = min(code, (int) max);
274 buf += code;
275 max -= code;
277 if ((is_cppi_enabled() || is_cppi41_enabled())
278 && epnum
279 && hw_ep->rx_channel) {
280 unsigned cppi = epnum - 1;
281 unsigned off1 = cppi << 2;
282 void __iomem *base;
283 void __iomem *ram;
284 char tmp[16];
286 base = musb->ctrl_base;
287 ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
288 cppi) + base;
289 snprintf(tmp, sizeof tmp, "%d left, ",
290 musb_readl(base,
291 DAVINCI_RXCPPI_BUFCNT0_REG
292 + off1));
294 code = snprintf(buf, max,
295 " rx dma%d: %s"
296 "%08x %08x, %08x %08x; "
297 "%08x %08x %08x .. %08x\n",
298 cppi, tmp,
299 musb_readl(ram, 0 * 4),
300 musb_readl(ram, 1 * 4),
301 musb_readl(ram, 2 * 4),
302 musb_readl(ram, 3 * 4),
303 musb_readl(ram, 4 * 4),
304 musb_readl(ram, 5 * 4),
305 musb_readl(ram, 6 * 4),
306 musb_readl(ram, 7 * 4));
307 if (code <= 0)
308 break;
309 code = min(code, (int) max);
310 buf += code;
311 max -= code;
314 if (hw_ep == musb->bulk_ep
315 && !list_empty(
316 &musb->in_bulk)) {
317 code = dump_queue(&musb->in_bulk,
318 buf, max);
319 if (code <= 0)
320 break;
321 code = min(code, (int) max);
322 buf += code;
323 max -= code;
324 } else if (hw_ep->in_qh) {
325 code = dump_qh(hw_ep->in_qh,
326 buf, max);
327 if (code <= 0)
328 break;
329 code = min(code, (int) max);
330 buf += code;
331 max -= code;
335 if (dump_tx) {
336 code = snprintf(buf, max,
337 "\nTX%d: %s txcsr %04x interval %02x "
338 "max %04x type %02x; "
339 "dev %d hub %d port %d"
340 "\n",
341 epnum,
342 hw_ep->tx_double_buffered
343 ? "2buf" : "1buf",
344 musb_readw(regs, MUSB_TXCSR),
345 musb_readb(regs, MUSB_TXINTERVAL),
346 musb_readw(regs, MUSB_TXMAXP),
347 musb_readb(regs, MUSB_TXTYPE),
348 /* FIXME: assumes multipoint */
349 musb_readb(musb->mregs,
350 MUSB_BUSCTL_OFFSET(epnum,
351 MUSB_TXFUNCADDR)),
352 musb_readb(musb->mregs,
353 MUSB_BUSCTL_OFFSET(epnum,
354 MUSB_TXHUBADDR)),
355 musb_readb(musb->mregs,
356 MUSB_BUSCTL_OFFSET(epnum,
357 MUSB_TXHUBPORT))
359 if (code <= 0)
360 break;
361 code = min(code, (int) max);
362 buf += code;
363 max -= code;
365 if ((is_cppi_enabled() || is_cppi41_enabled())
366 && epnum
367 && hw_ep->tx_channel) {
368 unsigned cppi = epnum - 1;
369 void __iomem *base;
370 void __iomem *ram;
372 base = musb->ctrl_base;
373 ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
374 cppi) + base;
375 code = snprintf(buf, max,
376 " tx dma%d: "
377 "%08x %08x, %08x %08x; "
378 "%08x %08x %08x .. %08x\n",
379 cppi,
380 musb_readl(ram, 0 * 4),
381 musb_readl(ram, 1 * 4),
382 musb_readl(ram, 2 * 4),
383 musb_readl(ram, 3 * 4),
384 musb_readl(ram, 4 * 4),
385 musb_readl(ram, 5 * 4),
386 musb_readl(ram, 6 * 4),
387 musb_readl(ram, 7 * 4));
388 if (code <= 0)
389 break;
390 code = min(code, (int) max);
391 buf += code;
392 max -= code;
395 if (hw_ep == musb->control_ep
396 && !list_empty(
397 &musb->control)) {
398 code = dump_queue(&musb->control,
399 buf, max);
400 if (code <= 0)
401 break;
402 code = min(code, (int) max);
403 buf += code;
404 max -= code;
405 } else if (hw_ep == musb->bulk_ep
406 && !list_empty(
407 &musb->out_bulk)) {
408 code = dump_queue(&musb->out_bulk,
409 buf, max);
410 if (code <= 0)
411 break;
412 code = min(code, (int) max);
413 buf += code;
414 max -= code;
415 } else if (hw_ep->out_qh) {
416 code = dump_qh(hw_ep->out_qh,
417 buf, max);
418 if (code <= 0)
419 break;
420 code = min(code, (int) max);
421 buf += code;
422 max -= code;
426 #endif
427 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
428 if (is_peripheral_active(musb)) {
429 code = 0;
431 if (hw_ep->ep_in.desc || !epnum) {
432 code = dump_ep(&hw_ep->ep_in, buf, max);
433 if (code <= 0)
434 break;
435 code = min(code, (int) max);
436 buf += code;
437 max -= code;
439 if (hw_ep->ep_out.desc) {
440 code = dump_ep(&hw_ep->ep_out, buf, max);
441 if (code <= 0)
442 break;
443 code = min(code, (int) max);
444 buf += code;
445 max -= code;
448 #endif
449 } while (0);
451 return buf - aBuffer;
454 /* Dump the current status and compile options.
455 * @param musb the device driver instance
456 * @param buffer where to dump the status; it must be big enough to hold the
457 * result otherwise "BAD THINGS HAPPENS(TM)".
459 static int dump_header_stats(struct musb *musb, char *buffer)
461 int code, count = 0;
462 const void __iomem *mbase = musb->mregs;
464 *buffer = 0;
465 count = sprintf(buffer, "Status: %sHDRC, Mode=%s "
466 "(Power=%02x, DevCtl=%02x)\n",
467 (musb->is_multipoint ? "M" : ""), MUSB_MODE(musb),
468 musb_readb(mbase, MUSB_POWER),
469 musb_readb(mbase, MUSB_DEVCTL));
470 if (count <= 0)
471 return 0;
472 buffer += count;
474 code = sprintf(buffer, "OTG state: %s; %sactive\n",
475 otg_state_string(musb),
476 musb->is_active ? "" : "in");
477 if (code <= 0)
478 goto done;
479 buffer += code;
480 count += code;
482 code = sprintf(buffer,
483 "Options: "
484 #ifdef CONFIG_MUSB_PIO_ONLY
485 "pio"
486 #elif defined(CONFIG_USB_TI_CPPI_DMA)
487 "cppi-dma"
488 #elif defined(CONFIG_USB_INVENTRA_DMA)
489 "musb-dma"
490 #elif defined(CONFIG_USB_TUSB_OMAP_DMA)
491 "tusb-omap-dma"
492 #else
493 "?dma?"
494 #endif
495 ", "
496 #ifdef CONFIG_USB_MUSB_OTG
497 "otg (peripheral+host)"
498 #elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
499 "peripheral"
500 #elif defined(CONFIG_USB_MUSB_HDRC_HCD)
501 "host"
502 #endif
503 ", debug=%d [eps=%d]\n",
504 musb_debug,
505 musb->nr_endpoints);
506 if (code <= 0)
507 goto done;
508 count += code;
509 buffer += code;
511 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
512 code = sprintf(buffer, "Peripheral address: %02x\n",
513 musb_readb(musb->ctrl_base, MUSB_FADDR));
514 if (code <= 0)
515 goto done;
516 buffer += code;
517 count += code;
518 #endif
520 #ifdef CONFIG_USB_MUSB_HDRC_HCD
521 code = sprintf(buffer, "Root port status: %08x\n",
522 musb->port1_status);
523 if (code <= 0)
524 goto done;
525 buffer += code;
526 count += code;
527 #endif
529 #ifdef CONFIG_ARCH_DAVINCI
530 code = sprintf(buffer,
531 "DaVinci: ctrl=%02x stat=%1x phy=%03x\n"
532 "\trndis=%05x auto=%04x intsrc=%08x intmsk=%08x"
533 "\n",
534 musb_readl(musb->ctrl_base, DAVINCI_USB_CTRL_REG),
535 musb_readl(musb->ctrl_base, DAVINCI_USB_STAT_REG),
536 __raw_readl((void __force __iomem *)
537 IO_ADDRESS(USBPHY_CTL_PADDR)),
538 musb_readl(musb->ctrl_base, DAVINCI_RNDIS_REG),
539 musb_readl(musb->ctrl_base, DAVINCI_AUTOREQ_REG),
540 musb_readl(musb->ctrl_base,
541 DAVINCI_USB_INT_SOURCE_REG),
542 musb_readl(musb->ctrl_base,
543 DAVINCI_USB_INT_MASK_REG));
544 if (code <= 0)
545 goto done;
546 count += code;
547 buffer += code;
548 #endif /* DAVINCI */
550 #ifdef CONFIG_USB_TUSB6010
551 code = sprintf(buffer,
552 "TUSB6010: devconf %08x, phy enable %08x drive %08x"
553 "\n\totg %03x timer %08x"
554 "\n\tprcm conf %08x mgmt %08x; int src %08x mask %08x"
555 "\n",
556 musb_readl(musb->ctrl_base, TUSB_DEV_CONF),
557 musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
558 musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL),
559 musb_readl(musb->ctrl_base, TUSB_DEV_OTG_STAT),
560 musb_readl(musb->ctrl_base, TUSB_DEV_OTG_TIMER),
561 musb_readl(musb->ctrl_base, TUSB_PRCM_CONF),
562 musb_readl(musb->ctrl_base, TUSB_PRCM_MNGMT),
563 musb_readl(musb->ctrl_base, TUSB_INT_SRC),
564 musb_readl(musb->ctrl_base, TUSB_INT_MASK));
565 if (code <= 0)
566 goto done;
567 count += code;
568 buffer += code;
569 #endif /* DAVINCI */
571 if ((is_cppi_enabled() || is_cppi41_enabled())
572 && musb->dma_controller) {
573 code = sprintf(buffer,
574 "CPPI: txcr=%d txsrc=%01x txena=%01x; "
575 "rxcr=%d rxsrc=%01x rxena=%01x "
576 "\n",
577 musb_readl(musb->ctrl_base,
578 DAVINCI_TXCPPI_CTRL_REG),
579 musb_readl(musb->ctrl_base,
580 DAVINCI_TXCPPI_RAW_REG),
581 musb_readl(musb->ctrl_base,
582 DAVINCI_TXCPPI_INTENAB_REG),
583 musb_readl(musb->ctrl_base,
584 DAVINCI_RXCPPI_CTRL_REG),
585 musb_readl(musb->ctrl_base,
586 DAVINCI_RXCPPI_RAW_REG),
587 musb_readl(musb->ctrl_base,
588 DAVINCI_RXCPPI_INTENAB_REG));
589 if (code <= 0)
590 goto done;
591 count += code;
592 buffer += code;
595 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
596 if (is_peripheral_enabled(musb)) {
597 code = sprintf(buffer, "Gadget driver: %s\n",
598 musb->gadget_driver
599 ? musb->gadget_driver->driver.name
600 : "(none)");
601 if (code <= 0)
602 goto done;
603 count += code;
604 buffer += code;
606 #endif
608 done:
609 return count;
612 /* Write to ProcFS
614 * C soft-connect
615 * c soft-disconnect
616 * I enable HS
617 * i disable HS
618 * s stop session
619 * F force session (OTG-unfriendly)
620 * E rElinquish bus (OTG)
621 * H request host mode
622 * h cancel host request
623 * T start sending TEST_PACKET
624 * D<num> set/query the debug level
626 static int musb_proc_write(struct file *file, const char __user *buffer,
627 unsigned long count, void *data)
629 char cmd;
630 u8 reg;
631 struct musb *musb = (struct musb *)data;
632 void __iomem *mbase = musb->mregs;
634 /* MOD_INC_USE_COUNT; */
636 if (unlikely(copy_from_user(&cmd, buffer, 1)))
637 return -EFAULT;
639 switch (cmd) {
640 case 'S':
641 if (mbase) {
642 reg = musb_readb(mbase, MUSB_POWER)
643 | MUSB_POWER_SUSPENDM;
644 musb_writeb(mbase, MUSB_POWER, reg);
646 break;
648 case 'C':
649 if (mbase) {
650 reg = musb_readb(mbase, MUSB_POWER)
651 | MUSB_POWER_SOFTCONN;
652 musb_writeb(mbase, MUSB_POWER, reg);
654 break;
656 case 'c':
657 if (mbase) {
658 reg = musb_readb(mbase, MUSB_POWER)
659 & ~MUSB_POWER_SOFTCONN;
660 musb_writeb(mbase, MUSB_POWER, reg);
662 break;
664 case 'I':
665 if (mbase) {
666 reg = musb_readb(mbase, MUSB_POWER)
667 | MUSB_POWER_HSENAB;
668 musb_writeb(mbase, MUSB_POWER, reg);
670 break;
672 case 'i':
673 if (mbase) {
674 reg = musb_readb(mbase, MUSB_POWER)
675 & ~MUSB_POWER_HSENAB;
676 musb_writeb(mbase, MUSB_POWER, reg);
678 break;
680 case 'F':
681 reg = musb_readb(mbase, MUSB_DEVCTL);
682 reg |= MUSB_DEVCTL_SESSION;
683 musb_writeb(mbase, MUSB_DEVCTL, reg);
684 break;
686 case 'H':
687 if (mbase) {
688 reg = musb_readb(mbase, MUSB_DEVCTL);
689 reg |= MUSB_DEVCTL_HR;
690 musb_writeb(mbase, MUSB_DEVCTL, reg);
691 /* MUSB_HST_MODE( ((struct musb*)data) ); */
692 /* WARNING("Host Mode\n"); */
694 break;
696 case 'h':
697 if (mbase) {
698 reg = musb_readb(mbase, MUSB_DEVCTL);
699 reg &= ~MUSB_DEVCTL_HR;
700 musb_writeb(mbase, MUSB_DEVCTL, reg);
702 break;
704 case 'T':
705 if (mbase) {
706 musb_load_testpacket(musb);
707 musb_writeb(mbase, MUSB_TESTMODE,
708 MUSB_TEST_PACKET);
710 break;
712 #if (CONFIG_USB_MUSB_DEBUG > 0)
713 /* set/read debug level */
714 case 'D':{
715 if (count > 1) {
716 char digits[8], *p = digits;
717 int i = 0, level = 0, sign = 1;
718 int len = min(count - 1, (unsigned long)8);
720 if (copy_from_user(&digits, &buffer[1], len))
721 return -EFAULT;
723 /* optional sign */
724 if (*p == '-') {
725 len -= 1;
726 sign = -sign;
727 p++;
730 /* read it */
731 while (i++ < len && *p > '0' && *p < '9') {
732 level = level * 10 + (*p - '0');
733 p++;
736 level *= sign;
737 DBG(1, "debug level %d\n", level);
738 musb_debug = level;
741 break;
744 case '?':
745 INFO("?: you are seeing it\n");
746 INFO("S: suspend the usb bus\n");
747 INFO("C/c: soft connect enable/disable\n");
748 INFO("I/i: hispeed enable/disable\n");
749 INFO("F: force session start\n");
750 INFO("H: host mode\n");
751 INFO("T: start sending TEST_PACKET\n");
752 INFO("D: set/read dbug level\n");
753 break;
754 #endif
756 default:
757 ERR("Command %c not implemented\n", cmd);
758 break;
761 musb_platform_try_idle(musb, 0);
763 return count;
766 static int musb_proc_read(char *page, char **start,
767 off_t off, int count, int *eof, void *data)
769 char *buffer = page;
770 int code = 0;
771 unsigned long flags;
772 struct musb *musb = data;
773 unsigned epnum;
775 count -= off;
776 count -= 1; /* for NUL at end */
777 if (count <= 0)
778 return -EINVAL;
780 spin_lock_irqsave(&musb->lock, flags);
782 code = dump_header_stats(musb, buffer);
783 if (code > 0) {
784 buffer += code;
785 count -= code;
788 /* generate the report for the end points */
789 /* REVISIT ... not unless something's connected! */
790 for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints;
791 epnum++) {
792 code = dump_end_info(musb, epnum, buffer, count);
793 if (code > 0) {
794 buffer += code;
795 count -= code;
799 musb_platform_try_idle(musb, 0);
801 spin_unlock_irqrestore(&musb->lock, flags);
802 *eof = 1;
804 return buffer - page;
807 void __devexit musb_debug_delete(char *name, struct musb *musb)
809 if (musb->proc_entry)
810 remove_proc_entry(name, NULL);
813 struct proc_dir_entry *__init
814 musb_debug_create(char *name, struct musb *data)
816 struct proc_dir_entry *pde;
818 /* FIXME convert everything to seq_file; then later, debugfs */
820 if (!name)
821 return NULL;
823 pde = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, NULL);
824 data->proc_entry = pde;
825 if (pde) {
826 pde->data = data;
827 /* pde->owner = THIS_MODULE; */
829 pde->read_proc = musb_proc_read;
830 pde->write_proc = musb_proc_write;
832 pde->size = 0;
834 pr_debug("Registered /proc/%s\n", name);
835 } else {
836 pr_debug("Cannot create a valid proc file entry");
839 return pde;