Sync with trunk head
[reactos.git] / drivers / usb / nt4compat / usbdriver / ehci.h
1 /*
2 * Copyright (c) 2001-2002 by David Brownell
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef __EHCI_H__
20 #define __EHCI_H__
21
22 #define EHCI_QH_SIZE sizeof( EHCI_QH )
23 #define EHCI_ITD_SIZE sizeof( EHCI_ITD )
24 #define EHCI_SITD_SIZE sizeof( EHCI_SITD )
25 #define EHCI_FSTN_SIZE sizeof( EHCI_FSTN )
26 #define EHCI_QTD_SIZE sizeof( EHCI_QTD )
27
28 #define INIT_LIST_FLAG_TYPE 0x0f
29 #define INIT_LIST_FLAG_ITD 0x00
30 #define INIT_LIST_FLAG_QH 0x01
31 #define INIT_LIST_FLAG_SITD 0x02
32 #define INIT_LIST_FLAG_FSTN 0x03
33 #define INIT_LIST_FLAG_QTD 0x04
34
35 #define EHCI_MAX_SIZE_TRANSFER 0x100000 // 1 MB per transfer
36 #define EHCI_MAX_ELEMS_POOL 1024
37 #define EHCI_MAX_LISTS_POOL 0x08
38 #define EHCI_MAX_QHS_LIST 256 // 4 pages
39 #define EHCI_MAX_ITDS_LIST ( PAGE_SIZE / EHCI_ITD_SIZE * 2 ) // 2 pages
40 #define EHCI_MAX_SITDS_LIST ( PAGE_SIZE / EHCI_SITD_SIZE )// 1 page
41 #define EHCI_MAX_FSTNS_LIST ( PAGE_SIZE / EHCI_FSTN_SIZE )// 1 page
42 #define EHCI_MAX_QTDS_LIST 256 // 4 pages
43
44 #define EHCI_PTR_TERM 0x01
45 #define EHCI_NAK_RL_COUNT 0x04
46
47 #define EHCI_QTD_MAX_TRANS_SIZE 20480
48 #define PHYS_PART_TYPE_MASK 0x01f
49 #define PHYS_PART_ADDR_MASK ( ~PHYS_PART_TYPE_MASK )
50
51 typedef struct _EHCI_ELEM_LINKS
52 {
53 LIST_ENTRY elem_link; // link for one urb request
54 LIST_ENTRY sched_link; // to shadow link of schedule
55 struct _EHCI_ELEM_POOL* pool_link;
56 struct _EHCI_ELEM_LIST* list_link; // opaque to client, which list this td belongs to
57 PVOID phys_part; // point to EHCI_XXX, the lower 5 bits is used to indicate the type of the element
58 PURB purb;
59
60 } EHCI_ELEM_LINKS, *PEHCI_ELEM_LINKS;
61
62 typedef struct _INIT_ELEM_LIST_CONTEXT
63 {
64 PADAPTER_OBJECT padapter;
65 struct _EHCI_ELEM_POOL *pool;
66
67 } INIT_ELEM_LIST_CONTEXT, *PINIT_ELEM_LIST_CONTEXT;
68
69 typedef VOID ( *PDESTROY_ELEM_LIST )( struct _EHCI_ELEM_LIST* plist );
70 typedef PLIST_ENTRY ( *PGET_LIST_HEAD )( struct _EHCI_ELEM_LIST* plist );
71 typedef LONG ( *PGET_TOTAL_COUNT )( struct _EHCI_ELEM_LIST* plist );
72 typedef LONG ( *PGET_ELEM_SIZE )( struct _EHCI_ELEM_LIST* plist );
73 typedef LONG ( *PGET_LINK_OFFSET )( struct _EHCI_ELEM_LIST* plist );
74 typedef LONG ( *PADD_REF )( struct _EHCI_ELEM_LIST* plist );
75 typedef LONG ( *PRELEASE_REF )( struct _EHCI_ELEM_LIST* plist );
76 typedef LONG ( *PGET_REF )( struct _EHCI_ELEM_LIST* plist );
77
78 typedef struct _EHCI_ELEM_LIST
79 {
80 PDESTROY_ELEM_LIST destroy_list;
81 PGET_LIST_HEAD get_list_head;
82 PGET_TOTAL_COUNT get_total_count;
83 PGET_ELEM_SIZE get_elem_size;
84 PGET_LINK_OFFSET get_link_offset;
85 PADD_REF add_ref;
86 PRELEASE_REF release_ref;
87 PGET_REF get_ref;
88
89 // private area
90 LONG flags; // contails element's type info
91 LONG total_count;
92 LONG elem_size;
93 LIST_HEAD free_list; // chains of all the elements
94 struct _EHCI_ELEM_POOL *parent_pool;
95 LONG reference;
96
97 // used to represent the physical memory
98 PPHYSICAL_ADDRESS phys_addrs; // array of non-contigous memory
99 PBYTE *phys_bufs;
100 PEHCI_ELEM_LINKS elem_head_buf;
101 PADAPTER_OBJECT padapter;
102
103 } EHCI_ELEM_LIST, *PEHCI_ELEM_LIST;
104
105 BOOLEAN elem_pool_init_pool( struct _EHCI_ELEM_POOL* pool, LONG flags, PVOID context);
106 VOID elem_pool_destroy_pool ( struct _EHCI_ELEM_POOL* pool );
107 PEHCI_ELEM_LINKS elem_pool_alloc_elem ( struct _EHCI_ELEM_POOL* pool );
108 VOID elem_pool_free_elem ( PEHCI_ELEM_LINKS elem_link );
109 LONG elem_pool_get_total_count ( struct _EHCI_ELEM_POOL* pool );
110 BOOLEAN elem_pool_is_empty ( struct _EHCI_ELEM_POOL* pool );
111 LONG elem_pool_get_free_count ( struct _EHCI_ELEM_POOL* pool );
112 LONG elem_pool_get_link_offset ( struct _EHCI_ELEM_POOL* pool );
113 PEHCI_ELEM_LINKS elem_pool_alloc_elems ( struct _EHCI_ELEM_POOL* pool, LONG count );
114 BOOLEAN elem_pool_free_elems( PEHCI_ELEM_LINKS elem_chains );
115 LONG elem_pool_get_type( struct _EHCI_ELEM_POOL* pool );
116
117 // the following are private functions
118 BOOLEAN elem_pool_expand_pool( struct _EHCI_ELEM_POOL* pool, LONG elem_count );
119 BOOLEAN elem_pool_collect_garbage( struct _EHCI_ELEM_POOL* pool );
120
121 // lock operations
122 BOOLEAN elem_pool_lock( struct _EHCI_ELEM_POOL* pool, BOOLEAN at_dpc );
123 BOOLEAN elem_pool_unlock( struct _EHCI_ELEM_POOL* pool, BOOLEAN at_dpc );
124
125 // helper
126 LONG get_elem_phys_part_size( ULONG type );
127
128 typedef struct _EHCI_ELEM_POOL
129 {
130 LONG flags;
131 LONG free_count; // free count of all the lists currently allocated
132 LONG link_offset; // a cache for elem_list->get_link_offset
133 LONG list_count; // lists currently allocated
134 PEHCI_ELEM_LIST elem_lists[ EHCI_MAX_LISTS_POOL ];
135
136 } EHCI_ELEM_POOL, *PEHCI_ELEM_POOL;
137
138 /*-------------------------------------------------------------------------*/
139
140 #define QTD_NEXT(dma) cpu_to_le32((u32)dma)
141
142 /*
143 * EHCI Specification 0.95 Section 3.5
144 * QTD: describe data transfer components (buffer, direction, ...)
145 * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
146 *
147 * These are associated only with "QH" (Queue Head) structures,
148 * used with control, bulk, and interrupt transfers.
149 */
150 #define QTD_TOGGLE (1 << 31) /* data toggle */
151 #define QTD_LENGTH(tok) (((tok)>>16) & 0x7fff)
152 #define QTD_IOC (1 << 15) /* interrupt on complete */
153 #define QTD_CERR(tok) (((tok)>>10) & 0x3)
154 #define QTD_PID(tok) (((tok)>>8) & 0x3)
155 #define QTD_STS_ACTIVE (1 << 7) /* HC may execute this */
156 #define QTD_STS_HALT (1 << 6) /* halted on error */
157 #define QTD_STS_DBE (1 << 5) /* data buffer error (in HC) */
158 #define QTD_STS_BABBLE (1 << 4) /* device was babbling (qtd halted) */
159 #define QTD_STS_XACT (1 << 3) /* device gave illegal response */
160 #define QTD_STS_MMF (1 << 2) /* incomplete split transaction */
161 #define QTD_STS_STS (1 << 1) /* split transaction state */
162 #define QTD_STS_PING (1 << 0) /* issue PING? */
163 #define QTD_ANY_ERROR ( QTD_STS_HALT | QTD_STS_DBE | QTD_STS_XACT | QTD_STS_MMF | QTD_STS_BABBLE )
164
165 #define QTD_PID_SETUP 0x02
166 #define QTD_PID_IN 0x01
167 #define QTD_PID_OUT 0x00
168
169 #pragma pack( push, usb_align, 1 )
170
171 typedef struct _EHCI_QTD_CONTENT
172 {
173 // DWORD 0
174 ULONG terminal : 1;
175 ULONG reserved : 4;
176 ULONG next_qtd : 27;
177
178 // DWORD 1
179 ULONG alt_terminal : 1;
180 ULONG reserved1 : 4;
181 ULONG alt_qtd : 27;
182
183 // DWORD 2
184 ULONG status : 8;
185 ULONG pid : 2;
186 ULONG err_count : 2;
187 ULONG cur_page : 3;
188 ULONG ioc : 1;
189 ULONG bytes_to_transfer : 15;
190 ULONG data_toggle : 1;
191
192 // DWORD 3
193 ULONG cur_offset : 12;
194 ULONG page0 : 20;
195
196 // DWORD 4-
197 ULONG pages[ 4 ];
198
199 } EHCI_QTD_CONTENT, *PEHCI_QTD_CONTENT;
200
201 typedef struct _EHCI_QTD
202 {
203 /* first part defined by EHCI spec */
204 ULONG hw_next; /* see EHCI 3.5.1 */
205 ULONG hw_alt_next; /* see EHCI 3.5.2 */
206 ULONG hw_token; /* see EHCI 3.5.3 */
207 ULONG hw_buf [5]; /* see EHCI 3.5.4 */
208
209 /* the rest is HCD-private */
210 PEHCI_ELEM_LINKS elem_head_link;
211 ULONG phys_addr; /* qtd address */
212 USHORT bytes_to_transfer; /* the bytes_to_transfer in hw_token will drop to zero when completed*/
213 USHORT reserved2;
214 ULONG reserved[ 5 ];
215
216 } EHCI_QTD, *PEHCI_QTD; //__attribute__ ((aligned (32)));
217
218 #define QTD_MASK cpu_to_le32 (~0x1f) /* mask NakCnt+T in qh->hw_alt_next */
219
220 /*-------------------------------------------------------------------------*/
221
222 /* type tag from {qh,itd,sitd,fstn}->hw_next */
223 #define Q_NEXT_TYPE(dma) ((dma) & __constant_cpu_to_le32 (3 << 1))
224
225 /* values for that type tag */
226 #define Q_TYPE_ITD (0 << 1)
227 #define Q_TYPE_QH (1 << 1)
228 #define Q_TYPE_SITD (2 << 1)
229 #define Q_TYPE_FSTN (3 << 1)
230
231 /* next async queue entry, or pointer to interrupt/periodic QH */
232 #define QH_NEXT(dma) (cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH)
233
234 /* for periodic/async schedules and qtd lists, mark end of list */
235 #define EHCI_LIST_END __constant_cpu_to_le32(1) /* "null pointer" to hw */
236
237 /*-------------------------------------------------------------------------*/
238
239 /*
240 * EHCI Specification 0.95 Section 3.6
241 * QH: describes control/bulk/interrupt endpoints
242 * See Fig 3-7 "Queue Head Structure Layout".
243 *
244 * These appear in both the async and (for interrupt) periodic schedules.
245 */
246
247 #define QH_HEAD 0x00008000
248 #define QH_STATE_LINKED 1 /* HC sees this */
249 #define QH_STATE_UNLINK 2 /* HC may still see this */
250 #define QH_STATE_IDLE 3 /* HC doesn't see this */
251 #define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */
252 #define QH_STATE_COMPLETING 5 /* don't touch token.HALT */
253 #define NO_FRAME ((unsigned short)~0) /* pick new start */
254
255 typedef struct _EHCI_QH_CONTENT
256 {
257 // DWORD 0
258 ULONG terminal : 1;
259 ULONG ptr_type : 2;
260 ULONG reserved : 2;
261 ULONG next_link : 27;
262
263 // DWORD 1
264 ULONG dev_addr : 7;
265 ULONG inactive : 1;
266 ULONG endp_addr : 4;
267 ULONG endp_spd : 2;
268 ULONG data_toggle : 1;
269 ULONG is_async_head : 1;
270 ULONG max_packet_size : 11;
271 ULONG is_ctrl_endp : 1;
272 ULONG reload_counter : 4;
273
274 // DWORD 2
275 ULONG s_mask : 8;
276 ULONG c_mask : 8;
277 ULONG hub_addr : 7;
278 ULONG port_idx : 7;
279 ULONG mult : 2;
280
281 // DWORD 3
282 ULONG cur_qtd_ptr;
283
284 // overlay
285 EHCI_QTD_CONTENT cur_qtd;
286
287 } EHCI_QH_CONTENT, *PEHCI_QH_CONTENT;
288
289 typedef struct _EHCI_QH
290 {
291 /* first part defined by EHCI spec */
292 ULONG hw_next; /* see EHCI 3.6.1 */
293 ULONG hw_info1; /* see EHCI 3.6.2 */
294 ULONG hw_info2; /* see EHCI 3.6.2 */
295 ULONG hw_current; /* qtd list - see EHCI 3.6.4 */
296
297 /* qtd overlay (hardware parts of a struct ehci_qtd) */
298 ULONG hw_qtd_next;
299 ULONG hw_alt_next;
300 ULONG hw_token;
301 ULONG hw_buf [5];
302
303 /* the rest is HCD-private */
304 PEHCI_ELEM_LINKS elem_head_link;
305 ULONG phys_addr; /* address of qh */
306 ULONG reserved[ 2 ];
307
308 } EHCI_QH, *PEHCI_QH; // __attribute__ ((aligned (32)));
309
310 /*-------------------------------------------------------------------------*/
311
312 /*
313 * EHCI Specification 0.95 Section 3.3
314 * Fig 3-4 "Isochronous Transaction Descriptor (iTD)"
315 *
316 * Schedule records for high speed iso xfers
317 */
318
319 #define EHCI_ISOC_ACTIVE (1<<31) /* activate transfer this slot */
320 #define EHCI_ISOC_BUF_ERR (1<<30) /* Data buffer error */
321 #define EHCI_ISOC_BABBLE (1<<29) /* babble detected */
322 #define EHCI_ISOC_XACTERR (1<<28) /* XactErr - transaction error */
323 #define EHCI_ITD_LENGTH(tok) (((tok)>>16) & 0x7fff)
324 #define EHCI_ITD_IOC (1 << 15) /* interrupt on complete */
325
326 #define ITD_STS_ACTIVE 8
327 #define ITD_STS_BUFERR 4
328 #define ITD_STS_BABBLE 2
329 #define ITD_STS_XACTERR 1
330
331 #define ITD_ANY_ERROR ( ITD_STS_BUFERR | ITD_STS_BABBLE | ITD_STS_XACTERR )
332
333 typedef struct _EHCI_ITD_STATUS_SLOT
334 {
335 ULONG offset : 12;
336 ULONG page_sel : 3;
337 ULONG ioc : 1;
338 ULONG trans_length : 12;
339 ULONG status : 4;
340
341 } EHCI_ITD_STATUS_SLOT, *PEHCI_ITD_STATUS_SLOT;
342
343 typedef struct _EHCI_ITD_CONTENT
344 {
345 // DWORD 0;
346 ULONG terminal : 1;
347 ULONG ptr_type : 2;
348 ULONG reserved : 2;
349 ULONG next_link : 27;
350 // DWORD 1-8;
351 EHCI_ITD_STATUS_SLOT status_slot[ 8 ];
352 // DWORD 9;
353 ULONG dev_addr : 7;
354 ULONG reserved1 : 1;
355 ULONG endp_num : 4;
356 ULONG page0 : 20;
357 // DWORD 10;
358 ULONG max_packet_size : 11;
359 ULONG io_dir : 1;
360 ULONG page1 : 20;
361 // DWORD 11;
362 ULONG mult : 2;
363 ULONG reserved2 : 10;
364 ULONG page2 : 20;
365 // DWORD 12-;
366 ULONG pages[ 4 ];
367
368 } EHCI_ITD_CONTENT, *PEHCI_ITD_CONTENT;
369
370 typedef struct _EHCI_ITD {
371
372 /* first part defined by EHCI spec */
373 ULONG hw_next; /* see EHCI 3.3.1 */
374 ULONG hw_transaction [8]; /* see EHCI 3.3.2 */
375 ULONG hw_bufp [7]; /* see EHCI 3.3.3 */
376
377 /* the rest is EHCI-private */
378 PEHCI_ELEM_LINKS elem_head_link;
379 ULONG phys_addr; /* for this itd */
380 ULONG buf_phys_addr; /* buffer address */
381 ULONG reserved[ 5 ];
382
383 } EHCI_ITD, *PEHCI_ITD; // __attribute__ ((aligned (32)));
384
385 /*-------------------------------------------------------------------------*/
386
387 /*
388 * EHCI Specification 0.95 Section 3.4
389 * siTD, aka split-transaction isochronous Transfer Descriptor
390 * ... describe low/full speed iso xfers through TT in hubs
391 * see Figure 3-5 "Split-transaction Isochronous Transaction Descriptor (siTD)
392 */
393 #define SITD_STS_ACTIVE 0x80
394 #define SITD_STS_ERR 0x40 // error from device
395 #define SITD_STS_DBE 0x20 // data buffer error
396 #define SITD_STS_BABBLE 0x10 // data more than expected
397 #define SITD_STS_XACTERR 0x08 // general error on hc
398 #define SITD_STS_MISSFRM 0x04 // missd micro frames
399 #define SITD_STS_SC 0x02 // state is whether start-split( 0 ) or complete-split( 1 )
400 #define SITD_STS_RESERVED 0x01
401 #define SITD_ANY_ERROR ( SITD_STS_ERR | SITD_STS_DBE | SITD_STS_BABBLE | SITD_STS_XACTERR | SITD_STS_MISSFRM )
402
403 typedef struct _EHCI_SITD_CONTENT
404 {
405 // DWORD 0;
406 ULONG terminal : 1;
407 ULONG ptr_type : 2;
408 ULONG reserved : 2;
409 ULONG next_link : 27;
410 // DWORD 1;
411 ULONG dev_addr : 7;
412 ULONG reserved1 : 1;
413 ULONG endp_num : 4;
414 ULONG reserved2 : 4;
415 ULONG hub_addr : 7;
416 ULONG reserved3 : 1;
417 ULONG port_idx : 7;
418 ULONG io_dir : 1;
419 // DWORD 2;
420 ULONG s_mask : 8;
421 ULONG c_mask : 8;
422 ULONG reserved4 : 16;
423 // DWORD 3:
424 ULONG status : 8;
425 ULONG c_prog_mask : 8;
426 ULONG bytes_to_transfer : 10;
427 ULONG reserved5 : 4;
428 ULONG page_sel : 1;
429 ULONG ioc : 1;
430 // DWORD 4;
431 ULONG cur_offset : 12;
432 ULONG page0 : 20;
433 // DWORD 5;
434 ULONG trans_count : 3;
435 ULONG trans_pos : 2;
436 ULONG reserved6 : 7;
437 ULONG page1 : 20;
438 // DWORD 6;
439 ULONG back_terminal : 1;
440 ULONG reserved7 : 4;
441 ULONG back_ptr : 27;
442
443 } EHCI_SITD_CONTENT, *PEHCI_SITD_CONTENT;
444
445 typedef struct _EHCI_SITD
446 {
447 /* first part defined by EHCI spec */
448 ULONG hw_next;
449 /* uses bit field macros above - see EHCI 0.95 Table 3-8 */
450
451 ULONG hw_fullspeed_ep; /* see EHCI table 3-9 */
452 ULONG hw_uframe; /* see EHCI table 3-10 */
453 ULONG hw_tx_results1; /* see EHCI table 3-11 */
454 ULONG hw_tx_results2; /* see EHCI table 3-12 */
455 ULONG hw_tx_results3; /* see EHCI table 3-12 */
456 ULONG hw_backpointer; /* see EHCI table 3-13 */
457
458 /* the rest is HCD-private */
459 PEHCI_ELEM_LINKS elem_head_link;
460 ULONG phys_addr;
461 ULONG buf_phys_addr; /* buffer address */
462
463 USHORT usecs; /* start bandwidth */
464 USHORT c_usecs; /* completion bandwidth */
465 ULONG reserved[ 5 ];
466
467 } EHCI_SITD, *PEHCI_SITD; // __attribute__ ((aligned (32)));
468
469 /*-------------------------------------------------------------------------*/
470
471 /*
472 * EHCI Specification 0.96 Section 3.7
473 * Periodic Frame Span Traversal Node (FSTN)
474 *
475 * Manages split interrupt transactions (using TT) that span frame boundaries
476 * into uframes 0/1; see 4.12.2.2. In those uframes, a "save place" FSTN
477 * makes the HC jump (back) to a QH to scan for fs/ls QH completions until
478 * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
479 */
480 typedef struct _EHCI_FSTN
481 {
482 ULONG hw_next; /* any periodic q entry */
483 ULONG hw_prev; /* qh or EHCI_LIST_END */
484
485 /* the rest is HCD-private */
486 PEHCI_ELEM_LINKS elem_head_link;
487 ULONG phys_addr;
488 ULONG reserved[ 4 ];
489
490 } EHCI_FSTN, *PEHCI_FSTN; // __attribute__ ((aligned (32)));
491
492
493 /* NOTE: urb->transfer_flags expected to not use this bit !!! */
494 #define EHCI_STATE_UNLINK 0x8000 /* urb being unlinked */
495
496 /*-------------------------------------------------------------------------*/
497
498 /* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
499
500 /* Section 2.2 Host Controller Capability Registers */
501 #define HCS_DEBUG_PORT(p) (((p)>>20)&0xf) /* bits 23:20, debug port? */
502 #define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */
503 #define HCS_N_CC(p) (((p)>>12)&0xf) /* bits 15:12, #companion HCs */
504 #define HCS_N_PCC(p) (((p)>>8)&0xf) /* bits 11:8, ports per CC */
505 #define HCS_PORTROUTED(p) ((p)&(1 << 7)) /* true: port routing */
506 #define HCS_PPC(p) ((p)&(1 << 4)) /* true: port power control */
507 #define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */
508
509 #define HCC_EXT_CAPS(p) (((p)>>8)&0xff) /* for pci extended caps */
510 #define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */
511 #define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */
512 #define HCC_CANPARK(p) ((p)&(1 << 2)) /* true: can park on async qh */
513 #define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1)) /* true: periodic_size changes*/
514 #define HCC_64BIT_ADDR(p) ((p)&(1)) /* true: can use 64-bit addr */
515
516 /* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
517 #define CMD_PARK (1<<11) /* enable "park" on async qh */
518 #define CMD_PARK_CNT(c) (((c)>>8)&3) /* how many transfers to park for */
519 #define CMD_LRESET (1<<7) /* partial reset (no ports, etc) */
520 #define CMD_IAAD (1<<6) /* "doorbell" interrupt async advance */
521 #define CMD_ASE (1<<5) /* async schedule enable */
522 #define CMD_PSE (1<<4) /* periodic schedule enable */
523 /* 3:2 is periodic frame list size */
524 #define CMD_RESET (1<<1) /* reset HC not bus */
525 #define CMD_RUN (1<<0) /* start/stop HC */
526
527 /* these STS_* flags are also intr_enable bits (USBINTR) */
528 #define STS_IAA (1<<5) /* Interrupted on async advance */
529 #define STS_FATAL (1<<4) /* such as some PCI access errors */
530 #define STS_FLR (1<<3) /* frame list rolled over */
531 #define STS_PCD (1<<2) /* port change detect */
532 #define STS_ERR (1<<1) /* "error" completion (overflow, ...) */
533 #define STS_INT (1<<0) /* "normal" completion (short, ...) */
534
535 #define STS_ASS (1<<15) /* Async Schedule Status */
536 #define STS_PSS (1<<14) /* Periodic Schedule Status */
537 #define STS_RECL (1<<13) /* Reclamation */
538 #define STS_HALT (1<<12) /* Not running (any reason) */
539
540 /* 31:23 reserved */
541 #define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */
542 #define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */
543 #define PORT_WKCONN_E (1<<20) /* wake on connect (enable) */
544 /* 19:16 for port testing */
545 /* 15:14 for using port indicator leds (if HCS_INDICATOR allows) */
546 #define PORT_OWNER (1<<13) /* true: companion hc owns this port */
547 #define PORT_POWER (1<<12) /* true: has power (see PPC) */
548 #define PORT_USB11(x) (((x)&(3<<10))==(1<<10)) /* USB 1.1 device */
549 /* 11:10 for detecting lowspeed devices (reset vs release ownership) */
550 /* 9 reserved */
551 #define PORT_PR (1<<8) /* reset port */
552 #define PORT_SUSP (1<<7) /* suspend port */
553 #define PORT_RESUME (1<<6) /* resume it */
554 #define PORT_OCC (1<<5) /* over current change */
555 #define PORT_OC (1<<4) /* over current active */
556 #define PORT_PEC (1<<3) /* port enable change */
557 #define PORT_PE (1<<2) /* port enable */
558 #define PORT_CSC (1<<1) /* connect status change */
559 #define PORT_CCS (1<<0) /* device connected */
560
561 #define FLAG_CF (1<<0) /* true: we'll support "high speed" */
562
563 typedef struct _EHCI_HCS_CONTENT
564 {
565 ULONG port_count : 4;
566 ULONG port_power_control : 1;
567 ULONG reserved : 2;
568 ULONG port_rout_rules : 1;
569 ULONG port_per_chc : 4;
570 ULONG chc_count : 4;
571 ULONG port_indicator : 1;
572 ULONG reserved2 : 3;
573 ULONG dbg_port_num : 4;
574 ULONG reserved3 : 8;
575
576 } EHCI_HCS_CONTENT, *PEHCI_HCS_CONTENT;
577
578 typedef struct _EHCI_HCC_CONTENT
579 {
580 ULONG cur_addr_bits : 1; /* 0: 32 bit addressing 1: 64 bit addressing */
581 ULONG var_frame_list : 1; /* 0: 1024 frames, 1: support other number of frames */
582 ULONG park_mode : 1;
583 ULONG reserved : 1;
584 ULONG iso_sched_threshold : 4;
585 ULONG eecp_capable : 8;
586 ULONG reserved2 : 16;
587
588 } EHCI_HCC_CONTENT, *PEHCI_HCC_CONTENT;
589
590 typedef struct _EHCI_CAPS {
591 UCHAR length; /* CAPLENGTH - size of this struct */
592 UCHAR reserved; /* offset 0x1 */
593 USHORT hci_version; /* HCIVERSION - offset 0x2 */
594 ULONG hcs_params; /* HCSPARAMS - offset 0x4 */
595
596 ULONG hcc_params; /* HCCPARAMS - offset 0x8 */
597 UCHAR portroute [8]; /* nibbles for routing - offset 0xC */
598
599 } EHCI_CAPS, *PEHCI_CAPS;
600
601 /* Section 2.3 Host Controller Operational Registers */
602
603 #define EHCI_USBCMD 0x00
604 #define EHCI_USBSTS 0x04
605 #define EHCI_USBINTR 0x08
606 #define EHCI_FRINDEX 0x0c
607 #define EHCI_CTRLDSSEGMENT 0x10
608 #define EHCI_PERIODICLISTBASE 0x14
609 #define EHCI_ASYNCLISTBASE 0x18
610 #define EHCI_CONFIGFLAG 0x40
611 #define EHCI_PORTSC 0x44
612
613 #define EHCI_USBINTR_INTE 0x01
614 #define EHCI_USBINTR_ERR 0x02
615 #define EHCI_USBINTR_PC 0x04
616 #define EHCI_USBINTR_FLROVR 0x08
617 #define EHCI_USBINTR_HSERR 0x10
618 #define EHCI_USBINTR_ASYNC 0x20
619
620 typedef struct _EHCI_USBCMD_CONTENT
621 {
622 ULONG run_stop : 1;
623 ULONG hcreset : 1;
624 ULONG frame_list_size : 2;
625 ULONG periodic_enable : 1;
626 ULONG async_enable : 1;
627 ULONG door_bell : 1;
628 ULONG light_reset : 1;
629 ULONG async_park_count : 2;
630 ULONG reserved : 1;
631 ULONG async_park_enable : 1;
632 ULONG reserved1 : 4;
633 ULONG int_threshold : 8;
634 ULONG reserved2 : 8;
635
636 } EHCI_USBCMD_CONTENT, *PEHCI_USBCMD_CONTENT;
637
638 typedef struct _EHCI_USBSTS_CONTENT
639 {
640 ULONG ioc : 1;
641 ULONG trasac_error : 1;
642 ULONG port_change : 1;
643 ULONG fl_rollover : 1;
644 ULONG host_system_error : 1;
645 ULONG async_advance : 1;
646 ULONG reserved : 6;
647 ULONG hc_halted : 1;
648 ULONG reclaimation : 1;
649 ULONG periodic_status : 1;
650 ULONG async_status : 1;
651 ULONG reserved1 : 16;
652
653 } EHCI_USBSTS_CONTENT, *PEHCI_USBSTS_CONTENT;
654
655 typedef struct _EHCI_RHPORTSC_CONTENT
656 {
657 ULONG cur_connect : 1;
658 ULONG cur_connect_change : 1;
659 ULONG port_enable : 1;
660 ULONG port_enable_change : 1;
661 ULONG over_current : 1;
662 ULONG over_current_change : 1;
663 ULONG force_port_resume : 1;
664 ULONG suspend : 1;
665 ULONG port_reset : 1;
666 ULONG reserved : 1;
667 ULONG line_status : 2;
668 ULONG port_power : 1;
669 ULONG port_owner : 1;
670 ULONG port_indicator : 2;
671 ULONG port_test : 4;
672 ULONG we_connect : 1;
673 ULONG we_disconnect : 1;
674 ULONG we_over_current : 1;
675 ULONG reserved1 : 9;
676
677 } EHCI_RHPORTSC_CONTENT, *PEHCI_RHPORTSC_CONTENT;
678
679 typedef struct _EHCI_REGS {
680
681 ULONG command;
682 ULONG status;
683 ULONG intr_enable;
684 ULONG frame_index; /* current microframe number */
685 ULONG segment; /* address bits 63:32 if needed */
686 ULONG frame_list; /* points to periodic list */
687 ULONG async_next; /* address of next async queue head */
688 ULONG reserved [9];
689 ULONG configured_flag;
690 ULONG port_status [0]; /* up to N_PORTS */
691
692 } EHCI_REGS, *PEHCI_REGS;
693
694 #pragma pack( pop, usb_align )
695
696 /* ehci_hcd->lock guards shared data against other CPUs:
697 * ehci_hcd: async, reclaim, periodic (and shadow), ...
698 * hcd_dev: ep[]
699 * ehci_qh: qh_next, qtd_list
700 * ehci_qtd: qtd_list
701 *
702 * Also, hold this lock when talking to HC registers or
703 * when updating hw_* fields in shared qh/qtd/... structures.
704 */
705
706 #define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */
707
708 #define EHCI_DEVICE_NAME "\\Device\\EHCI"
709
710 #define EHCI_DOS_DEVICE_NAME "\\DosDevices\\EHCI"
711
712 #define EHCI_ITD_POOL_IDX INIT_LIST_FLAG_ITD
713 #define EHCI_QH_POOL_IDX INIT_LIST_FLAG_QH
714 #define EHCI_SITD_POOL_IDX INIT_LIST_FLAG_SITD
715 #define EHCI_FSTN_POOL_IDX INIT_LIST_FLAG_FSTN
716 #define EHCI_QTD_POOL_IDX INIT_LIST_FLAG_QTD
717
718 #define EHCI_DEFAULT_FRAMES UHCI_MAX_FRAMES
719 #define EHCI_MAX_SYNC_BUS_TIME 50000 // stands for 100000 ns, only to get wrapped within one word
720
721 #define EHCI_SCHED_INT8_INDEX 0
722 #define EHCI_SCHED_INT4_INDEX 1
723 #define EHCI_SCHED_INT2_INDEX 2
724 #define EHCI_SCHED_FSTN_INDEX 3
725 #define EHCI_SCHED_INT1_INDEX 4
726
727 #define qtd_pool ( &ehci->elem_pools[ EHCI_QTD_POOL_IDX ] )
728 #define qh_pool ( &ehci->elem_pools[ EHCI_QH_POOL_IDX ] )
729 #define fstn_pool ( &ehci->elem_pools[ EHCI_FSTN_POOL_IDX ] )
730 #define itd_pool ( &ehci->elem_pools[ EHCI_ITD_POOL_IDX ] )
731 #define sitd_pool ( &ehci->elem_pools[ EHCI_SITD_POOL_IDX ] )
732
733
734 typedef struct _EHCI_DEV
735 {
736 HCD hcd_interf;
737
738 EHCI_CAPS ehci_caps;
739
740 PHYSICAL_ADDRESS ehci_reg_base; // io space
741 BOOLEAN port_mapped;
742 PBYTE port_base; // note: added by ehci_caps.length, operational regs base addr, not the actural base
743
744 ULONG frame_count;
745 PHYSICAL_ADDRESS frame_list_phys_addr;
746
747 KSPIN_LOCK frame_list_lock; // run at DIRQL
748 PULONG frame_list; // periodic schedule
749
750 PFRAME_LIST_CPU_ENTRY frame_list_cpu; // periodic schedule shadow
751
752 LIST_HEAD urb_list; // active urb-list
753
754 LIST_HEAD async_list_cpu;
755 LIST_HEAD periodic_list_cpu[ 8 ]; // each slot for one periodic
756 PEHCI_QH skel_async_qh;
757
758
759 //
760 // pools for device specific data
761 //
762 EHCI_ELEM_POOL elem_pools[ 5 ];
763
764 //
765 //for iso and int bandwidth claim, bandwidth schedule
766 //
767 KSPIN_LOCK pending_endp_list_lock; //lock to access the following two
768 LIST_HEAD pending_endp_list;
769 UHCI_PENDING_ENDP_POOL pending_endp_pool;
770 PUSHORT frame_bw; //unit uFrame
771 USHORT min_bw; //the bottle-neck of the bandwidths across frame-list
772
773 KTIMER reset_timer; //used to reset the host controller
774 struct _EHCI_DEVICE_EXTENSION *pdev_ext;
775 PUSB_DEV root_hub; //root hub
776
777 } EHCI_DEV, *PEHCI_DEV;
778
779 typedef UHCI_PORT EHCI_MEMORY;
780
781 typedef struct _EHCI_DEVICE_EXTENSION
782 {
783 //struct _USB_DEV_MANAGER *pdev_mgr;
784 DEVEXT_HEADER dev_ext_hdr;
785 PDEVICE_OBJECT pdev_obj;
786 PDRIVER_OBJECT pdrvr_obj;
787 PEHCI_DEV ehci;
788
789 //device resources
790 PADAPTER_OBJECT padapter;
791 ULONG map_regs;
792 PCM_RESOURCE_LIST res_list;
793 ULONG pci_addr; // bus number | slot number | funciton number
794 UHCI_INTERRUPT res_interrupt;
795 union
796 {
797 UHCI_PORT res_port;
798 EHCI_MEMORY res_memory;
799 };
800
801 PKINTERRUPT ehci_int;
802 KDPC ehci_dpc;
803
804 } EHCI_DEVICE_EXTENSION, *PEHCI_DEVICE_EXTENSION;
805
806 /*-------------------------------------------------------------------------*/
807
808 #endif /* __EHCI_H__ */