ReactOS  0.4.14-dev-297-g23e575c
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 
13 VOID
14 NTAPI
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 
39 NTAPI
40 UhciRHGetStatus(IN PVOID uhciExtension,
42 {
43  DPRINT("UhciRHGetStatus: ...\n");
45  return MP_STATUS_SUCCESS;
46 }
47 
49 NTAPI
51  IN USHORT Port,
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 
135 MPSTATUS
136 NTAPI
138  IN PUSB_HUB_STATUS_AND_CHANGE HubStatus)
139 {
140  //DPRINT("UhciRHGetHubStatus: ...\n");
141  HubStatus->AsUlong32 = 0;
142  return MP_STATUS_SUCCESS;
143 }
144 
145 VOID
146 NTAPI
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  DPRINT("UhciRHPortResetComplete: Via chip. FIXME\n");
205  DbgBreakPoint();
206  return;
207  }
208 
209  UhciExtension->ResetChangePortMask |= (1 << (Port - 1));
210  UhciExtension->ResetPortMask &= ~(1 << (Port - 1));
211 
212  RegPacket.UsbPortInvalidateRootHub(UhciExtension);
213 }
214 
215 VOID
216 NTAPI
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 
248 MPSTATUS
249 NTAPI
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 
284 MPSTATUS
285 NTAPI
287  IN USHORT Port)
288 {
289  DPRINT("UhciRHSetFeaturePortPower: ...\n");
290  ASSERT(Port);
291  return MP_STATUS_SUCCESS;
292 }
293 
294 MPSTATUS
295 NTAPI
296 UhciRHPortEnable(IN PVOID uhciExtension,
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 
327 MPSTATUS
328 NTAPI
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 
338 MPSTATUS
339 NTAPI
341  IN USHORT Port)
342 {
343  DPRINT("UhciRHSetFeaturePortSuspend: UNIMPLEMENTED. FIXME\n");
344  ASSERT(Port);
345  return MP_STATUS_SUCCESS;
346 }
347 
348 MPSTATUS
349 NTAPI
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 
359 MPSTATUS
360 NTAPI
362  IN USHORT Port)
363 {
364  DPRINT("UhciRHClearFeaturePortPower: UNIMPLEMENTED. FIXME\n");
365  ASSERT(Port);
366  return MP_STATUS_SUCCESS;
367 }
368 
369 MPSTATUS
370 NTAPI
372  IN USHORT Port)
373 {
374  DPRINT("UhciRHClearFeaturePortSuspend: UNIMPLEMENTED. FIXME\n");
375  ASSERT(Port);
376  return MP_STATUS_SUCCESS;
377 }
378 
379 MPSTATUS
380 NTAPI
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 
404 MPSTATUS
405 NTAPI
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 
433 MPSTATUS
434 NTAPI
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 
445 MPSTATUS
446 NTAPI
448  IN USHORT Port)
449 {
450  DPRINT("UhciRHClearFeaturePortSuspendChange: UNIMPLEMENTED. FIXME\n");
451  ASSERT(Port);
452  return MP_STATUS_SUCCESS;
453 }
454 
455 MPSTATUS
456 NTAPI
458  IN USHORT Port)
459 {
460  DPRINT("UhciRHClearFeaturePortOvercurrentChange: UNIMPLEMENTED. FIXME\n");
461  ASSERT(Port);
462  return MP_STATUS_SUCCESS;
463 }
464 
465 VOID
466 NTAPI
467 UhciRHDisableIrq(IN PVOID uhciExtension)
468 {
469  /* Do nothing */
470  return;
471 }
472 
473 VOID
474 NTAPI
475 UhciRHEnableIrq(IN PVOID uhciExtension)
476 {
477  /* Do nothing */
478  return;
479 }
480 
ULONG MPSTATUS
Definition: usbmport.h:131
VOID NTAPI UhciRHPortResetComplete(IN PVOID uhciExtension, IN PVOID pPort)
Definition: roothub.c:147
#define UHCI_NUM_ROOT_HUB_PORTS
Definition: hardware.h:9
CPPORT Port[4]
Definition: headless.c:34
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
USBPORT_REGISTRATION_PACKET RegPacket
Definition: usbehci.c:16
MPSTATUS NTAPI UhciRHSetFeaturePortSuspend(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:340
VOID NTAPI WRITE_PORT_USHORT(IN PUSHORT Port, IN USHORT Value)
Definition: portio.c:115
USHORT CurrentConnectStatus
Definition: usb200.h:133
PUHCI_HW_REGISTERS BaseRegister
Definition: usbuhci.h:154
MPSTATUS NTAPI UhciRHClearFeaturePortConnectChange(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:406
void DbgBreakPoint()
Definition: mach.c:553
VOID NTAPI UhciRHGetRootHubData(IN PVOID uhciExtension, IN PVOID rootHubData)
Definition: roothub.c:15
MPSTATUS NTAPI UhciRHClearFeaturePortPower(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:361
MPSTATUS NTAPI UhciRHGetHubStatus(IN PVOID uhciExtension, IN PUSB_HUB_STATUS_AND_CHANGE HubStatus)
Definition: roothub.c:137
USHORT HighSpeedDeviceAttached
Definition: usb200.h:142
VOID NTAPI UhciRHEnableIrq(IN PVOID uhciExtension)
Definition: roothub.c:475
ULONG ResetChangePortMask
Definition: usbuhci.h:169
USHORT PortPower
Definition: usb200.h:140
MPSTATUS NTAPI UhciRHClearFeaturePortResetChange(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:435
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
USBPORT_HUB_CHARACTERISTICS HubCharacteristics
Definition: usbmport.h:697
MPSTATUS NTAPI UhciRHPortEnable(IN PVOID uhciExtension, IN USHORT Port, IN BOOLEAN IsSet)
Definition: roothub.c:296
MPSTATUS NTAPI UhciRHClearFeaturePortSuspend(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:371
PUSBPORT_REQUEST_ASYNC_CALLBACK UsbPortRequestAsyncCallback
Definition: usbmport.h:620
BOOLEAN NTAPI UhciHardwarePresent(IN PUHCI_EXTENSION UhciExtension)
Definition: usbuhci.c:792
unsigned char BOOLEAN
USHORT SuspendChange
Definition: usb200.h:165
void DPRINT(...)
Definition: polytest.cpp:61
USHORT PortEnableDisableChange
Definition: usb200.h:164
#define MP_STATUS_FAILURE
Definition: usbmport.h:135
MPSTATUS NTAPI UhciRHSetFeaturePortReset(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:250
Definition: usb.h:60
PUSBPORT_INVALIDATE_ROOT_HUB UsbPortInvalidateRootHub
Definition: usbmport.h:614
USHORT OverCurrent
Definition: usb200.h:136
USHORT AsUshort16
Definition: usb200.h:131
MPSTATUS NTAPI UhciRHGetStatus(IN PVOID uhciExtension, IN PUSHORT Status)
Definition: roothub.c:40
Definition: usb.h:70
MPSTATUS NTAPI UhciRHClearFeaturePortSuspendChange(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:447
USHORT AsUshort16
Definition: usb200.h:161
VOID NTAPI UhciRHSetFeaturePortResetWorker(IN PUHCI_EXTENSION UhciExtension, IN PUSHORT pPort)
Definition: roothub.c:217
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI UhciRHDisableIrq(IN PVOID uhciExtension)
Definition: roothub.c:467
USHORT ConnectStatusChange
Definition: usb200.h:163
#define USB_GETSTATUS_SELF_POWERED
Definition: usb100.h:45
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:40
USBPORT_HUB_11_CHARACTERISTICS Usb11HubCharacteristics
Definition: usbmport.h:688
Status
Definition: gdiplustypes.h:24
USHORT LowSpeedDeviceAttached
Definition: usb200.h:141
MPSTATUS NTAPI UhciRHClearFeaturePortOvercurrentChange(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:457
MPSTATUS NTAPI UhciRHClearFeaturePortEnable(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:350
UHCI_PORT_STATUS_CONTROL PortControl[UHCI_NUM_ROOT_HUB_PORTS]
Definition: hardware.h:135
MPSTATUS NTAPI UhciRHGetPortStatus(IN PVOID uhciExtension, IN USHORT Port, IN PUSB_PORT_STATUS_AND_CHANGE PortStatus)
Definition: roothub.c:50
unsigned short USHORT
Definition: pedump.c:61
MPSTATUS NTAPI UhciRHSetFeaturePortPower(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:286
USHORT PortEnabledDisabled
Definition: usb200.h:134
MPSTATUS NTAPI UhciRHSetFeaturePortEnable(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:329
#define MP_STATUS_SUCCESS
Definition: usbmport.h:134
#define DPRINT1
Definition: precomp.h:8
USB_CONTROLLER_FLAVOR HcFlavor
Definition: usbuhci.h:155
MPSTATUS NTAPI UhciRHClearFeaturePortEnableChange(IN PVOID uhciExtension, IN USHORT Port)
Definition: roothub.c:381
ULONG ResetPortMask
Definition: usbuhci.h:168
unsigned int ULONG
Definition: retypes.h:1
USHORT NTAPI READ_PORT_USHORT(IN PUSHORT Port)
Definition: portio.c:63
USHORT OverCurrentIndicatorChange
Definition: usb200.h:166
ULONG SuspendChangePortMask
Definition: usbuhci.h:170
USHORT ResetChange
Definition: usb200.h:167
unsigned short * PUSHORT
Definition: retypes.h:2
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:99