diff options
Diffstat (limited to 'drivers/usb/host/uhci-hcd.h')
-rw-r--r-- | drivers/usb/host/uhci-hcd.h | 98 |
1 files changed, 53 insertions, 45 deletions
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 282f40b75881..e576db57a926 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #define usb_packetid(pipe) (usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT) | 7 | #define usb_packetid(pipe) (usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT) |
8 | #define PIPE_DEVEP_MASK 0x0007ff00 | 8 | #define PIPE_DEVEP_MASK 0x0007ff00 |
9 | 9 | ||
10 | |||
10 | /* | 11 | /* |
11 | * Universal Host Controller Interface data structures and defines | 12 | * Universal Host Controller Interface data structures and defines |
12 | */ | 13 | */ |
@@ -82,15 +83,10 @@ | |||
82 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ | 83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ |
83 | #define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ | 84 | #define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ |
84 | 85 | ||
85 | struct uhci_frame_list { | ||
86 | __le32 frame[UHCI_NUMFRAMES]; | ||
87 | |||
88 | void *frame_cpu[UHCI_NUMFRAMES]; | ||
89 | |||
90 | dma_addr_t dma_handle; | ||
91 | }; | ||
92 | 86 | ||
93 | struct urb_priv; | 87 | /* |
88 | * Queue Headers | ||
89 | */ | ||
94 | 90 | ||
95 | /* | 91 | /* |
96 | * One role of a QH is to hold a queue of TDs for some endpoint. Each QH is | 92 | * One role of a QH is to hold a queue of TDs for some endpoint. Each QH is |
@@ -116,13 +112,13 @@ struct uhci_qh { | |||
116 | 112 | ||
117 | struct urb_priv *urbp; | 113 | struct urb_priv *urbp; |
118 | 114 | ||
119 | struct list_head list; /* P: uhci->frame_list_lock */ | 115 | struct list_head list; |
120 | struct list_head remove_list; /* P: uhci->remove_list_lock */ | 116 | struct list_head remove_list; |
121 | } __attribute__((aligned(16))); | 117 | } __attribute__((aligned(16))); |
122 | 118 | ||
123 | /* | 119 | /* |
124 | * We need a special accessor for the element pointer because it is | 120 | * We need a special accessor for the element pointer because it is |
125 | * subject to asynchronous updates by the controller | 121 | * subject to asynchronous updates by the controller. |
126 | */ | 122 | */ |
127 | static __le32 inline qh_element(struct uhci_qh *qh) { | 123 | static __le32 inline qh_element(struct uhci_qh *qh) { |
128 | __le32 element = qh->element; | 124 | __le32 element = qh->element; |
@@ -131,6 +127,11 @@ static __le32 inline qh_element(struct uhci_qh *qh) { | |||
131 | return element; | 127 | return element; |
132 | } | 128 | } |
133 | 129 | ||
130 | |||
131 | /* | ||
132 | * Transfer Descriptors | ||
133 | */ | ||
134 | |||
134 | /* | 135 | /* |
135 | * for TD <status>: | 136 | * for TD <status>: |
136 | */ | 137 | */ |
@@ -183,17 +184,10 @@ static __le32 inline qh_element(struct uhci_qh *qh) { | |||
183 | * | 184 | * |
184 | * That's silly, the hardware doesn't care. The hardware only cares that | 185 | * That's silly, the hardware doesn't care. The hardware only cares that |
185 | * the hardware words are 16-byte aligned, and we can have any amount of | 186 | * the hardware words are 16-byte aligned, and we can have any amount of |
186 | * sw space after the TD entry as far as I can tell. | 187 | * sw space after the TD entry. |
187 | * | ||
188 | * But let's just go with the documentation, at least for 32-bit machines. | ||
189 | * On 64-bit machines we probably want to take advantage of the fact that | ||
190 | * hw doesn't really care about the size of the sw-only area. | ||
191 | * | ||
192 | * Alas, not anymore, we have more than 4 words for software, woops. | ||
193 | * Everything still works tho, surprise! -jerdfelt | ||
194 | * | 188 | * |
195 | * td->link points to either another TD (not necessarily for the same urb or | 189 | * td->link points to either another TD (not necessarily for the same urb or |
196 | * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs) | 190 | * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs). |
197 | */ | 191 | */ |
198 | struct uhci_td { | 192 | struct uhci_td { |
199 | /* Hardware fields */ | 193 | /* Hardware fields */ |
@@ -205,18 +199,16 @@ struct uhci_td { | |||
205 | /* Software fields */ | 199 | /* Software fields */ |
206 | dma_addr_t dma_handle; | 200 | dma_addr_t dma_handle; |
207 | 201 | ||
208 | struct urb *urb; | 202 | struct list_head list; |
209 | 203 | struct list_head remove_list; | |
210 | struct list_head list; /* P: urb->lock */ | ||
211 | struct list_head remove_list; /* P: uhci->td_remove_list_lock */ | ||
212 | 204 | ||
213 | int frame; /* for iso: what frame? */ | 205 | int frame; /* for iso: what frame? */ |
214 | struct list_head fl_list; /* P: uhci->frame_list_lock */ | 206 | struct list_head fl_list; |
215 | } __attribute__((aligned(16))); | 207 | } __attribute__((aligned(16))); |
216 | 208 | ||
217 | /* | 209 | /* |
218 | * We need a special accessor for the control/status word because it is | 210 | * We need a special accessor for the control/status word because it is |
219 | * subject to asynchronous updates by the controller | 211 | * subject to asynchronous updates by the controller. |
220 | */ | 212 | */ |
221 | static u32 inline td_status(struct uhci_td *td) { | 213 | static u32 inline td_status(struct uhci_td *td) { |
222 | __le32 status = td->status; | 214 | __le32 status = td->status; |
@@ -227,6 +219,10 @@ static u32 inline td_status(struct uhci_td *td) { | |||
227 | 219 | ||
228 | 220 | ||
229 | /* | 221 | /* |
222 | * Skeleton Queue Headers | ||
223 | */ | ||
224 | |||
225 | /* | ||
230 | * The UHCI driver places Interrupt, Control and Bulk into QH's both | 226 | * The UHCI driver places Interrupt, Control and Bulk into QH's both |
231 | * to group together TD's for one transfer, and also to faciliate queuing | 227 | * to group together TD's for one transfer, and also to faciliate queuing |
232 | * of URB's. To make it easy to insert entries into the schedule, we have | 228 | * of URB's. To make it easy to insert entries into the schedule, we have |
@@ -256,15 +252,15 @@ static u32 inline td_status(struct uhci_td *td) { | |||
256 | * | 252 | * |
257 | * The terminating QH is used for 2 reasons: | 253 | * The terminating QH is used for 2 reasons: |
258 | * - To place a terminating TD which is used to workaround a PIIX bug | 254 | * - To place a terminating TD which is used to workaround a PIIX bug |
259 | * (see Intel errata for explanation) | 255 | * (see Intel errata for explanation), and |
260 | * - To loop back to the full-speed control queue for full-speed bandwidth | 256 | * - To loop back to the full-speed control queue for full-speed bandwidth |
261 | * reclamation | 257 | * reclamation. |
262 | * | 258 | * |
263 | * Isochronous transfers are stored before the start of the skeleton | 259 | * Isochronous transfers are stored before the start of the skeleton |
264 | * schedule and don't use QH's. While the UHCI spec doesn't forbid the | 260 | * schedule and don't use QH's. While the UHCI spec doesn't forbid the |
265 | * use of QH's for Isochronous, it doesn't use them either. Since we don't | 261 | * use of QH's for Isochronous, it doesn't use them either. And the spec |
266 | * need to use them either, we follow the spec diagrams in hope that it'll | 262 | * says that queues never advance on an error completion status, which |
267 | * be more compatible with future UHCI implementations. | 263 | * makes them totally unsuitable for Isochronous transfers. |
268 | */ | 264 | */ |
269 | 265 | ||
270 | #define UHCI_NUM_SKELQH 12 | 266 | #define UHCI_NUM_SKELQH 12 |
@@ -314,8 +310,13 @@ static inline int __interval_to_skel(int interval) | |||
314 | return 0; /* int128 for 128-255 ms (Max.) */ | 310 | return 0; /* int128 for 128-255 ms (Max.) */ |
315 | } | 311 | } |
316 | 312 | ||
313 | |||
314 | /* | ||
315 | * The UHCI controller and root hub | ||
316 | */ | ||
317 | |||
317 | /* | 318 | /* |
318 | * States for the root hub. | 319 | * States for the root hub: |
319 | * | 320 | * |
320 | * To prevent "bouncing" in the presence of electrical noise, | 321 | * To prevent "bouncing" in the presence of electrical noise, |
321 | * when there are no devices attached we delay for 1 second in the | 322 | * when there are no devices attached we delay for 1 second in the |
@@ -326,7 +327,7 @@ static inline int __interval_to_skel(int interval) | |||
326 | */ | 327 | */ |
327 | enum uhci_rh_state { | 328 | enum uhci_rh_state { |
328 | /* In the following states the HC must be halted. | 329 | /* In the following states the HC must be halted. |
329 | * These two must come first */ | 330 | * These two must come first. */ |
330 | UHCI_RH_RESET, | 331 | UHCI_RH_RESET, |
331 | UHCI_RH_SUSPENDED, | 332 | UHCI_RH_SUSPENDED, |
332 | 333 | ||
@@ -338,13 +339,13 @@ enum uhci_rh_state { | |||
338 | UHCI_RH_SUSPENDING, | 339 | UHCI_RH_SUSPENDING, |
339 | 340 | ||
340 | /* In the following states it's an error if the HC is halted. | 341 | /* In the following states it's an error if the HC is halted. |
341 | * These two must come last */ | 342 | * These two must come last. */ |
342 | UHCI_RH_RUNNING, /* The normal state */ | 343 | UHCI_RH_RUNNING, /* The normal state */ |
343 | UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */ | 344 | UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */ |
344 | }; | 345 | }; |
345 | 346 | ||
346 | /* | 347 | /* |
347 | * This describes the full uhci information. | 348 | * The full UHCI controller information: |
348 | */ | 349 | */ |
349 | struct uhci_hcd { | 350 | struct uhci_hcd { |
350 | 351 | ||
@@ -361,7 +362,11 @@ struct uhci_hcd { | |||
361 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ | 362 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ |
362 | 363 | ||
363 | spinlock_t lock; | 364 | spinlock_t lock; |
364 | struct uhci_frame_list *fl; /* P: uhci->lock */ | 365 | |
366 | dma_addr_t frame_dma_handle; /* Hardware frame list */ | ||
367 | __le32 *frame; | ||
368 | void **frame_cpu; /* CPU's frame list */ | ||
369 | |||
365 | int fsbr; /* Full-speed bandwidth reclamation */ | 370 | int fsbr; /* Full-speed bandwidth reclamation */ |
366 | unsigned long fsbrtimeout; /* FSBR delay */ | 371 | unsigned long fsbrtimeout; /* FSBR delay */ |
367 | 372 | ||
@@ -385,22 +390,22 @@ struct uhci_hcd { | |||
385 | unsigned long ports_timeout; /* Time to stop signalling */ | 390 | unsigned long ports_timeout; /* Time to stop signalling */ |
386 | 391 | ||
387 | /* Main list of URB's currently controlled by this HC */ | 392 | /* Main list of URB's currently controlled by this HC */ |
388 | struct list_head urb_list; /* P: uhci->lock */ | 393 | struct list_head urb_list; |
389 | 394 | ||
390 | /* List of QH's that are done, but waiting to be unlinked (race) */ | 395 | /* List of QH's that are done, but waiting to be unlinked (race) */ |
391 | struct list_head qh_remove_list; /* P: uhci->lock */ | 396 | struct list_head qh_remove_list; |
392 | unsigned int qh_remove_age; /* Age in frames */ | 397 | unsigned int qh_remove_age; /* Age in frames */ |
393 | 398 | ||
394 | /* List of TD's that are done, but waiting to be freed (race) */ | 399 | /* List of TD's that are done, but waiting to be freed (race) */ |
395 | struct list_head td_remove_list; /* P: uhci->lock */ | 400 | struct list_head td_remove_list; |
396 | unsigned int td_remove_age; /* Age in frames */ | 401 | unsigned int td_remove_age; /* Age in frames */ |
397 | 402 | ||
398 | /* List of asynchronously unlinked URB's */ | 403 | /* List of asynchronously unlinked URB's */ |
399 | struct list_head urb_remove_list; /* P: uhci->lock */ | 404 | struct list_head urb_remove_list; |
400 | unsigned int urb_remove_age; /* Age in frames */ | 405 | unsigned int urb_remove_age; /* Age in frames */ |
401 | 406 | ||
402 | /* List of URB's awaiting completion callback */ | 407 | /* List of URB's awaiting completion callback */ |
403 | struct list_head complete_list; /* P: uhci->lock */ | 408 | struct list_head complete_list; |
404 | 409 | ||
405 | int rh_numports; /* Number of root-hub ports */ | 410 | int rh_numports; /* Number of root-hub ports */ |
406 | 411 | ||
@@ -419,13 +424,17 @@ static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci) | |||
419 | 424 | ||
420 | #define uhci_dev(u) (uhci_to_hcd(u)->self.controller) | 425 | #define uhci_dev(u) (uhci_to_hcd(u)->self.controller) |
421 | 426 | ||
427 | |||
428 | /* | ||
429 | * Private per-URB data | ||
430 | */ | ||
422 | struct urb_priv { | 431 | struct urb_priv { |
423 | struct list_head urb_list; | 432 | struct list_head urb_list; |
424 | 433 | ||
425 | struct urb *urb; | 434 | struct urb *urb; |
426 | 435 | ||
427 | struct uhci_qh *qh; /* QH for this URB */ | 436 | struct uhci_qh *qh; /* QH for this URB */ |
428 | struct list_head td_list; /* P: urb->lock */ | 437 | struct list_head td_list; |
429 | 438 | ||
430 | unsigned fsbr : 1; /* URB turned on FSBR */ | 439 | unsigned fsbr : 1; /* URB turned on FSBR */ |
431 | unsigned fsbr_timeout : 1; /* URB timed out on FSBR */ | 440 | unsigned fsbr_timeout : 1; /* URB timed out on FSBR */ |
@@ -434,12 +443,12 @@ struct urb_priv { | |||
434 | /* a control transfer, retrigger */ | 443 | /* a control transfer, retrigger */ |
435 | /* the status phase */ | 444 | /* the status phase */ |
436 | 445 | ||
437 | unsigned long inserttime; /* In jiffies */ | ||
438 | unsigned long fsbrtime; /* In jiffies */ | 446 | unsigned long fsbrtime; /* In jiffies */ |
439 | 447 | ||
440 | struct list_head queue_list; /* P: uhci->frame_list_lock */ | 448 | struct list_head queue_list; |
441 | }; | 449 | }; |
442 | 450 | ||
451 | |||
443 | /* | 452 | /* |
444 | * Locking in uhci.c | 453 | * Locking in uhci.c |
445 | * | 454 | * |
@@ -459,6 +468,5 @@ struct urb_priv { | |||
459 | 468 | ||
460 | #define PCI_VENDOR_ID_GENESYS 0x17a0 | 469 | #define PCI_VENDOR_ID_GENESYS 0x17a0 |
461 | #define PCI_DEVICE_ID_GL880S_UHCI 0x8083 | 470 | #define PCI_DEVICE_ID_GL880S_UHCI 0x8083 |
462 | #define PCI_DEVICE_ID_GL880S_EHCI 0x8084 | ||
463 | 471 | ||
464 | #endif | 472 | #endif |