2 * PROJECT: ReactOS USB EHCI Miniport Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBEHCI hardware declarations
5 * COPYRIGHT: Copyright 2017-2018 Vadim Galyant <vgal@rambler.ru>
8 #define EHCI_FRAME_LIST_MAX_ENTRIES 1024 // Number of frames in Frame List
10 /* EHCI hardware registers */
13 #define EHCI_USBINTR 2
14 #define EHCI_FRINDEX 3
15 #define EHCI_CTRLDSSEGMENT 4
16 #define EHCI_PERIODICLISTBASE 5
17 #define EHCI_ASYNCLISTBASE 6
18 #define EHCI_CONFIGFLAG 16
19 #define EHCI_PORTSC 17
21 #define EHCI_FLADJ_PCI_CONFIG_OFFSET 0x61
23 typedef union _EHCI_LEGACY_EXTENDED_CAPABILITY
{
25 ULONG CapabilityID
: 8;
26 ULONG NextCapabilityPointer
: 8;
27 ULONG BiosOwnedSemaphore
: 1;
29 ULONG OsOwnedSemaphore
: 1;
33 } EHCI_LEGACY_EXTENDED_CAPABILITY
;
35 C_ASSERT(sizeof(EHCI_LEGACY_EXTENDED_CAPABILITY
) == sizeof(ULONG
));
37 typedef union _EHCI_HC_STRUCTURAL_PARAMS
{
40 ULONG PortPowerControl
: 1;
42 ULONG PortRouteRules
: 1;
43 ULONG PortsPerCompanion
: 4;
44 ULONG CompanionControllers
: 4;
45 ULONG PortIndicators
: 1;
47 ULONG DebugPortNumber
: 4; //Optional
51 } EHCI_HC_STRUCTURAL_PARAMS
;
53 C_ASSERT(sizeof(EHCI_HC_STRUCTURAL_PARAMS
) == sizeof(ULONG
));
55 typedef union _EHCI_HC_CAPABILITY_PARAMS
{
57 ULONG Addressing64bitCapability
: 1;
58 ULONG IsProgrammableFrameList
: 1;
59 ULONG IsScheduleParkSupport
: 1;
61 ULONG IsoSchedulingThreshold
: 4;
62 ULONG ExtCapabilitiesPointer
: 8; // (EECP)
66 } EHCI_HC_CAPABILITY_PARAMS
;
68 C_ASSERT(sizeof(EHCI_HC_CAPABILITY_PARAMS
) == sizeof(ULONG
));
70 typedef struct _EHCI_HC_CAPABILITY_REGISTERS
{
71 UCHAR RegistersLength
; // RO
73 USHORT InterfaceVersion
; // RO
74 EHCI_HC_STRUCTURAL_PARAMS StructParameters
; // RO
75 EHCI_HC_CAPABILITY_PARAMS CapParameters
; // RO
76 UCHAR CompanionPortRouteDesc
[8]; // RO
77 } EHCI_HC_CAPABILITY_REGISTERS
, *PEHCI_HC_CAPABILITY_REGISTERS
;
79 typedef union _EHCI_USB_COMMAND
{
83 ULONG FrameListSize
: 2;
84 ULONG PeriodicEnable
: 1;
85 ULONG AsynchronousEnable
: 1;
86 ULONG InterruptAdvanceDoorbell
: 1;
87 ULONG LightResetHC
: 1; // optional
88 ULONG AsynchronousParkModeCount
: 2; // optional
90 ULONG AsynchronousParkModeEnable
: 1; // optional
92 ULONG InterruptThreshold
: 8;
98 C_ASSERT(sizeof(EHCI_USB_COMMAND
) == sizeof(ULONG
));
100 typedef union _EHCI_USB_STATUS
{
103 ULONG ErrorInterrupt
: 1;
104 ULONG PortChangeDetect
: 1;
105 ULONG FrameListRollover
: 1;
106 ULONG HostSystemError
: 1;
107 ULONG InterruptOnAsyncAdvance
: 1;
110 ULONG Reclamation
: 1;
111 ULONG PeriodicStatus
: 1;
112 ULONG AsynchronousStatus
: 1;
113 ULONG Reserved2
: 16;
118 C_ASSERT(sizeof(EHCI_USB_STATUS
) == sizeof(ULONG
));
120 #define EHCI_INTERRUPT_MASK 0x3F
122 typedef union _EHCI_INTERRUPT_ENABLE
{
125 ULONG ErrorInterrupt
: 1;
126 ULONG PortChangeInterrupt
: 1;
127 ULONG FrameListRollover
: 1;
128 ULONG HostSystemError
: 1;
129 ULONG InterruptOnAsyncAdvance
: 1;
133 } EHCI_INTERRUPT_ENABLE
;
135 C_ASSERT(sizeof(EHCI_INTERRUPT_ENABLE
) == sizeof(ULONG
));
137 #define EHCI_LINE_STATUS_K_STATE_LOW_SPEED 1
138 #define EHCI_PORT_OWNER_COMPANION_CONTROLLER 1
140 typedef union _EHCI_PORT_STATUS_CONTROL
{
142 ULONG CurrentConnectStatus
: 1;
143 ULONG ConnectStatusChange
: 1;
144 ULONG PortEnabledDisabled
: 1;
145 ULONG PortEnableDisableChange
: 1;
146 ULONG OverCurrentActive
: 1;
147 ULONG OverCurrentChange
: 1;
148 ULONG ForcePortResume
: 1;
152 ULONG LineStatus
: 2;
155 ULONG PortIndicatorControl
: 2;
156 ULONG PortTestControl
: 4;
157 ULONG WakeOnConnectEnable
: 1;
158 ULONG WakeOnDisconnectEnable
: 1;
159 ULONG WakeOnOverCurrentEnable
: 1;
163 } EHCI_PORT_STATUS_CONTROL
;
165 C_ASSERT(sizeof(EHCI_PORT_STATUS_CONTROL
) == sizeof(ULONG
));
167 /* FRINDEX Frame Index Register */
168 #define EHCI_FRINDEX_FRAME_MASK 0x7FF
169 #define EHCI_FRINDEX_INDEX_MASK 0x3FF
171 #define EHCI_CONFIG_FLAG_CONFIGURED 1
173 typedef struct _EHCI_HW_REGISTERS
{
174 EHCI_USB_COMMAND HcCommand
; // RO, R/W (field dependent), WO
175 EHCI_USB_STATUS HcStatus
; // RO, R/W, R/WC, (field dependent)
176 EHCI_INTERRUPT_ENABLE HcInterruptEnable
; // R/W
177 ULONG FrameIndex
; // R/W (Writes must be DWord Writes)
178 ULONG SegmentSelector
; // R/W (Writes must be DWord Writes)
179 ULONG PeriodicListBase
; // R/W (Writes must be DWord Writes)
180 ULONG AsyncListBase
; // Read/Write (Writes must be DWord Writes)
182 ULONG ConfigFlag
; // R/W
183 EHCI_PORT_STATUS_CONTROL PortControl
[15]; // (1-15) RO, R/W, R/WC (field dependent)
184 } EHCI_HW_REGISTERS
, *PEHCI_HW_REGISTERS
;
187 #define EHCI_LINK_TYPE_iTD 0 // isochronous transfer descriptor
188 #define EHCI_LINK_TYPE_QH 1 // queue head
189 #define EHCI_LINK_TYPE_siTD 2 // split transaction isochronous transfer
190 #define EHCI_LINK_TYPE_FSTN 3 // frame span traversal node
192 /* Used for QHs and qTDs to mark Pointers as the end */
193 #define TERMINATE_POINTER 1
195 #define LINK_POINTER_MASK 0xFFFFFFE0
197 typedef union _EHCI_LINK_POINTER
{
207 C_ASSERT(sizeof(EHCI_LINK_POINTER
) == sizeof(ULONG
));
209 /* Isochronous (High-Speed) Transfer Descriptor (iTD) */
210 typedef union _EHCI_TRANSACTION_CONTROL
{
213 ULONG PageSelect
: 3;
214 ULONG InterruptOnComplete
: 1;
219 } EHCI_TRANSACTION_CONTROL
;
221 C_ASSERT(sizeof(EHCI_TRANSACTION_CONTROL
) == sizeof(ULONG
));
223 typedef union _EHCI_TRANSACTION_BUFFER
{
225 ULONG DeviceAddress
: 7;
227 ULONG EndpointNumber
: 4;
228 ULONG DataBuffer0
: 20;
231 ULONG MaximumPacketSize
: 11;
233 ULONG DataBuffer1
: 20;
237 ULONG Reserved2
: 10;
238 ULONG DataBuffer2
: 20;
241 ULONG Reserved3
: 12;
242 ULONG DataBuffer
: 20;
245 } EHCI_TRANSACTION_BUFFER
;
247 C_ASSERT(sizeof(EHCI_TRANSACTION_BUFFER
) == sizeof(ULONG
));
249 typedef struct _EHCI_ISOCHRONOUS_TD
{ // must be aligned on a 32-byte boundary
250 EHCI_LINK_POINTER NextLink
;
251 EHCI_TRANSACTION_CONTROL Transaction
[8];
252 EHCI_TRANSACTION_BUFFER Buffer
[7];
253 ULONG ExtendedBuffer
[7];
254 } EHCI_ISOCHRONOUS_TD
, *PEHCI_ISOCHRONOUS_TD
;
256 C_ASSERT(sizeof(EHCI_ISOCHRONOUS_TD
) == 92);
258 /* Split Transaction Isochronous Transfer Descriptor (siTD) */
259 typedef union _EHCI_FS_ENDPOINT_PARAMS
{
261 ULONG DeviceAddress
: 7;
263 ULONG EndpointNumber
: 4;
265 ULONG HubAddress
: 7;
267 ULONG PortNumber
: 7;
271 } EHCI_FS_ENDPOINT_PARAMS
;
273 C_ASSERT(sizeof(EHCI_FS_ENDPOINT_PARAMS
) == sizeof(ULONG
));
275 typedef union _EHCI_MICROFRAME_CONTROL
{
278 ULONG CompletionMask
: 8;
282 } EHCI_MICROFRAME_CONTROL
;
284 C_ASSERT(sizeof(EHCI_MICROFRAME_CONTROL
) == sizeof(ULONG
));
286 typedef union _EHCI_SPLIT_TRANSFER_STATE
{
289 ULONG ProgressMask
: 8;
290 ULONG TotalBytes
: 10;
292 ULONG PageSelect
: 1;
293 ULONG InterruptOnComplete
: 1;
296 } EHCI_SPLIT_TRANSFER_STATE
;
298 C_ASSERT(sizeof(EHCI_SPLIT_TRANSFER_STATE
) == sizeof(ULONG
));
300 typedef union _EHCI_SPLIT_BUFFER_POINTER
{
302 ULONG CurrentOffset
: 12;
303 ULONG DataBuffer0
: 20;
306 ULONG TransactionCount
: 3;
307 ULONG TransactionPosition
: 2;
309 ULONG DataBuffer1
: 20;
312 } EHCI_SPLIT_BUFFER_POINTER
;
314 C_ASSERT(sizeof(EHCI_SPLIT_BUFFER_POINTER
) == sizeof(ULONG
));
316 typedef struct _EHCI_SPLIT_ISOCHRONOUS_TD
{ // must be aligned on a 32-byte boundary
317 EHCI_LINK_POINTER NextLink
;
318 EHCI_FS_ENDPOINT_PARAMS EndpointCharacteristics
;
319 EHCI_MICROFRAME_CONTROL MicroFrameControl
;
320 EHCI_SPLIT_TRANSFER_STATE TransferState
;
321 EHCI_SPLIT_BUFFER_POINTER Buffer
[2];
323 ULONG ExtendedBuffer
[2];
324 } EHCI_SPLIT_ISOCHRONOUS_TD
, *PEHCI_SPLIT_ISOCHRONOUS_TD
;
326 C_ASSERT(sizeof(EHCI_SPLIT_ISOCHRONOUS_TD
) == 36);
328 /* Queue Element Transfer Descriptor (qTD) */
329 #define EHCI_MAX_QTD_BUFFER_PAGES 5
331 #define EHCI_TOKEN_STATUS_ACTIVE (1 << 7)
332 #define EHCI_TOKEN_STATUS_HALTED (1 << 6)
333 #define EHCI_TOKEN_STATUS_DATA_BUFFER_ERROR (1 << 5)
334 #define EHCI_TOKEN_STATUS_BABBLE_DETECTED (1 << 4)
335 #define EHCI_TOKEN_STATUS_TRANSACTION_ERROR (1 << 3)
336 #define EHCI_TOKEN_STATUS_MISSED_MICROFRAME (1 << 2)
337 #define EHCI_TOKEN_STATUS_SPLIT_STATE (1 << 1)
338 #define EHCI_TOKEN_STATUS_PING_STATE (1 << 0)
340 #define EHCI_TD_TOKEN_PID_OUT 0
341 #define EHCI_TD_TOKEN_PID_IN 1
342 #define EHCI_TD_TOKEN_PID_SETUP 2
343 #define EHCI_TD_TOKEN_PID_RESERVED 3
345 typedef union _EHCI_TD_TOKEN
{
349 ULONG ErrorCounter
: 2;
350 ULONG CurrentPage
: 3;
351 ULONG InterruptOnComplete
: 1;
352 ULONG TransferBytes
: 15;
353 ULONG DataToggle
: 1;
356 } EHCI_TD_TOKEN
, *PEHCI_TD_TOKEN
;
358 C_ASSERT(sizeof(EHCI_TD_TOKEN
) == sizeof(ULONG
));
360 typedef struct _EHCI_QUEUE_TD
{ // must be aligned on 32-byte boundaries
362 ULONG AlternateNextTD
;
365 ULONG ExtendedBuffer
[5];
366 } EHCI_QUEUE_TD
, *PEHCI_QUEUE_TD
;
368 C_ASSERT(sizeof(EHCI_QUEUE_TD
) == 52);
371 #define EHCI_QH_EP_FULL_SPEED 0
372 #define EHCI_QH_EP_LOW_SPEED 1
373 #define EHCI_QH_EP_HIGH_SPEED 2
375 typedef union _EHCI_QH_EP_PARAMS
{
377 ULONG DeviceAddress
: 7;
378 ULONG InactivateOnNextTransaction
: 1;
379 ULONG EndpointNumber
: 4;
380 ULONG EndpointSpeed
: 2;
381 ULONG DataToggleControl
: 1;
382 ULONG HeadReclamationListFlag
: 1;
383 ULONG MaximumPacketLength
: 11; // corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize).
384 ULONG ControlEndpointFlag
: 1;
385 ULONG NakCountReload
: 4;
390 C_ASSERT(sizeof(EHCI_QH_EP_PARAMS
) == sizeof(ULONG
));
392 typedef union _EHCI_QH_EP_CAPS
{
394 ULONG InterruptMask
: 8;
395 ULONG SplitCompletionMask
: 8;
397 ULONG PortNumber
: 7;
398 ULONG PipeMultiplier
: 2;
403 C_ASSERT(sizeof(EHCI_QH_EP_CAPS
) == sizeof(ULONG
));
405 typedef struct _EHCI_QUEUE_HEAD
{ // must be aligned on 32-byte boundaries
406 EHCI_LINK_POINTER HorizontalLink
;
407 EHCI_QH_EP_PARAMS EndpointParams
;
408 EHCI_QH_EP_CAPS EndpointCaps
;
411 ULONG AlternateNextTD
;
414 ULONG ExtendedBuffer
[5];
415 } EHCI_QUEUE_HEAD
, *PEHCI_QUEUE_HEAD
;
417 C_ASSERT(sizeof(EHCI_QUEUE_HEAD
) == 68);