packaging: release out (3.8.3)
[profile/ivi/kernel-adaptation-intel-automotive.git] / drivers / usb / host / ohci-dbg.c
1 /*
2  * OHCI HCD (Host Controller Driver) for USB.
3  *
4  * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
5  * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
6  *
7  * This file is licenced under the GPL.
8  */
9
10 /*-------------------------------------------------------------------------*/
11
12 #ifdef DEBUG
13
14 #define edstring(ed_type) ({ char *temp; \
15         switch (ed_type) { \
16         case PIPE_CONTROL:      temp = "ctrl"; break; \
17         case PIPE_BULK:         temp = "bulk"; break; \
18         case PIPE_INTERRUPT:    temp = "intr"; break; \
19         default:                temp = "isoc"; break; \
20         }; temp;})
21 #define pipestring(pipe) edstring(usb_pipetype(pipe))
22
23 /* debug| print the main components of an URB
24  * small: 0) header + data packets 1) just header
25  */
26 static void __maybe_unused
27 urb_print(struct urb * urb, char * str, int small, int status)
28 {
29         unsigned int pipe= urb->pipe;
30
31         if (!urb->dev || !urb->dev->bus) {
32                 printk(KERN_DEBUG "%s URB: no dev\n", str);
33                 return;
34         }
35
36 #ifndef OHCI_VERBOSE_DEBUG
37         if (status != 0)
38 #endif
39         printk(KERN_DEBUG "%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d stat=%d\n",
40                     str,
41                     urb,
42                     usb_pipedevice (pipe),
43                     usb_pipeendpoint (pipe),
44                     usb_pipeout (pipe)? "out" : "in",
45                     pipestring (pipe),
46                     urb->transfer_flags,
47                     urb->actual_length,
48                     urb->transfer_buffer_length,
49                     status);
50
51 #ifdef  OHCI_VERBOSE_DEBUG
52         if (!small) {
53                 int i, len;
54
55                 if (usb_pipecontrol (pipe)) {
56                         printk (KERN_DEBUG "%s: setup(8):", __FILE__);
57                         for (i = 0; i < 8 ; i++)
58                                 printk (" %02x", ((__u8 *) urb->setup_packet) [i]);
59                         printk ("\n");
60                 }
61                 if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) {
62                         printk (KERN_DEBUG "%s: data(%d/%d):", __FILE__,
63                                 urb->actual_length,
64                                 urb->transfer_buffer_length);
65                         len = usb_pipeout (pipe)?
66                                                 urb->transfer_buffer_length: urb->actual_length;
67                         for (i = 0; i < 16 && i < len; i++)
68                                 printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]);
69                         printk ("%s stat:%d\n", i < len? "...": "", status);
70                 }
71         }
72 #endif
73 }
74
75 #define ohci_dbg_sw(ohci, next, size, format, arg...) \
76         do { \
77         if (next != NULL) { \
78                 unsigned s_len; \
79                 s_len = scnprintf (*next, *size, format, ## arg ); \
80                 *size -= s_len; *next += s_len; \
81         } else \
82                 ohci_dbg(ohci,format, ## arg ); \
83         } while (0);
84
85 /* Version for use where "next" is the address of a local variable */
86 #define ohci_dbg_nosw(ohci, next, size, format, arg...) \
87         do { \
88                 unsigned s_len; \
89                 s_len = scnprintf(*next, *size, format, ## arg); \
90                 *size -= s_len; *next += s_len; \
91         } while (0);
92
93
94 static void ohci_dump_intr_mask (
95         struct ohci_hcd *ohci,
96         char *label,
97         u32 mask,
98         char **next,
99         unsigned *size)
100 {
101         ohci_dbg_sw (ohci, next, size, "%s 0x%08x%s%s%s%s%s%s%s%s%s\n",
102                 label,
103                 mask,
104                 (mask & OHCI_INTR_MIE) ? " MIE" : "",
105                 (mask & OHCI_INTR_OC) ? " OC" : "",
106                 (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
107                 (mask & OHCI_INTR_FNO) ? " FNO" : "",
108                 (mask & OHCI_INTR_UE) ? " UE" : "",
109                 (mask & OHCI_INTR_RD) ? " RD" : "",
110                 (mask & OHCI_INTR_SF) ? " SF" : "",
111                 (mask & OHCI_INTR_WDH) ? " WDH" : "",
112                 (mask & OHCI_INTR_SO) ? " SO" : ""
113                 );
114 }
115
116 static void maybe_print_eds (
117         struct ohci_hcd *ohci,
118         char *label,
119         u32 value,
120         char **next,
121         unsigned *size)
122 {
123         if (value)
124                 ohci_dbg_sw (ohci, next, size, "%s %08x\n", label, value);
125 }
126
127 static char *hcfs2string (int state)
128 {
129         switch (state) {
130                 case OHCI_USB_RESET:    return "reset";
131                 case OHCI_USB_RESUME:   return "resume";
132                 case OHCI_USB_OPER:     return "operational";
133                 case OHCI_USB_SUSPEND:  return "suspend";
134         }
135         return "?";
136 }
137
138 static const char *rh_state_string(struct ohci_hcd *ohci)
139 {
140         switch (ohci->rh_state) {
141         case OHCI_RH_HALTED:
142                 return "halted";
143         case OHCI_RH_SUSPENDED:
144                 return "suspended";
145         case OHCI_RH_RUNNING:
146                 return "running";
147         }
148         return "?";
149 }
150
151 // dump control and status registers
152 static void
153 ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
154 {
155         struct ohci_regs __iomem *regs = controller->regs;
156         u32                     temp;
157
158         temp = ohci_readl (controller, &regs->revision) & 0xff;
159         ohci_dbg_sw (controller, next, size,
160                 "OHCI %d.%d, %s legacy support registers, rh state %s\n",
161                 0x03 & (temp >> 4), (temp & 0x0f),
162                 (temp & 0x0100) ? "with" : "NO",
163                 rh_state_string(controller));
164
165         temp = ohci_readl (controller, &regs->control);
166         ohci_dbg_sw (controller, next, size,
167                 "control 0x%03x%s%s%s HCFS=%s%s%s%s%s CBSR=%d\n",
168                 temp,
169                 (temp & OHCI_CTRL_RWE) ? " RWE" : "",
170                 (temp & OHCI_CTRL_RWC) ? " RWC" : "",
171                 (temp & OHCI_CTRL_IR) ? " IR" : "",
172                 hcfs2string (temp & OHCI_CTRL_HCFS),
173                 (temp & OHCI_CTRL_BLE) ? " BLE" : "",
174                 (temp & OHCI_CTRL_CLE) ? " CLE" : "",
175                 (temp & OHCI_CTRL_IE) ? " IE" : "",
176                 (temp & OHCI_CTRL_PLE) ? " PLE" : "",
177                 temp & OHCI_CTRL_CBSR
178                 );
179
180         temp = ohci_readl (controller, &regs->cmdstatus);
181         ohci_dbg_sw (controller, next, size,
182                 "cmdstatus 0x%05x SOC=%d%s%s%s%s\n", temp,
183                 (temp & OHCI_SOC) >> 16,
184                 (temp & OHCI_OCR) ? " OCR" : "",
185                 (temp & OHCI_BLF) ? " BLF" : "",
186                 (temp & OHCI_CLF) ? " CLF" : "",
187                 (temp & OHCI_HCR) ? " HCR" : ""
188                 );
189
190         ohci_dump_intr_mask (controller, "intrstatus",
191                         ohci_readl (controller, &regs->intrstatus),
192                         next, size);
193         ohci_dump_intr_mask (controller, "intrenable",
194                         ohci_readl (controller, &regs->intrenable),
195                         next, size);
196         // intrdisable always same as intrenable
197
198         maybe_print_eds (controller, "ed_periodcurrent",
199                         ohci_readl (controller, &regs->ed_periodcurrent),
200                         next, size);
201
202         maybe_print_eds (controller, "ed_controlhead",
203                         ohci_readl (controller, &regs->ed_controlhead),
204                         next, size);
205         maybe_print_eds (controller, "ed_controlcurrent",
206                         ohci_readl (controller, &regs->ed_controlcurrent),
207                         next, size);
208
209         maybe_print_eds (controller, "ed_bulkhead",
210                         ohci_readl (controller, &regs->ed_bulkhead),
211                         next, size);
212         maybe_print_eds (controller, "ed_bulkcurrent",
213                         ohci_readl (controller, &regs->ed_bulkcurrent),
214                         next, size);
215
216         maybe_print_eds (controller, "donehead",
217                         ohci_readl (controller, &regs->donehead), next, size);
218 }
219
220 #define dbg_port_sw(hc,num,value,next,size) \
221         ohci_dbg_sw (hc, next, size, \
222                 "roothub.portstatus [%d] " \
223                 "0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", \
224                 num, temp, \
225                 (temp & RH_PS_PRSC) ? " PRSC" : "", \
226                 (temp & RH_PS_OCIC) ? " OCIC" : "", \
227                 (temp & RH_PS_PSSC) ? " PSSC" : "", \
228                 (temp & RH_PS_PESC) ? " PESC" : "", \
229                 (temp & RH_PS_CSC) ? " CSC" : "", \
230                 \
231                 (temp & RH_PS_LSDA) ? " LSDA" : "", \
232                 (temp & RH_PS_PPS) ? " PPS" : "", \
233                 (temp & RH_PS_PRS) ? " PRS" : "", \
234                 (temp & RH_PS_POCI) ? " POCI" : "", \
235                 (temp & RH_PS_PSS) ? " PSS" : "", \
236                 \
237                 (temp & RH_PS_PES) ? " PES" : "", \
238                 (temp & RH_PS_CCS) ? " CCS" : "" \
239                 );
240
241
242 static void
243 ohci_dump_roothub (
244         struct ohci_hcd *controller,
245         int verbose,
246         char **next,
247         unsigned *size)
248 {
249         u32                     temp, i;
250
251         temp = roothub_a (controller);
252         if (temp == ~(u32)0)
253                 return;
254
255         if (verbose) {
256                 ohci_dbg_sw (controller, next, size,
257                         "roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d(%d)\n", temp,
258                         ((temp & RH_A_POTPGT) >> 24) & 0xff,
259                         (temp & RH_A_NOCP) ? " NOCP" : "",
260                         (temp & RH_A_OCPM) ? " OCPM" : "",
261                         (temp & RH_A_DT) ? " DT" : "",
262                         (temp & RH_A_NPS) ? " NPS" : "",
263                         (temp & RH_A_PSM) ? " PSM" : "",
264                         (temp & RH_A_NDP), controller->num_ports
265                         );
266                 temp = roothub_b (controller);
267                 ohci_dbg_sw (controller, next, size,
268                         "roothub.b %08x PPCM=%04x DR=%04x\n",
269                         temp,
270                         (temp & RH_B_PPCM) >> 16,
271                         (temp & RH_B_DR)
272                         );
273                 temp = roothub_status (controller);
274                 ohci_dbg_sw (controller, next, size,
275                         "roothub.status %08x%s%s%s%s%s%s\n",
276                         temp,
277                         (temp & RH_HS_CRWE) ? " CRWE" : "",
278                         (temp & RH_HS_OCIC) ? " OCIC" : "",
279                         (temp & RH_HS_LPSC) ? " LPSC" : "",
280                         (temp & RH_HS_DRWE) ? " DRWE" : "",
281                         (temp & RH_HS_OCI) ? " OCI" : "",
282                         (temp & RH_HS_LPS) ? " LPS" : ""
283                         );
284         }
285
286         for (i = 0; i < controller->num_ports; i++) {
287                 temp = roothub_portstatus (controller, i);
288                 dbg_port_sw (controller, i, temp, next, size);
289         }
290 }
291
292 static void ohci_dump (struct ohci_hcd *controller, int verbose)
293 {
294         ohci_dbg (controller, "OHCI controller state\n");
295
296         // dumps some of the state we know about
297         ohci_dump_status (controller, NULL, NULL);
298         if (controller->hcca)
299                 ohci_dbg (controller,
300                         "hcca frame #%04x\n", ohci_frame_no(controller));
301         ohci_dump_roothub (controller, 1, NULL, NULL);
302 }
303
304 static const char data0 [] = "DATA0";
305 static const char data1 [] = "DATA1";
306
307 static void ohci_dump_td (const struct ohci_hcd *ohci, const char *label,
308                 const struct td *td)
309 {
310         u32     tmp = hc32_to_cpup (ohci, &td->hwINFO);
311
312         ohci_dbg (ohci, "%s td %p%s; urb %p index %d; hw next td %08x\n",
313                 label, td,
314                 (tmp & TD_DONE) ? " (DONE)" : "",
315                 td->urb, td->index,
316                 hc32_to_cpup (ohci, &td->hwNextTD));
317         if ((tmp & TD_ISO) == 0) {
318                 const char      *toggle, *pid;
319                 u32     cbp, be;
320
321                 switch (tmp & TD_T) {
322                 case TD_T_DATA0: toggle = data0; break;
323                 case TD_T_DATA1: toggle = data1; break;
324                 case TD_T_TOGGLE: toggle = "(CARRY)"; break;
325                 default: toggle = "(?)"; break;
326                 }
327                 switch (tmp & TD_DP) {
328                 case TD_DP_SETUP: pid = "SETUP"; break;
329                 case TD_DP_IN: pid = "IN"; break;
330                 case TD_DP_OUT: pid = "OUT"; break;
331                 default: pid = "(bad pid)"; break;
332                 }
333                 ohci_dbg (ohci, "     info %08x CC=%x %s DI=%d %s %s\n", tmp,
334                         TD_CC_GET(tmp), /* EC, */ toggle,
335                         (tmp & TD_DI) >> 21, pid,
336                         (tmp & TD_R) ? "R" : "");
337                 cbp = hc32_to_cpup (ohci, &td->hwCBP);
338                 be = hc32_to_cpup (ohci, &td->hwBE);
339                 ohci_dbg (ohci, "     cbp %08x be %08x (len %d)\n", cbp, be,
340                         cbp ? (be + 1 - cbp) : 0);
341         } else {
342                 unsigned        i;
343                 ohci_dbg (ohci, "  info %08x CC=%x FC=%d DI=%d SF=%04x\n", tmp,
344                         TD_CC_GET(tmp),
345                         (tmp >> 24) & 0x07,
346                         (tmp & TD_DI) >> 21,
347                         tmp & 0x0000ffff);
348                 ohci_dbg (ohci, "  bp0 %08x be %08x\n",
349                         hc32_to_cpup (ohci, &td->hwCBP) & ~0x0fff,
350                         hc32_to_cpup (ohci, &td->hwBE));
351                 for (i = 0; i < MAXPSW; i++) {
352                         u16     psw = ohci_hwPSW (ohci, td, i);
353                         int     cc = (psw >> 12) & 0x0f;
354                         ohci_dbg (ohci, "    psw [%d] = %2x, CC=%x %s=%d\n", i,
355                                 psw, cc,
356                                 (cc >= 0x0e) ? "OFFSET" : "SIZE",
357                                 psw & 0x0fff);
358                 }
359         }
360 }
361
362 /* caller MUST own hcd spinlock if verbose is set! */
363 static void __maybe_unused
364 ohci_dump_ed (const struct ohci_hcd *ohci, const char *label,
365                 const struct ed *ed, int verbose)
366 {
367         u32     tmp = hc32_to_cpu (ohci, ed->hwINFO);
368         char    *type = "";
369
370         ohci_dbg (ohci, "%s, ed %p state 0x%x type %s; next ed %08x\n",
371                 label,
372                 ed, ed->state, edstring (ed->type),
373                 hc32_to_cpup (ohci, &ed->hwNextED));
374         switch (tmp & (ED_IN|ED_OUT)) {
375         case ED_OUT: type = "-OUT"; break;
376         case ED_IN: type = "-IN"; break;
377         /* else from TDs ... control */
378         }
379         ohci_dbg (ohci,
380                 "  info %08x MAX=%d%s%s%s%s EP=%d%s DEV=%d\n", tmp,
381                 0x03ff & (tmp >> 16),
382                 (tmp & ED_DEQUEUE) ? " DQ" : "",
383                 (tmp & ED_ISO) ? " ISO" : "",
384                 (tmp & ED_SKIP) ? " SKIP" : "",
385                 (tmp & ED_LOWSPEED) ? " LOW" : "",
386                 0x000f & (tmp >> 7),
387                 type,
388                 0x007f & tmp);
389         tmp = hc32_to_cpup (ohci, &ed->hwHeadP);
390         ohci_dbg (ohci, "  tds: head %08x %s%s tail %08x%s\n",
391                 tmp,
392                 (tmp & ED_C) ? data1 : data0,
393                 (tmp & ED_H) ? " HALT" : "",
394                 hc32_to_cpup (ohci, &ed->hwTailP),
395                 verbose ? "" : " (not listing)");
396         if (verbose) {
397                 struct list_head        *tmp;
398
399                 /* use ed->td_list because HC concurrently modifies
400                  * hwNextTD as it accumulates ed_donelist.
401                  */
402                 list_for_each (tmp, &ed->td_list) {
403                         struct td               *td;
404                         td = list_entry (tmp, struct td, td_list);
405                         ohci_dump_td (ohci, "  ->", td);
406                 }
407         }
408 }
409
410 #else
411 static inline void ohci_dump (struct ohci_hcd *controller, int verbose) {}
412
413 #undef OHCI_VERBOSE_DEBUG
414
415 #endif /* DEBUG */
416
417 /*-------------------------------------------------------------------------*/
418
419 #ifdef STUB_DEBUG_FILES
420
421 static inline void create_debug_files (struct ohci_hcd *bus) { }
422 static inline void remove_debug_files (struct ohci_hcd *bus) { }
423
424 #else
425
426 static int debug_async_open(struct inode *, struct file *);
427 static int debug_periodic_open(struct inode *, struct file *);
428 static int debug_registers_open(struct inode *, struct file *);
429 static int debug_async_open(struct inode *, struct file *);
430 static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
431 static int debug_close(struct inode *, struct file *);
432
433 static const struct file_operations debug_async_fops = {
434         .owner          = THIS_MODULE,
435         .open           = debug_async_open,
436         .read           = debug_output,
437         .release        = debug_close,
438         .llseek         = default_llseek,
439 };
440 static const struct file_operations debug_periodic_fops = {
441         .owner          = THIS_MODULE,
442         .open           = debug_periodic_open,
443         .read           = debug_output,
444         .release        = debug_close,
445         .llseek         = default_llseek,
446 };
447 static const struct file_operations debug_registers_fops = {
448         .owner          = THIS_MODULE,
449         .open           = debug_registers_open,
450         .read           = debug_output,
451         .release        = debug_close,
452         .llseek         = default_llseek,
453 };
454
455 static struct dentry *ohci_debug_root;
456
457 struct debug_buffer {
458         ssize_t (*fill_func)(struct debug_buffer *);    /* fill method */
459         struct ohci_hcd *ohci;
460         struct mutex mutex;     /* protect filling of buffer */
461         size_t count;           /* number of characters filled into buffer */
462         char *page;
463 };
464
465 static ssize_t
466 show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed)
467 {
468         unsigned                temp, size = count;
469
470         if (!ed)
471                 return 0;
472
473         /* print first --> last */
474         while (ed->ed_prev)
475                 ed = ed->ed_prev;
476
477         /* dump a snapshot of the bulk or control schedule */
478         while (ed) {
479                 u32             info = hc32_to_cpu (ohci, ed->hwINFO);
480                 u32             headp = hc32_to_cpu (ohci, ed->hwHeadP);
481                 struct list_head *entry;
482                 struct td       *td;
483
484                 temp = scnprintf (buf, size,
485                         "ed/%p %cs dev%d ep%d%s max %d %08x%s%s %s",
486                         ed,
487                         (info & ED_LOWSPEED) ? 'l' : 'f',
488                         info & 0x7f,
489                         (info >> 7) & 0xf,
490                         (info & ED_IN) ? "in" : "out",
491                         0x03ff & (info >> 16),
492                         info,
493                         (info & ED_SKIP) ? " s" : "",
494                         (headp & ED_H) ? " H" : "",
495                         (headp & ED_C) ? data1 : data0);
496                 size -= temp;
497                 buf += temp;
498
499                 list_for_each (entry, &ed->td_list) {
500                         u32             cbp, be;
501
502                         td = list_entry (entry, struct td, td_list);
503                         info = hc32_to_cpup (ohci, &td->hwINFO);
504                         cbp = hc32_to_cpup (ohci, &td->hwCBP);
505                         be = hc32_to_cpup (ohci, &td->hwBE);
506                         temp = scnprintf (buf, size,
507                                         "\n\ttd %p %s %d cc=%x urb %p (%08x)",
508                                         td,
509                                         ({ char *pid;
510                                         switch (info & TD_DP) {
511                                         case TD_DP_SETUP: pid = "setup"; break;
512                                         case TD_DP_IN: pid = "in"; break;
513                                         case TD_DP_OUT: pid = "out"; break;
514                                         default: pid = "(?)"; break;
515                                          } pid;}),
516                                         cbp ? (be + 1 - cbp) : 0,
517                                         TD_CC_GET (info), td->urb, info);
518                         size -= temp;
519                         buf += temp;
520                 }
521
522                 temp = scnprintf (buf, size, "\n");
523                 size -= temp;
524                 buf += temp;
525
526                 ed = ed->ed_next;
527         }
528         return count - size;
529 }
530
531 static ssize_t fill_async_buffer(struct debug_buffer *buf)
532 {
533         struct ohci_hcd         *ohci;
534         size_t                  temp;
535         unsigned long           flags;
536
537         ohci = buf->ohci;
538
539         /* display control and bulk lists together, for simplicity */
540         spin_lock_irqsave (&ohci->lock, flags);
541         temp = show_list(ohci, buf->page, buf->count, ohci->ed_controltail);
542         temp += show_list(ohci, buf->page + temp, buf->count - temp,
543                           ohci->ed_bulktail);
544         spin_unlock_irqrestore (&ohci->lock, flags);
545
546         return temp;
547 }
548
549 #define DBG_SCHED_LIMIT 64
550
551 static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
552 {
553         struct ohci_hcd         *ohci;
554         struct ed               **seen, *ed;
555         unsigned long           flags;
556         unsigned                temp, size, seen_count;
557         char                    *next;
558         unsigned                i;
559
560         if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC)))
561                 return 0;
562         seen_count = 0;
563
564         ohci = buf->ohci;
565         next = buf->page;
566         size = PAGE_SIZE;
567
568         temp = scnprintf (next, size, "size = %d\n", NUM_INTS);
569         size -= temp;
570         next += temp;
571
572         /* dump a snapshot of the periodic schedule (and load) */
573         spin_lock_irqsave (&ohci->lock, flags);
574         for (i = 0; i < NUM_INTS; i++) {
575                 if (!(ed = ohci->periodic [i]))
576                         continue;
577
578                 temp = scnprintf (next, size, "%2d [%3d]:", i, ohci->load [i]);
579                 size -= temp;
580                 next += temp;
581
582                 do {
583                         temp = scnprintf (next, size, " ed%d/%p",
584                                 ed->interval, ed);
585                         size -= temp;
586                         next += temp;
587                         for (temp = 0; temp < seen_count; temp++) {
588                                 if (seen [temp] == ed)
589                                         break;
590                         }
591
592                         /* show more info the first time around */
593                         if (temp == seen_count) {
594                                 u32     info = hc32_to_cpu (ohci, ed->hwINFO);
595                                 struct list_head        *entry;
596                                 unsigned                qlen = 0;
597
598                                 /* qlen measured here in TDs, not urbs */
599                                 list_for_each (entry, &ed->td_list)
600                                         qlen++;
601
602                                 temp = scnprintf (next, size,
603                                         " (%cs dev%d ep%d%s-%s qlen %u"
604                                         " max %d %08x%s%s)",
605                                         (info & ED_LOWSPEED) ? 'l' : 'f',
606                                         info & 0x7f,
607                                         (info >> 7) & 0xf,
608                                         (info & ED_IN) ? "in" : "out",
609                                         (info & ED_ISO) ? "iso" : "int",
610                                         qlen,
611                                         0x03ff & (info >> 16),
612                                         info,
613                                         (info & ED_SKIP) ? " K" : "",
614                                         (ed->hwHeadP &
615                                                 cpu_to_hc32(ohci, ED_H)) ?
616                                                         " H" : "");
617                                 size -= temp;
618                                 next += temp;
619
620                                 if (seen_count < DBG_SCHED_LIMIT)
621                                         seen [seen_count++] = ed;
622
623                                 ed = ed->ed_next;
624
625                         } else {
626                                 /* we've seen it and what's after */
627                                 temp = 0;
628                                 ed = NULL;
629                         }
630
631                 } while (ed);
632
633                 temp = scnprintf (next, size, "\n");
634                 size -= temp;
635                 next += temp;
636         }
637         spin_unlock_irqrestore (&ohci->lock, flags);
638         kfree (seen);
639
640         return PAGE_SIZE - size;
641 }
642 #undef DBG_SCHED_LIMIT
643
644 static ssize_t fill_registers_buffer(struct debug_buffer *buf)
645 {
646         struct usb_hcd          *hcd;
647         struct ohci_hcd         *ohci;
648         struct ohci_regs __iomem *regs;
649         unsigned long           flags;
650         unsigned                temp, size;
651         char                    *next;
652         u32                     rdata;
653
654         ohci = buf->ohci;
655         hcd = ohci_to_hcd(ohci);
656         regs = ohci->regs;
657         next = buf->page;
658         size = PAGE_SIZE;
659
660         spin_lock_irqsave (&ohci->lock, flags);
661
662         /* dump driver info, then registers in spec order */
663
664         ohci_dbg_nosw(ohci, &next, &size,
665                 "bus %s, device %s\n"
666                 "%s\n"
667                 "%s\n",
668                 hcd->self.controller->bus->name,
669                 dev_name(hcd->self.controller),
670                 hcd->product_desc,
671                 hcd_name);
672
673         if (!HCD_HW_ACCESSIBLE(hcd)) {
674                 size -= scnprintf (next, size,
675                         "SUSPENDED (no register access)\n");
676                 goto done;
677         }
678
679         ohci_dump_status(ohci, &next, &size);
680
681         /* hcca */
682         if (ohci->hcca)
683                 ohci_dbg_nosw(ohci, &next, &size,
684                         "hcca frame 0x%04x\n", ohci_frame_no(ohci));
685
686         /* other registers mostly affect frame timings */
687         rdata = ohci_readl (ohci, &regs->fminterval);
688         temp = scnprintf (next, size,
689                         "fmintvl 0x%08x %sFSMPS=0x%04x FI=0x%04x\n",
690                         rdata, (rdata >> 31) ? "FIT " : "",
691                         (rdata >> 16) & 0xefff, rdata & 0xffff);
692         size -= temp;
693         next += temp;
694
695         rdata = ohci_readl (ohci, &regs->fmremaining);
696         temp = scnprintf (next, size, "fmremaining 0x%08x %sFR=0x%04x\n",
697                         rdata, (rdata >> 31) ? "FRT " : "",
698                         rdata & 0x3fff);
699         size -= temp;
700         next += temp;
701
702         rdata = ohci_readl (ohci, &regs->periodicstart);
703         temp = scnprintf (next, size, "periodicstart 0x%04x\n",
704                         rdata & 0x3fff);
705         size -= temp;
706         next += temp;
707
708         rdata = ohci_readl (ohci, &regs->lsthresh);
709         temp = scnprintf (next, size, "lsthresh 0x%04x\n",
710                         rdata & 0x3fff);
711         size -= temp;
712         next += temp;
713
714         temp = scnprintf (next, size, "hub poll timer %s\n",
715                         HCD_POLL_RH(ohci_to_hcd(ohci)) ? "ON" : "off");
716         size -= temp;
717         next += temp;
718
719         /* roothub */
720         ohci_dump_roothub (ohci, 1, &next, &size);
721
722 done:
723         spin_unlock_irqrestore (&ohci->lock, flags);
724
725         return PAGE_SIZE - size;
726 }
727
728 static struct debug_buffer *alloc_buffer(struct ohci_hcd *ohci,
729                                 ssize_t (*fill_func)(struct debug_buffer *))
730 {
731         struct debug_buffer *buf;
732
733         buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
734
735         if (buf) {
736                 buf->ohci = ohci;
737                 buf->fill_func = fill_func;
738                 mutex_init(&buf->mutex);
739         }
740
741         return buf;
742 }
743
744 static int fill_buffer(struct debug_buffer *buf)
745 {
746         int ret = 0;
747
748         if (!buf->page)
749                 buf->page = (char *)get_zeroed_page(GFP_KERNEL);
750
751         if (!buf->page) {
752                 ret = -ENOMEM;
753                 goto out;
754         }
755
756         ret = buf->fill_func(buf);
757
758         if (ret >= 0) {
759                 buf->count = ret;
760                 ret = 0;
761         }
762
763 out:
764         return ret;
765 }
766
767 static ssize_t debug_output(struct file *file, char __user *user_buf,
768                         size_t len, loff_t *offset)
769 {
770         struct debug_buffer *buf = file->private_data;
771         int ret = 0;
772
773         mutex_lock(&buf->mutex);
774         if (buf->count == 0) {
775                 ret = fill_buffer(buf);
776                 if (ret != 0) {
777                         mutex_unlock(&buf->mutex);
778                         goto out;
779                 }
780         }
781         mutex_unlock(&buf->mutex);
782
783         ret = simple_read_from_buffer(user_buf, len, offset,
784                                       buf->page, buf->count);
785
786 out:
787         return ret;
788
789 }
790
791 static int debug_close(struct inode *inode, struct file *file)
792 {
793         struct debug_buffer *buf = file->private_data;
794
795         if (buf) {
796                 if (buf->page)
797                         free_page((unsigned long)buf->page);
798                 kfree(buf);
799         }
800
801         return 0;
802 }
803 static int debug_async_open(struct inode *inode, struct file *file)
804 {
805         file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
806
807         return file->private_data ? 0 : -ENOMEM;
808 }
809
810 static int debug_periodic_open(struct inode *inode, struct file *file)
811 {
812         file->private_data = alloc_buffer(inode->i_private,
813                                           fill_periodic_buffer);
814
815         return file->private_data ? 0 : -ENOMEM;
816 }
817
818 static int debug_registers_open(struct inode *inode, struct file *file)
819 {
820         file->private_data = alloc_buffer(inode->i_private,
821                                           fill_registers_buffer);
822
823         return file->private_data ? 0 : -ENOMEM;
824 }
825 static inline void create_debug_files (struct ohci_hcd *ohci)
826 {
827         struct usb_bus *bus = &ohci_to_hcd(ohci)->self;
828
829         ohci->debug_dir = debugfs_create_dir(bus->bus_name, ohci_debug_root);
830         if (!ohci->debug_dir)
831                 goto dir_error;
832
833         ohci->debug_async = debugfs_create_file("async", S_IRUGO,
834                                                 ohci->debug_dir, ohci,
835                                                 &debug_async_fops);
836         if (!ohci->debug_async)
837                 goto async_error;
838
839         ohci->debug_periodic = debugfs_create_file("periodic", S_IRUGO,
840                                                    ohci->debug_dir, ohci,
841                                                    &debug_periodic_fops);
842         if (!ohci->debug_periodic)
843                 goto periodic_error;
844
845         ohci->debug_registers = debugfs_create_file("registers", S_IRUGO,
846                                                     ohci->debug_dir, ohci,
847                                                     &debug_registers_fops);
848         if (!ohci->debug_registers)
849                 goto registers_error;
850
851         ohci_dbg (ohci, "created debug files\n");
852         return;
853
854 registers_error:
855         debugfs_remove(ohci->debug_periodic);
856 periodic_error:
857         debugfs_remove(ohci->debug_async);
858 async_error:
859         debugfs_remove(ohci->debug_dir);
860 dir_error:
861         ohci->debug_periodic = NULL;
862         ohci->debug_async = NULL;
863         ohci->debug_dir = NULL;
864 }
865
866 static inline void remove_debug_files (struct ohci_hcd *ohci)
867 {
868         debugfs_remove(ohci->debug_registers);
869         debugfs_remove(ohci->debug_periodic);
870         debugfs_remove(ohci->debug_async);
871         debugfs_remove(ohci->debug_dir);
872 }
873
874 #endif
875
876 /*-------------------------------------------------------------------------*/
877