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 18:03:45 -0500 |
commit | 17230acdc71137622ca7dfd789b3944c75d39404 (patch) | |
tree | 67eb75c5e8d254b2d5490ea9982efe73952f90d5 /drivers/usb/host/uhci-debug.c | |
parent | 28b9325e6ae45ffb5e99fedcafe00f25fcaacf06 (diff) |
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 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) | |||
220 | return out - buf; | 220 | return out - buf; |
221 | } | 221 | } |
222 | 222 | ||
223 | static const char * const qh_names[] = { | ||
224 | "skel_unlink_qh", "skel_iso_qh", | ||
225 | "skel_int128_qh", "skel_int64_qh", | ||
226 | "skel_int32_qh", "skel_int16_qh", | ||
227 | "skel_int8_qh", "skel_int4_qh", | ||
228 | "skel_int2_qh", "skel_int1_qh", | ||
229 | "skel_ls_control_qh", "skel_fs_control_qh", | ||
230 | "skel_bulk_qh", "skel_term_qh" | ||
231 | }; | ||
232 | |||
233 | static int uhci_show_sc(int port, unsigned short status, char *buf, int len) | 223 | static int uhci_show_sc(int port, unsigned short status, char *buf, int len) |
234 | { | 224 | { |
235 | char *out = buf; | 225 | char *out = buf; |
@@ -352,6 +342,12 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
352 | struct uhci_td *td; | 342 | struct uhci_td *td; |
353 | struct list_head *tmp, *head; | 343 | struct list_head *tmp, *head; |
354 | int nframes, nerrs; | 344 | int nframes, nerrs; |
345 | __le32 link; | ||
346 | |||
347 | static const char * const qh_names[] = { | ||
348 | "unlink", "iso", "int128", "int64", "int32", "int16", | ||
349 | "int8", "int4", "int2", "async", "term" | ||
350 | }; | ||
355 | 351 | ||
356 | out += uhci_show_root_hub_state(uhci, out, len - (out - buf)); | 352 | out += uhci_show_root_hub_state(uhci, out, len - (out - buf)); |
357 | out += sprintf(out, "HC status\n"); | 353 | out += sprintf(out, "HC status\n"); |
@@ -374,7 +370,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
374 | nframes = 10; | 370 | nframes = 10; |
375 | nerrs = 0; | 371 | nerrs = 0; |
376 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { | 372 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { |
377 | __le32 link, qh_dma; | 373 | __le32 qh_dma; |
378 | 374 | ||
379 | j = 0; | 375 | j = 0; |
380 | td = uhci->frame_cpu[i]; | 376 | td = uhci->frame_cpu[i]; |
@@ -430,23 +426,21 @@ check_link: | |||
430 | 426 | ||
431 | for (i = 0; i < UHCI_NUM_SKELQH; ++i) { | 427 | for (i = 0; i < UHCI_NUM_SKELQH; ++i) { |
432 | int cnt = 0; | 428 | int cnt = 0; |
429 | __le32 fsbr_link = 0; | ||
433 | 430 | ||
434 | qh = uhci->skelqh[i]; | 431 | qh = uhci->skelqh[i]; |
435 | out += sprintf(out, "- %s\n", qh_names[i]); \ | 432 | out += sprintf(out, "- skel_%s_qh\n", qh_names[i]); \ |
436 | out += uhci_show_qh(qh, out, len - (out - buf), 4); | 433 | out += uhci_show_qh(qh, out, len - (out - buf), 4); |
437 | 434 | ||
438 | /* Last QH is the Terminating QH, it's different */ | 435 | /* Last QH is the Terminating QH, it's different */ |
439 | if (i == UHCI_NUM_SKELQH - 1) { | 436 | if (i == SKEL_TERM) { |
440 | if (qh->link != UHCI_PTR_TERM) | ||
441 | out += sprintf(out, " bandwidth reclamation on!\n"); | ||
442 | |||
443 | if (qh_element(qh) != LINK_TO_TD(uhci->term_td)) | 437 | if (qh_element(qh) != LINK_TO_TD(uhci->term_td)) |
444 | out += sprintf(out, " skel_term_qh element is not set to term_td!\n"); | 438 | out += sprintf(out, " skel_term_qh element is not set to term_td!\n"); |
445 | 439 | if (link == LINK_TO_QH(uhci->skel_term_qh)) | |
440 | goto check_qh_link; | ||
446 | continue; | 441 | continue; |
447 | } | 442 | } |
448 | 443 | ||
449 | j = (i < 9) ? 9 : i+1; /* Next skeleton */ | ||
450 | head = &qh->node; | 444 | head = &qh->node; |
451 | tmp = head->next; | 445 | tmp = head->next; |
452 | 446 | ||
@@ -456,14 +450,26 @@ check_link: | |||
456 | if (++cnt <= 10) | 450 | if (++cnt <= 10) |
457 | out += uhci_show_qh(qh, out, | 451 | out += uhci_show_qh(qh, out, |
458 | len - (out - buf), 4); | 452 | len - (out - buf), 4); |
453 | if (!fsbr_link && qh->skel >= SKEL_FSBR) | ||
454 | fsbr_link = LINK_TO_QH(qh); | ||
459 | } | 455 | } |
460 | if ((cnt -= 10) > 0) | 456 | if ((cnt -= 10) > 0) |
461 | out += sprintf(out, " Skipped %d QHs\n", cnt); | 457 | out += sprintf(out, " Skipped %d QHs\n", cnt); |
462 | 458 | ||
463 | if (i > 1 && i < UHCI_NUM_SKELQH - 1) { | 459 | link = UHCI_PTR_TERM; |
464 | if (qh->link != LINK_TO_QH(uhci->skelqh[j])) | 460 | if (i <= SKEL_ISO) |
465 | out += sprintf(out, " last QH not linked to next skeleton!\n"); | 461 | ; |
466 | } | 462 | else if (i < SKEL_ASYNC) |
463 | link = LINK_TO_QH(uhci->skel_async_qh); | ||
464 | else if (!uhci->fsbr_is_on) | ||
465 | ; | ||
466 | else if (fsbr_link) | ||
467 | link = fsbr_link; | ||
468 | else | ||
469 | link = LINK_TO_QH(uhci->skel_term_qh); | ||
470 | check_qh_link: | ||
471 | if (qh->link != link) | ||
472 | out += sprintf(out, " last QH not linked to next skeleton!\n"); | ||
467 | } | 473 | } |
468 | 474 | ||
469 | return out - buf; | 475 | return out - buf; |