6846f3155bfa07417441dcb227cfedfb02a90672
[kernel-power] / usbhost / drivers / usb / musb / musb_procfs.c
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
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>
40 #include <asm/mach-types.h>
41
42 #include "musb_core.h"
43
44 #include "davinci.h"
45
46 extern unsigned musb_debug;
47
48 #ifdef CONFIG_USB_MUSB_HDRC_HCD
49
50 static int dump_qh(struct musb_qh *qh, char *buf, unsigned max)
51 {
52         int                             count;
53         int                             tmp;
54         struct usb_host_endpoint        *hep = qh->hep;
55         struct urb                      *urb;
56
57         count = snprintf(buf, max, "    qh %p dev%d ep%d%s max%d\n",
58                         qh, qh->dev->devnum, qh->epnum,
59                         ({ char *s; switch (qh->type) {
60                         case USB_ENDPOINT_XFER_BULK:
61                                 s = "-bulk"; break;
62                         case USB_ENDPOINT_XFER_INT:
63                                 s = "-int"; break;
64                         case USB_ENDPOINT_XFER_CONTROL:
65                                 s = ""; break;
66                         default:
67                                 s = "iso"; break;
68                         }; s; }),
69                         qh->maxpacket);
70         if (count <= 0)
71                 return 0;
72         buf += count;
73         max -= count;
74
75         list_for_each_entry(urb, &hep->urb_list, urb_list) {
76                 tmp = snprintf(buf, max, "\t%s urb %p %d/%d\n",
77                                 usb_pipein(urb->pipe) ? "in" : "out",
78                                 urb, urb->actual_length,
79                                 urb->transfer_buffer_length);
80                 if (tmp <= 0)
81                         break;
82                 tmp = min(tmp, (int)max);
83                 count += tmp;
84                 buf += tmp;
85                 max -= tmp;
86         }
87         return count;
88 }
89
90 static int
91 dump_queue(struct list_head *q, char *buf, unsigned max)
92 {
93         int             count = 0;
94         struct musb_qh  *qh;
95
96         list_for_each_entry(qh, q, ring) {
97                 int     tmp;
98
99                 tmp = dump_qh(qh, buf, max);
100                 if (tmp <= 0)
101                         break;
102                 tmp = min(tmp, (int)max);
103                 count += tmp;
104                 buf += tmp;
105                 max -= tmp;
106         }
107         return count;
108 }
109
110 #endif  /* HCD */
111
112 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
113 static int dump_ep(struct musb_ep *ep, char *buffer, unsigned max)
114 {
115         char            *buf = buffer;
116         int             code = 0;
117         void __iomem    *regs = ep->hw_ep->regs;
118         char            *mode = "1buf";
119
120         if (ep->is_in) {
121                 if (ep->hw_ep->tx_double_buffered)
122                         mode = "2buf";
123         } else {
124                 if (ep->hw_ep->rx_double_buffered)
125                         mode = "2buf";
126         }
127
128         do {
129                 struct usb_request      *req;
130
131                 code = snprintf(buf, max,
132                                 "\n%s (hw%d): %s%s, csr %04x maxp %04x\n",
133                                 ep->name, ep->current_epnum,
134                                 mode, ep->dma ? " dma" : "",
135                                 musb_readw(regs,
136                                         (ep->is_in || !ep->current_epnum)
137                                                 ? MUSB_TXCSR
138                                                 : MUSB_RXCSR),
139                                 musb_readw(regs, ep->is_in
140                                                 ? MUSB_TXMAXP
141                                                 : MUSB_RXMAXP)
142                                 );
143                 if (code <= 0)
144                         break;
145                 code = min(code, (int) max);
146                 buf += code;
147                 max -= code;
148
149                 if (cppi_ti_dma() && ep->current_epnum) {
150                         unsigned        cppi = ep->current_epnum - 1;
151                         void __iomem    *base = ep->musb->ctrl_base;
152                         unsigned        off1 = cppi << 2;
153                         void __iomem    *ram = base;
154                         char            tmp[16];
155
156                         if (ep->is_in) {
157                                 ram += DAVINCI_TXCPPI_STATERAM_OFFSET(cppi);
158                                 tmp[0] = 0;
159                         } else {
160                                 ram += DAVINCI_RXCPPI_STATERAM_OFFSET(cppi);
161                                 snprintf(tmp, sizeof tmp, "%d left, ",
162                                         musb_readl(base,
163                                         DAVINCI_RXCPPI_BUFCNT0_REG + off1));
164                         }
165
166                         code = snprintf(buf, max, "%cX DMA%d: %s"
167                                         "%08x %08x, %08x %08x; "
168                                         "%08x %08x %08x .. %08x\n",
169                                 ep->is_in ? 'T' : 'R',
170                                 ep->current_epnum - 1, tmp,
171                                 musb_readl(ram, 0 * 4),
172                                 musb_readl(ram, 1 * 4),
173                                 musb_readl(ram, 2 * 4),
174                                 musb_readl(ram, 3 * 4),
175                                 musb_readl(ram, 4 * 4),
176                                 musb_readl(ram, 5 * 4),
177                                 musb_readl(ram, 6 * 4),
178                                 musb_readl(ram, 7 * 4));
179                         if (code <= 0)
180                                 break;
181                         code = min(code, (int) max);
182                         buf += code;
183                         max -= code;
184                 }
185
186                 if (list_empty(&ep->req_list)) {
187                         code = snprintf(buf, max, "\t(queue empty)\n");
188                         if (code <= 0)
189                                 break;
190                         code = min(code, (int) max);
191                         buf += code;
192                         max -= code;
193                         break;
194                 }
195                 list_for_each_entry(req, &ep->req_list, list) {
196                         code = snprintf(buf, max, "\treq %p, %s%s%d/%d\n",
197                                         req,
198                                         req->zero ? "zero, " : "",
199                                         req->short_not_ok ? "!short, " : "",
200                                         req->actual, req->length);
201                         if (code <= 0)
202                                 break;
203                         code = min(code, (int) max);
204                         buf += code;
205                         max -= code;
206                 }
207         } while (0);
208         return buf - buffer;
209 }
210 #endif
211
212 static int
213 dump_end_info(struct musb *musb, u8 epnum, char *aBuffer, unsigned max)
214 {
215         int                     code = 0;
216         char                    *buf = aBuffer;
217         struct musb_hw_ep       *hw_ep = &musb->endpoints[epnum];
218
219         do {
220                 musb_ep_select(musb->mregs, epnum);
221 #ifdef CONFIG_USB_MUSB_HDRC_HCD
222                 if (is_host_active(musb)) {
223                         int             dump_rx, dump_tx;
224                         void __iomem    *regs = hw_ep->regs;
225
226                         /* TEMPORARY (!) until we have a real periodic
227                          * schedule tree ...
228                          */
229                         if (!epnum) {
230                                 /* control is shared, uses RX queue
231                                  * but (mostly) shadowed tx registers
232                                  */
233                                 dump_tx = !list_empty(&hw_ep->in_list);
234                                 dump_rx = 0;
235                         } else if (hw_ep == musb->bulk_ep) {
236                                 dump_tx = !list_empty(&hw_ep->out_list);
237                                 dump_rx = !list_empty(&hw_ep->in_list);
238                         } else
239                                 break;
240                         /* END TEMPORARY */
241
242
243                         if (dump_rx) {
244                                 code = snprintf(buf, max,
245                                         "\nRX%d: %s rxcsr %04x interval %02x "
246                                         "max %04x type %02x; "
247                                         "dev %d hub %d port %d"
248                                         "\n",
249                                         epnum,
250                                         hw_ep->rx_double_buffered
251                                                 ? "2buf" : "1buf",
252                                         musb_readw(regs, MUSB_RXCSR),
253                                         musb_readb(regs, MUSB_RXINTERVAL),
254                                         musb_readw(regs, MUSB_RXMAXP),
255                                         musb_readb(regs, MUSB_RXTYPE),
256                                         /* FIXME:  assumes multipoint */
257                                         musb_readb(musb->mregs,
258                                                 MUSB_BUSCTL_OFFSET(epnum,
259                                                 MUSB_RXFUNCADDR)),
260                                         musb_readb(musb->mregs,
261                                                 MUSB_BUSCTL_OFFSET(epnum,
262                                                 MUSB_RXHUBADDR)),
263                                         musb_readb(musb->mregs,
264                                                 MUSB_BUSCTL_OFFSET(epnum,
265                                                 MUSB_RXHUBPORT))
266                                         );
267                                 if (code <= 0)
268                                         break;
269                                 code = min(code, (int) max);
270                                 buf += code;
271                                 max -= code;
272
273                                 if (cppi_ti_dma()
274                                                 && epnum
275                                                 && hw_ep->rx_channel) {
276                                         unsigned        cppi = epnum - 1;
277                                         unsigned        off1 = cppi << 2;
278                                         void __iomem    *base;
279                                         void __iomem    *ram;
280                                         char            tmp[16];
281
282                                         base = musb->ctrl_base;
283                                         ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
284                                                         cppi) + base;
285                                         snprintf(tmp, sizeof tmp, "%d left, ",
286                                                 musb_readl(base,
287                                                 DAVINCI_RXCPPI_BUFCNT0_REG
288                                                                 + off1));
289
290                                         code = snprintf(buf, max,
291                                                 "    rx dma%d: %s"
292                                                 "%08x %08x, %08x %08x; "
293                                                 "%08x %08x %08x .. %08x\n",
294                                                 cppi, tmp,
295                                                 musb_readl(ram, 0 * 4),
296                                                 musb_readl(ram, 1 * 4),
297                                                 musb_readl(ram, 2 * 4),
298                                                 musb_readl(ram, 3 * 4),
299                                                 musb_readl(ram, 4 * 4),
300                                                 musb_readl(ram, 5 * 4),
301                                                 musb_readl(ram, 6 * 4),
302                                                 musb_readl(ram, 7 * 4));
303                                         if (code <= 0)
304                                                 break;
305                                         code = min(code, (int) max);
306                                         buf += code;
307                                         max -= code;
308                                 }
309
310                                 if (hw_ep == musb->bulk_ep
311                                                 && !list_empty(
312                                                         &hw_ep->in_list)) {
313                                         code = dump_queue(&hw_ep->in_list,
314                                                         buf, max);
315                                         if (code <= 0)
316                                                 break;
317                                         code = min(code, (int) max);
318                                         buf += code;
319                                         max -= code;
320                                 }
321                         }
322
323                         if (dump_tx) {
324                                 code = snprintf(buf, max,
325                                         "\nTX%d: %s txcsr %04x interval %02x "
326                                         "max %04x type %02x; "
327                                         "dev %d hub %d port %d"
328                                         "\n",
329                                         epnum,
330                                         hw_ep->tx_double_buffered
331                                                 ? "2buf" : "1buf",
332                                         musb_readw(regs, MUSB_TXCSR),
333                                         musb_readb(regs, MUSB_TXINTERVAL),
334                                         musb_readw(regs, MUSB_TXMAXP),
335                                         musb_readb(regs, MUSB_TXTYPE),
336                                         /* FIXME:  assumes multipoint */
337                                         musb_readb(musb->mregs,
338                                                 MUSB_BUSCTL_OFFSET(epnum,
339                                                 MUSB_TXFUNCADDR)),
340                                         musb_readb(musb->mregs,
341                                                 MUSB_BUSCTL_OFFSET(epnum,
342                                                 MUSB_TXHUBADDR)),
343                                         musb_readb(musb->mregs,
344                                                 MUSB_BUSCTL_OFFSET(epnum,
345                                                 MUSB_TXHUBPORT))
346                                         );
347                                 if (code <= 0)
348                                         break;
349                                 code = min(code, (int) max);
350                                 buf += code;
351                                 max -= code;
352
353                                 if (cppi_ti_dma()
354                                                 && epnum
355                                                 && hw_ep->tx_channel) {
356                                         unsigned        cppi = epnum - 1;
357                                         void __iomem    *base;
358                                         void __iomem    *ram;
359
360                                         base = musb->ctrl_base;
361                                         ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
362                                                         cppi) + base;
363                                         code = snprintf(buf, max,
364                                                 "    tx dma%d: "
365                                                 "%08x %08x, %08x %08x; "
366                                                 "%08x %08x %08x .. %08x\n",
367                                                 cppi,
368                                                 musb_readl(ram, 0 * 4),
369                                                 musb_readl(ram, 1 * 4),
370                                                 musb_readl(ram, 2 * 4),
371                                                 musb_readl(ram, 3 * 4),
372                                                 musb_readl(ram, 4 * 4),
373                                                 musb_readl(ram, 5 * 4),
374                                                 musb_readl(ram, 6 * 4),
375                                                 musb_readl(ram, 7 * 4));
376                                         if (code <= 0)
377                                                 break;
378                                         code = min(code, (int) max);
379                                         buf += code;
380                                         max -= code;
381                                 }
382
383                                 if (hw_ep == musb->control_ep
384                                                 && !list_empty(
385                                                         &hw_ep->in_list)) {
386                                         code = dump_queue(&hw_ep->in_list,
387                                                         buf, max);
388                                         if (code <= 0)
389                                                 break;
390                                         code = min(code, (int) max);
391                                         buf += code;
392                                         max -= code;
393                                 } else if (hw_ep == musb->bulk_ep
394                                                 && !list_empty(
395                                                         &hw_ep->out_list)) {
396                                         code = dump_queue(&hw_ep->out_list,
397                                                         buf, max);
398                                         if (code <= 0)
399                                                 break;
400                                         code = min(code, (int) max);
401                                         buf += code;
402                                         max -= code;
403                                 }
404                         }
405                 }
406 #endif
407 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
408                 if (is_peripheral_active(musb)) {
409                         code = 0;
410
411                         if (hw_ep->ep_in.desc || !epnum) {
412                                 code = dump_ep(&hw_ep->ep_in, buf, max);
413                                 if (code <= 0)
414                                         break;
415                                 code = min(code, (int) max);
416                                 buf += code;
417                                 max -= code;
418                         }
419                         if (hw_ep->ep_out.desc) {
420                                 code = dump_ep(&hw_ep->ep_out, buf, max);
421                                 if (code <= 0)
422                                         break;
423                                 code = min(code, (int) max);
424                                 buf += code;
425                                 max -= code;
426                         }
427                 }
428 #endif
429         } while (0);
430
431         return buf - aBuffer;
432 }
433
434 /* Dump the current status and compile options.
435  * @param musb the device driver instance
436  * @param buffer where to dump the status; it must be big enough to hold the
437  * result otherwise "BAD THINGS HAPPENS(TM)".
438  */
439 static int dump_header_stats(struct musb *musb, char *buffer)
440 {
441         int code, count = 0;
442         const void __iomem *mbase = musb->mregs;
443
444         *buffer = 0;
445         count = sprintf(buffer, "Status: %sHDRC, Mode=%s "
446                                 "(Power=%02x, DevCtl=%02x)\n",
447                         (musb->is_multipoint ? "M" : ""), MUSB_MODE(musb),
448                         musb_readb(mbase, MUSB_POWER),
449                         musb_readb(mbase, MUSB_DEVCTL));
450         if (count <= 0)
451                 return 0;
452         buffer += count;
453
454         code = sprintf(buffer, "OTG state: %s:%d; %sactive\n",
455                                                                  otg_state_string(musb),musb->xceiv->state,
456                         musb->is_active ? "" : "in");
457         if (code <= 0)
458                 goto done;
459         buffer += code;
460         count += code;
461
462         code = sprintf(buffer,
463                         "Options: "
464 #ifdef CONFIG_MUSB_PIO_ONLY
465                         "pio"
466 #elif defined(CONFIG_USB_TI_CPPI_DMA)
467                         "cppi-dma"
468 #elif defined(CONFIG_USB_INVENTRA_DMA)
469                         "musb-dma"
470 #elif defined(CONFIG_USB_TUSB_OMAP_DMA)
471                         "tusb-omap-dma"
472 #else
473                         "?dma?"
474 #endif
475                         ", "
476 #ifdef CONFIG_USB_MUSB_OTG
477                         "otg (peripheral+host)"
478 #elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
479                         "peripheral"
480 #elif defined(CONFIG_USB_MUSB_HDRC_HCD)
481                         "host"
482 #endif
483                         ", debug=%d [eps=%d]\n",
484                 musb_debug,
485                 musb->nr_endpoints);
486         if (code <= 0)
487                 goto done;
488         count += code;
489         buffer += code;
490
491 #ifdef  CONFIG_USB_GADGET_MUSB_HDRC
492         code = sprintf(buffer, "Peripheral address: %02x\n",
493                         musb_readb(musb->ctrl_base, MUSB_FADDR));
494         if (code <= 0)
495                 goto done;
496         buffer += code;
497         count += code;
498 #endif
499
500 #ifdef  CONFIG_USB_MUSB_HDRC_HCD
501         code = sprintf(buffer, "Root port status: %08x\n",
502                         musb->port1_status);
503         if (code <= 0)
504                 goto done;
505         buffer += code;
506         count += code;
507 #endif
508
509 #ifdef  CONFIG_ARCH_DAVINCI
510         code = sprintf(buffer,
511                         "DaVinci: ctrl=%02x stat=%1x phy=%03x\n"
512                         "\trndis=%05x auto=%04x intsrc=%08x intmsk=%08x"
513                         "\n",
514                         musb_readl(musb->ctrl_base, DAVINCI_USB_CTRL_REG),
515                         musb_readl(musb->ctrl_base, DAVINCI_USB_STAT_REG),
516                         __raw_readl((void __force __iomem *)
517                                         IO_ADDRESS(USBPHY_CTL_PADDR)),
518                         musb_readl(musb->ctrl_base, DAVINCI_RNDIS_REG),
519                         musb_readl(musb->ctrl_base, DAVINCI_AUTOREQ_REG),
520                         musb_readl(musb->ctrl_base,
521                                         DAVINCI_USB_INT_SOURCE_REG),
522                         musb_readl(musb->ctrl_base,
523                                         DAVINCI_USB_INT_MASK_REG));
524         if (code <= 0)
525                 goto done;
526         count += code;
527         buffer += code;
528 #endif  /* DAVINCI */
529
530 #ifdef CONFIG_USB_TUSB6010
531         code = sprintf(buffer,
532                         "TUSB6010: devconf %08x, phy enable %08x drive %08x"
533                         "\n\totg %03x timer %08x"
534                         "\n\tprcm conf %08x mgmt %08x; int src %08x mask %08x"
535                         "\n",
536                         musb_readl(musb->ctrl_base, TUSB_DEV_CONF),
537                         musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
538                         musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL),
539                         musb_readl(musb->ctrl_base, TUSB_DEV_OTG_STAT),
540                         musb_readl(musb->ctrl_base, TUSB_DEV_OTG_TIMER),
541                         musb_readl(musb->ctrl_base, TUSB_PRCM_CONF),
542                         musb_readl(musb->ctrl_base, TUSB_PRCM_MNGMT),
543                         musb_readl(musb->ctrl_base, TUSB_INT_SRC),
544                         musb_readl(musb->ctrl_base, TUSB_INT_MASK));
545         if (code <= 0)
546                 goto done;
547         count += code;
548         buffer += code;
549 #endif  /* DAVINCI */
550
551         if (cppi_ti_dma() && musb->dma_controller) {
552                 code = sprintf(buffer,
553                                 "CPPI: txcr=%d txsrc=%01x txena=%01x; "
554                                 "rxcr=%d rxsrc=%01x rxena=%01x "
555                                 "\n",
556                                 musb_readl(musb->ctrl_base,
557                                                 DAVINCI_TXCPPI_CTRL_REG),
558                                 musb_readl(musb->ctrl_base,
559                                                 DAVINCI_TXCPPI_RAW_REG),
560                                 musb_readl(musb->ctrl_base,
561                                                 DAVINCI_TXCPPI_INTENAB_REG),
562                                 musb_readl(musb->ctrl_base,
563                                                 DAVINCI_RXCPPI_CTRL_REG),
564                                 musb_readl(musb->ctrl_base,
565                                                 DAVINCI_RXCPPI_RAW_REG),
566                                 musb_readl(musb->ctrl_base,
567                                                 DAVINCI_RXCPPI_INTENAB_REG));
568                 if (code <= 0)
569                         goto done;
570                 count += code;
571                 buffer += code;
572         }
573
574 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
575         if (is_peripheral_enabled(musb)) {
576                 code = sprintf(buffer, "Gadget driver: %s\n",
577                                 musb->gadget_driver
578                                         ? musb->gadget_driver->driver.name
579                                         : "(none)");
580                 if (code <= 0)
581                         goto done;
582                 count += code;
583                 buffer += code;
584         }
585 #endif
586
587 done:
588         return count;
589 }
590
591 /* Write to ProcFS
592  *
593  * C soft-connect
594  * c soft-disconnect
595  * D<num> set/query the debug level
596  * E rElinquish bus (OTG)
597  * e enumerate
598  * F force session (OTG-unfriendly)
599  * H request host mode
600  * h cancel host request
601  * I enable HS
602  * i disable HS
603  * J set HS test mode
604  * j clear HS test mode
605  * K set FS test mode
606  * k clear FS test mode
607  * M set host test mode
608  * m clear host test mode
609  * R reset peripheral
610  * r resume root hub
611  * s stop session
612  * T start sending TEST_PACKET
613  * X term highspeed
614  * Y term fullspeed
615  * Z term lowspeed
616  * 
617  */
618
619 extern inline void mbusywait(int ms);
620 extern  void musb_port_reset(struct musb *musb, bool do_reset);
621 extern void musb_port_suspend(struct musb *musb, bool do_suspend);
622
623 static int musb_proc_write(struct file *file, const char __user *buffer,
624                         unsigned long count, void *data)
625 {
626         char cmd;
627         u8 reg;
628         struct musb *musb = (struct musb *)data;
629         void __iomem *mbase = musb->mregs;
630         unsigned long   flags;
631         struct usb_hcd *hcd = musb_to_hcd(musb);
632         struct usb_bus *bus = hcd_to_bus(hcd);
633
634         /* MOD_INC_USE_COUNT; */
635
636         if (unlikely(copy_from_user(&cmd, buffer, 1)))
637                 return -EFAULT;
638
639
640         switch (cmd) {
641         case 'C':
642                 if (mbase) {
643                         reg = musb_readb(mbase, MUSB_POWER);
644                         reg |= MUSB_POWER_SOFTCONN;
645                         musb_writeb(mbase, MUSB_POWER, reg);
646                 }
647                 break;
648
649         case 'c':
650                 if (mbase) {
651                         reg = musb_readb(mbase, MUSB_POWER);
652                         reg &= ~MUSB_POWER_SOFTCONN;
653                         musb_writeb(mbase, MUSB_POWER, reg);
654                 }
655                 break;
656
657         case 'I':
658                 if (mbase) {
659                         reg = musb_readb(mbase, MUSB_POWER);
660                         reg |= MUSB_POWER_HSENAB;
661                         musb_writeb(mbase, MUSB_POWER, reg);
662                 }
663                 break;
664
665         case 'i':
666                 if (mbase) {
667                         reg = musb_readb(mbase, MUSB_POWER);
668                         reg &= ~MUSB_POWER_HSENAB;
669                         musb_writeb(mbase, MUSB_POWER, reg);
670                 }
671                 break;
672
673         case 'F':
674                 if (mbase) {
675                         reg = musb_readb(mbase, MUSB_DEVCTL);
676                         reg |= MUSB_DEVCTL_SESSION;
677                         musb_writeb(mbase, MUSB_DEVCTL, reg);
678                 }
679                 break;
680
681         case 's':
682                 if (mbase) {
683                         reg = musb_readb(mbase, MUSB_DEVCTL);
684                         reg &= ~MUSB_DEVCTL_SESSION;
685                         musb_writeb(mbase, MUSB_DEVCTL, reg);
686                 }
687                 break;
688
689         case 'H':
690                 if (mbase) {
691                         reg = musb_readb(mbase, MUSB_DEVCTL);
692                         reg |= MUSB_DEVCTL_HR;
693                         musb_writeb(mbase, MUSB_DEVCTL, reg);
694                         /* MUSB_HST_MODE( ((struct musb*)data) ); */
695                         /* WARNING("Host Mode\n"); */
696                 }
697                 break;
698
699         case 'h':
700                 if (mbase) {
701                         reg = musb_readb(mbase, MUSB_DEVCTL);
702                         reg &= ~MUSB_DEVCTL_HR;
703                         musb_writeb(mbase, MUSB_DEVCTL, reg);
704                 }
705                 break;
706
707         case 'T':
708                 if (mbase) {
709                         musb_load_testpacket(musb);
710                         musb_writeb(mbase, MUSB_TESTMODE,
711                                         MUSB_TEST_PACKET);
712                 }
713                 break;
714
715         case 'M':
716                 if (mbase) {
717                         reg = musb_readb(mbase, MUSB_TESTMODE);
718                         reg |= MUSB_TEST_FORCE_HOST;
719                         musb_writeb(mbase, MUSB_TESTMODE, reg);
720                 }
721                 break;
722         
723         case 'm':
724                 if (mbase) {
725                         reg = musb_readb(mbase, MUSB_TESTMODE);
726                         reg &= ~MUSB_TEST_FORCE_HOST;
727                         musb_writeb(mbase, MUSB_TESTMODE, reg);
728                         MUSB_DEV_MODE(musb);
729                         musb->xceiv->state = OTG_STATE_B_IDLE;
730                 }
731                 break;
732
733   case 'L':
734                         musb->xceiv->state = OTG_STATE_A_HOST;
735                         MUSB_HST_MODE(musb);
736                 break;
737
738   case 'l':
739                         musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
740                         MUSB_HST_MODE(musb);
741                 break;
742
743         case 'J':
744                 if (mbase) {
745                         reg = musb_readb(mbase, MUSB_TESTMODE);
746                         reg |= MUSB_TEST_FORCE_HS;
747                         musb_writeb(mbase, MUSB_TESTMODE, reg);
748                 }
749                 break;
750
751         case 'j':
752                 if (mbase) {
753                         reg = musb_readb(mbase, MUSB_TESTMODE);
754                         reg &= ~MUSB_TEST_FORCE_HS;
755                         musb_writeb(mbase, MUSB_TESTMODE, reg);
756                 }
757                 break;
758
759         case 'K':
760                 if (mbase) {
761                         reg = musb_readb(mbase, MUSB_TESTMODE);
762                         reg |= MUSB_TEST_FORCE_FS;
763                         musb_writeb(mbase, MUSB_TESTMODE, reg);
764                 }
765                 break;
766
767         case 'k':
768                 if (mbase) {
769                         reg = musb_readb(mbase, MUSB_TESTMODE);
770                         reg &= ~MUSB_TEST_FORCE_FS;
771                         musb_writeb(mbase, MUSB_TESTMODE, reg);
772                 }
773                 break;
774
775   case 'X':
776     if (mbase)
777                         musb_force_term(mbase,MUSB_TERM_HOST_HIGHSPEED);
778                 break;
779
780   case 'Y':
781     if (mbase)
782                         musb_force_term(mbase,MUSB_TERM_HOST_FULLSPEED);
783                 break;
784
785   case 'Z':
786     if (mbase)
787                         musb_force_term(mbase,MUSB_TERM_HOST_LOWSPEED);
788                 break;
789
790         case 'R':
791                 musb_port_reset(musb, true);
792                 while (time_before(jiffies, musb->rh_timer))
793                         msleep(1);
794                 musb_port_reset(musb, false);
795
796                 break;
797                 
798   case 'r':
799                 usb_hcd_resume_root_hub(hcd);
800                 break;
801
802   case 'e':
803                 if(bus) 
804                         usb_bus_start_enum(bus,bus->otg_port);
805                 break;
806
807         case 'U':
808                 /*Suspend*/
809                 musb_port_suspend(musb, true);
810                 break;
811
812         case 'u':
813                 /*Resume*/
814                 musb_port_suspend(musb, false);
815                 /*How to end sanely? */
816                 musb_port_reset(musb, true);
817                 while (time_before(jiffies, musb->rh_timer))
818                         msleep(1);
819                 musb_port_reset(musb, false);
820
821         break;
822
823         case '?':
824                 INFO("?: you are seeing it\n");
825                 INFO("C/c: soft connect enable/disable\n");
826                 INFO("I/i: hispeed enable/disable\n");
827                 INFO("F: force session start\n");
828                 INFO("H: host mode\n");
829                 INFO("T: start sending TEST_PACKET\n");
830                 break;
831
832         default:
833                 ERR("Command %c not implemented\n", cmd);
834                 break;
835         }
836
837         musb_platform_try_idle(musb, 0);
838
839
840         return count;
841 }
842
843 static int musb_proc_read(char *page, char **start,
844                         off_t off, int count, int *eof, void *data)
845 {
846         char *buffer = page;
847         int code = 0;
848         unsigned long   flags;
849         struct musb     *musb = data;
850         unsigned        epnum;
851
852         count -= off;
853         count -= 1;             /* for NUL at end */
854         count -= 20; /* Padding */
855
856         if (count <= 0)
857                 return -EINVAL;
858
859         spin_lock_irqsave(&musb->lock, flags);
860
861         code = dump_header_stats(musb, buffer);
862         if (code > 0) {
863                 buffer += code;
864                 count -= code;
865         }
866
867         if (count < 0)
868                 goto done;
869
870         /* generate the report for the end points */
871         /* REVISIT ... not unless something's connected! */
872         for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints;
873                         epnum++) {
874                 code = dump_end_info(musb, epnum, buffer, count);
875                 if (code > 0) {
876                         buffer += code;
877                         count -= code;
878                         if (count < 0)
879                                 goto done;
880                 }
881         }
882
883
884  done:
885
886         musb_platform_try_idle(musb, 0);
887
888         spin_unlock_irqrestore(&musb->lock, flags);
889         *eof = 1;
890
891         if(count < 0)
892                 return -EINVAL;
893
894         return buffer - page;
895 }
896
897 void __devexit musb_debug_delete(char *name, struct musb *musb)
898 {
899         if (musb->proc_entry)
900                 remove_proc_entry(name, NULL);
901 }
902
903 struct proc_dir_entry *__init
904 musb_debug_create(char *name, struct musb *data)
905 {
906         struct proc_dir_entry   *pde;
907
908         /* FIXME convert everything to seq_file; then later, debugfs */
909
910         if (!name)
911                 return NULL;
912
913         pde = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, NULL);
914         data->proc_entry = pde;
915         if (pde) {
916                 pde->data = data;
917                 /* pde->owner = THIS_MODULE; */
918
919                 pde->read_proc = musb_proc_read;
920                 pde->write_proc = musb_proc_write;
921
922                 pde->size = 0;
923
924                 pr_debug("Registered /proc/%s\n", name);
925         } else {
926                 pr_debug("Cannot create a valid proc file entry");
927         }
928
929         return pde;
930 }