[USBOHCI_NEW] Add license headers.
[reactos.git] / drivers / usb / usbohci_new / hardware.h
1 /*
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>
6 */
7
8 #define OHCI_NUMBER_OF_INTERRUPTS 32
9 #define OHCI_MAX_PORT_COUNT 15
10 #define ED_EOF -1
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)
14
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
20
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
25
26 #define OHCI_ENDPOINT_FULL_SPEED 0
27 #define OHCI_ENDPOINT_LOW_SPEED 1
28
29 #define OHCI_ENDPOINT_GENERAL_FORMAT 0
30 #define OHCI_ENDPOINT_ISOCHRONOUS_FORMAT 1
31
32 /* Transfer Descriptor Control */
33 #define OHCI_TD_INTERRUPT_IMMEDIATE 0
34 #define OHCI_TD_INTERRUPT_NONE 7
35
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
40
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
44
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
58
59 typedef union _OHCI_TRANSFER_CONTROL {
60 struct {
61 ULONG Reserved : 18;
62 ULONG BufferRounding : 1;
63 ULONG DirectionPID : 2;
64 ULONG DelayInterrupt : 3;
65 ULONG DataToggle : 2;
66 ULONG ErrorCount : 2;
67 ULONG ConditionCode : 4;
68 };
69 ULONG AsULONG;
70 } OHCI_TRANSFER_CONTROL, *POHCI_TRANSFER_CONTROL;
71
72 C_ASSERT(sizeof(OHCI_TRANSFER_CONTROL) == sizeof(ULONG));
73
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;
80
81 C_ASSERT(sizeof(OHCI_TRANSFER_DESCRIPTOR) == 16);
82
83 typedef union _OHCI_ISO_TRANSFER_CONTROL {
84 struct {
85 ULONG StartingFrame : 16;
86 ULONG Reserved1 : 5;
87 ULONG DelayInterrupt : 3;
88 ULONG FrameCount : 3;
89 ULONG Reserved2 : 1;
90 ULONG ConditionCode : 4;
91 };
92 ULONG AsULONG;
93 } OHCI_ISO_TRANSFER_CONTROL, *POHCI_ISO_TRANSFER_CONTROL;
94
95 C_ASSERT(sizeof(OHCI_ISO_TRANSFER_CONTROL) == sizeof(ULONG));
96
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;
104
105 C_ASSERT(sizeof(OHCI_ISO_TRANSFER_DESCRIPTOR) == 32);
106
107 typedef union _OHCI_ENDPOINT_CONTROL {
108 struct {
109 ULONG FunctionAddress : 7;
110 ULONG EndpointNumber : 4;
111 ULONG Direction : 2;
112 ULONG Speed : 1;
113 ULONG sKip : 1;
114 ULONG Format : 1;
115 ULONG MaximumPacketSize : 11;
116 ULONG Reserved : 5;
117 };
118 ULONG AsULONG;
119 } OHCI_ENDPOINT_CONTROL, *POHCI_ENDPOINT_CONTROL;
120
121 C_ASSERT(sizeof(OHCI_ENDPOINT_CONTROL) == sizeof(ULONG));
122
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
128
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;
135
136 C_ASSERT(sizeof(OHCI_ENDPOINT_DESCRIPTOR) == 16);
137
138 typedef struct _OHCI_HCCA { // must be located on a 256-byte boundary
139 ULONG InterrruptTable[OHCI_NUMBER_OF_INTERRUPTS];
140 USHORT FrameNumber;
141 USHORT Pad1;
142 ULONG DoneHead;
143 UCHAR reserved_hc[116];
144 UCHAR Pad[4];
145 } OHCI_HCCA, *POHCI_HCCA;
146
147 C_ASSERT(sizeof(OHCI_HCCA) == 256);
148
149 typedef union _OHCI_REG_CONTROL {
150 struct {
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;
160 ULONG Reserved : 21;
161 };
162 ULONG AsULONG;
163 } OHCI_REG_CONTROL, *POHCI_REG_CONTROL;
164
165 C_ASSERT(sizeof(OHCI_REG_CONTROL) == sizeof(ULONG));
166
167 typedef union _OHCI_REG_COMMAND_STATUS {
168 struct {
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;
176 };
177 ULONG AsULONG;
178 } OHCI_REG_COMMAND_STATUS, *POHCI_REG_COMMAND_STATUS;
179
180 C_ASSERT(sizeof(OHCI_REG_COMMAND_STATUS) == sizeof(ULONG));
181
182 typedef union _OHCI_REG_INTERRUPT_STATUS {
183 struct {
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;
193 ULONG Reserved2 : 1;
194 };
195 ULONG AsULONG;
196 } OHCI_REG_INTERRUPT_STATUS, *POHCI_REG_INTERRUPT_STATUS;
197
198 C_ASSERT(sizeof(OHCI_REG_INTERRUPT_STATUS) == sizeof(ULONG));
199
200 typedef union _OHCI_REG_INTERRUPT_ENABLE_DISABLE {
201 struct {
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;
212 };
213 ULONG AsULONG;
214 } OHCI_REG_INTERRUPT_ENABLE_DISABLE, *POHCI_REG_INTERRUPT_ENABLE_DISABLE;
215
216 C_ASSERT(sizeof(OHCI_REG_INTERRUPT_ENABLE_DISABLE) == sizeof(ULONG));
217
218 typedef union _OHCI_REG_FRAME_INTERVAL {
219 struct {
220 ULONG FrameInterval : 14;
221 ULONG Reserved : 2;
222 ULONG FSLargestDataPacket : 15;
223 ULONG FrameIntervalToggle : 1;
224 };
225 ULONG AsULONG;
226 } OHCI_REG_FRAME_INTERVAL, *POHCI_REG_FRAME_INTERVAL;
227
228 C_ASSERT(sizeof(OHCI_REG_FRAME_INTERVAL) == sizeof(ULONG));
229
230 typedef union _OHCI_REG_RH_DESCRIPTORA {
231 struct {
232 ULONG NumberDownstreamPorts : 8;
233 ULONG PowerSwitchingMode : 1;
234 ULONG NoPowerSwitching : 1;
235 ULONG DeviceType : 1;
236 ULONG OverCurrentProtectionMode : 1;
237 ULONG NoOverCurrentProtection : 1;
238 ULONG Reserved : 11;
239 ULONG PowerOnToPowerGoodTime : 8;
240 };
241 ULONG AsULONG;
242 } OHCI_REG_RH_DESCRIPTORA, *POHCI_REG_RH_DESCRIPTORA;
243
244 C_ASSERT(sizeof(OHCI_REG_RH_DESCRIPTORA) == sizeof(ULONG));
245
246 typedef union _OHCI_REG_RH_STATUS {
247 union {
248 struct { // read
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;
256 };
257 struct { // write
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;
265 };
266 };
267 ULONG AsULONG;
268 } OHCI_REG_RH_STATUS, *POHCI_REG_RH_STATUS;
269
270 C_ASSERT(sizeof(OHCI_REG_RH_STATUS) == sizeof(ULONG));
271
272 typedef union _OHCI_REG_RH_PORT_STATUS {
273 struct {
274 union {
275 struct { // read
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;
285 };
286 struct { // write
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;
296 };
297 };
298 USHORT ConnectStatusChange : 1;
299 USHORT PortEnableStatusChange : 1;
300 USHORT PortSuspendStatusChange : 1;
301 USHORT PortOverCurrentIndicatorChange : 1;
302 USHORT PortResetStatusChange : 1;
303 USHORT Reserved3 : 11;
304 };
305 ULONG AsULONG;
306 } OHCI_REG_RH_PORT_STATUS, *POHCI_REG_RH_PORT_STATUS;
307
308 C_ASSERT(sizeof(OHCI_REG_RH_PORT_STATUS) == sizeof(ULONG));
309
310 typedef struct _OHCI_OPERATIONAL_REGISTERS {
311 ULONG HcRevision;
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;
317 ULONG HcHCCA;
318 ULONG HcPeriodCurrentED;
319 ULONG HcControlHeadED;
320 ULONG HcControlCurrentED;
321 ULONG HcBulkHeadED;
322 ULONG HcBulkCurrentED;
323 ULONG HcDoneHead;
324 OHCI_REG_FRAME_INTERVAL HcFmInterval;
325 ULONG HcFmRemaining;
326 ULONG HcFmNumber;
327 ULONG HcPeriodicStart;
328 ULONG HcLSThreshold;
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;