[USBOHCI_NEW] Avoid storing pointers as ULONG and physical addresses as pointers.
[reactos.git] / drivers / usb / usbohci_new / hardware.h
1 #define OHCI_NUMBER_OF_INTERRUPTS 32
2 #define OHCI_MAX_PORT_COUNT 15
3 #define ED_EOF -1
4 #define OHCI_MAXIMUM_OVERHEAD 210 // 5.4 FrameInterval Counter, in bit-times
5 #define OHCI_DEFAULT_FRAME_INTERVAL 11999 // 6.3.1 Frame Timing
6 #define OHCI_MINIMAL_POTPGT 25 // == 50 ms., PowerOnToPowerGoodTime (HcRhDescriptorA Register)
7
8 /* Controller states */
9 #define OHCI_HC_STATE_RESET 0
10 #define OHCI_HC_STATE_RESUME 1
11 #define OHCI_HC_STATE_OPERATIONAL 2
12 #define OHCI_HC_STATE_SUSPEND 3
13
14 /* Endpoint Descriptor Control */
15 #define OHCI_ED_DATA_FLOW_DIRECTION_FROM_TD 0
16 #define OHCI_ED_DATA_FLOW_DIRECTION_OUT 1
17 #define OHCI_ED_DATA_FLOW_DIRECTION_IN 2
18
19 #define OHCI_ENDPOINT_FULL_SPEED 0
20 #define OHCI_ENDPOINT_LOW_SPEED 1
21
22 #define OHCI_ENDPOINT_GENERAL_FORMAT 0
23 #define OHCI_ENDPOINT_ISOCHRONOUS_FORMAT 1
24
25 /* Transfer Descriptor Control */
26 #define OHCI_TD_INTERRUPT_IMMEDIATE 0
27 #define OHCI_TD_INTERRUPT_NONE 7
28
29 #define OHCI_TD_DIRECTION_PID_SETUP 0
30 #define OHCI_TD_DIRECTION_PID_OUT 1
31 #define OHCI_TD_DIRECTION_PID_IN 2
32 #define OHCI_TD_DIRECTION_PID_RESERVED 3
33
34 #define OHCI_TD_DATA_TOGGLE_FROM_ED 0
35 #define OHCI_TD_DATA_TOGGLE_DATA0 2
36 #define OHCI_TD_DATA_TOGGLE_DATA1 3
37
38 #define OHCI_TD_CONDITION_NO_ERROR 0x00
39 #define OHCI_TD_CONDITION_CRC_ERROR 0x01
40 #define OHCI_TD_CONDITION_BIT_STUFFING 0x02
41 #define OHCI_TD_CONDITION_TOGGLE_MISMATCH 0x03
42 #define OHCI_TD_CONDITION_STALL 0x04
43 #define OHCI_TD_CONDITION_NO_RESPONSE 0x05
44 #define OHCI_TD_CONDITION_PID_CHECK_FAILURE 0x06
45 #define OHCI_TD_CONDITION_UNEXPECTED_PID 0x07
46 #define OHCI_TD_CONDITION_DATA_OVERRUN 0x08
47 #define OHCI_TD_CONDITION_DATA_UNDERRUN 0x09
48 #define OHCI_TD_CONDITION_BUFFER_OVERRUN 0x0C
49 #define OHCI_TD_CONDITION_BUFFER_UNDERRUN 0x0D
50 #define OHCI_TD_CONDITION_NOT_ACCESSED 0x0E
51
52 #define OHCI_RH_STATUS_GOOD 1
53
54 typedef union _OHCI_TRANSFER_CONTROL {
55 struct {
56 ULONG Reserved : 18;
57 ULONG BufferRounding : 1;
58 ULONG DirectionPID : 2;
59 ULONG DelayInterrupt : 3;
60 ULONG DataToggle : 2;
61 ULONG ErrorCount : 2;
62 ULONG ConditionCode : 4;
63 };
64 ULONG AsULONG;
65 } OHCI_TRANSFER_CONTROL, *POHCI_TRANSFER_CONTROL;
66
67 C_ASSERT(sizeof(OHCI_TRANSFER_CONTROL) == sizeof(ULONG));
68
69 typedef struct _OHCI_TRANSFER_DESCRIPTOR { // must be aligned to a 16-byte boundary
70 OHCI_TRANSFER_CONTROL Control;
71 ULONG CurrentBuffer; // physical address of the next memory location
72 ULONG NextTD; // pointer to the next TD on the list of TDs
73 ULONG BufferEnd; // physical address of the last byte
74 } OHCI_TRANSFER_DESCRIPTOR, *POHCI_TRANSFER_DESCRIPTOR;
75
76 C_ASSERT(sizeof(OHCI_TRANSFER_DESCRIPTOR) == 16);
77
78 typedef union _OHCI_ISO_TRANSFER_CONTROL {
79 struct {
80 ULONG StartingFrame : 16;
81 ULONG Reserved1 : 5;
82 ULONG DelayInterrupt : 3;
83 ULONG FrameCount : 3;
84 ULONG Reserved2 : 1;
85 ULONG ConditionCode : 4;
86 };
87 ULONG AsULONG;
88 } OHCI_ISO_TRANSFER_CONTROL, *POHCI_ISO_TRANSFER_CONTROL;
89
90 C_ASSERT(sizeof(OHCI_ISO_TRANSFER_CONTROL) == sizeof(ULONG));
91
92 typedef struct _OHCI_ISO_TRANSFER_DESCRIPTOR { // must be aligned to a 32-byte boundary
93 OHCI_ISO_TRANSFER_CONTROL Control;
94 ULONG BufferPage0; // physical page number of the 1 byte of the data buffer
95 ULONG NextTD; // pointer to the next Isochronous TD on the queue of Isochronous TDs
96 ULONG BufferEnd; // physical address of the last byte in the buffer
97 USHORT Offset[8]; // for determine size and start addr. iso packet | PacketStatusWord - completion code
98 } OHCI_ISO_TRANSFER_DESCRIPTOR, *POHCI_ISO_TRANSFER_DESCRIPTOR;
99
100 C_ASSERT(sizeof(OHCI_ISO_TRANSFER_DESCRIPTOR) == 32);
101
102 typedef union _OHCI_ENDPOINT_CONTROL {
103 struct {
104 ULONG FunctionAddress : 7;
105 ULONG EndpointNumber : 4;
106 ULONG Direction : 2;
107 ULONG Speed : 1;
108 ULONG sKip : 1;
109 ULONG Format : 1;
110 ULONG MaximumPacketSize : 11;
111 ULONG Reserved : 5;
112 };
113 ULONG AsULONG;
114 } OHCI_ENDPOINT_CONTROL, *POHCI_ENDPOINT_CONTROL;
115
116 C_ASSERT(sizeof(OHCI_ENDPOINT_CONTROL) == sizeof(ULONG));
117
118 /* Bit flags for HeadPointer member of the EP descriptor */
119 #define OHCI_ED_HEAD_POINTER_HALT 0x00000001 // hardware stopped bit
120 #define OHCI_ED_HEAD_POINTER_CARRY 0x00000002 // hardware toggle carry bit
121 #define OHCI_ED_HEAD_POINTER_MASK 0XFFFFFFF0 // mask physical pointer
122 #define OHCI_ED_HEAD_POINTER_FLAGS_MASK 0X0000000F // mask bit flags
123
124 typedef struct _OHCI_ENDPOINT_DESCRIPTOR { // must be aligned to a 16-byte boundary
125 OHCI_ENDPOINT_CONTROL EndpointControl;
126 ULONG TailPointer; // if TailP and HeadP are different, then the list contains a TD to be processed
127 ULONG HeadPointer; // physical pointer to the next TD to be processed for this endpoint
128 ULONG NextED; // entry points to the next ED on the list
129 } OHCI_ENDPOINT_DESCRIPTOR, *POHCI_ENDPOINT_DESCRIPTOR;
130
131 C_ASSERT(sizeof(OHCI_ENDPOINT_DESCRIPTOR) == 16);
132
133 typedef struct _OHCI_HCCA { // must be located on a 256-byte boundary
134 ULONG InterrruptTable[OHCI_NUMBER_OF_INTERRUPTS];
135 USHORT FrameNumber;
136 USHORT Pad1;
137 ULONG DoneHead;
138 UCHAR reserved_hc[116];
139 UCHAR Pad[4];
140 } OHCI_HCCA, *POHCI_HCCA;
141
142 C_ASSERT(sizeof(OHCI_HCCA) == 256);
143
144 typedef union _OHCI_REG_CONTROL {
145 struct {
146 ULONG ControlBulkServiceRatio : 2;
147 ULONG PeriodicListEnable : 1;
148 ULONG IsochronousEnable : 1;
149 ULONG ControlListEnable : 1;
150 ULONG BulkListEnable : 1;
151 ULONG HostControllerFunctionalState : 2;
152 ULONG InterruptRouting : 1;
153 ULONG RemoteWakeupConnected : 1;
154 ULONG RemoteWakeupEnable : 1;
155 ULONG Reserved : 21;
156 };
157 ULONG AsULONG;
158 } OHCI_REG_CONTROL, *POHCI_REG_CONTROL;
159
160 C_ASSERT(sizeof(OHCI_REG_CONTROL) == sizeof(ULONG));
161
162 typedef union _OHCI_REG_COMMAND_STATUS {
163 struct {
164 ULONG HostControllerReset : 1;
165 ULONG ControlListFilled : 1;
166 ULONG BulkListFilled : 1;
167 ULONG OwnershipChangeRequest : 1;
168 ULONG Reserved1 : 12;
169 ULONG SchedulingOverrunCount : 1;
170 ULONG Reserved2 : 15;
171 };
172 ULONG AsULONG;
173 } OHCI_REG_COMMAND_STATUS, *POHCI_REG_COMMAND_STATUS;
174
175 C_ASSERT(sizeof(OHCI_REG_COMMAND_STATUS) == sizeof(ULONG));
176
177 typedef union _OHCI_REG_INTERRUPT_STATUS {
178 struct {
179 ULONG SchedulingOverrun : 1;
180 ULONG WritebackDoneHead : 1;
181 ULONG StartofFrame : 1;
182 ULONG ResumeDetected : 1;
183 ULONG UnrecoverableError : 1;
184 ULONG FrameNumberOverflow : 1;
185 ULONG RootHubStatusChange : 1;
186 ULONG Reserved1 : 23;
187 ULONG OwnershipChange : 1;
188 ULONG Reserved2 : 1;
189 };
190 ULONG AsULONG;
191 } OHCI_REG_INTERRUPT_STATUS, *POHCI_REG_INTERRUPT_STATUS;
192
193 C_ASSERT(sizeof(OHCI_REG_INTERRUPT_STATUS) == sizeof(ULONG));
194
195 typedef union _OHCI_REG_INTERRUPT_ENABLE_DISABLE {
196 struct {
197 ULONG SchedulingOverrun : 1;
198 ULONG WritebackDoneHead : 1;
199 ULONG StartofFrame : 1;
200 ULONG ResumeDetected : 1;
201 ULONG UnrecoverableError : 1;
202 ULONG FrameNumberOverflow : 1;
203 ULONG RootHubStatusChange : 1;
204 ULONG Reserved1 : 23;
205 ULONG OwnershipChange : 1;
206 ULONG MasterInterruptEnable : 1;
207 };
208 ULONG AsULONG;
209 } OHCI_REG_INTERRUPT_ENABLE_DISABLE, *POHCI_REG_INTERRUPT_ENABLE_DISABLE;
210
211 C_ASSERT(sizeof(OHCI_REG_INTERRUPT_ENABLE_DISABLE) == sizeof(ULONG));
212
213 typedef union _OHCI_REG_FRAME_INTERVAL {
214 struct {
215 ULONG FrameInterval : 14;
216 ULONG Reserved : 2;
217 ULONG FSLargestDataPacket : 15;
218 ULONG FrameIntervalToggle : 1;
219 };
220 ULONG AsULONG;
221 } OHCI_REG_FRAME_INTERVAL, *POHCI_REG_FRAME_INTERVAL;
222
223 C_ASSERT(sizeof(OHCI_REG_FRAME_INTERVAL) == sizeof(ULONG));
224
225 typedef union _OHCI_REG_RH_DESCRIPTORA {
226 struct {
227 ULONG NumberDownstreamPorts : 8;
228 ULONG PowerSwitchingMode : 1;
229 ULONG NoPowerSwitching : 1;
230 ULONG DeviceType : 1;
231 ULONG OverCurrentProtectionMode : 1;
232 ULONG NoOverCurrentProtection : 1;
233 ULONG Reserved : 11;
234 ULONG PowerOnToPowerGoodTime : 8;
235 };
236 ULONG AsULONG;
237 } OHCI_REG_RH_DESCRIPTORA, *POHCI_REG_RH_DESCRIPTORA;
238
239 C_ASSERT(sizeof(OHCI_REG_RH_DESCRIPTORA) == sizeof(ULONG));
240
241 typedef union _OHCI_REG_RH_STATUS {
242 union {
243 struct { // read
244 ULONG LocalPowerStatus : 1;
245 ULONG OverCurrentIndicator : 1;
246 ULONG Reserved10 : 13;
247 ULONG DeviceRemoteWakeupEnable : 1;
248 ULONG LocalPowerStatusChange : 1;
249 ULONG OverCurrentIndicatorChangeR : 1;
250 ULONG Reserved20 : 14;
251 };
252 struct { // write
253 ULONG ClearGlobalPower : 1;
254 ULONG Reserved11 : 14;
255 ULONG SetRemoteWakeupEnable : 1;
256 ULONG SetGlobalPower : 1;
257 ULONG OverCurrentIndicatorChangeW : 1;
258 ULONG Reserved22 : 13;
259 ULONG ClearRemoteWakeupEnable : 1;
260 };
261 };
262 ULONG AsULONG;
263 } OHCI_REG_RH_STATUS, *POHCI_REG_RH_STATUS;
264
265 C_ASSERT(sizeof(OHCI_REG_RH_STATUS) == sizeof(ULONG));
266
267 typedef union _OHCI_REG_RH_PORT_STATUS {
268 struct {
269 union {
270 struct { // read
271 USHORT CurrentConnectStatus : 1;
272 USHORT PortEnableStatus : 1;
273 USHORT PortSuspendStatus : 1;
274 USHORT PortOverCurrentIndicator : 1;
275 USHORT PortResetStatus : 1;
276 USHORT Reserved1r : 3;
277 USHORT PortPowerStatus : 1;
278 USHORT LowSpeedDeviceAttached : 1;
279 USHORT Reserved2r : 6;
280 };
281 struct { // write
282 USHORT ClearPortEnable : 1;
283 USHORT SetPortEnable : 1;
284 USHORT SetPortSuspend : 1;
285 USHORT ClearSuspendStatus : 1;
286 USHORT SetPortReset : 1;
287 USHORT Reserved1w : 3;
288 USHORT SetPortPower : 1;
289 USHORT ClearPortPower : 1;
290 USHORT Reserved2w : 6;
291 };
292 };
293 USHORT ConnectStatusChange : 1;
294 USHORT PortEnableStatusChange : 1;
295 USHORT PortSuspendStatusChange : 1;
296 USHORT PortOverCurrentIndicatorChange : 1;
297 USHORT PortResetStatusChange : 1;
298 USHORT Reserved3 : 11;
299 };
300 ULONG AsULONG;
301 } OHCI_REG_RH_PORT_STATUS, *POHCI_REG_RH_PORT_STATUS;
302
303 C_ASSERT(sizeof(OHCI_REG_RH_PORT_STATUS) == sizeof(ULONG));
304
305 typedef struct _OHCI_OPERATIONAL_REGISTERS {
306 ULONG HcRevision;
307 OHCI_REG_CONTROL HcControl;
308 OHCI_REG_COMMAND_STATUS HcCommandStatus;
309 OHCI_REG_INTERRUPT_STATUS HcInterruptStatus;
310 OHCI_REG_INTERRUPT_ENABLE_DISABLE HcInterruptEnable;
311 OHCI_REG_INTERRUPT_ENABLE_DISABLE HcInterruptDisable;
312 ULONG HcHCCA;
313 ULONG HcPeriodCurrentED;
314 ULONG HcControlHeadED;
315 ULONG HcControlCurrentED;
316 ULONG HcBulkHeadED;
317 ULONG HcBulkCurrentED;
318 ULONG HcDoneHead;
319 OHCI_REG_FRAME_INTERVAL HcFmInterval;
320 ULONG HcFmRemaining;
321 ULONG HcFmNumber;
322 ULONG HcPeriodicStart;
323 ULONG HcLSThreshold;
324 OHCI_REG_RH_DESCRIPTORA HcRhDescriptorA;
325 ULONG HcRhDescriptorB;
326 OHCI_REG_RH_STATUS HcRhStatus;
327 OHCI_REG_RH_PORT_STATUS HcRhPortStatus[OHCI_MAX_PORT_COUNT];
328 } OHCI_OPERATIONAL_REGISTERS, *POHCI_OPERATIONAL_REGISTERS;