LCOV - code coverage report
Current view: top level - drivers/usb/host - ehci-dbg.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 4 4 100.0 %
Date: 2017-01-25 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2001-2002 by David Brownell
       3             :  *
       4             :  * This program is free software; you can redistribute it and/or modify it
       5             :  * under the terms of the GNU General Public License as published by the
       6             :  * Free Software Foundation; either version 2 of the License, or (at your
       7             :  * option) any later version.
       8             :  *
       9             :  * This program is distributed in the hope that it will be useful, but
      10             :  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      11             :  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      12             :  * for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with this program; if not, write to the Free Software Foundation,
      16             :  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
      17             :  */
      18             : 
      19             : /* this file is part of ehci-hcd.c */
      20             : 
      21             : #define ehci_dbg(ehci, fmt, args...) \
      22             :         dev_dbg (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
      23             : #define ehci_err(ehci, fmt, args...) \
      24             :         dev_err (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
      25             : #define ehci_info(ehci, fmt, args...) \
      26             :         dev_info (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
      27             : #define ehci_warn(ehci, fmt, args...) \
      28             :         dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
      29             : 
      30             : #ifdef VERBOSE_DEBUG
      31             : #       define vdbg dbg
      32             : #       define ehci_vdbg ehci_dbg
      33             : #else
      34             : #       define vdbg(fmt,args...) do { } while (0)
      35             : #       define ehci_vdbg(ehci, fmt, args...) do { } while (0)
      36             : #endif
      37             : 
      38             : #ifdef  DEBUG
      39             : 
      40             : /* check the values in the HCSPARAMS register
      41             :  * (host controller _Structural_ parameters)
      42             :  * see EHCI spec, Table 2-4 for each value
      43             :  */
      44             : static void dbg_hcs_params (struct ehci_hcd *ehci, char *label)
      45             : {
      46             :         u32     params = ehci_readl(ehci, &ehci->caps->hcs_params);
      47             : 
      48             :         ehci_dbg (ehci,
      49             :                 "%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n",
      50             :                 label, params,
      51             :                 HCS_DEBUG_PORT (params),
      52             :                 HCS_INDICATOR (params) ? " ind" : "",
      53             :                 HCS_N_CC (params),
      54             :                 HCS_N_PCC (params),
      55             :                 HCS_PORTROUTED (params) ? "" : " ordered",
      56             :                 HCS_PPC (params) ? "" : " !ppc",
      57             :                 HCS_N_PORTS (params)
      58             :                 );
      59             :         /* Port routing, per EHCI 0.95 Spec, Section 2.2.5 */
      60             :         if (HCS_PORTROUTED (params)) {
      61             :                 int i;
      62             :                 char buf [46], tmp [7], byte;
      63             : 
      64             :                 buf[0] = 0;
      65             :                 for (i = 0; i < HCS_N_PORTS (params); i++) {
      66             :                         // FIXME MIPS won't readb() ...
      67             :                         byte = readb (&ehci->caps->portroute[(i>>1)]);
      68             :                         sprintf(tmp, "%d ",
      69             :                                 ((i & 0x1) ? ((byte)&0xf) : ((byte>>4)&0xf)));
      70             :                         strcat(buf, tmp);
      71             :                 }
      72             :                 ehci_dbg (ehci, "%s portroute %s\n",
      73             :                                 label, buf);
      74             :         }
      75             : }
      76             : #else
      77             : 
      78             : static inline void dbg_hcs_params (struct ehci_hcd *ehci, char *label) {}
      79             : 
      80           2 : #endif
      81             : 
      82             : #ifdef  DEBUG
      83             : 
      84             : /* check the values in the HCCPARAMS register
      85             :  * (host controller _Capability_ parameters)
      86             :  * see EHCI Spec, Table 2-5 for each value
      87             :  * */
      88             : static void dbg_hcc_params (struct ehci_hcd *ehci, char *label)
      89             : {
      90             :         u32     params = ehci_readl(ehci, &ehci->caps->hcc_params);
      91             : 
      92             :         if (HCC_ISOC_CACHE (params)) {
      93             :                 ehci_dbg (ehci,
      94             :                         "%s hcc_params %04x caching frame %s%s%s\n",
      95             :                         label, params,
      96             :                         HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
      97             :                         HCC_CANPARK(params) ? " park" : "",
      98             :                         HCC_64BIT_ADDR(params) ? " 64 bit addr" : "");
      99             :         } else {
     100             :                 ehci_dbg (ehci,
     101             :                         "%s hcc_params %04x thresh %d uframes %s%s%s\n",
     102             :                         label,
     103             :                         params,
     104             :                         HCC_ISOC_THRES(params),
     105             :                         HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
     106             :                         HCC_CANPARK(params) ? " park" : "",
     107             :                         HCC_64BIT_ADDR(params) ? " 64 bit addr" : "");
     108             :         }
     109             : }
     110             : #else
     111             : 
     112             : static inline void dbg_hcc_params (struct ehci_hcd *ehci, char *label) {}
     113             : 
     114             : #endif
     115             : 
     116             : #ifdef  DEBUG
     117             : 
     118             : static void __maybe_unused
     119             : dbg_qtd (const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd)
     120             : {
     121             :         ehci_dbg(ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
     122             :                 hc32_to_cpup(ehci, &qtd->hw_next),
     123             :                 hc32_to_cpup(ehci, &qtd->hw_alt_next),
     124             :                 hc32_to_cpup(ehci, &qtd->hw_token),
     125             :                 hc32_to_cpup(ehci, &qtd->hw_buf [0]));
     126             :         if (qtd->hw_buf [1])
     127             :                 ehci_dbg(ehci, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
     128             :                         hc32_to_cpup(ehci, &qtd->hw_buf[1]),
     129             :                         hc32_to_cpup(ehci, &qtd->hw_buf[2]),
     130             :                         hc32_to_cpup(ehci, &qtd->hw_buf[3]),
     131             :                         hc32_to_cpup(ehci, &qtd->hw_buf[4]));
     132             : }
     133             : 
     134             : static void __maybe_unused
     135             : dbg_qh (const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
     136             : {
     137             :         struct ehci_qh_hw *hw = qh->hw;
     138             : 
     139             :         ehci_dbg (ehci, "%s qh %p n%08x info %x %x qtd %x\n", label,
     140             :                 qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
     141             :         dbg_qtd("overlay", ehci, (struct ehci_qtd *) &hw->hw_qtd_next);
     142             : }
     143             : 
     144             : static void __maybe_unused
     145             : dbg_itd (const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd)
     146             : {
     147             :         ehci_dbg (ehci, "%s [%d] itd %p, next %08x, urb %p\n",
     148             :                 label, itd->frame, itd, hc32_to_cpu(ehci, itd->hw_next),
     149             :                 itd->urb);
     150             :         ehci_dbg (ehci,
     151             :                 "  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
     152             :                 hc32_to_cpu(ehci, itd->hw_transaction[0]),
     153             :                 hc32_to_cpu(ehci, itd->hw_transaction[1]),
     154             :                 hc32_to_cpu(ehci, itd->hw_transaction[2]),
     155             :                 hc32_to_cpu(ehci, itd->hw_transaction[3]),
     156             :                 hc32_to_cpu(ehci, itd->hw_transaction[4]),
     157             :                 hc32_to_cpu(ehci, itd->hw_transaction[5]),
     158             :                 hc32_to_cpu(ehci, itd->hw_transaction[6]),
     159             :                 hc32_to_cpu(ehci, itd->hw_transaction[7]));
     160             :         ehci_dbg (ehci,
     161             :                 "  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
     162             :                 hc32_to_cpu(ehci, itd->hw_bufp[0]),
     163             :                 hc32_to_cpu(ehci, itd->hw_bufp[1]),
     164             :                 hc32_to_cpu(ehci, itd->hw_bufp[2]),
     165             :                 hc32_to_cpu(ehci, itd->hw_bufp[3]),
     166             :                 hc32_to_cpu(ehci, itd->hw_bufp[4]),
     167             :                 hc32_to_cpu(ehci, itd->hw_bufp[5]),
     168             :                 hc32_to_cpu(ehci, itd->hw_bufp[6]));
     169             :         ehci_dbg (ehci, "  index: %d %d %d %d %d %d %d %d\n",
     170             :                 itd->index[0], itd->index[1], itd->index[2],
     171             :                 itd->index[3], itd->index[4], itd->index[5],
     172             :                 itd->index[6], itd->index[7]);
     173             : }
     174             : 
     175             : static void __maybe_unused
     176             : dbg_sitd (const char *label, struct ehci_hcd *ehci, struct ehci_sitd *sitd)
     177             : {
     178             :         ehci_dbg (ehci, "%s [%d] sitd %p, next %08x, urb %p\n",
     179             :                 label, sitd->frame, sitd, hc32_to_cpu(ehci, sitd->hw_next),
     180             :                 sitd->urb);
     181             :         ehci_dbg (ehci,
     182             :                 "  addr %08x sched %04x result %08x buf %08x %08x\n",
     183             :                 hc32_to_cpu(ehci, sitd->hw_fullspeed_ep),
     184             :                 hc32_to_cpu(ehci, sitd->hw_uframe),
     185             :                 hc32_to_cpu(ehci, sitd->hw_results),
     186             :                 hc32_to_cpu(ehci, sitd->hw_buf[0]),
     187             :                 hc32_to_cpu(ehci, sitd->hw_buf[1]));
     188             : }
     189             : 
     190             : static int __maybe_unused
     191             : dbg_status_buf (char *buf, unsigned len, const char *label, u32 status)
     192             : {
     193             :         return scnprintf (buf, len,
     194             :                 "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
     195             :                 label, label [0] ? " " : "", status,
     196             :                 (status & STS_ASS) ? " Async" : "",
     197             :                 (status & STS_PSS) ? " Periodic" : "",
     198             :                 (status & STS_RECL) ? " Recl" : "",
     199             :                 (status & STS_HALT) ? " Halt" : "",
     200             :                 (status & STS_IAA) ? " IAA" : "",
     201             :                 (status & STS_FATAL) ? " FATAL" : "",
     202             :                 (status & STS_FLR) ? " FLR" : "",
     203             :                 (status & STS_PCD) ? " PCD" : "",
     204             :                 (status & STS_ERR) ? " ERR" : "",
     205             :                 (status & STS_INT) ? " INT" : ""
     206             :                 );
     207             : }
     208             : 
     209             : static int __maybe_unused
     210             : dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable)
     211             : {
     212             :         return scnprintf (buf, len,
     213             :                 "%s%sintrenable %02x%s%s%s%s%s%s",
     214             :                 label, label [0] ? " " : "", enable,
     215             :                 (enable & STS_IAA) ? " IAA" : "",
     216             :                 (enable & STS_FATAL) ? " FATAL" : "",
     217             :                 (enable & STS_FLR) ? " FLR" : "",
     218             :                 (enable & STS_PCD) ? " PCD" : "",
     219             :                 (enable & STS_ERR) ? " ERR" : "",
     220             :                 (enable & STS_INT) ? " INT" : ""
     221             :                 );
     222             : }
     223             : 
     224             : static const char *const fls_strings [] =
     225             :     { "1024", "512", "256", "??" };
     226             : 
     227             : static int
     228             : dbg_command_buf (char *buf, unsigned len, const char *label, u32 command)
     229             : {
     230             :         return scnprintf (buf, len,
     231             :                 "%s%scommand %06x %s=%d ithresh=%d%s%s%s%s period=%s%s %s",
     232             :                 label, label [0] ? " " : "", command,
     233             :                 (command & CMD_PARK) ? "park" : "(park)",
     234             :                 CMD_PARK_CNT (command),
     235             :                 (command >> 16) & 0x3f,
     236             :                 (command & CMD_LRESET) ? " LReset" : "",
     237             :                 (command & CMD_IAAD) ? " IAAD" : "",
     238             :                 (command & CMD_ASE) ? " Async" : "",
     239             :                 (command & CMD_PSE) ? " Periodic" : "",
     240             :                 fls_strings [(command >> 2) & 0x3],
     241             :                 (command & CMD_RESET) ? " Reset" : "",
     242             :                 (command & CMD_RUN) ? "RUN" : "HALT"
     243             :                 );
     244             : }
     245             : 
     246             : static int
     247             : dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
     248             : {
     249             :         char    *sig;
     250             : 
     251             :         /* signaling state */
     252             :         switch (status & (3 << 10)) {
     253             :         case 0 << 10: sig = "se0"; break;
     254             :         case 1 << 10: sig = "k"; break;         /* low speed */
     255             :         case 2 << 10: sig = "j"; break;
     256             :         default: sig = "?"; break;
     257             :         }
     258             : 
     259             :         return scnprintf (buf, len,
     260             :                 "%s%sport %d status %06x%s%s sig=%s%s%s%s%s%s%s%s%s%s",
     261             :                 label, label [0] ? " " : "", port, status,
     262             :                 (status & PORT_POWER) ? " POWER" : "",
     263             :                 (status & PORT_OWNER) ? " OWNER" : "",
     264             :                 sig,
     265             :                 (status & PORT_RESET) ? " RESET" : "",
     266             :                 (status & PORT_SUSPEND) ? " SUSPEND" : "",
     267             :                 (status & PORT_RESUME) ? " RESUME" : "",
     268             :                 (status & PORT_OCC) ? " OCC" : "",
     269             :                 (status & PORT_OC) ? " OC" : "",
     270             :                 (status & PORT_PEC) ? " PEC" : "",
     271             :                 (status & PORT_PE) ? " PE" : "",
     272             :                 (status & PORT_CSC) ? " CSC" : "",
     273             :                 (status & PORT_CONNECT) ? " CONNECT" : "");
     274             : }
     275             : 
     276             : #else
     277             : static inline void __maybe_unused
     278             : dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
     279             : {}
     280             : 
     281             : static inline int __maybe_unused
     282             : dbg_status_buf (char *buf, unsigned len, const char *label, u32 status)
     283          28 : { return 0; }
     284             : 
     285             : static inline int __maybe_unused
     286             : dbg_command_buf (char *buf, unsigned len, const char *label, u32 command)
     287             : { return 0; }
     288             : 
     289             : static inline int __maybe_unused
     290             : dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable)
     291             : { return 0; }
     292             : 
     293             : static inline int __maybe_unused
     294             : dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
     295           4 : { return 0; }
     296             : 
     297             : #endif  /* DEBUG */
     298             : 
     299             : /* functions have the "wrong" filename when they're output... */
     300             : #define dbg_status(ehci, label, status) { \
     301             :         char _buf [80]; \
     302             :         dbg_status_buf (_buf, sizeof _buf, label, status); \
     303             :         ehci_dbg (ehci, "%s\n", _buf); \
     304             : }
     305             : 
     306             : #define dbg_cmd(ehci, label, command) { \
     307             :         char _buf [80]; \
     308             :         dbg_command_buf (_buf, sizeof _buf, label, command); \
     309             :         ehci_dbg (ehci, "%s\n", _buf); \
     310             : }
     311             : 
     312             : #define dbg_port(ehci, label, port, status) { \
     313             :         char _buf [80]; \
     314             :         dbg_port_buf (_buf, sizeof _buf, label, port, status); \
     315             :         ehci_dbg (ehci, "%s\n", _buf); \
     316             : }
     317             : 
     318             : /*-------------------------------------------------------------------------*/
     319             : 
     320             : #ifdef STUB_DEBUG_FILES
     321             : 
     322             : static inline void create_debug_files (struct ehci_hcd *bus) { }
     323             : static inline void remove_debug_files (struct ehci_hcd *bus) { }
     324           2 : 
     325             : #else
     326             : 
     327             : /* troubleshooting help: expose state in debugfs */
     328             : 
     329             : static int debug_async_open(struct inode *, struct file *);
     330             : static int debug_periodic_open(struct inode *, struct file *);
     331             : static int debug_registers_open(struct inode *, struct file *);
     332             : static int debug_async_open(struct inode *, struct file *);
     333             : static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
     334             : static int debug_close(struct inode *, struct file *);
     335             : 
     336             : static const struct file_operations debug_async_fops = {
     337             :         .owner          = THIS_MODULE,
     338             :         .open           = debug_async_open,
     339             :         .read           = debug_output,
     340             :         .release        = debug_close,
     341             : };
     342             : static const struct file_operations debug_periodic_fops = {
     343             :         .owner          = THIS_MODULE,
     344             :         .open           = debug_periodic_open,
     345             :         .read           = debug_output,
     346             :         .release        = debug_close,
     347             : };
     348             : static const struct file_operations debug_registers_fops = {
     349             :         .owner          = THIS_MODULE,
     350             :         .open           = debug_registers_open,
     351             :         .read           = debug_output,
     352             :         .release        = debug_close,
     353             : };
     354             : 
     355             : static struct dentry *ehci_debug_root;
     356             : 
     357             : struct debug_buffer {
     358             :         ssize_t (*fill_func)(struct debug_buffer *);    /* fill method */
     359             :         struct usb_bus *bus;
     360             :         struct mutex mutex;     /* protect filling of buffer */
     361             :         size_t count;           /* number of characters filled into buffer */
     362             :         char *output_buf;
     363             :         size_t alloc_size;
     364             : };
     365             : 
     366             : #define speed_char(info1) ({ char tmp; \
     367             :                 switch (info1 & (3 << 12)) { \
     368             :                 case 0 << 12: tmp = 'f'; break; \
     369             :                 case 1 << 12: tmp = 'l'; break; \
     370             :                 case 2 << 12: tmp = 'h'; break; \
     371             :                 default: tmp = '?'; break; \
     372             :                 }; tmp; })
     373             : 
     374             : static inline char token_mark(struct ehci_hcd *ehci, __hc32 token)
     375             : {
     376             :         __u32 v = hc32_to_cpu(ehci, token);
     377             : 
     378             :         if (v & QTD_STS_ACTIVE)
     379             :                 return '*';
     380             :         if (v & QTD_STS_HALT)
     381             :                 return '-';
     382             :         if (!IS_SHORT_READ (v))
     383             :                 return ' ';
     384             :         /* tries to advance through hw_alt_next */
     385             :         return '/';
     386             : }
     387             : 
     388             : static void qh_lines (
     389             :         struct ehci_hcd *ehci,
     390             :         struct ehci_qh *qh,
     391             :         char **nextp,
     392             :         unsigned *sizep
     393             : )
     394             : {
     395             :         u32                     scratch;
     396             :         u32                     hw_curr;
     397             :         struct list_head        *entry;
     398             :         struct ehci_qtd         *td;
     399             :         unsigned                temp;
     400             :         unsigned                size = *sizep;
     401             :         char                    *next = *nextp;
     402             :         char                    mark;
     403             :         __le32                  list_end = EHCI_LIST_END(ehci);
     404             :         struct ehci_qh_hw       *hw = qh->hw;
     405             : 
     406             :         if (hw->hw_qtd_next == list_end)     /* NEC does this */
     407             :                 mark = '@';
     408             :         else
     409             :                 mark = token_mark(ehci, hw->hw_token);
     410             :         if (mark == '/') {      /* qh_alt_next controls qh advance? */
     411             :                 if ((hw->hw_alt_next & QTD_MASK(ehci))
     412             :                                 == ehci->async->hw->hw_alt_next)
     413             :                         mark = '#';     /* blocked */
     414             :                 else if (hw->hw_alt_next == list_end)
     415             :                         mark = '.';     /* use hw_qtd_next */
     416             :                 /* else alt_next points to some other qtd */
     417             :         }
     418             :         scratch = hc32_to_cpup(ehci, &hw->hw_info1);
     419             :         hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &hw->hw_current) : 0;
     420             :         temp = scnprintf (next, size,
     421             :                         "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)",
     422             :                         qh, scratch & 0x007f,
     423             :                         speed_char (scratch),
     424             :                         (scratch >> 8) & 0x000f,
     425             :                         scratch, hc32_to_cpup(ehci, &hw->hw_info2),
     426             :                         hc32_to_cpup(ehci, &hw->hw_token), mark,
     427             :                         (cpu_to_hc32(ehci, QTD_TOGGLE) & hw->hw_token)
     428             :                                 ? "data1" : "data0",
     429             :                         (hc32_to_cpup(ehci, &hw->hw_alt_next) >> 1) & 0x0f);
     430             :         size -= temp;
     431             :         next += temp;
     432             : 
     433             :         /* hc may be modifying the list as we read it ... */
     434             :         list_for_each (entry, &qh->qtd_list) {
     435             :                 td = list_entry (entry, struct ehci_qtd, qtd_list);
     436             :                 scratch = hc32_to_cpup(ehci, &td->hw_token);
     437             :                 mark = ' ';
     438             :                 if (hw_curr == td->qtd_dma)
     439             :                         mark = '*';
     440             :                 else if (hw->hw_qtd_next == cpu_to_hc32(ehci, td->qtd_dma))
     441             :                         mark = '+';
     442             :                 else if (QTD_LENGTH (scratch)) {
     443             :                         if (td->hw_alt_next == ehci->async->hw->hw_alt_next)
     444             :                                 mark = '#';
     445             :                         else if (td->hw_alt_next != list_end)
     446             :                                 mark = '/';
     447             :                 }
     448             :                 temp = snprintf (next, size,
     449             :                                 "\n\t%p%c%s len=%d %08x urb %p",
     450             :                                 td, mark, ({ char *tmp;
     451             :                                  switch ((scratch>>8)&0x03) {
     452             :                                  case 0: tmp = "out"; break;
     453             :                                  case 1: tmp = "in"; break;
     454             :                                  case 2: tmp = "setup"; break;
     455             :                                  default: tmp = "?"; break;
     456             :                                  } tmp;}),
     457             :                                 (scratch >> 16) & 0x7fff,
     458             :                                 scratch,
     459             :                                 td->urb);
     460             :                 if (size < temp)
     461             :                         temp = size;
     462             :                 size -= temp;
     463             :                 next += temp;
     464             :                 if (temp == size)
     465             :                         goto done;
     466             :         }
     467             : 
     468             :         temp = snprintf (next, size, "\n");
     469             :         if (size < temp)
     470             :                 temp = size;
     471             :         size -= temp;
     472             :         next += temp;
     473             : 
     474             : done:
     475             :         *sizep = size;
     476             :         *nextp = next;
     477             : }
     478             : 
     479             : static ssize_t fill_async_buffer(struct debug_buffer *buf)
     480             : {
     481             :         struct usb_hcd          *hcd;
     482             :         struct ehci_hcd         *ehci;
     483             :         unsigned long           flags;
     484             :         unsigned                temp, size;
     485             :         char                    *next;
     486             :         struct ehci_qh          *qh;
     487             : 
     488             :         hcd = bus_to_hcd(buf->bus);
     489             :         ehci = hcd_to_ehci (hcd);
     490             :         next = buf->output_buf;
     491             :         size = buf->alloc_size;
     492             : 
     493             :         *next = 0;
     494             : 
     495             :         /* dumps a snapshot of the async schedule.
     496             :          * usually empty except for long-term bulk reads, or head.
     497             :          * one QH per line, and TDs we know about
     498             :          */
     499             :         spin_lock_irqsave (&ehci->lock, flags);
     500             :         for (qh = ehci->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh)
     501             :                 qh_lines (ehci, qh, &next, &size);
     502             :         if (ehci->reclaim && size > 0) {
     503             :                 temp = scnprintf (next, size, "\nreclaim =\n");
     504             :                 size -= temp;
     505             :                 next += temp;
     506             : 
     507             :                 for (qh = ehci->reclaim; size > 0 && qh; qh = qh->reclaim)
     508             :                         qh_lines (ehci, qh, &next, &size);
     509             :         }
     510             :         spin_unlock_irqrestore (&ehci->lock, flags);
     511             : 
     512             :         return strlen(buf->output_buf);
     513             : }
     514             : 
     515             : #define DBG_SCHED_LIMIT 64
     516             : static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
     517             : {
     518             :         struct usb_hcd          *hcd;
     519             :         struct ehci_hcd         *ehci;
     520             :         unsigned long           flags;
     521             :         union ehci_shadow       p, *seen;
     522             :         unsigned                temp, size, seen_count;
     523             :         char                    *next;
     524             :         unsigned                i;
     525             :         __hc32                  tag;
     526             : 
     527             :         if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC)))
     528             :                 return 0;
     529             :         seen_count = 0;
     530             : 
     531             :         hcd = bus_to_hcd(buf->bus);
     532             :         ehci = hcd_to_ehci (hcd);
     533             :         next = buf->output_buf;
     534             :         size = buf->alloc_size;
     535             : 
     536             :         temp = scnprintf (next, size, "size = %d\n", ehci->periodic_size);
     537             :         size -= temp;
     538             :         next += temp;
     539             : 
     540             :         /* dump a snapshot of the periodic schedule.
     541             :          * iso changes, interrupt usually doesn't.
     542             :          */
     543             :         spin_lock_irqsave (&ehci->lock, flags);
     544             :         for (i = 0; i < ehci->periodic_size; i++) {
     545             :                 p = ehci->pshadow [i];
     546             :                 if (likely (!p.ptr))
     547             :                         continue;
     548             :                 tag = Q_NEXT_TYPE(ehci, ehci->periodic [i]);
     549             : 
     550             :                 temp = scnprintf (next, size, "%4d: ", i);
     551             :                 size -= temp;
     552             :                 next += temp;
     553             : 
     554             :                 do {
     555             :                         struct ehci_qh_hw *hw;
     556             : 
     557             :                         switch (hc32_to_cpu(ehci, tag)) {
     558             :                         case Q_TYPE_QH:
     559             :                                 hw = p.qh->hw;
     560             :                                 temp = scnprintf (next, size, " qh%d-%04x/%p",
     561             :                                                 p.qh->period,
     562             :                                                 hc32_to_cpup(ehci,
     563             :                                                         &hw->hw_info2)
     564             :                                                         /* uframe masks */
     565             :                                                         & (QH_CMASK | QH_SMASK),
     566             :                                                 p.qh);
     567             :                                 size -= temp;
     568             :                                 next += temp;
     569             :                                 /* don't repeat what follows this qh */
     570             :                                 for (temp = 0; temp < seen_count; temp++) {
     571             :                                         if (seen [temp].ptr != p.ptr)
     572             :                                                 continue;
     573             :                                         if (p.qh->qh_next.ptr) {
     574             :                                                 temp = scnprintf (next, size,
     575             :                                                         " ...");
     576             :                                                 size -= temp;
     577             :                                                 next += temp;
     578             :                                         }
     579             :                                         break;
     580             :                                 }
     581             :                                 /* show more info the first time around */
     582             :                                 if (temp == seen_count) {
     583             :                                         u32     scratch = hc32_to_cpup(ehci,
     584             :                                                         &hw->hw_info1);
     585             :                                         struct ehci_qtd *qtd;
     586             :                                         char            *type = "";
     587             : 
     588             :                                         /* count tds, get ep direction */
     589             :                                         temp = 0;
     590             :                                         list_for_each_entry (qtd,
     591             :                                                         &p.qh->qtd_list,
     592             :                                                         qtd_list) {
     593             :                                                 temp++;
     594             :                                                 switch (0x03 & (hc32_to_cpu(
     595             :                                                         ehci,
     596             :                                                         qtd->hw_token) >> 8)) {
     597             :                                                 case 0: type = "out"; continue;
     598             :                                                 case 1: type = "in"; continue;
     599             :                                                 }
     600             :                                         }
     601             : 
     602             :                                         temp = scnprintf (next, size,
     603             :                                                 " (%c%d ep%d%s "
     604             :                                                 "[%d/%d] q%d p%d)",
     605             :                                                 speed_char (scratch),
     606             :                                                 scratch & 0x007f,
     607             :                                                 (scratch >> 8) & 0x000f, type,
     608             :                                                 p.qh->usecs, p.qh->c_usecs,
     609             :                                                 temp,
     610             :                                                 0x7ff & (scratch >> 16));
     611             : 
     612             :                                         if (seen_count < DBG_SCHED_LIMIT)
     613             :                                                 seen [seen_count++].qh = p.qh;
     614             :                                 } else
     615             :                                         temp = 0;
     616             :                                 if (p.qh) {
     617             :                                         tag = Q_NEXT_TYPE(ehci, hw->hw_next);
     618             :                                         p = p.qh->qh_next;
     619             :                                 }
     620             :                                 break;
     621             :                         case Q_TYPE_FSTN:
     622             :                                 temp = scnprintf (next, size,
     623             :                                         " fstn-%8x/%p", p.fstn->hw_prev,
     624             :                                         p.fstn);
     625             :                                 tag = Q_NEXT_TYPE(ehci, p.fstn->hw_next);
     626             :                                 p = p.fstn->fstn_next;
     627             :                                 break;
     628             :                         case Q_TYPE_ITD:
     629             :                                 temp = scnprintf (next, size,
     630             :                                         " itd/%p", p.itd);
     631             :                                 tag = Q_NEXT_TYPE(ehci, p.itd->hw_next);
     632             :                                 p = p.itd->itd_next;
     633             :                                 break;
     634             :                         case Q_TYPE_SITD:
     635             :                                 temp = scnprintf (next, size,
     636             :                                         " sitd%d-%04x/%p",
     637             :                                         p.sitd->stream->interval,
     638             :                                         hc32_to_cpup(ehci, &p.sitd->hw_uframe)
     639             :                                                 & 0x0000ffff,
     640             :                                         p.sitd);
     641             :                                 tag = Q_NEXT_TYPE(ehci, p.sitd->hw_next);
     642             :                                 p = p.sitd->sitd_next;
     643             :                                 break;
     644             :                         }
     645             :                         size -= temp;
     646             :                         next += temp;
     647             :                 } while (p.ptr);
     648             : 
     649             :                 temp = scnprintf (next, size, "\n");
     650             :                 size -= temp;
     651             :                 next += temp;
     652             :         }
     653             :         spin_unlock_irqrestore (&ehci->lock, flags);
     654             :         kfree (seen);
     655             : 
     656             :         return buf->alloc_size - size;
     657             : }
     658             : #undef DBG_SCHED_LIMIT
     659             : 
     660             : static ssize_t fill_registers_buffer(struct debug_buffer *buf)
     661             : {
     662             :         struct usb_hcd          *hcd;
     663             :         struct ehci_hcd         *ehci;
     664             :         unsigned long           flags;
     665             :         unsigned                temp, size, i;
     666             :         char                    *next, scratch [80];
     667             :         static char             fmt [] = "%*s\n";
     668             :         static char             label [] = "";
     669             : 
     670             :         hcd = bus_to_hcd(buf->bus);
     671             :         ehci = hcd_to_ehci (hcd);
     672             :         next = buf->output_buf;
     673             :         size = buf->alloc_size;
     674             : 
     675             :         spin_lock_irqsave (&ehci->lock, flags);
     676             : 
     677             :         if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
     678             :                 size = scnprintf (next, size,
     679             :                         "bus %s, device %s\n"
     680             :                         "%s\n"
     681             :                         "SUSPENDED (no register access)\n",
     682             :                         hcd->self.controller->bus->name,
     683             :                         dev_name(hcd->self.controller),
     684             :                         hcd->product_desc);
     685             :                 goto done;
     686             :         }
     687             : 
     688             :         /* Capability Registers */
     689             :         i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
     690             :         temp = scnprintf (next, size,
     691             :                 "bus %s, device %s\n"
     692             :                 "%s\n"
     693             :                 "EHCI %x.%02x, hcd state %d\n",
     694             :                 hcd->self.controller->bus->name,
     695             :                 dev_name(hcd->self.controller),
     696             :                 hcd->product_desc,
     697             :                 i >> 8, i & 0x0ff, hcd->state);
     698             :         size -= temp;
     699             :         next += temp;
     700             : 
     701             : #ifdef  CONFIG_PCI
     702             :         /* EHCI 0.96 and later may have "extended capabilities" */
     703             :         if (hcd->self.controller->bus == &pci_bus_type) {
     704             :                 struct pci_dev  *pdev;
     705             :                 u32             offset, cap, cap2;
     706             :                 unsigned        count = 256/4;
     707             : 
     708             :                 pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
     709             :                 offset = HCC_EXT_CAPS(ehci_readl(ehci,
     710             :                                 &ehci->caps->hcc_params));
     711             :                 while (offset && count--) {
     712             :                         pci_read_config_dword (pdev, offset, &cap);
     713             :                         switch (cap & 0xff) {
     714             :                         case 1:
     715             :                                 temp = scnprintf (next, size,
     716             :                                         "ownership %08x%s%s\n", cap,
     717             :                                         (cap & (1 << 24)) ? " linux" : "",
     718             :                                         (cap & (1 << 16)) ? " firmware" : "");
     719             :                                 size -= temp;
     720             :                                 next += temp;
     721             : 
     722             :                                 offset += 4;
     723             :                                 pci_read_config_dword (pdev, offset, &cap2);
     724             :                                 temp = scnprintf (next, size,
     725             :                                         "SMI sts/enable 0x%08x\n", cap2);
     726             :                                 size -= temp;
     727             :                                 next += temp;
     728             :                                 break;
     729             :                         case 0:         /* illegal reserved capability */
     730             :                                 cap = 0;
     731             :                                 /* FALLTHROUGH */
     732             :                         default:                /* unknown */
     733             :                                 break;
     734             :                         }
     735             :                         temp = (cap >> 8) & 0xff;
     736             :                 }
     737             :         }
     738             : #endif
     739             : 
     740             :         // FIXME interpret both types of params
     741             :         i = ehci_readl(ehci, &ehci->caps->hcs_params);
     742             :         temp = scnprintf (next, size, "structural params 0x%08x\n", i);
     743             :         size -= temp;
     744             :         next += temp;
     745             : 
     746             :         i = ehci_readl(ehci, &ehci->caps->hcc_params);
     747             :         temp = scnprintf (next, size, "capability params 0x%08x\n", i);
     748             :         size -= temp;
     749             :         next += temp;
     750             : 
     751             :         /* Operational Registers */
     752             :         temp = dbg_status_buf (scratch, sizeof scratch, label,
     753             :                         ehci_readl(ehci, &ehci->regs->status));
     754             :         temp = scnprintf (next, size, fmt, temp, scratch);
     755             :         size -= temp;
     756             :         next += temp;
     757             : 
     758             :         temp = dbg_command_buf (scratch, sizeof scratch, label,
     759             :                         ehci_readl(ehci, &ehci->regs->command));
     760             :         temp = scnprintf (next, size, fmt, temp, scratch);
     761             :         size -= temp;
     762             :         next += temp;
     763             : 
     764             :         temp = dbg_intr_buf (scratch, sizeof scratch, label,
     765             :                         ehci_readl(ehci, &ehci->regs->intr_enable));
     766             :         temp = scnprintf (next, size, fmt, temp, scratch);
     767             :         size -= temp;
     768             :         next += temp;
     769             : 
     770             :         temp = scnprintf (next, size, "uframe %04x\n",
     771             :                         ehci_readl(ehci, &ehci->regs->frame_index));
     772             :         size -= temp;
     773             :         next += temp;
     774             : 
     775             :         for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) {
     776             :                 temp = dbg_port_buf (scratch, sizeof scratch, label, i,
     777             :                                 ehci_readl(ehci,
     778             :                                         &ehci->regs->port_status[i - 1]));
     779             :                 temp = scnprintf (next, size, fmt, temp, scratch);
     780             :                 size -= temp;
     781             :                 next += temp;
     782             :                 if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) {
     783             :                         temp = scnprintf (next, size,
     784             :                                         "    debug control %08x\n",
     785             :                                         ehci_readl(ehci,
     786             :                                                 &ehci->debug->control));
     787             :                         size -= temp;
     788             :                         next += temp;
     789             :                 }
     790             :         }
     791             : 
     792             :         if (ehci->reclaim) {
     793             :                 temp = scnprintf(next, size, "reclaim qh %p\n", ehci->reclaim);
     794             :                 size -= temp;
     795             :                 next += temp;
     796             :         }
     797             : 
     798             : #ifdef EHCI_STATS
     799             :         temp = scnprintf (next, size,
     800             :                 "irq normal %ld err %ld reclaim %ld (lost %ld)\n",
     801             :                 ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim,
     802             :                 ehci->stats.lost_iaa);
     803             :         size -= temp;
     804             :         next += temp;
     805             : 
     806             :         temp = scnprintf (next, size, "complete %ld unlink %ld\n",
     807             :                 ehci->stats.complete, ehci->stats.unlink);
     808             :         size -= temp;
     809             :         next += temp;
     810             : #endif
     811             : 
     812             : done:
     813             :         spin_unlock_irqrestore (&ehci->lock, flags);
     814             : 
     815             :         return buf->alloc_size - size;
     816             : }
     817             : 
     818             : static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
     819             :                                 ssize_t (*fill_func)(struct debug_buffer *))
     820             : {
     821             :         struct debug_buffer *buf;
     822             : 
     823             :         buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
     824             : 
     825             :         if (buf) {
     826             :                 buf->bus = bus;
     827             :                 buf->fill_func = fill_func;
     828             :                 mutex_init(&buf->mutex);
     829             :                 buf->alloc_size = PAGE_SIZE;
     830             :         }
     831             : 
     832             :         return buf;
     833             : }
     834             : 
     835             : static int fill_buffer(struct debug_buffer *buf)
     836             : {
     837             :         int ret = 0;
     838             : 
     839             :         if (!buf->output_buf)
     840             :                 buf->output_buf = (char *)vmalloc(buf->alloc_size);
     841             : 
     842             :         if (!buf->output_buf) {
     843             :                 ret = -ENOMEM;
     844             :                 goto out;
     845             :         }
     846             : 
     847             :         ret = buf->fill_func(buf);
     848             : 
     849             :         if (ret >= 0) {
     850             :                 buf->count = ret;
     851             :                 ret = 0;
     852             :         }
     853             : 
     854             : out:
     855             :         return ret;
     856             : }
     857             : 
     858             : static ssize_t debug_output(struct file *file, char __user *user_buf,
     859             :                             size_t len, loff_t *offset)
     860             : {
     861             :         struct debug_buffer *buf = file->private_data;
     862             :         int ret = 0;
     863             : 
     864             :         mutex_lock(&buf->mutex);
     865             :         if (buf->count == 0) {
     866             :                 ret = fill_buffer(buf);
     867             :                 if (ret != 0) {
     868             :                         mutex_unlock(&buf->mutex);
     869             :                         goto out;
     870             :                 }
     871             :         }
     872             :         mutex_unlock(&buf->mutex);
     873             : 
     874             :         ret = simple_read_from_buffer(user_buf, len, offset,
     875             :                                       buf->output_buf, buf->count);
     876             : 
     877             : out:
     878             :         return ret;
     879             : 
     880             : }
     881             : 
     882             : static int debug_close(struct inode *inode, struct file *file)
     883             : {
     884             :         struct debug_buffer *buf = file->private_data;
     885             : 
     886             :         if (buf) {
     887             :                 vfree(buf->output_buf);
     888             :                 kfree(buf);
     889             :         }
     890             : 
     891             :         return 0;
     892             : }
     893             : static int debug_async_open(struct inode *inode, struct file *file)
     894             : {
     895             :         file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
     896             : 
     897             :         return file->private_data ? 0 : -ENOMEM;
     898             : }
     899             : 
     900             : static int debug_periodic_open(struct inode *inode, struct file *file)
     901             : {
     902             :         struct debug_buffer *buf;
     903             :         buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
     904             :         if (!buf)
     905             :                 return -ENOMEM;
     906             : 
     907             :         buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE;
     908             :         file->private_data = buf;
     909             :         return 0;
     910             : }
     911             : 
     912             : static int debug_registers_open(struct inode *inode, struct file *file)
     913             : {
     914             :         file->private_data = alloc_buffer(inode->i_private,
     915             :                                           fill_registers_buffer);
     916             : 
     917             :         return file->private_data ? 0 : -ENOMEM;
     918             : }
     919             : 
     920             : static inline void create_debug_files (struct ehci_hcd *ehci)
     921             : {
     922             :         struct usb_bus *bus = &ehci_to_hcd(ehci)->self;
     923             : 
     924             :         ehci->debug_dir = debugfs_create_dir(bus->bus_name, ehci_debug_root);
     925             :         if (!ehci->debug_dir)
     926             :                 goto dir_error;
     927             : 
     928             :         ehci->debug_async = debugfs_create_file("async", S_IRUGO,
     929             :                                                 ehci->debug_dir, bus,
     930             :                                                 &debug_async_fops);
     931             :         if (!ehci->debug_async)
     932             :                 goto async_error;
     933             : 
     934             :         ehci->debug_periodic = debugfs_create_file("periodic", S_IRUGO,
     935             :                                                    ehci->debug_dir, bus,
     936             :                                                    &debug_periodic_fops);
     937             :         if (!ehci->debug_periodic)
     938             :                 goto periodic_error;
     939             : 
     940             :         ehci->debug_registers = debugfs_create_file("registers", S_IRUGO,
     941             :                                                     ehci->debug_dir, bus,
     942             :                                                     &debug_registers_fops);
     943             :         if (!ehci->debug_registers)
     944             :                 goto registers_error;
     945             :         return;
     946             : 
     947             : registers_error:
     948             :         debugfs_remove(ehci->debug_periodic);
     949             : periodic_error:
     950             :         debugfs_remove(ehci->debug_async);
     951             : async_error:
     952             :         debugfs_remove(ehci->debug_dir);
     953             : dir_error:
     954             :         ehci->debug_periodic = NULL;
     955             :         ehci->debug_async = NULL;
     956             :         ehci->debug_dir = NULL;
     957             : }
     958             : 
     959             : static inline void remove_debug_files (struct ehci_hcd *ehci)
     960             : {
     961             :         debugfs_remove(ehci->debug_registers);
     962             :         debugfs_remove(ehci->debug_periodic);
     963             :         debugfs_remove(ehci->debug_async);
     964             :         debugfs_remove(ehci->debug_dir);
     965             : }
     966             : 
     967             : #endif /* STUB_DEBUG_FILES */

Generated by: LCOV version 1.10