From f3fe239b67424d88104e32076aec902c0642925f Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 8 Jan 2007 12:00:28 -0500 Subject: 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 Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-debug.c | 48 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) (limited to 'drivers/usb/host/uhci-debug.c') 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"); -- cgit v1.2.2 From 85a975d0ce48dfa8dec5bf1bd970f8fd2c48af32 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 8 Jan 2007 12:01:43 -0500 Subject: UHCI: no dummy TDs for Iso QHs Isochronous queues don't need a dummy TD because the Queue Header isn't managed by the hardware. This patch (as836) removes the unnecessary dummy TDs. The patch also fixes a long-standing typo in a comment (a "don't" was missing -- potentially very confusing!). Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/host/uhci-debug.c') diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index b40bc1ac9b8c..3fbb5ba80249 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -208,7 +208,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) space, "", nurbs); } - if (qh->udev) { + if (qh->dummy_td) { out += sprintf(out, "%*s Dummy TD\n", space, ""); out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0); } -- cgit v1.2.2 From 3ca2a3211ee5078d49b04fe7149ff2a76473be51 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 16 Jan 2007 11:56:32 -0500 Subject: UHCI: fix bandwidth allocation This patch (as840) fixes the bandwidth allocation mechanism in uhci-hcd. It has never worked correctly. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-debug.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers/usb/host/uhci-debug.c') diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 3fbb5ba80249..5d6c06bc4524 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -168,9 +168,13 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) space, "", qh, qtype, le32_to_cpu(qh->link), le32_to_cpu(element)); if (qh->type == USB_ENDPOINT_XFER_ISOC) - out += sprintf(out, "%*s period %d frame %x desc [%p]\n", - space, "", qh->period, qh->iso_frame, - qh->iso_packet_desc); + out += sprintf(out, "%*s period %d phase %d load %d us, " + "frame %x desc [%p]\n", + space, "", qh->period, qh->phase, qh->load, + qh->iso_frame, qh->iso_packet_desc); + else if (qh->type == USB_ENDPOINT_XFER_INT) + out += sprintf(out, "%*s period %d phase %d load %d us\n", + space, "", qh->period, qh->phase, qh->load); if (element & UHCI_PTR_QH) out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); @@ -352,6 +356,17 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) out += uhci_show_root_hub_state(uhci, out, len - (out - buf)); out += sprintf(out, "HC status\n"); out += uhci_show_status(uhci, out, len - (out - buf)); + + out += sprintf(out, "Periodic load table\n"); + for (i = 0; i < MAX_PHASE; ++i) { + out += sprintf(out, "\t%d", uhci->load[i]); + if (i % 8 == 7) + *out++ = '\n'; + } + out += sprintf(out, "Total: %d, #INT: %d, #ISO: %d\n", + uhci->total_load, + uhci_to_hcd(uhci)->self.bandwidth_int_reqs, + uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs); if (debug <= 1) return out - buf; -- cgit v1.2.2