1 #define OHCI_NUMBER_OF_INTERRUPTS 32
2 #define OHCI_MAX_PORT_COUNT 15
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)
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
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
19 #define OHCI_ENDPOINT_FULL_SPEED 0
20 #define OHCI_ENDPOINT_LOW_SPEED 1
22 #define OHCI_ENDPOINT_GENERAL_FORMAT 0
23 #define OHCI_ENDPOINT_ISOCHRONOUS_FORMAT 1
25 /* Transfer Descriptor Control */
26 #define OHCI_TD_INTERRUPT_IMMEDIATE 0
27 #define OHCI_TD_INTERRUPT_NONE 7
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
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
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
52 #define OHCI_RH_STATUS_GOOD 1
54 typedef union _OHCI_TRANSFER_CONTROL
{
57 ULONG BufferRounding
: 1;
58 ULONG DirectionPID
: 2;
59 ULONG DelayInterrupt
: 3;
62 ULONG ConditionCode
: 4;
65 } OHCI_TRANSFER_CONTROL
, *POHCI_TRANSFER_CONTROL
;
67 C_ASSERT(sizeof(OHCI_TRANSFER_CONTROL
) == sizeof(ULONG
));
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
;
76 C_ASSERT(sizeof(OHCI_TRANSFER_DESCRIPTOR
) == 16);
78 typedef union _OHCI_ISO_TRANSFER_CONTROL
{
80 ULONG StartingFrame
: 16;
82 ULONG DelayInterrupt
: 3;
85 ULONG ConditionCode
: 4;
88 } OHCI_ISO_TRANSFER_CONTROL
, *POHCI_ISO_TRANSFER_CONTROL
;
90 C_ASSERT(sizeof(OHCI_ISO_TRANSFER_CONTROL
) == sizeof(ULONG
));
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
;
100 C_ASSERT(sizeof(OHCI_ISO_TRANSFER_DESCRIPTOR
) == 32);
102 typedef union _OHCI_ENDPOINT_CONTROL
{
104 ULONG FunctionAddress
: 7;
105 ULONG EndpointNumber
: 4;
110 ULONG MaximumPacketSize
: 11;
114 } OHCI_ENDPOINT_CONTROL
, *POHCI_ENDPOINT_CONTROL
;
116 C_ASSERT(sizeof(OHCI_ENDPOINT_CONTROL
) == sizeof(ULONG
));
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
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
;
131 C_ASSERT(sizeof(OHCI_ENDPOINT_DESCRIPTOR
) == 16);
133 typedef struct _OHCI_HCCA
{ // must be located on a 256-byte boundary
134 ULONG InterrruptTable
[OHCI_NUMBER_OF_INTERRUPTS
];
138 UCHAR reserved_hc
[116];
140 } OHCI_HCCA
, *POHCI_HCCA
;
142 C_ASSERT(sizeof(OHCI_HCCA
) == 256);
144 typedef union _OHCI_REG_CONTROL
{
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;
158 } OHCI_REG_CONTROL
, *POHCI_REG_CONTROL
;
160 C_ASSERT(sizeof(OHCI_REG_CONTROL
) == sizeof(ULONG
));
162 typedef union _OHCI_REG_COMMAND_STATUS
{
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;
173 } OHCI_REG_COMMAND_STATUS
, *POHCI_REG_COMMAND_STATUS
;
175 C_ASSERT(sizeof(OHCI_REG_COMMAND_STATUS
) == sizeof(ULONG
));
177 typedef union _OHCI_REG_INTERRUPT_STATUS
{
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;
191 } OHCI_REG_INTERRUPT_STATUS
, *POHCI_REG_INTERRUPT_STATUS
;
193 C_ASSERT(sizeof(OHCI_REG_INTERRUPT_STATUS
) == sizeof(ULONG
));
195 typedef union _OHCI_REG_INTERRUPT_ENABLE_DISABLE
{
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;
209 } OHCI_REG_INTERRUPT_ENABLE_DISABLE
, *POHCI_REG_INTERRUPT_ENABLE_DISABLE
;
211 C_ASSERT(sizeof(OHCI_REG_INTERRUPT_ENABLE_DISABLE
) == sizeof(ULONG
));
213 typedef union _OHCI_REG_FRAME_INTERVAL
{
215 ULONG FrameInterval
: 14;
217 ULONG FSLargestDataPacket
: 15;
218 ULONG FrameIntervalToggle
: 1;
221 } OHCI_REG_FRAME_INTERVAL
, *POHCI_REG_FRAME_INTERVAL
;
223 C_ASSERT(sizeof(OHCI_REG_FRAME_INTERVAL
) == sizeof(ULONG
));
225 typedef union _OHCI_REG_RH_DESCRIPTORA
{
227 ULONG NumberDownstreamPorts
: 8;
228 ULONG PowerSwitchingMode
: 1;
229 ULONG NoPowerSwitching
: 1;
230 ULONG DeviceType
: 1;
231 ULONG OverCurrentProtectionMode
: 1;
232 ULONG NoOverCurrentProtection
: 1;
234 ULONG PowerOnToPowerGoodTime
: 8;
237 } OHCI_REG_RH_DESCRIPTORA
, *POHCI_REG_RH_DESCRIPTORA
;
239 C_ASSERT(sizeof(OHCI_REG_RH_DESCRIPTORA
) == sizeof(ULONG
));
241 typedef union _OHCI_REG_RH_STATUS
{
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;
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;
263 } OHCI_REG_RH_STATUS
, *POHCI_REG_RH_STATUS
;
265 C_ASSERT(sizeof(OHCI_REG_RH_STATUS
) == sizeof(ULONG
));
267 typedef union _OHCI_REG_RH_PORT_STATUS
{
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;
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;
293 USHORT ConnectStatusChange
: 1;
294 USHORT PortEnableStatusChange
: 1;
295 USHORT PortSuspendStatusChange
: 1;
296 USHORT PortOverCurrentIndicatorChange
: 1;
297 USHORT PortResetStatusChange
: 1;
298 USHORT Reserved3
: 11;
301 } OHCI_REG_RH_PORT_STATUS
, *POHCI_REG_RH_PORT_STATUS
;
303 C_ASSERT(sizeof(OHCI_REG_RH_PORT_STATUS
) == sizeof(ULONG
));
305 typedef struct _OHCI_OPERATIONAL_REGISTERS
{
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
;
313 ULONG HcPeriodCurrentED
;
314 ULONG HcControlHeadED
;
315 ULONG HcControlCurrentED
;
317 ULONG HcBulkCurrentED
;
319 OHCI_REG_FRAME_INTERVAL HcFmInterval
;
322 ULONG HcPeriodicStart
;
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
;