diff options
| author | Alan Stern <stern@rowland.harvard.edu> | 2007-02-19 15:52:45 -0500 | 
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-02-23 15:03:45 -0800 | 
| commit | 17230acdc71137622ca7dfd789b3944c75d39404 (patch) | |
| tree | 67eb75c5e8d254b2d5490ea9982efe73952f90d5 /drivers/usb/host/uhci-debug.c | |
| parent | 28b9325e6ae45ffb5e99fedcafe00f25fcaacf06 (diff) | |
| download | olio-linux-3.10-17230acdc71137622ca7dfd789b3944c75d39404.tar.xz olio-linux-3.10-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.c | 50 | 
1 files changed, 28 insertions, 22 deletions
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index a0677133577..8d24d3dc0a6 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;  |