2 * PROJECT: ReactOS USB OHCI Miniport Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBOHCI hardware declarations
5 * COPYRIGHT: Copyright 2017-2018 Vadim Galyant <vgal@rambler.ru>
8 #define OHCI_NUMBER_OF_INTERRUPTS 32
9 #define OHCI_MAX_PORT_COUNT 15
11 #define OHCI_MAXIMUM_OVERHEAD 210 // 5.4 FrameInterval Counter, in bit-times
12 #define OHCI_DEFAULT_FRAME_INTERVAL 11999 // 6.3.1 Frame Timing
13 #define OHCI_MINIMAL_POTPGT 25 // == 50 ms., PowerOnToPowerGoodTime (HcRhDescriptorA Register)
15 /* Controller states */
16 #define OHCI_HC_STATE_RESET 0
17 #define OHCI_HC_STATE_RESUME 1
18 #define OHCI_HC_STATE_OPERATIONAL 2
19 #define OHCI_HC_STATE_SUSPEND 3
21 /* Endpoint Descriptor Control */
22 #define OHCI_ED_DATA_FLOW_DIRECTION_FROM_TD 0
23 #define OHCI_ED_DATA_FLOW_DIRECTION_OUT 1
24 #define OHCI_ED_DATA_FLOW_DIRECTION_IN 2
26 #define OHCI_ENDPOINT_FULL_SPEED 0
27 #define OHCI_ENDPOINT_LOW_SPEED 1
29 #define OHCI_ENDPOINT_GENERAL_FORMAT 0
30 #define OHCI_ENDPOINT_ISOCHRONOUS_FORMAT 1
32 /* Transfer Descriptor Control */
33 #define OHCI_TD_INTERRUPT_IMMEDIATE 0
34 #define OHCI_TD_INTERRUPT_NONE 7
36 #define OHCI_TD_DIRECTION_PID_SETUP 0
37 #define OHCI_TD_DIRECTION_PID_OUT 1
38 #define OHCI_TD_DIRECTION_PID_IN 2
39 #define OHCI_TD_DIRECTION_PID_RESERVED 3
41 #define OHCI_TD_DATA_TOGGLE_FROM_ED 0
42 #define OHCI_TD_DATA_TOGGLE_DATA0 2
43 #define OHCI_TD_DATA_TOGGLE_DATA1 3
45 #define OHCI_TD_CONDITION_NO_ERROR 0x00
46 #define OHCI_TD_CONDITION_CRC_ERROR 0x01
47 #define OHCI_TD_CONDITION_BIT_STUFFING 0x02
48 #define OHCI_TD_CONDITION_TOGGLE_MISMATCH 0x03
49 #define OHCI_TD_CONDITION_STALL 0x04
50 #define OHCI_TD_CONDITION_NO_RESPONSE 0x05
51 #define OHCI_TD_CONDITION_PID_CHECK_FAILURE 0x06
52 #define OHCI_TD_CONDITION_UNEXPECTED_PID 0x07
53 #define OHCI_TD_CONDITION_DATA_OVERRUN 0x08
54 #define OHCI_TD_CONDITION_DATA_UNDERRUN 0x09
55 #define OHCI_TD_CONDITION_BUFFER_OVERRUN 0x0C
56 #define OHCI_TD_CONDITION_BUFFER_UNDERRUN 0x0D
57 #define OHCI_TD_CONDITION_NOT_ACCESSED 0x0E
59 typedef union _OHCI_TRANSFER_CONTROL
{
62 ULONG BufferRounding
: 1;
63 ULONG DirectionPID
: 2;
64 ULONG DelayInterrupt
: 3;
67 ULONG ConditionCode
: 4;
70 } OHCI_TRANSFER_CONTROL
, *POHCI_TRANSFER_CONTROL
;
72 C_ASSERT(sizeof(OHCI_TRANSFER_CONTROL
) == sizeof(ULONG
));
74 typedef struct _OHCI_TRANSFER_DESCRIPTOR
{ // must be aligned to a 16-byte boundary
75 OHCI_TRANSFER_CONTROL Control
;
76 ULONG CurrentBuffer
; // physical address of the next memory location
77 ULONG NextTD
; // pointer to the next TD on the list of TDs
78 ULONG BufferEnd
; // physical address of the last byte
79 } OHCI_TRANSFER_DESCRIPTOR
, *POHCI_TRANSFER_DESCRIPTOR
;
81 C_ASSERT(sizeof(OHCI_TRANSFER_DESCRIPTOR
) == 16);
83 typedef union _OHCI_ISO_TRANSFER_CONTROL
{
85 ULONG StartingFrame
: 16;
87 ULONG DelayInterrupt
: 3;
90 ULONG ConditionCode
: 4;
93 } OHCI_ISO_TRANSFER_CONTROL
, *POHCI_ISO_TRANSFER_CONTROL
;
95 C_ASSERT(sizeof(OHCI_ISO_TRANSFER_CONTROL
) == sizeof(ULONG
));
97 typedef struct _OHCI_ISO_TRANSFER_DESCRIPTOR
{ // must be aligned to a 32-byte boundary
98 OHCI_ISO_TRANSFER_CONTROL Control
;
99 ULONG BufferPage0
; // physical page number of the 1 byte of the data buffer
100 ULONG NextTD
; // pointer to the next Isochronous TD on the queue of Isochronous TDs
101 ULONG BufferEnd
; // physical address of the last byte in the buffer
102 USHORT Offset
[8]; // for determine size and start addr. iso packet | PacketStatusWord - completion code
103 } OHCI_ISO_TRANSFER_DESCRIPTOR
, *POHCI_ISO_TRANSFER_DESCRIPTOR
;
105 C_ASSERT(sizeof(OHCI_ISO_TRANSFER_DESCRIPTOR
) == 32);
107 typedef union _OHCI_ENDPOINT_CONTROL
{
109 ULONG FunctionAddress
: 7;
110 ULONG EndpointNumber
: 4;
115 ULONG MaximumPacketSize
: 11;
119 } OHCI_ENDPOINT_CONTROL
, *POHCI_ENDPOINT_CONTROL
;
121 C_ASSERT(sizeof(OHCI_ENDPOINT_CONTROL
) == sizeof(ULONG
));
123 /* Bit flags for HeadPointer member of the EP descriptor */
124 #define OHCI_ED_HEAD_POINTER_HALT 0x00000001 // hardware stopped bit
125 #define OHCI_ED_HEAD_POINTER_CARRY 0x00000002 // hardware toggle carry bit
126 #define OHCI_ED_HEAD_POINTER_MASK 0XFFFFFFF0 // mask physical pointer
127 #define OHCI_ED_HEAD_POINTER_FLAGS_MASK 0X0000000F // mask bit flags
129 typedef struct _OHCI_ENDPOINT_DESCRIPTOR
{ // must be aligned to a 16-byte boundary
130 OHCI_ENDPOINT_CONTROL EndpointControl
;
131 ULONG TailPointer
; // if TailP and HeadP are different, then the list contains a TD to be processed
132 ULONG HeadPointer
; // physical pointer to the next TD to be processed for this endpoint
133 ULONG NextED
; // entry points to the next ED on the list
134 } OHCI_ENDPOINT_DESCRIPTOR
, *POHCI_ENDPOINT_DESCRIPTOR
;
136 C_ASSERT(sizeof(OHCI_ENDPOINT_DESCRIPTOR
) == 16);
138 typedef struct _OHCI_HCCA
{ // must be located on a 256-byte boundary
139 ULONG InterrruptTable
[OHCI_NUMBER_OF_INTERRUPTS
];
143 UCHAR reserved_hc
[116];
145 } OHCI_HCCA
, *POHCI_HCCA
;
147 C_ASSERT(sizeof(OHCI_HCCA
) == 256);
149 typedef union _OHCI_REG_CONTROL
{
151 ULONG ControlBulkServiceRatio
: 2;
152 ULONG PeriodicListEnable
: 1;
153 ULONG IsochronousEnable
: 1;
154 ULONG ControlListEnable
: 1;
155 ULONG BulkListEnable
: 1;
156 ULONG HostControllerFunctionalState
: 2;
157 ULONG InterruptRouting
: 1;
158 ULONG RemoteWakeupConnected
: 1;
159 ULONG RemoteWakeupEnable
: 1;
163 } OHCI_REG_CONTROL
, *POHCI_REG_CONTROL
;
165 C_ASSERT(sizeof(OHCI_REG_CONTROL
) == sizeof(ULONG
));
167 typedef union _OHCI_REG_COMMAND_STATUS
{
169 ULONG HostControllerReset
: 1;
170 ULONG ControlListFilled
: 1;
171 ULONG BulkListFilled
: 1;
172 ULONG OwnershipChangeRequest
: 1;
173 ULONG Reserved1
: 12;
174 ULONG SchedulingOverrunCount
: 1;
175 ULONG Reserved2
: 15;
178 } OHCI_REG_COMMAND_STATUS
, *POHCI_REG_COMMAND_STATUS
;
180 C_ASSERT(sizeof(OHCI_REG_COMMAND_STATUS
) == sizeof(ULONG
));
182 typedef union _OHCI_REG_INTERRUPT_STATUS
{
184 ULONG SchedulingOverrun
: 1;
185 ULONG WritebackDoneHead
: 1;
186 ULONG StartofFrame
: 1;
187 ULONG ResumeDetected
: 1;
188 ULONG UnrecoverableError
: 1;
189 ULONG FrameNumberOverflow
: 1;
190 ULONG RootHubStatusChange
: 1;
191 ULONG Reserved1
: 23;
192 ULONG OwnershipChange
: 1;
196 } OHCI_REG_INTERRUPT_STATUS
, *POHCI_REG_INTERRUPT_STATUS
;
198 C_ASSERT(sizeof(OHCI_REG_INTERRUPT_STATUS
) == sizeof(ULONG
));
200 typedef union _OHCI_REG_INTERRUPT_ENABLE_DISABLE
{
202 ULONG SchedulingOverrun
: 1;
203 ULONG WritebackDoneHead
: 1;
204 ULONG StartofFrame
: 1;
205 ULONG ResumeDetected
: 1;
206 ULONG UnrecoverableError
: 1;
207 ULONG FrameNumberOverflow
: 1;
208 ULONG RootHubStatusChange
: 1;
209 ULONG Reserved1
: 23;
210 ULONG OwnershipChange
: 1;
211 ULONG MasterInterruptEnable
: 1;
214 } OHCI_REG_INTERRUPT_ENABLE_DISABLE
, *POHCI_REG_INTERRUPT_ENABLE_DISABLE
;
216 C_ASSERT(sizeof(OHCI_REG_INTERRUPT_ENABLE_DISABLE
) == sizeof(ULONG
));
218 typedef union _OHCI_REG_FRAME_INTERVAL
{
220 ULONG FrameInterval
: 14;
222 ULONG FSLargestDataPacket
: 15;
223 ULONG FrameIntervalToggle
: 1;
226 } OHCI_REG_FRAME_INTERVAL
, *POHCI_REG_FRAME_INTERVAL
;
228 C_ASSERT(sizeof(OHCI_REG_FRAME_INTERVAL
) == sizeof(ULONG
));
230 typedef union _OHCI_REG_RH_DESCRIPTORA
{
232 ULONG NumberDownstreamPorts
: 8;
233 ULONG PowerSwitchingMode
: 1;
234 ULONG NoPowerSwitching
: 1;
235 ULONG DeviceType
: 1;
236 ULONG OverCurrentProtectionMode
: 1;
237 ULONG NoOverCurrentProtection
: 1;
239 ULONG PowerOnToPowerGoodTime
: 8;
242 } OHCI_REG_RH_DESCRIPTORA
, *POHCI_REG_RH_DESCRIPTORA
;
244 C_ASSERT(sizeof(OHCI_REG_RH_DESCRIPTORA
) == sizeof(ULONG
));
246 typedef union _OHCI_REG_RH_STATUS
{
249 ULONG LocalPowerStatus
: 1;
250 ULONG OverCurrentIndicator
: 1;
251 ULONG Reserved10
: 13;
252 ULONG DeviceRemoteWakeupEnable
: 1;
253 ULONG LocalPowerStatusChange
: 1;
254 ULONG OverCurrentIndicatorChangeR
: 1;
255 ULONG Reserved20
: 14;
258 ULONG ClearGlobalPower
: 1;
259 ULONG Reserved11
: 14;
260 ULONG SetRemoteWakeupEnable
: 1;
261 ULONG SetGlobalPower
: 1;
262 ULONG OverCurrentIndicatorChangeW
: 1;
263 ULONG Reserved22
: 13;
264 ULONG ClearRemoteWakeupEnable
: 1;
268 } OHCI_REG_RH_STATUS
, *POHCI_REG_RH_STATUS
;
270 C_ASSERT(sizeof(OHCI_REG_RH_STATUS
) == sizeof(ULONG
));
272 typedef union _OHCI_REG_RH_PORT_STATUS
{
276 USHORT CurrentConnectStatus
: 1;
277 USHORT PortEnableStatus
: 1;
278 USHORT PortSuspendStatus
: 1;
279 USHORT PortOverCurrentIndicator
: 1;
280 USHORT PortResetStatus
: 1;
281 USHORT Reserved1r
: 3;
282 USHORT PortPowerStatus
: 1;
283 USHORT LowSpeedDeviceAttached
: 1;
284 USHORT Reserved2r
: 6;
287 USHORT ClearPortEnable
: 1;
288 USHORT SetPortEnable
: 1;
289 USHORT SetPortSuspend
: 1;
290 USHORT ClearSuspendStatus
: 1;
291 USHORT SetPortReset
: 1;
292 USHORT Reserved1w
: 3;
293 USHORT SetPortPower
: 1;
294 USHORT ClearPortPower
: 1;
295 USHORT Reserved2w
: 6;
298 USHORT ConnectStatusChange
: 1;
299 USHORT PortEnableStatusChange
: 1;
300 USHORT PortSuspendStatusChange
: 1;
301 USHORT PortOverCurrentIndicatorChange
: 1;
302 USHORT PortResetStatusChange
: 1;
303 USHORT Reserved3
: 11;
306 } OHCI_REG_RH_PORT_STATUS
, *POHCI_REG_RH_PORT_STATUS
;
308 C_ASSERT(sizeof(OHCI_REG_RH_PORT_STATUS
) == sizeof(ULONG
));
310 typedef struct _OHCI_OPERATIONAL_REGISTERS
{
312 OHCI_REG_CONTROL HcControl
;
313 OHCI_REG_COMMAND_STATUS HcCommandStatus
;
314 OHCI_REG_INTERRUPT_STATUS HcInterruptStatus
;
315 OHCI_REG_INTERRUPT_ENABLE_DISABLE HcInterruptEnable
;
316 OHCI_REG_INTERRUPT_ENABLE_DISABLE HcInterruptDisable
;
318 ULONG HcPeriodCurrentED
;
319 ULONG HcControlHeadED
;
320 ULONG HcControlCurrentED
;
322 ULONG HcBulkCurrentED
;
324 OHCI_REG_FRAME_INTERVAL HcFmInterval
;
327 ULONG HcPeriodicStart
;
329 OHCI_REG_RH_DESCRIPTORA HcRhDescriptorA
;
330 ULONG HcRhDescriptorB
;
331 OHCI_REG_RH_STATUS HcRhStatus
;
332 OHCI_REG_RH_PORT_STATUS HcRhPortStatus
[OHCI_MAX_PORT_COUNT
];
333 } OHCI_OPERATIONAL_REGISTERS
, *POHCI_OPERATIONAL_REGISTERS
;