diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2006-05-12 11:35:45 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-06-21 18:04:11 -0400 |
commit | 84afddd7ac58adad00cb0e50d0af25fcf825668b (patch) | |
tree | b528f0169ae61309ea4a0020bd53504f8faa827e /drivers/usb/host/uhci-hcd.h | |
parent | 04538a255ac8b404c20cbf15867c9829254c470f (diff) |
[PATCH] UHCI: Reimplement FSBR
This patch (as683) re-implements Full-Speed Bandwidth Reclamation (FSBR)
properly. It keeps track of which endpoint queues have advanced, and
when none have advanced for a sufficiently long time, FSBR is turned
off. The next TD on each of the non-moving queues is modified to
generate an interrupt on completion, so that FSBR can be re-enabled as
soon as the hardware starts to make some progress.
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-hcd.h')
-rw-r--r-- | drivers/usb/host/uhci-hcd.h | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 90ef7fbbf2fb..04938e64799f 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -84,6 +84,13 @@ | |||
84 | #define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames | 84 | #define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames |
85 | * can be scheduled */ | 85 | * can be scheduled */ |
86 | 86 | ||
87 | /* When no queues need Full-Speed Bandwidth Reclamation, | ||
88 | * delay this long before turning FSBR off */ | ||
89 | #define FSBR_OFF_DELAY msecs_to_jiffies(400) | ||
90 | |||
91 | /* If a queue hasn't advanced after this much time, assume it is stuck */ | ||
92 | #define QH_WAIT_TIMEOUT msecs_to_jiffies(200) | ||
93 | |||
87 | 94 | ||
88 | /* | 95 | /* |
89 | * Queue Headers | 96 | * Queue Headers |
@@ -131,6 +138,7 @@ struct uhci_qh { | |||
131 | struct uhci_td *dummy_td; /* Dummy TD to end the queue */ | 138 | struct uhci_td *dummy_td; /* Dummy TD to end the queue */ |
132 | struct uhci_td *post_td; /* Last TD completed */ | 139 | struct uhci_td *post_td; /* Last TD completed */ |
133 | 140 | ||
141 | unsigned long advance_jiffies; /* Time of last queue advance */ | ||
134 | unsigned int unlink_frame; /* When the QH was unlinked */ | 142 | unsigned int unlink_frame; /* When the QH was unlinked */ |
135 | int state; /* QH_STATE_xxx; see above */ | 143 | int state; /* QH_STATE_xxx; see above */ |
136 | int type; /* Queue type (control, bulk, etc) */ | 144 | int type; /* Queue type (control, bulk, etc) */ |
@@ -138,6 +146,7 @@ struct uhci_qh { | |||
138 | unsigned int initial_toggle:1; /* Endpoint's current toggle value */ | 146 | unsigned int initial_toggle:1; /* Endpoint's current toggle value */ |
139 | unsigned int needs_fixup:1; /* Must fix the TD toggle values */ | 147 | unsigned int needs_fixup:1; /* Must fix the TD toggle values */ |
140 | unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ | 148 | unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ |
149 | unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */ | ||
141 | } __attribute__((aligned(16))); | 150 | } __attribute__((aligned(16))); |
142 | 151 | ||
143 | /* | 152 | /* |
@@ -397,8 +406,7 @@ struct uhci_hcd { | |||
397 | __le32 *frame; | 406 | __le32 *frame; |
398 | void **frame_cpu; /* CPU's frame list */ | 407 | void **frame_cpu; /* CPU's frame list */ |
399 | 408 | ||
400 | int fsbr; /* Full-speed bandwidth reclamation */ | 409 | unsigned long fsbr_jiffies; /* Time when FSBR was last wanted */ |
401 | unsigned long fsbrtimeout; /* FSBR delay */ | ||
402 | 410 | ||
403 | enum uhci_rh_state rh_state; | 411 | enum uhci_rh_state rh_state; |
404 | unsigned long auto_stop_time; /* When to AUTO_STOP */ | 412 | unsigned long auto_stop_time; /* When to AUTO_STOP */ |
@@ -413,6 +421,7 @@ struct uhci_hcd { | |||
413 | unsigned int working_RD:1; /* Suspended root hub doesn't | 421 | unsigned int working_RD:1; /* Suspended root hub doesn't |
414 | need to be polled */ | 422 | need to be polled */ |
415 | unsigned int is_initialized:1; /* Data structure is usable */ | 423 | unsigned int is_initialized:1; /* Data structure is usable */ |
424 | unsigned int fsbr_is_on:1; /* FSBR is turned on */ | ||
416 | 425 | ||
417 | /* Support for port suspend/resume/reset */ | 426 | /* Support for port suspend/resume/reset */ |
418 | unsigned long port_c_suspend; /* Bit-arrays of ports */ | 427 | unsigned long port_c_suspend; /* Bit-arrays of ports */ |
@@ -451,7 +460,7 @@ struct urb_priv { | |||
451 | struct uhci_qh *qh; /* QH for this URB */ | 460 | struct uhci_qh *qh; /* QH for this URB */ |
452 | struct list_head td_list; | 461 | struct list_head td_list; |
453 | 462 | ||
454 | unsigned fsbr : 1; /* URB turned on FSBR */ | 463 | unsigned fsbr:1; /* URB wants FSBR */ |
455 | }; | 464 | }; |
456 | 465 | ||
457 | 466 | ||