summaryrefslogtreecommitdiff
path: root/drivers/usb/host/uhci-debug.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-01-08 12:00:28 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 15:44:35 -0800
commitf3fe239b67424d88104e32076aec902c0642925f (patch)
treed7b3986dcdcb434111c0570eb2a129b2570e3bfa /drivers/usb/host/uhci-debug.c
parentf38649fee955c19f4df9b9e7267f87702712d973 (diff)
UHCI: improved debugging checks for the frame list
This patch (as768) improves the debugging checks for the uhci-hcd frame list. The number of entries displayed is limited to 10, and the driver now checks for the correct Skeleton QH link value at the end of each chain of Isochronous TDs. The code to compute these link values is now used in two spots, so it is moved into its own separate subroutine. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/uhci-debug.c')
-rw-r--r--drivers/usb/host/uhci-debug.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index e345f15b7d87..b40bc1ac9b8c 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -347,6 +347,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
struct uhci_qh *qh;
struct uhci_td *td;
struct list_head *tmp, *head;
+ int nframes, nerrs;
out += uhci_show_root_hub_state(uhci, out, len - (out - buf));
out += sprintf(out, "HC status\n");
@@ -355,23 +356,60 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
return out - buf;
out += sprintf(out, "Frame List\n");
+ nframes = 10;
+ nerrs = 0;
for (i = 0; i < UHCI_NUMFRAMES; ++i) {
+ __le32 link, qh_dma;
+
+ j = 0;
td = uhci->frame_cpu[i];
+ link = uhci->frame[i];
if (!td)
- continue;
+ goto check_link;
- out += sprintf(out, "- Frame %d\n", i); \
- if (td->dma_handle != (dma_addr_t)uhci->frame[i])
- out += sprintf(out, " frame list does not match td->dma_handle!\n");
+ if (nframes > 0) {
+ out += sprintf(out, "- Frame %d -> (%08x)\n",
+ i, le32_to_cpu(link));
+ j = 1;
+ }
head = &td->fl_list;
tmp = head;
do {
td = list_entry(tmp, struct uhci_td, fl_list);
tmp = tmp->next;
- out += uhci_show_td(td, out, len - (out - buf), 4);
+ if (cpu_to_le32(td->dma_handle) != link) {
+ if (nframes > 0)
+ out += sprintf(out, " link does "
+ "not match list entry!\n");
+ else
+ ++nerrs;
+ }
+ if (nframes > 0)
+ out += uhci_show_td(td, out,
+ len - (out - buf), 4);
+ link = td->link;
} while (tmp != head);
+
+check_link:
+ qh_dma = uhci_frame_skel_link(uhci, i);
+ if (link != qh_dma) {
+ if (nframes > 0) {
+ if (!j) {
+ out += sprintf(out,
+ "- Frame %d -> (%08x)\n",
+ i, le32_to_cpu(link));
+ j = 1;
+ }
+ out += sprintf(out, " link does not match "
+ "QH (%08x)!\n", le32_to_cpu(qh_dma));
+ } else
+ ++nerrs;
+ }
+ nframes -= j;
}
+ if (nerrs > 0)
+ out += sprintf(out, "Skipped %d bad links\n", nerrs);
out += sprintf(out, "Skeleton QHs\n");