ReactOS 0.4.15-dev-8413-gc1c91f2
roothub.c
Go to the documentation of this file.
1/*
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>
6 */
7
8#include "usbuhci.h"
9
10#define NDEBUG
11#include <debug.h>
12
13VOID
16 IN PVOID rootHubData)
17{
18 PUHCI_EXTENSION UhciExtension = uhciExtension;
19 PUSBPORT_ROOT_HUB_DATA RootHubData = rootHubData;
20 USBPORT_HUB_11_CHARACTERISTICS HubCharacteristics;
21
22 DPRINT("UhciRHGetRootHubData: ...\n");
23
24 HubCharacteristics.AsUSHORT = 0;
25 HubCharacteristics.PowerControlMode = 1;
26 HubCharacteristics.NoPowerSwitching = 1;
27 HubCharacteristics.OverCurrentProtectionMode = 1;
28
29 if (UhciExtension->HcFlavor != UHCI_Piix4)
30 HubCharacteristics.NoOverCurrentProtection = 1;
31
33 RootHubData->HubCharacteristics.Usb11HubCharacteristics = HubCharacteristics;
34 RootHubData->PowerOnToPowerGood = 1;
35 RootHubData->HubControlCurrent = 0;
36}
37
40UhciRHGetStatus(IN PVOID uhciExtension,
42{
43 DPRINT("UhciRHGetStatus: ...\n");
45 return MP_STATUS_SUCCESS;
46}
47
53{
54 PUHCI_EXTENSION UhciExtension = uhciExtension;
55 PUHCI_HW_REGISTERS BaseRegister;
56 PUSHORT PortControlRegister;
57 UHCI_PORT_STATUS_CONTROL PortControl;
58 ULONG PortBit;
59 USB_20_PORT_STATUS portStatus;
60 USB_20_PORT_CHANGE portChange;
61
62 //DPRINT("UhciRHGetPortStatus: ...\n");
63
64 ASSERT(Port);
65
66 BaseRegister = UhciExtension->BaseRegister;
67 PortControlRegister = &BaseRegister->PortControl[Port-1].AsUSHORT;
68 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
69
70 portStatus.AsUshort16 = 0;
71 portChange.AsUshort16 = 0;
72
73 portStatus.CurrentConnectStatus = PortControl.CurrentConnectStatus;
74 portStatus.PortEnabledDisabled = PortControl.PortEnabledDisabled;
75
76 if (PortControl.Suspend == 1 &&
77 PortControl.PortEnabledDisabled == 1)
78 {
79 portStatus.Suspend = 1;
80 }
81 else
82 {
83 portStatus.Suspend = 0;
84 }
85
86 //if (UhciExtension->HcFlavor == UHCI_Piix4) // check will work after supporting HcFlavor in usbport.
87 if (TRUE)
88 {
89 portStatus.OverCurrent = PortControl.Reserved2 & 1;
90 portStatus.PortPower = (~PortControl.Reserved2 & 1);
91 portChange.OverCurrentIndicatorChange = (PortControl.Reserved2 & 2) != 0;
92 }
93 else
94 {
95 portStatus.OverCurrent = 0;
96 portStatus.PortPower = 1;
97 portChange.OverCurrentIndicatorChange = 0;
98 }
99
100 portStatus.HighSpeedDeviceAttached = 0;
101
102 portStatus.Reset = PortControl.PortReset;
103 portStatus.LowSpeedDeviceAttached = PortControl.LowSpeedDevice;
104 portChange.ConnectStatusChange = PortControl.ConnectStatusChange;
105
106 PortBit = 1 << (Port - 1);
107
108 if (UhciExtension->ResetPortMask & PortBit)
109 {
110 portChange.ConnectStatusChange = 0;
111 portChange.PortEnableDisableChange = 0;
112 }
113 else
114 {
115 portChange.PortEnableDisableChange = PortControl.PortEnableDisableChange;
116 }
117
118 if (UhciExtension->SuspendChangePortMask & PortBit)
119 portChange.SuspendChange = 1;
120
121 if (UhciExtension->ResetChangePortMask & PortBit)
122 portChange.ResetChange = 1;
123
124 PortStatus->PortStatus.Usb20PortStatus = portStatus;
125 PortStatus->PortChange.Usb20PortChange = portChange;
126
127 //DPRINT("UhciRHGetPortStatus: PortControl.AsUSHORT[%x] - %X, PortStatus - %X\n",
128 // Port,
129 // PortControl.AsUSHORT,
130 // PortStatus->AsUlong32);
131
132 return MP_STATUS_SUCCESS;
133}
134
136NTAPI
139{
140 //DPRINT("UhciRHGetHubStatus: ...\n");
141 HubStatus->AsUlong32 = 0;
142 return MP_STATUS_SUCCESS;
143}
144
145VOID
146NTAPI
148 IN PVOID pPort)
149{
150 PUHCI_EXTENSION UhciExtension = uhciExtension;
151 ULONG ix;
152 PUHCI_HW_REGISTERS BaseRegister;
153 PUSHORT PortControlRegister;
154 UHCI_PORT_STATUS_CONTROL PortControl;
155 USHORT Port;
156
157 DPRINT("UhciRHPortResetComplete: ...\n");
158
159 BaseRegister = UhciExtension->BaseRegister;
160
161 Port = *(PUSHORT)pPort;
162 ASSERT(Port);
163
164 PortControlRegister = &BaseRegister->PortControl[Port - 1].AsUSHORT;
165 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
166
167 PortControl.ConnectStatusChange = 0;
168 PortControl.PortEnableDisableChange = 0;
169 PortControl.PortReset = 0;
170
171 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
172
173 while (UhciHardwarePresent(UhciExtension))
174 {
175 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
176
177 if (PortControl.PortReset == 0)
178 break;
179 }
180
181 for (ix = 0; ix < 10; ++ix)
182 {
184
185 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
186
187 if (PortControl.PortEnabledDisabled == 1)
188 break;
189
190 PortControl.PortEnabledDisabled = 1;
191 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
192 }
193
194 PortControl.ConnectStatusChange = 1;
195 PortControl.PortEnableDisableChange = 1;
196 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
197
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)
203 {
204 DPRINT1("UhciRHPortResetComplete: Via chip. FIXME\n");
206 return;
207 }
208
209 UhciExtension->ResetChangePortMask |= (1 << (Port - 1));
210 UhciExtension->ResetPortMask &= ~(1 << (Port - 1));
211
212 RegPacket.UsbPortInvalidateRootHub(UhciExtension);
213}
214
215VOID
216NTAPI
218 IN PUSHORT pPort)
219{
220 PUHCI_HW_REGISTERS BaseRegister;
221 PUSHORT PortControlRegister;
222 UHCI_PORT_STATUS_CONTROL PortControl;
223 USHORT Port;
224
225 DPRINT("UhciRHSetFeaturePortResetWorker: ...\n");
226
227 BaseRegister = UhciExtension->BaseRegister;
228
229 Port = *(PUSHORT)pPort;
230 ASSERT(Port);
231
232 PortControlRegister = &BaseRegister->PortControl[Port - 1].AsUSHORT;
233 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
234
235 PortControl.ConnectStatusChange = 0;
236 PortControl.PortEnableDisableChange = 0;
237 PortControl.PortReset = 1;
238
239 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
240
242 10, // TimerValue
243 pPort,
244 sizeof(*pPort),
246}
247
249NTAPI
251 IN USHORT Port)
252{
253 PUHCI_EXTENSION UhciExtension = uhciExtension;
254 ULONG ResetPortMask;
255 ULONG PortBit;
256
257 DPRINT("UhciRHSetFeaturePortReset: ...\n");
258
259 ASSERT(Port);
260
261 ResetPortMask = UhciExtension->ResetPortMask;
262 PortBit = 1 << (Port - 1);
263
264 if (ResetPortMask & PortBit)
265 return MP_STATUS_FAILURE;
266
267 UhciExtension->ResetPortMask = ResetPortMask | PortBit;
268
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)
274 {
275 DPRINT1("UhciRHSetFeaturePortReset: Via chip. FIXME\n");
276 return MP_STATUS_SUCCESS;
277 }
278
279 UhciRHSetFeaturePortResetWorker(UhciExtension, &Port);
280
281 return MP_STATUS_SUCCESS;
282}
283
285NTAPI
287 IN USHORT Port)
288{
289 DPRINT("UhciRHSetFeaturePortPower: ...\n");
290 ASSERT(Port);
291 return MP_STATUS_SUCCESS;
292}
293
295NTAPI
297 IN USHORT Port,
298 IN BOOLEAN IsSet)
299{
300 PUHCI_EXTENSION UhciExtension = uhciExtension;
301 PUHCI_HW_REGISTERS BaseRegister;
302 PUSHORT PortControlRegister;
303 UHCI_PORT_STATUS_CONTROL PortControl;
304
305 DPRINT("UhciRHPortEnable: ...\n");
306
307 ASSERT(Port);
308
309 BaseRegister = UhciExtension->BaseRegister;
310 PortControlRegister = &BaseRegister->PortControl[Port-1].AsUSHORT;
311
312 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
313
314 PortControl.ConnectStatusChange = 0;
315 PortControl.PortEnableDisableChange = 0;
316
317 if (IsSet)
318 PortControl.PortEnabledDisabled = 1;
319 else
320 PortControl.PortEnabledDisabled = 0;
321
322 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
323
324 return MP_STATUS_SUCCESS;
325}
326
328NTAPI
330 IN USHORT Port)
331{
332 PUHCI_EXTENSION UhciExtension = uhciExtension;
333 DPRINT("UhciRHSetFeaturePortEnable: ...\n");
334 ASSERT(Port);
335 return UhciRHPortEnable(UhciExtension, Port, TRUE);
336}
337
339NTAPI
341 IN USHORT Port)
342{
343 DPRINT("UhciRHSetFeaturePortSuspend: UNIMPLEMENTED. FIXME\n");
344 ASSERT(Port);
345 return MP_STATUS_SUCCESS;
346}
347
349NTAPI
351 IN USHORT Port)
352{
353 PUHCI_EXTENSION UhciExtension = uhciExtension;
354 DPRINT("UhciRHClearFeaturePortEnable: ...\n");
355 ASSERT(Port);
356 return UhciRHPortEnable(UhciExtension, Port, FALSE);
357}
358
360NTAPI
362 IN USHORT Port)
363{
364 DPRINT("UhciRHClearFeaturePortPower: UNIMPLEMENTED. FIXME\n");
365 ASSERT(Port);
366 return MP_STATUS_SUCCESS;
367}
368
370NTAPI
372 IN USHORT Port)
373{
374 DPRINT("UhciRHClearFeaturePortSuspend: UNIMPLEMENTED. FIXME\n");
375 ASSERT(Port);
376 return MP_STATUS_SUCCESS;
377}
378
380NTAPI
382 IN USHORT Port)
383{
384 PUHCI_EXTENSION UhciExtension = uhciExtension;
385 PUHCI_HW_REGISTERS BaseRegister;
386 PUSHORT PortControlRegister;
387 UHCI_PORT_STATUS_CONTROL PortControl;
388
389 DPRINT("UhciRHClearFeaturePortEnableChange: ...\n");
390
391 ASSERT(Port);
392
393 BaseRegister = UhciExtension->BaseRegister;
394 PortControlRegister = (PUSHORT)&BaseRegister->PortControl[Port - 1];
395 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
396
397 PortControl.ConnectStatusChange = 0;
398 PortControl.PortEnableDisableChange = 1;
399 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
400
401 return MP_STATUS_SUCCESS;
402}
403
405NTAPI
407 IN USHORT Port)
408{
409 PUHCI_EXTENSION UhciExtension = uhciExtension;
410 PUHCI_HW_REGISTERS BaseRegister;
411 PUSHORT PortControlRegister;
412 UHCI_PORT_STATUS_CONTROL PortControl;
413
414 DPRINT("UhciRHClearFeaturePortConnectChange: Port - %04X\n", Port);
415
416 ASSERT(Port);
417
418 BaseRegister = UhciExtension->BaseRegister;
419 PortControlRegister = (PUSHORT)&BaseRegister->PortControl[Port - 1];
420 PortControl.AsUSHORT = READ_PORT_USHORT(PortControlRegister);
421
422 if (PortControl.ConnectStatusChange == 1)
423 {
424 /* WC (Write Clear) bits */
425 PortControl.PortEnableDisableChange = 0;
426 PortControl.ConnectStatusChange = 1;
427 WRITE_PORT_USHORT(PortControlRegister, PortControl.AsUSHORT);
428 }
429
430 return MP_STATUS_SUCCESS;
431}
432
434NTAPI
436 IN USHORT Port)
437{
438 PUHCI_EXTENSION UhciExtension = uhciExtension;
439 DPRINT("UhciRHClearFeaturePortResetChange: ...\n");
440 ASSERT(Port);
441 UhciExtension->ResetChangePortMask &= ~(1 << (Port - 1));
442 return MP_STATUS_SUCCESS;
443}
444
446NTAPI
448 IN USHORT Port)
449{
450 DPRINT("UhciRHClearFeaturePortSuspendChange: UNIMPLEMENTED. FIXME\n");
451 ASSERT(Port);
452 return MP_STATUS_SUCCESS;
453}
454
456NTAPI
458 IN USHORT Port)
459{
460 DPRINT("UhciRHClearFeaturePortOvercurrentChange: UNIMPLEMENTED. FIXME\n");
461 ASSERT(Port);
462 return MP_STATUS_SUCCESS;
463}
464
465VOID
466NTAPI
468{
469 /* Do nothing */
470 return;
471}
472
473VOID
474NTAPI
476{
477 /* Do nothing */
478 return;
479}
480
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:81
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define UHCI_NUM_ROOT_HUB_PORTS
Definition: hardware.h:9
Status
Definition: gdiplustypes.h:25
VOID NTAPI WRITE_PORT_USHORT(IN PUSHORT Port, IN USHORT Value)
Definition: portio.c:115
USHORT NTAPI READ_PORT_USHORT(IN PUSHORT Port)
Definition: portio.c:63
CPPORT Port[4]
Definition: headless.c:35
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:42
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define ASSERT(a)
Definition: mode.c:44
unsigned short USHORT
Definition: pedump.c:61
#define DPRINT
Definition: sndvol32.h:73
ULONG SuspendChangePortMask
Definition: usbuhci.h:170
ULONG ResetPortMask
Definition: usbuhci.h:168
ULONG ResetChangePortMask
Definition: usbuhci.h:169
PUHCI_HW_REGISTERS BaseRegister
Definition: usbuhci.h:154
USB_CONTROLLER_FLAVOR HcFlavor
Definition: usbuhci.h:155
UHCI_PORT_STATUS_CONTROL PortControl[UHCI_NUM_ROOT_HUB_PORTS]
Definition: hardware.h:135
PUSBPORT_REQUEST_ASYNC_CALLBACK UsbPortRequestAsyncCallback
Definition: usbmport.h:620
PUSBPORT_INVALIDATE_ROOT_HUB UsbPortInvalidateRootHub
Definition: usbmport.h:614
USBPORT_HUB_CHARACTERISTICS HubCharacteristics
Definition: usbmport.h:697
#define NTAPI
Definition: typedefs.h:36
uint16_t * PUSHORT
Definition: typedefs.h:56
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
USBPORT_HUB_11_CHARACTERISTICS Usb11HubCharacteristics
Definition: usbmport.h:688
USHORT AsUshort16
Definition: usb200.h:161
USHORT PortEnableDisableChange
Definition: usb200.h:164
USHORT ResetChange
Definition: usb200.h:167
USHORT SuspendChange
Definition: usb200.h:165
USHORT OverCurrentIndicatorChange
Definition: usb200.h:166
USHORT ConnectStatusChange
Definition: usb200.h:163
USHORT LowSpeedDeviceAttached
Definition: usb200.h:141
USHORT PortPower
Definition: usb200.h:140
USHORT CurrentConnectStatus
Definition: usb200.h:133
USHORT AsUshort16
Definition: usb200.h:131
USHORT OverCurrent
Definition: usb200.h:136
USHORT HighSpeedDeviceAttached
Definition: usb200.h:142
USHORT PortEnabledDisabled
Definition: usb200.h:134
#define USB_GETSTATUS_SELF_POWERED
Definition: usb100.h:45
@ UHCI_VIA_x03
Definition: usb.h:73
@ UHCI_VIA_x01
Definition: usb.h:71
@ UHCI_VIA
Definition: usb.h:70
@ UHCI_Piix4
Definition: usb.h:60
@ UHCI_VIA_x04
Definition: usb.h:74
@ UHCI_VIA_x02
Definition: usb.h:72
USBPORT_REGISTRATION_PACKET RegPacket
Definition: usbehci.c:16
ULONG MPSTATUS
Definition: usbmport.h:131
#define MP_STATUS_FAILURE
Definition: usbmport.h:135
#define MP_STATUS_SUCCESS
Definition: usbmport.h:134
VOID NTAPI UhciRHEnableIrq(IN PVOID uhciExtension)
Definition: roothub.c:475
MPSTATUS NTAPI UhciRHClearFeaturePortSuspend(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:371
MPSTATUS NTAPI UhciRHClearFeaturePortEnableChange(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:381
MPSTATUS NTAPI UhciRHPortEnable(IN PVOID uhciExtension, IN USHORT Port, IN BOOLEAN IsSet)
Definition: roothub.c:296
MPSTATUS NTAPI UhciRHClearFeaturePortPower(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:361
MPSTATUS NTAPI UhciRHSetFeaturePortReset(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:250
MPSTATUS NTAPI UhciRHClearFeaturePortEnable(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:350
MPSTATUS NTAPI UhciRHSetFeaturePortPower(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:286
MPSTATUS NTAPI UhciRHSetFeaturePortEnable(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:329
VOID NTAPI UhciRHGetRootHubData(IN PVOID uhciExtension, IN PVOID rootHubData)
Definition: roothub.c:15
MPSTATUS NTAPI UhciRHClearFeaturePortSuspendChange(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:447
MPSTATUS NTAPI UhciRHGetPortStatus(IN PVOID uhciExtension, IN USHORT Port, IN PUSB_PORT_STATUS_AND_CHANGE PortStatus)
Definition: roothub.c:50
MPSTATUS NTAPI UhciRHClearFeaturePortConnectChange(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:406
MPSTATUS NTAPI UhciRHClearFeaturePortResetChange(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:435
VOID NTAPI UhciRHSetFeaturePortResetWorker(IN PUHCI_EXTENSION UhciExtension, IN PUSHORT pPort)
Definition: roothub.c:217
MPSTATUS NTAPI UhciRHGetStatus(IN PVOID uhciExtension, IN PUSHORT Status)
Definition: roothub.c:40
MPSTATUS NTAPI UhciRHSetFeaturePortSuspend(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:340
VOID NTAPI UhciRHPortResetComplete(IN PVOID uhciExtension, IN PVOID pPort)
Definition: roothub.c:147
MPSTATUS NTAPI UhciRHGetHubStatus(IN PVOID uhciExtension, IN PUSB_HUB_STATUS_AND_CHANGE HubStatus)
Definition: roothub.c:137
MPSTATUS NTAPI UhciRHClearFeaturePortOvercurrentChange(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:457
VOID NTAPI UhciRHDisableIrq(IN PVOID uhciExtension)
Definition: roothub.c:467
BOOLEAN NTAPI UhciHardwarePresent(IN PUHCI_EXTENSION UhciExtension)
Definition: usbuhci.c:792