diff options
Diffstat (limited to 'drivers/usb/host/uhci-hcd.h')
-rw-r--r-- | drivers/usb/host/uhci-hcd.h | 81 |
1 files changed, 34 insertions, 47 deletions
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index d5c8f4d92823..108e3de2dc26 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(10) | ||
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 |
@@ -121,21 +128,31 @@ struct uhci_qh { | |||
121 | __le32 element; /* Queue element (TD) pointer */ | 128 | __le32 element; /* Queue element (TD) pointer */ |
122 | 129 | ||
123 | /* Software fields */ | 130 | /* Software fields */ |
124 | dma_addr_t dma_handle; | ||
125 | |||
126 | struct list_head node; /* Node in the list of QHs */ | 131 | struct list_head node; /* Node in the list of QHs */ |
127 | struct usb_host_endpoint *hep; /* Endpoint information */ | 132 | struct usb_host_endpoint *hep; /* Endpoint information */ |
128 | struct usb_device *udev; | 133 | struct usb_device *udev; |
129 | struct list_head queue; /* Queue of urbps for this QH */ | 134 | struct list_head queue; /* Queue of urbps for this QH */ |
130 | struct uhci_qh *skel; /* Skeleton for this QH */ | 135 | struct uhci_qh *skel; /* Skeleton for this QH */ |
131 | struct uhci_td *dummy_td; /* Dummy TD to end the queue */ | 136 | struct uhci_td *dummy_td; /* Dummy TD to end the queue */ |
137 | struct uhci_td *post_td; /* Last TD completed */ | ||
132 | 138 | ||
139 | struct usb_iso_packet_descriptor *iso_packet_desc; | ||
140 | /* Next urb->iso_frame_desc entry */ | ||
141 | unsigned long advance_jiffies; /* Time of last queue advance */ | ||
133 | unsigned int unlink_frame; /* When the QH was unlinked */ | 142 | unsigned int unlink_frame; /* When the QH was unlinked */ |
143 | unsigned int period; /* For Interrupt and Isochronous QHs */ | ||
144 | unsigned int iso_frame; /* Frame # for iso_packet_desc */ | ||
145 | int iso_status; /* Status for Isochronous URBs */ | ||
146 | |||
134 | int state; /* QH_STATE_xxx; see above */ | 147 | int state; /* QH_STATE_xxx; see above */ |
148 | int type; /* Queue type (control, bulk, etc) */ | ||
149 | |||
150 | dma_addr_t dma_handle; | ||
135 | 151 | ||
136 | unsigned int initial_toggle:1; /* Endpoint's current toggle value */ | 152 | unsigned int initial_toggle:1; /* Endpoint's current toggle value */ |
137 | unsigned int needs_fixup:1; /* Must fix the TD toggle values */ | 153 | unsigned int needs_fixup:1; /* Must fix the TD toggle values */ |
138 | unsigned int is_stopped:1; /* Queue was stopped by an error */ | 154 | unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ |
155 | unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */ | ||
139 | } __attribute__((aligned(16))); | 156 | } __attribute__((aligned(16))); |
140 | 157 | ||
141 | /* | 158 | /* |
@@ -226,7 +243,6 @@ struct uhci_td { | |||
226 | dma_addr_t dma_handle; | 243 | dma_addr_t dma_handle; |
227 | 244 | ||
228 | struct list_head list; | 245 | struct list_head list; |
229 | struct list_head remove_list; | ||
230 | 246 | ||
231 | int frame; /* for iso: what frame? */ | 247 | int frame; /* for iso: what frame? */ |
232 | struct list_head fl_list; | 248 | struct list_head fl_list; |
@@ -305,38 +321,8 @@ static inline u32 td_status(struct uhci_td *td) { | |||
305 | #define skel_bulk_qh skelqh[12] | 321 | #define skel_bulk_qh skelqh[12] |
306 | #define skel_term_qh skelqh[13] | 322 | #define skel_term_qh skelqh[13] |
307 | 323 | ||
308 | /* | 324 | /* Find the skelqh entry corresponding to an interval exponent */ |
309 | * Search tree for determining where <interval> fits in the skelqh[] | 325 | #define UHCI_SKEL_INDEX(exponent) (9 - exponent) |
310 | * skeleton. | ||
311 | * | ||
312 | * An interrupt request should be placed into the slowest skelqh[] | ||
313 | * which meets the interval/period/frequency requirement. | ||
314 | * An interrupt request is allowed to be faster than <interval> but not slower. | ||
315 | * | ||
316 | * For a given <interval>, this function returns the appropriate/matching | ||
317 | * skelqh[] index value. | ||
318 | */ | ||
319 | static inline int __interval_to_skel(int interval) | ||
320 | { | ||
321 | if (interval < 16) { | ||
322 | if (interval < 4) { | ||
323 | if (interval < 2) | ||
324 | return 9; /* int1 for 0-1 ms */ | ||
325 | return 8; /* int2 for 2-3 ms */ | ||
326 | } | ||
327 | if (interval < 8) | ||
328 | return 7; /* int4 for 4-7 ms */ | ||
329 | return 6; /* int8 for 8-15 ms */ | ||
330 | } | ||
331 | if (interval < 64) { | ||
332 | if (interval < 32) | ||
333 | return 5; /* int16 for 16-31 ms */ | ||
334 | return 4; /* int32 for 32-63 ms */ | ||
335 | } | ||
336 | if (interval < 128) | ||
337 | return 3; /* int64 for 64-127 ms */ | ||
338 | return 2; /* int128 for 128-255 ms (Max.) */ | ||
339 | } | ||
340 | 326 | ||
341 | 327 | ||
342 | /* | 328 | /* |
@@ -396,32 +382,32 @@ struct uhci_hcd { | |||
396 | __le32 *frame; | 382 | __le32 *frame; |
397 | void **frame_cpu; /* CPU's frame list */ | 383 | void **frame_cpu; /* CPU's frame list */ |
398 | 384 | ||
399 | int fsbr; /* Full-speed bandwidth reclamation */ | ||
400 | unsigned long fsbrtimeout; /* FSBR delay */ | ||
401 | |||
402 | enum uhci_rh_state rh_state; | 385 | enum uhci_rh_state rh_state; |
403 | unsigned long auto_stop_time; /* When to AUTO_STOP */ | 386 | unsigned long auto_stop_time; /* When to AUTO_STOP */ |
404 | 387 | ||
405 | unsigned int frame_number; /* As of last check */ | 388 | unsigned int frame_number; /* As of last check */ |
406 | unsigned int is_stopped; | 389 | unsigned int is_stopped; |
407 | #define UHCI_IS_STOPPED 9999 /* Larger than a frame # */ | 390 | #define UHCI_IS_STOPPED 9999 /* Larger than a frame # */ |
391 | unsigned int last_iso_frame; /* Frame of last scan */ | ||
392 | unsigned int cur_iso_frame; /* Frame for current scan */ | ||
408 | 393 | ||
409 | unsigned int scan_in_progress:1; /* Schedule scan is running */ | 394 | unsigned int scan_in_progress:1; /* Schedule scan is running */ |
410 | unsigned int need_rescan:1; /* Redo the schedule scan */ | 395 | unsigned int need_rescan:1; /* Redo the schedule scan */ |
411 | unsigned int hc_inaccessible:1; /* HC is suspended or dead */ | 396 | unsigned int dead:1; /* Controller has died */ |
412 | unsigned int working_RD:1; /* Suspended root hub doesn't | 397 | unsigned int working_RD:1; /* Suspended root hub doesn't |
413 | need to be polled */ | 398 | need to be polled */ |
414 | unsigned int is_initialized:1; /* Data structure is usable */ | 399 | unsigned int is_initialized:1; /* Data structure is usable */ |
400 | unsigned int fsbr_is_on:1; /* FSBR is turned on */ | ||
401 | unsigned int fsbr_is_wanted:1; /* Does any URB want FSBR? */ | ||
402 | unsigned int fsbr_expiring:1; /* FSBR is timing out */ | ||
403 | |||
404 | struct timer_list fsbr_timer; /* For turning off FBSR */ | ||
415 | 405 | ||
416 | /* Support for port suspend/resume/reset */ | 406 | /* Support for port suspend/resume/reset */ |
417 | unsigned long port_c_suspend; /* Bit-arrays of ports */ | 407 | unsigned long port_c_suspend; /* Bit-arrays of ports */ |
418 | unsigned long resuming_ports; | 408 | unsigned long resuming_ports; |
419 | unsigned long ports_timeout; /* Time to stop signalling */ | 409 | unsigned long ports_timeout; /* Time to stop signalling */ |
420 | 410 | ||
421 | /* List of TDs that are done, but waiting to be freed (race) */ | ||
422 | struct list_head td_remove_list; | ||
423 | unsigned int td_remove_age; /* Age in frames */ | ||
424 | |||
425 | struct list_head idle_qh_list; /* Where the idle QHs live */ | 411 | struct list_head idle_qh_list; /* Where the idle QHs live */ |
426 | 412 | ||
427 | int rh_numports; /* Number of root-hub ports */ | 413 | int rh_numports; /* Number of root-hub ports */ |
@@ -442,6 +428,9 @@ static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci) | |||
442 | 428 | ||
443 | #define uhci_dev(u) (uhci_to_hcd(u)->self.controller) | 429 | #define uhci_dev(u) (uhci_to_hcd(u)->self.controller) |
444 | 430 | ||
431 | /* Utility macro for comparing frame numbers */ | ||
432 | #define uhci_frame_before_eq(f1, f2) (0 <= (int) ((f2) - (f1))) | ||
433 | |||
445 | 434 | ||
446 | /* | 435 | /* |
447 | * Private per-URB data | 436 | * Private per-URB data |
@@ -454,9 +443,7 @@ struct urb_priv { | |||
454 | struct uhci_qh *qh; /* QH for this URB */ | 443 | struct uhci_qh *qh; /* QH for this URB */ |
455 | struct list_head td_list; | 444 | struct list_head td_list; |
456 | 445 | ||
457 | unsigned fsbr : 1; /* URB turned on FSBR */ | 446 | unsigned fsbr:1; /* URB wants FSBR */ |
458 | unsigned short_transfer : 1; /* URB got a short transfer, no | ||
459 | * need to rescan */ | ||
460 | }; | 447 | }; |
461 | 448 | ||
462 | 449 | ||