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