+
+#define DBG_SCHED_LIMIT 64
+
+static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
+{
+ struct usb_bus *bus;
+ struct usb_hcd *hcd;
+ struct admhcd *ahcd;
+ struct ed **seen, *ed;
+ unsigned long flags;
+ unsigned temp, size, seen_count;
+ char *next;
+ unsigned i;
+
+ seen = kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC);
+ if (!seen)
+ return 0;
+ seen_count = 0;
+
+ bus = dev_get_drvdata(buf->dev);
+ hcd = bus_to_hcd(bus);
+ ahcd = hcd_to_admhcd(hcd);
+ next = buf->page;
+ size = PAGE_SIZE;
+
+ temp = scnprintf(next, size, "size = %d\n", NUM_INTS);
+ size -= temp;
+ next += temp;
+
+ /* dump a snapshot of the periodic schedule (and load) */
+ spin_lock_irqsave(&ahcd->lock, flags);
+ for (i = 0; i < NUM_INTS; i++) {
+ ed = ahcd->periodic[i];
+ if (!ed)
+ continue;
+
+ temp = scnprintf(next, size, "%2d [%3d]:", i, ahcd->load[i]);
+ size -= temp;
+ next += temp;
+
+ do {
+ temp = scnprintf(next, size, " ed%d/%p",
+ ed->interval, ed);
+ size -= temp;
+ next += temp;
+ for (temp = 0; temp < seen_count; temp++) {
+ if (seen[temp] == ed)
+ break;
+ }
+
+ /* show more info the first time around */
+ if (temp == seen_count) {
+ u32 info = hc32_to_cpu(ahcd, ed->hwINFO);
+ struct list_head *entry;
+ unsigned qlen = 0;
+
+ /* qlen measured here in TDs, not urbs */
+ list_for_each(entry, &ed->td_list)
+ qlen++;
+ temp = scnprintf(next, size,
+ " (%cs dev%d ep%d%s qlen %u"
+ " max %d %08x%s%s)",
+ (info & ED_SPEED_FULL) ? 'f' : 'l',
+ ED_FA_GET(info),
+ ED_EN_GET(info),
+ (info & ED_ISO) ? "iso" : "int",
+ qlen,
+ ED_MPS_GET(info),
+ info,
+ (info & ED_SKIP) ? " K" : "",
+ (ed->hwHeadP &
+ cpu_to_hc32(ahcd, ED_H)) ?
+ " H" : "");
+ size -= temp;
+ next += temp;
+
+ if (seen_count < DBG_SCHED_LIMIT)
+ seen[seen_count++] = ed;
+
+ ed = ed->ed_next;
+
+ } else {
+ /* we've seen it and what's after */
+ temp = 0;
+ ed = NULL;
+ }
+
+ } while (ed);
+
+ temp = scnprintf(next, size, "\n");
+ size -= temp;
+ next += temp;
+ }
+ spin_unlock_irqrestore(&ahcd->lock, flags);
+ kfree(seen);
+
+ return PAGE_SIZE - size;
+}
+
+
+#undef DBG_SCHED_LIMIT
+
+static ssize_t fill_registers_buffer(struct debug_buffer *buf)