summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/uhci-debug.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-02-19 21:52:45 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-24 00:03:45 +0100
commit17230acdc71137622ca7dfd789b3944c75d39404 (patch)
tree67eb75c5e8d254b2d5490ea9982efe73952f90d5 /drivers/usb/host/uhci-debug.c
parentUHCI: Add macros for computing DMA values (diff)
downloadlinux-17230acdc71137622ca7dfd789b3944c75d39404.tar.xz
linux-17230acdc71137622ca7dfd789b3944c75d39404.zip
UHCI: Eliminate asynchronous skeleton Queue Headers
This patch (as856) attempts to improve the performance of uhci-hcd by removing the asynchronous skeleton Queue Headers. They don't contain any useful information but the controller has to read through them at least once every millisecond, incurring a non-zero DMA overhead. Now all the asynchronous queues are combined, along with the period-1 interrupt queue, into a single list with a single skeleton QH. The start of the low-speed control, full-speed control, and bulk sublists is determined by linear search. Since there should rarely be more than a couple of QHs in the list, the searches should incur a much smaller total load than keeping the skeleton QHs. 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.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index a0677133577b..8d24d3dc0a61 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -220,16 +220,6 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
return out - buf;
}
-static const char * const qh_names[] = {
- "skel_unlink_qh", "skel_iso_qh",
- "skel_int128_qh", "skel_int64_qh",
- "skel_int32_qh", "skel_int16_qh",
- "skel_int8_qh", "skel_int4_qh",
- "skel_int2_qh", "skel_int1_qh",
- "skel_ls_control_qh", "skel_fs_control_qh",
- "skel_bulk_qh", "skel_term_qh"
-};
-
static int uhci_show_sc(int port, unsigned short status, char *buf, int len)
{
char *out = buf;
@@ -352,6 +342,12 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
struct uhci_td *td;
struct list_head *tmp, *head;
int nframes, nerrs;
+ __le32 link;
+
+ static const char * const qh_names[] = {
+ "unlink", "iso", "int128", "int64", "int32", "int16",
+ "int8", "int4", "int2", "async", "term"
+ };
out += uhci_show_root_hub_state(uhci, out, len - (out - buf));
out += sprintf(out, "HC status\n");
@@ -374,7 +370,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
nframes = 10;
nerrs = 0;
for (i = 0; i < UHCI_NUMFRAMES; ++i) {
- __le32 link, qh_dma;
+ __le32 qh_dma;
j = 0;
td = uhci->frame_cpu[i];
@@ -430,23 +426,21 @@ check_link:
for (i = 0; i < UHCI_NUM_SKELQH; ++i) {
int cnt = 0;
+ __le32 fsbr_link = 0;
qh = uhci->skelqh[i];
- out += sprintf(out, "- %s\n", qh_names[i]); \
+ out += sprintf(out, "- skel_%s_qh\n", qh_names[i]); \
out += uhci_show_qh(qh, out, len - (out - buf), 4);
/* Last QH is the Terminating QH, it's different */
- if (i == UHCI_NUM_SKELQH - 1) {
- if (qh->link != UHCI_PTR_TERM)
- out += sprintf(out, " bandwidth reclamation on!\n");
-
+ if (i == SKEL_TERM) {
if (qh_element(qh) != LINK_TO_TD(uhci->term_td))
out += sprintf(out, " skel_term_qh element is not set to term_td!\n");
-
+ if (link == LINK_TO_QH(uhci->skel_term_qh))
+ goto check_qh_link;
continue;
}
- j = (i < 9) ? 9 : i+1; /* Next skeleton */
head = &qh->node;
tmp = head->next;
@@ -456,14 +450,26 @@ check_link:
if (++cnt <= 10)
out += uhci_show_qh(qh, out,
len - (out - buf), 4);
+ if (!fsbr_link && qh->skel >= SKEL_FSBR)
+ fsbr_link = LINK_TO_QH(qh);
}
if ((cnt -= 10) > 0)
out += sprintf(out, " Skipped %d QHs\n", cnt);
- if (i > 1 && i < UHCI_NUM_SKELQH - 1) {
- if (qh->link != LINK_TO_QH(uhci->skelqh[j]))
- out += sprintf(out, " last QH not linked to next skeleton!\n");
- }
+ link = UHCI_PTR_TERM;
+ if (i <= SKEL_ISO)
+ ;
+ else if (i < SKEL_ASYNC)
+ link = LINK_TO_QH(uhci->skel_async_qh);
+ else if (!uhci->fsbr_is_on)
+ ;
+ else if (fsbr_link)
+ link = fsbr_link;
+ else
+ link = LINK_TO_QH(uhci->skel_term_qh);
+check_qh_link:
+ if (qh->link != link)
+ out += sprintf(out, " last QH not linked to next skeleton!\n");
}
return out - buf;