2 * PROJECT: ReactOS USB UHCI Miniport Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBUHCI root hub functions
5 * COPYRIGHT: Copyright 2017-2018 Vadim Galyant <vgal@rambler.ru>
15 UhciRHGetRootHubData(IN PVOID uhciExtension
,
18 PUHCI_EXTENSION UhciExtension
= uhciExtension
;
19 PUSBPORT_ROOT_HUB_DATA RootHubData
= rootHubData
;
20 USBPORT_HUB_11_CHARACTERISTICS HubCharacteristics
;
22 DPRINT("UhciRHGetRootHubData: ...\n");
24 HubCharacteristics
.AsUSHORT
= 0;
25 HubCharacteristics
.PowerControlMode
= 1;
26 HubCharacteristics
.NoPowerSwitching
= 1;
27 HubCharacteristics
.OverCurrentProtectionMode
= 1;
29 if (UhciExtension
->HcFlavor
!= UHCI_Piix4
)
30 HubCharacteristics
.NoOverCurrentProtection
= 1;
32 RootHubData
->NumberOfPorts
= UHCI_NUM_ROOT_HUB_PORTS
;
33 RootHubData
->HubCharacteristics
.Usb11HubCharacteristics
= HubCharacteristics
;
34 RootHubData
->PowerOnToPowerGood
= 1;
35 RootHubData
->HubControlCurrent
= 0;
40 UhciRHGetStatus(IN PVOID uhciExtension
,
43 DPRINT("UhciRHGetStatus: ...\n");
44 *Status
= USB_GETSTATUS_SELF_POWERED
;
45 return MP_STATUS_SUCCESS
;
50 UhciRHGetPortStatus(IN PVOID uhciExtension
,
52 IN PUSB_PORT_STATUS_AND_CHANGE PortStatus
)
54 PUHCI_EXTENSION UhciExtension
= uhciExtension
;
55 PUHCI_HW_REGISTERS BaseRegister
;
56 PUSHORT PortControlRegister
;
57 UHCI_PORT_STATUS_CONTROL PortControl
;
59 USB_20_PORT_STATUS portStatus
;
60 USB_20_PORT_CHANGE portChange
;
62 //DPRINT("UhciRHGetPortStatus: ...\n");
66 BaseRegister
= UhciExtension
->BaseRegister
;
67 PortControlRegister
= &BaseRegister
->PortControl
[Port
-1].AsUSHORT
;
68 PortControl
.AsUSHORT
= READ_PORT_USHORT(PortControlRegister
);
70 portStatus
.AsUshort16
= 0;
71 portChange
.AsUshort16
= 0;
73 portStatus
.CurrentConnectStatus
= PortControl
.CurrentConnectStatus
;
74 portStatus
.PortEnabledDisabled
= PortControl
.PortEnabledDisabled
;
76 if (PortControl
.Suspend
== 1 &&
77 PortControl
.PortEnabledDisabled
== 1)
79 portStatus
.Suspend
= 1;
83 portStatus
.Suspend
= 0;
86 //if (UhciExtension->HcFlavor == UHCI_Piix4) // check will work after supporting HcFlavor in usbport.
89 portStatus
.OverCurrent
= PortControl
.Reserved2
& 1;
90 portStatus
.PortPower
= (~PortControl
.Reserved2
& 1);
91 portChange
.OverCurrentIndicatorChange
= (PortControl
.Reserved2
& 2) != 0;
95 portStatus
.OverCurrent
= 0;
96 portStatus
.PortPower
= 1;
97 portChange
.OverCurrentIndicatorChange
= 0;
100 portStatus
.HighSpeedDeviceAttached
= 0;
102 portStatus
.Reset
= PortControl
.PortReset
;
103 portStatus
.LowSpeedDeviceAttached
= PortControl
.LowSpeedDevice
;
104 portChange
.ConnectStatusChange
= PortControl
.ConnectStatusChange
;
106 PortBit
= 1 << (Port
- 1);
108 if (UhciExtension
->ResetPortMask
& PortBit
)
110 portChange
.ConnectStatusChange
= 0;
111 portChange
.PortEnableDisableChange
= 0;
115 portChange
.PortEnableDisableChange
= PortControl
.PortEnableDisableChange
;
118 if (UhciExtension
->SuspendChangePortMask
& PortBit
)
119 portChange
.SuspendChange
= 1;
121 if (UhciExtension
->ResetChangePortMask
& PortBit
)
122 portChange
.ResetChange
= 1;
124 PortStatus
->PortStatus
.Usb20PortStatus
= portStatus
;
125 PortStatus
->PortChange
.Usb20PortChange
= portChange
;
127 //DPRINT("UhciRHGetPortStatus: PortControl.AsUSHORT[%x] - %X, PortStatus - %X\n",
129 // PortControl.AsUSHORT,
130 // PortStatus->AsUlong32);
132 return MP_STATUS_SUCCESS
;
137 UhciRHGetHubStatus(IN PVOID uhciExtension
,
138 IN PUSB_HUB_STATUS_AND_CHANGE HubStatus
)
140 //DPRINT("UhciRHGetHubStatus: ...\n");
141 HubStatus
->AsUlong32
= 0;
142 return MP_STATUS_SUCCESS
;
147 UhciRHPortResetComplete(IN PVOID uhciExtension
,
150 PUHCI_EXTENSION UhciExtension
= uhciExtension
;
152 PUHCI_HW_REGISTERS BaseRegister
;
153 PUSHORT PortControlRegister
;
154 UHCI_PORT_STATUS_CONTROL PortControl
;
157 DPRINT("UhciRHPortResetComplete: ...\n");
159 BaseRegister
= UhciExtension
->BaseRegister
;
161 Port
= *(PUSHORT
)pPort
;
164 PortControlRegister
= &BaseRegister
->PortControl
[Port
- 1].AsUSHORT
;
165 PortControl
.AsUSHORT
= READ_PORT_USHORT(PortControlRegister
);
167 PortControl
.ConnectStatusChange
= 0;
168 PortControl
.PortEnableDisableChange
= 0;
169 PortControl
.PortReset
= 0;
171 WRITE_PORT_USHORT(PortControlRegister
, PortControl
.AsUSHORT
);
173 while (UhciHardwarePresent(UhciExtension
))
175 PortControl
.AsUSHORT
= READ_PORT_USHORT(PortControlRegister
);
177 if (PortControl
.PortReset
== 0)
181 for (ix
= 0; ix
< 10; ++ix
)
183 KeStallExecutionProcessor(50);
185 PortControl
.AsUSHORT
= READ_PORT_USHORT(PortControlRegister
);
187 if (PortControl
.PortEnabledDisabled
== 1)
190 PortControl
.PortEnabledDisabled
= 1;
191 WRITE_PORT_USHORT(PortControlRegister
, PortControl
.AsUSHORT
);
194 PortControl
.ConnectStatusChange
= 1;
195 PortControl
.PortEnableDisableChange
= 1;
196 WRITE_PORT_USHORT(PortControlRegister
, PortControl
.AsUSHORT
);
198 if (UhciExtension
->HcFlavor
== UHCI_VIA
&&
199 UhciExtension
->HcFlavor
== UHCI_VIA_x01
&&
200 UhciExtension
->HcFlavor
== UHCI_VIA_x02
&&
201 UhciExtension
->HcFlavor
== UHCI_VIA_x03
&&
202 UhciExtension
->HcFlavor
== UHCI_VIA_x04
)
204 DPRINT("UhciRHPortResetComplete: Via chip. FIXME\n");
209 UhciExtension
->ResetChangePortMask
|= (1 << (Port
- 1));
210 UhciExtension
->ResetPortMask
&= ~(1 << (Port
- 1));
212 RegPacket
.UsbPortInvalidateRootHub(UhciExtension
);
217 UhciRHSetFeaturePortResetWorker(IN PUHCI_EXTENSION UhciExtension
,
220 PUHCI_HW_REGISTERS BaseRegister
;
221 PUSHORT PortControlRegister
;
222 UHCI_PORT_STATUS_CONTROL PortControl
;
225 DPRINT("UhciRHSetFeaturePortResetWorker: ...\n");
227 BaseRegister
= UhciExtension
->BaseRegister
;
229 Port
= *(PUSHORT
)pPort
;
232 PortControlRegister
= &BaseRegister
->PortControl
[Port
- 1].AsUSHORT
;
233 PortControl
.AsUSHORT
= READ_PORT_USHORT(PortControlRegister
);
235 PortControl
.ConnectStatusChange
= 0;
236 PortControl
.PortEnableDisableChange
= 0;
237 PortControl
.PortReset
= 1;
239 WRITE_PORT_USHORT(PortControlRegister
, PortControl
.AsUSHORT
);
241 RegPacket
.UsbPortRequestAsyncCallback(UhciExtension
,
245 UhciRHPortResetComplete
);
250 UhciRHSetFeaturePortReset(IN PVOID uhciExtension
,
253 PUHCI_EXTENSION UhciExtension
= uhciExtension
;
257 DPRINT("UhciRHSetFeaturePortReset: ...\n");
261 ResetPortMask
= UhciExtension
->ResetPortMask
;
262 PortBit
= 1 << (Port
- 1);
264 if (ResetPortMask
& PortBit
)
265 return MP_STATUS_FAILURE
;
267 UhciExtension
->ResetPortMask
= ResetPortMask
| PortBit
;
269 if (UhciExtension
->HcFlavor
== UHCI_VIA
&&
270 UhciExtension
->HcFlavor
== UHCI_VIA_x01
&&
271 UhciExtension
->HcFlavor
== UHCI_VIA_x02
&&
272 UhciExtension
->HcFlavor
== UHCI_VIA_x03
&&
273 UhciExtension
->HcFlavor
== UHCI_VIA_x04
)
275 DPRINT1("UhciRHSetFeaturePortReset: Via chip. FIXME\n");
276 return MP_STATUS_SUCCESS
;
279 UhciRHSetFeaturePortResetWorker(UhciExtension
, &Port
);
281 return MP_STATUS_SUCCESS
;
286 UhciRHSetFeaturePortPower(IN PVOID uhciExtension
,
289 DPRINT("UhciRHSetFeaturePortPower: ...\n");
291 return MP_STATUS_SUCCESS
;
296 UhciRHPortEnable(IN PVOID uhciExtension
,
300 PUHCI_EXTENSION UhciExtension
= uhciExtension
;
301 PUHCI_HW_REGISTERS BaseRegister
;
302 PUSHORT PortControlRegister
;
303 UHCI_PORT_STATUS_CONTROL PortControl
;
305 DPRINT("UhciRHPortEnable: ...\n");
309 BaseRegister
= UhciExtension
->BaseRegister
;
310 PortControlRegister
= &BaseRegister
->PortControl
[Port
-1].AsUSHORT
;
312 PortControl
.AsUSHORT
= READ_PORT_USHORT(PortControlRegister
);
314 PortControl
.ConnectStatusChange
= 0;
315 PortControl
.PortEnableDisableChange
= 0;
318 PortControl
.PortEnabledDisabled
= 1;
320 PortControl
.PortEnabledDisabled
= 0;
322 WRITE_PORT_USHORT(PortControlRegister
, PortControl
.AsUSHORT
);
324 return MP_STATUS_SUCCESS
;
329 UhciRHSetFeaturePortEnable(IN PVOID uhciExtension
,
332 PUHCI_EXTENSION UhciExtension
= uhciExtension
;
333 DPRINT("UhciRHSetFeaturePortEnable: ...\n");
335 return UhciRHPortEnable(UhciExtension
, Port
, TRUE
);
340 UhciRHSetFeaturePortSuspend(IN PVOID uhciExtension
,
343 DPRINT("UhciRHSetFeaturePortSuspend: UNIMPLEMENTED. FIXME\n");
345 return MP_STATUS_SUCCESS
;
350 UhciRHClearFeaturePortEnable(IN PVOID uhciExtension
,
353 PUHCI_EXTENSION UhciExtension
= uhciExtension
;
354 DPRINT("UhciRHClearFeaturePortEnable: ...\n");
356 return UhciRHPortEnable(UhciExtension
, Port
, FALSE
);
361 UhciRHClearFeaturePortPower(IN PVOID uhciExtension
,
364 DPRINT("UhciRHClearFeaturePortPower: UNIMPLEMENTED. FIXME\n");
366 return MP_STATUS_SUCCESS
;
371 UhciRHClearFeaturePortSuspend(IN PVOID uhciExtension
,
374 DPRINT("UhciRHClearFeaturePortSuspend: UNIMPLEMENTED. FIXME\n");
376 return MP_STATUS_SUCCESS
;
381 UhciRHClearFeaturePortEnableChange(IN PVOID uhciExtension
,
384 PUHCI_EXTENSION UhciExtension
= uhciExtension
;
385 PUHCI_HW_REGISTERS BaseRegister
;
386 PUSHORT PortControlRegister
;
387 UHCI_PORT_STATUS_CONTROL PortControl
;
389 DPRINT("UhciRHClearFeaturePortEnableChange: ...\n");
393 BaseRegister
= UhciExtension
->BaseRegister
;
394 PortControlRegister
= (PUSHORT
)&BaseRegister
->PortControl
[Port
- 1];
395 PortControl
.AsUSHORT
= READ_PORT_USHORT(PortControlRegister
);
397 PortControl
.ConnectStatusChange
= 0;
398 PortControl
.PortEnableDisableChange
= 1;
399 WRITE_PORT_USHORT(PortControlRegister
, PortControl
.AsUSHORT
);
401 return MP_STATUS_SUCCESS
;
406 UhciRHClearFeaturePortConnectChange(IN PVOID uhciExtension
,
409 PUHCI_EXTENSION UhciExtension
= uhciExtension
;
410 PUHCI_HW_REGISTERS BaseRegister
;
411 PUSHORT PortControlRegister
;
412 UHCI_PORT_STATUS_CONTROL PortControl
;
414 DPRINT("UhciRHClearFeaturePortConnectChange: Port - %04X\n", Port
);
418 BaseRegister
= UhciExtension
->BaseRegister
;
419 PortControlRegister
= (PUSHORT
)&BaseRegister
->PortControl
[Port
- 1];
420 PortControl
.AsUSHORT
= READ_PORT_USHORT(PortControlRegister
);
422 if (PortControl
.ConnectStatusChange
== 1)
424 /* WC (Write Clear) bits */
425 PortControl
.PortEnableDisableChange
= 0;
426 PortControl
.ConnectStatusChange
= 1;
427 WRITE_PORT_USHORT(PortControlRegister
, PortControl
.AsUSHORT
);
430 return MP_STATUS_SUCCESS
;
435 UhciRHClearFeaturePortResetChange(IN PVOID uhciExtension
,
438 PUHCI_EXTENSION UhciExtension
= uhciExtension
;
439 DPRINT("UhciRHClearFeaturePortResetChange: ...\n");
441 UhciExtension
->ResetChangePortMask
&= ~(1 << (Port
- 1));
442 return MP_STATUS_SUCCESS
;
447 UhciRHClearFeaturePortSuspendChange(IN PVOID uhciExtension
,
450 DPRINT("UhciRHClearFeaturePortSuspendChange: UNIMPLEMENTED. FIXME\n");
452 return MP_STATUS_SUCCESS
;
457 UhciRHClearFeaturePortOvercurrentChange(IN PVOID uhciExtension
,
460 DPRINT("UhciRHClearFeaturePortOvercurrentChange: UNIMPLEMENTED. FIXME\n");
462 return MP_STATUS_SUCCESS
;
467 UhciRHDisableIrq(IN PVOID uhciExtension
)
475 UhciRHEnableIrq(IN PVOID uhciExtension
)