ReactOS 0.4.17-dev-1281-g065abb3
fdo.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS SuperSpeed USB Hub Driver
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Hub FDO creation, PnP and power callbacks, hub machine glue
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "usbhub3.h"
9
10#define NDEBUG
11#include <debug.h>
12
13/* Hub timer durations in ms */
14#define HUB_OVERCURRENT_TIME 500
15#define HUB_RESET_RETRY_TIME 500
16#define HUB_DESCRIPTOR_RETRY_TIME 100
17
18#define HUB_DEFAULT_IDLE_TIMEOUT 50
19#define HUB_ROOT_MAX_PORT_POWER 500
20
21/* Hub resets in a row, and recoveries per window, before giving up */
22#define HUB_RESET_LIMIT 3
23#define HUB_RECOVERY_LIMIT 10
24#define HUB_RECOVERY_WINDOW (60LL * 1000 * 1000 * 10)
25
26/* PnP problem text "hub reset failed" */
27#define HUB_MSG_HUB_RESET_FAILED 0x40020003
28
29/* Container of devices built into the computer */
31 RTL_CONSTANT_STRING(L"{00000000-0000-0000-FFFF-FFFFFFFFFFFF}");
32
33/* Description shown for a hub whose SuperSpeed side was turned off by errata */
34static const WCHAR HubNonFunctionalDescription[] = L"SuperSpeed USB Hub (Non Functional)";
35
36HubFdo*
38 _In_ WDFDEVICE Device)
39{
40 return HubGetFdoContext(Device);
41}
42
43/* Work items */
44
47{
49 WdfDeviceWdmGetDeviceObject(m_Device),
51}
52
53VOID
58 _In_ BOOLEAN ForwardProgress)
59{
61 Routine,
62 Context,
64}
65
67VOID
68HubFdo::FlushAndDeleteWorkItem(
70{
71 if (*WorkItem == NULL)
72 return;
73
76 *WorkItem = NULL;
77}
78
79/* The hub machine answers every PnP and power event by signaling m_PnpEvent */
82HubFdo::PostAndWait(
85{
86 PAGED_CODE();
87
88 DPRINT("Hub %p posting %s\n", m_Device, What);
89
91 Post(Event);
92 HubWaitForPnpEvent(&m_PnpEvent, What, m_Device);
93
95 DPRINT1("Hub %p %s failed 0x%lx\n", m_Device, What, m_PnpStatus);
96
97 return m_PnpStatus;
98}
99
100/*
101 * Raised to DISPATCH_LEVEL so KMDF cannot call a blocking PDO power callback
102 * on this thread while the hub machine holds it.
103 */
104VOID
106{
109
110 NT_ASSERT(!HasFlag(HubFlag::PowerReferencePending));
111
115
116 if (NT_SUCCESS(Status))
117 SetFlag(HubFlag::PowerReferencePending);
118 else
119 DPRINT1("Hub %p power reference failed 0x%lx\n", m_Device, Status);
120}
121
122VOID
124{
126
127 if (!HasFlag(HubFlag::PowerReferencePending))
128 return;
129
133
134 ClearFlag(HubFlag::PowerReferencePending);
135}
136
137/* AddDevice pieces */
138
141HubFdo::QueryCapabilities()
142{
146 WDFREQUEST Request;
147 WDFIOTARGET Target = WdfDeviceGetIoTarget(m_Device);
149
150 PAGED_CODE();
151
152 Status = WdfRequestCreate(WDF_NO_OBJECT_ATTRIBUTES, Target, &Request);
153 if (!NT_SUCCESS(Status))
154 {
155 DPRINT1("Hub %p capabilities request create failed 0x%lx\n", m_Device, Status);
156 return Status;
157 }
158
159 /* PnP IRPs must start out as not supported */
161 WdfRequestReuse(Request, &Reuse);
162
164 m_Capabilities.Size = sizeof(m_Capabilities);
165 m_Capabilities.Version = 1;
166 m_Capabilities.Address = MAXULONG;
167 m_Capabilities.UINumber = MAXULONG;
168
169 RtlZeroMemory(&Stack, sizeof(Stack));
170 Stack.MajorFunction = IRP_MJ_PNP;
171 Stack.MinorFunction = IRP_MN_QUERY_CAPABILITIES;
172 Stack.Parameters.DeviceCapabilities.Capabilities = &m_Capabilities;
173 WdfRequestWdmFormatUsingStackLocation(Request, &Stack);
174
177 Status = WdfRequestGetStatus(Request);
178 if (!NT_SUCCESS(Status))
179 DPRINT1("Hub %p capabilities query failed 0x%lx\n", m_Device, Status);
180
182 return Status;
183}
184
185/* The current interface layouts are asked for; the hub writes its own fields before each query */
188HubFdo::QueryInterfaces()
189{
191
192 PAGED_CODE();
193
196
197 Status = WdfFdoQueryForInterface(m_Device,
198 &GUID_UCXHUB_PARENT_INTERFACE,
200 sizeof(m_Parent),
202 NULL);
203 if (!NT_SUCCESS(Status))
204 {
205 DPRINT1("Hub %p parent interface query failed 0x%lx\n", m_Device, Status);
206 return Status;
207 }
208
209 if (IsRootHub())
210 {
211 m_ParentInfo.RootHubPdo = WdfIoTargetWdmGetTargetDeviceObject(WdfDeviceGetIoTarget(m_Device));
212 m_RootHubTarget = WdfDeviceGetIoTarget(m_Device);
214 }
215
216 return STATUS_SUCCESS;
217}
218
219/* The parent stack may not do selective suspend or SuperSpeedPlus isoch bursts */
221VOID
222HubFdo::ProbeParentCapabilities()
223{
224 USBD_HANDLE Handle;
226
227 PAGED_CODE();
228
229 Status = USBD_CreateHandle(WdfDeviceWdmGetDeviceObject(m_Device),
230 WdfIoTargetWdmGetTargetDeviceObject(WdfDeviceGetIoTarget(m_Device)),
233 &Handle);
234 if (NT_SUCCESS(Status))
235 {
237 &GUID_USB_CAPABILITY_HIGH_BANDWIDTH_ISOCH,
238 sizeof(m_SspIsochBurstCount),
240 NULL)))
241 {
243 }
244
245 Status = USBD_QueryUsbCapability(Handle, &GUID_USB_CAPABILITY_SELECTIVE_SUSPEND, 0, NULL, NULL);
247 }
248
249 if (!NT_SUCCESS(Status))
250 {
251 DPRINT1("Hub %p parent stack has no selective suspend 0x%lx\n", m_Device, Status);
252 SetFlag(HubFlag::ParentNoSelectiveSuspend);
253 }
254}
255
258HubFdo::AssignIdleSettings(
260{
262
263 PAGED_CODE();
264
266 Settings.IdleTimeout = m_IdleTimeout;
267 Settings.UserControlOfIdleSettings = IdleAllowUserControl;
268 Settings.Enabled = WdfUseDefault;
269 Settings.DxState = PowerDeviceD2;
270 Settings.IdleTimeoutType = TimeoutType;
271
272 return WdfDeviceAssignS0IdleSettings(m_Device, &Settings);
273}
274
275/*
276 * The root hub leaves its idle timeout to the power framework so it stays in D0
277 * during surprise removal, which avoids a UCX deadlock on controller reset.
278 * Failures here are ignored.
279 */
281VOID
282HubFdo::ConfigureIdle()
283{
286
287 PAGED_CODE();
288
290
291 if (!HasFlag(HubFlag::ParentNoSelectiveSuspend) && m_Parent.ParentCanWake)
292 {
294 if (NT_SUCCESS(Status))
295 {
296 SetFlag(HubFlag::S0IdleConfigured);
297
299 !NT_SUCCESS(HubDriver.RegisterPowerSetting(WdfDeviceWdmGetDeviceObject(m_Device),
300 &GUID_HUB_IDLE_TIMEOUT_SETTING,
302 this,
304 {
305 DPRINT1("Hub %p idle timeout setting registration failed\n", m_Device);
307 }
308 }
309 else
310 {
311 DPRINT1("Hub %p cannot idle, 0x%lx\n", m_Device, Status);
312 }
313 }
314
316
318 Wake.ArmForWakeIfChildrenAreArmedForWake = TRUE;
319 Wake.IndicateChildWakeOnParentWake = TRUE;
320 Wake.Enabled = WdfFalse;
321 Wake.UserControlOfWakeSettings = WakeDoNotAllowUserControl;
322
323 Status = WdfDeviceAssignSxWakeSettings(m_Device, &Wake);
324 if (!NT_SUCCESS(Status))
325 DPRINT1("Hub %p Sx wake settings failed 0x%lx\n", m_Device, Status);
326}
327
330HubFdo::CreateQueue()
331{
334
335 PAGED_CODE();
336
337 /* Most requests return cached data; the ones that need D0 go through a machine */
339 Config.PowerManaged = WdfFalse;
340 Config.EvtIoDeviceControl = HubEvtIoDeviceControl;
341 Config.EvtIoInternalDeviceControl = HubEvtIoInternalDeviceControl;
342
344 Attributes.ExecutionLevel = WdfExecutionLevelPassive;
345
346 return WdfIoQueueCreate(m_Device, &Config, &Attributes, WDF_NO_HANDLE);
347}
348
349/* The KTIMER based machine timer needs no allocation */
352HubFdo::InitializeMachine()
353{
355 WDFIOTARGET Target = WdfDeviceGetIoTarget(m_Device);
356 HubKind Kind;
358
359 PAGED_CODE();
360
362 if (!NT_SUCCESS(Status))
363 {
364 DPRINT1("Hub %p control transfer setup failed 0x%lx\n", m_Device, Status);
365 return Status;
366 }
367
369 Attributes.ParentObject = m_Device;
370
371 Status = WdfRequestCreate(&Attributes, Target, &m_Interrupt.Request);
372 if (!NT_SUCCESS(Status))
373 {
374 DPRINT1("Hub %p interrupt request create failed 0x%lx\n", m_Device, Status);
375 return Status;
376 }
377
379
380 if (IsRootHub())
381 {
382 Kind = HubKind::Root;
383 }
385 {
386 Kind = HubKind::Usb20;
387 }
388 else if (m_Parent.HubSpeed == UsbSuperSpeed)
389 {
390 Kind = HubKind::Usb30;
391 }
392 else
393 {
394 /* A low speed hub cannot exist */
395 DPRINT1("Hub %p has unsupported speed %lu\n", m_Device, (ULONG)m_Parent.HubSpeed);
397 }
398
400
402 if (m_WorkItem == NULL)
403 {
404 DPRINT1("Hub %p work item allocation failed\n", m_Device);
406 }
407
408 m_Machine.Initialize(this, Kind);
409 return STATUS_SUCCESS;
410}
411
412/* Everything AddDevice does once the WDFDEVICE exists */
415HubFdo::Initialize(
416 _In_ WDFDEVICE Device)
417{
419 PNP_BUS_INFORMATION BusInfo;
421
422 PAGED_CODE();
423
424 Status = IoRegisterShutdownNotification(WdfDeviceWdmGetDeviceObject(Device));
425 if (!NT_SUCCESS(Status))
426 DPRINT1("Hub %p shutdown registration failed 0x%lx\n", Device, Status);
427
429 m_WdmPdo = WdfDeviceWdmGetPhysicalDevice(Device);
432
433 Status = HubAllocateHubNumber(&m_HubNumber);
434 if (!NT_SUCCESS(Status))
435 {
436 DPRINT1("Hub %p hub number allocation failed 0x%lx\n", Device, Status);
437 return Status;
438 }
439
440 Status = HubUsb4Initialize(this);
441 if (!NT_SUCCESS(Status))
442 return Status;
443
448
449 Status = QueryCapabilities();
450 if (!NT_SUCCESS(Status))
451 return Status;
452
454 PnpCaps.SurpriseRemovalOK = WdfTrue;
455 WdfDeviceSetPnpCapabilities(Device, &PnpCaps);
456
457 Status = QueryInterfaces();
458 if (!NT_SUCCESS(Status))
459 return Status;
460
461 ProbeParentCapabilities();
462 ConfigureIdle();
463
464 RtlZeroMemory(&m_Stack, sizeof(m_Stack));
466 m_Stack.HubContext = (UCXHUB_HUB_CONTEXT)this;
469
470 Status = WdfFdoQueryForInterface(Device,
471 &GUID_UCXHUB_STACK_INTERFACE,
473 sizeof(m_Stack),
475 NULL);
476 if (!NT_SUCCESS(Status))
477 {
478 /* A controller extension without endpoint priorities still answers version 1 */
479 Status = WdfFdoQueryForInterface(Device,
480 &GUID_UCXHUB_STACK_INTERFACE,
482 sizeof(m_Stack),
484 NULL);
485 }
486
487 if (!NT_SUCCESS(Status))
488 {
489 DPRINT1("Hub %p stack interface query failed 0x%lx\n", Device, Status);
490 return Status;
491 }
492
493 RtlZeroMemory(&m_Usbdi, sizeof(m_Usbdi));
494 Status = WdfFdoQueryForInterface(Device,
495 &USB_BUS_INTERFACE_USBDI_GUID,
497 sizeof(m_Usbdi),
499 IsRootHub() ? (PVOID)UsbDevice() : NULL);
500 if (!NT_SUCCESS(Status))
501 {
502 DPRINT1("Hub %p USBDI interface query failed 0x%lx\n", Device, Status);
503 return Status;
504 }
505
506 Status = CreateQueue();
507 if (!NT_SUCCESS(Status))
508 {
509 DPRINT1("Hub %p queue create failed 0x%lx\n", Device, Status);
510 return Status;
511 }
512
513 BusInfo.BusTypeGuid = GUID_BUS_TYPE_USB;
514 BusInfo.LegacyBusType = PNPBus;
515 BusInfo.BusNumber = 0;
516 WdfDeviceSetBusInformationForChildren(Device, &BusInfo);
517
519
520 Status = InitializeMachine();
521 if (!NT_SUCCESS(Status))
522 return Status;
523
524 SetFlag(HubFlag::Initialized);
525 return PostAndWait(HubEvent::DeviceAdded, "DeviceAdded");
526}
527
529NTAPI
531 _In_ WDFDRIVER Driver,
533{
537 WDFDEVICE Device;
538 HubFdo* Hub;
540
542
543 PAGED_CODE();
544
546 Attributes.EvtCleanupCallback = EvtCleanup;
547 Attributes.EvtDestroyCallback = EvtDestroy;
548
550 PnpPower.EvtDeviceD0Entry = EvtD0Entry;
551 PnpPower.EvtDeviceD0Exit = EvtD0Exit;
556 WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &PnpPower);
557
558 Status = WdfDeviceInitAssignWdmIrpPreprocessCallback(DeviceInit, EvtShutdown, IRP_MJ_SHUTDOWN, NULL, 0);
559 if (!NT_SUCCESS(Status))
560 {
561 DPRINT1("Shutdown preprocess callback failed 0x%lx\n", Status);
562 return Status;
563 }
564
570 WdfDeviceInitSetPowerPolicyEventCallbacks(DeviceInit, &PowerPolicy);
571
572 /* Children get release hardware first when D0 entry fails */
573 WdfDeviceInitSetReleaseHardwareOrderOnFailure(DeviceInit, WdfReleaseHardwareOrderOnFailureAfterDescendants);
574
575 Status = WdfDeviceCreate(&DeviceInit, &Attributes, &Device);
576 if (!NT_SUCCESS(Status))
577 {
578 DPRINT1("Hub WdfDeviceCreate failed 0x%lx\n", Status);
579 return Status;
580 }
581
582 Hub = new (HubGetFdoContext(Device)) HubFdo();
583 Status = Hub->Initialize(Device);
584
585 /* A zero number keeps the cleanup callback from releasing it twice */
586 if (!NT_SUCCESS(Status) && Hub->m_HubNumber != 0)
587 {
588 HubReleaseHubNumber(Hub->m_HubNumber);
589 Hub->m_HubNumber = 0;
590 }
591
592 if (NT_SUCCESS(Status))
593 DPRINT("Hub %p added, root %u\n", Device, Hub->IsRootHub());
594
595 return Status;
596}
597
598/* PnP and power callbacks */
599
600/* ReactOS PnP does not report container IDs yet, so a failed query counts as the system container */
602static
604NTAPI
605HubFdoInSystemContainer(
606 _In_ HubFdo* Hub)
607{
608 WDFMEMORY Memory;
611 size_t Bytes;
614
615 Status = WdfDeviceAllocAndQueryProperty(Hub->m_Device,
617 PagedPool,
619 &Memory);
620 if (!NT_SUCCESS(Status))
621 {
622 DPRINT("Hub %p container ID query failed 0x%lx\n", Hub, Status);
623 return TRUE;
624 }
625
626 Buffer = (PWCHAR)WdfMemoryGetBuffer(Memory, &Bytes);
627 ContainerId.Buffer = Buffer;
628 ContainerId.Length = 0;
629 while (ContainerId.Length + sizeof(WCHAR) <= Bytes && ContainerId.Length < MAXUSHORT - 1 &&
630 Buffer[ContainerId.Length / sizeof(WCHAR)] != UNICODE_NULL)
631 {
632 ContainerId.Length += sizeof(WCHAR);
633 }
634 ContainerId.MaximumLength = ContainerId.Length;
635
638 return Result;
639}
640
646static
647VOID
648NTAPI
649HubFdoApplyTunnelLpmRule(
650 _In_ HubFdo* Hub)
651{
652 HubPdo* ParentPdo;
654
655 if (Hub->IsRootHub())
656 {
657 Disable = !HubFdoInSystemContainer(Hub);
658 }
659 else
660 {
661 /* The parent interface context of an external hub is its PDO in the parent hub */
662 ParentPdo = (HubPdo*)Hub->m_Parent.Header.Context;
664 }
665
666 if (!Disable)
667 return;
668
669 DPRINT("Hub %p turns link power management off below it\n", Hub);
671}
672
673/* A failed prepare still puts the hub on the list; release hardware takes it off */
675NTAPI
677 _In_ WDFDEVICE Device,
678 _In_ WDFCMRESLIST ResourcesRaw,
679 _In_ WDFCMRESLIST ResourcesTranslated)
680{
684
687
688 PAGED_CODE();
689
690 DPRINT("Hub %p prepare hardware, root %u\n", Device, Hub->IsRootHub());
691
692 HubReadHubRegistryValues(Hub);
693 HubReadUsb4HostName(Hub);
694 HubFdoApplyTunnelLpmRule(Hub);
695
696 Status = Hub->PostAndWait(HubEvent::PrepareHardware, "PrepareHardware");
697 if (!NT_SUCCESS(Status))
698 goto Exit;
699
700 if (Hub->HasFlag(HubFlag::DisableSuperSpeed))
701 {
702 Status = IoSetDevicePropertyData(Hub->m_WdmPdo,
703 &DEVPKEY_Device_DeviceDesc,
709 if (!NT_SUCCESS(Status))
710 DPRINT1("Hub %p description update failed 0x%lx\n", Device, Status);
711 }
712
713 RtlZeroMemory(&Name, sizeof(Name));
715 if (Name.Length == 0)
716 {
717 DPRINT1("Hub %p has no symbolic link name\n", Device);
719 goto Exit;
720 }
721
722 /* Twice the length is allocated */
725 {
726 DPRINT1("Hub %p symbolic link name allocation failed\n", Device);
728 goto Exit;
729 }
730
733
734 Status = HubAcpiReadPortAttributes(Hub);
735 if (!NT_SUCCESS(Status))
736 {
737 DPRINT1("Hub %p ACPI port walk failed 0x%lx\n", Device, Status);
738 goto Exit;
739 }
740
741 HubConnectorMapPorts(Hub);
742 HubUsb4MapDvsecHosts(Hub);
743
744 Status = HubUsb4AssignPortMappings(Hub);
745 if (!NT_SUCCESS(Status))
746 DPRINT1("Hub %p USB4 port mapping property failed 0x%lx\n", Device, Status);
747
748 HubWmiRegister(Hub);
749
752
753 HubDromReportFirmwareUpdateDevice(Hub);
754
756
757Exit:
758 {
760
763 }
764
765 DPRINT("Hub %p prepare hardware done 0x%lx, flags 0x%lx\n", Device, Status, (ULONG)Hub->m_Flags);
766
767 return Status;
768}
769
770/* The controller is kept in D0 while the devices below are torn down in it */
772NTAPI
774 _In_ WDFDEVICE Device,
775 _In_ WDFCMRESLIST ResourcesTranslated)
776{
780
782
783 PAGED_CODE();
784
785 DPRINT("Hub %p release hardware\n", Device);
786
787 Hub->ClearFlag(HubFlag::PowerReferenceAllowed);
788 HubConnectorUnmapPorts(Hub);
789 HubUsb4UnregisterNotification(Hub);
790
791 RtlZeroMemory(&StopIdle, sizeof(StopIdle));
793
794 Status = Hub->PostAndWait(HubEvent::ReleaseHardware, "ReleaseHardware");
795
797
798 {
800
801 if (Hub->m_OnHubList)
802 {
806 }
807 }
808
810 {
813 }
814
815 return Status;
816}
817
818/* The on/off setting takes a power reference, so it waits for the first D0 */
820NTAPI
822 _In_ WDFDEVICE Device,
824{
826 POWER_ACTION Action = WdfDeviceGetSystemPowerAction(Device);
827
829
831 Hub->SetFlag(HubFlag::PowerReferenceAllowed);
832 HubUsb4RegisterNotification(Hub);
833
835 Hub->HasFlag(HubFlag::S0IdleConfigured) &&
837 !NT_SUCCESS(HubDriver.RegisterPowerSetting(WdfDeviceWdmGetDeviceObject(Device),
838 &GUID_HUB_SELECTIVE_SUSPEND_POLICY,
840 Hub,
842 {
843 DPRINT1("Hub %p selective suspend setting registration failed\n", Device);
845 }
846
847 DPRINT("Hub %p D0 entry from state %d, action %d\n",
848 Device, (int)PreviousState, (int)Action);
849
850 switch (Action)
851 {
852 case PowerActionSleep:
857 return Hub->PostAndWait(HubEvent::D0EntryFromSx, "D0EntryFromSx");
858
859 case PowerActionNone:
860 return Hub->PostAndWait(HubEvent::D0Entry, "D0Entry");
861
862 default:
863 DPRINT1("Hub %p D0 entry with unexpected power action %d\n", Device, (int)Action);
865 return STATUS_SUCCESS;
866 }
867}
868
870NTAPI
872 _In_ WDFDEVICE Device,
874{
876 POWER_ACTION Action = WdfDeviceGetSystemPowerAction(Device);
877
879 Hub->ClearFlag(HubFlag::PowerReferenceAllowed);
880
881 DPRINT("Hub %p D0 exit to state %d, action %d\n",
882 Device, (int)TargetState, (int)Action);
883
884 switch (Action)
885 {
886 case PowerActionSleep:
891 return Hub->PostAndWait(HubEvent::D0Exit, "D0Exit");
892
893 case PowerActionNone:
895 return Hub->PostAndWait(HubEvent::D0ExitFinal, "D0ExitFinal");
896 return Hub->PostAndWait(HubEvent::D0Exit, "D0Exit");
897
898 default:
899 DPRINT1("Hub %p D0 exit with unexpected power action %d\n", Device, (int)Action);
900 return STATUS_SUCCESS;
901 }
902}
903
904/* The hub machine never sees surprise removal; only the ports do */
905VOID
906NTAPI
908 _In_ WDFDEVICE Device)
909{
910 DPRINT("Hub %p surprise removed\n", Device);
912}
913
914/* Leaving a path is ignored and wake stays armed */
915VOID
916NTAPI
918 _In_ WDFDEVICE Device,
921{
922 static BOOLEAN CodeLocked = FALSE;
926
927 PAGED_CODE();
928
930 return;
931
932 DPRINT("Hub %p in special file path %d\n", Device, (int)NotificationType);
933
934 switch (NotificationType)
935 {
938 Hub->SetFlag(HubFlag::InBootOrPagingPath);
939
941 Wake.ArmForWakeIfChildrenAreArmedForWake = TRUE;
942 Wake.IndicateChildWakeOnParentWake = TRUE;
943 Wake.Enabled = WdfTrue;
944 Wake.UserControlOfWakeSettings = WakeDoNotAllowUserControl;
945 Status = WdfDeviceAssignSxWakeSettings(Device, &Wake);
946 if (!NT_SUCCESS(Status))
947 DPRINT1("Hub %p boot path Sx wake settings failed 0x%lx\n", Device, Status);
948
949 /* Fall through */
952 return;
953
955 HubRequestReservedIo(Hub);
956
957 /* Never unlocked */
958 if (Hub->IsRootHub() && !CodeLocked)
959 {
960 CodeLocked = TRUE;
962 }
963 break;
964
965 default:
966 break;
967 }
968}
969
971NTAPI
973 _In_ WDFDEVICE Device)
974{
976
977 Hub->SetFlag(HubFlag::ArmedForWake);
978 Hub->SetFlag(HubFlag::WaitWakeQueued);
979 return STATUS_SUCCESS;
980}
981
982VOID
983NTAPI
985 _In_ WDFDEVICE Device)
986{
988
989 Hub->ClearFlag(HubFlag::ArmedForWake);
990 Hub->ClearFlag(HubFlag::WaitWakeQueued);
991}
992
994NTAPI
996 _In_ WDFDEVICE Device)
997{
998 FromDevice(Device)->SetFlag(HubFlag::WaitWakeQueued);
999 return STATUS_SUCCESS;
1000}
1001
1002VOID
1003NTAPI
1005 _In_ WDFDEVICE Device)
1006{
1007 FromDevice(Device)->ClearFlag(HubFlag::WaitWakeQueued);
1008}
1009
1010VOID
1011NTAPI
1014{
1015 HubFdo* Hub = HubGetFdoContext(Object);
1017
1018 PAGED_CODE();
1019
1020 DPRINT("Hub %p cleanup\n", Object);
1021
1022 HubUsb4UnregisterNotification(Hub);
1023 HubUsb4CloseAllHosts(Hub);
1024
1026 {
1028 if (!NT_SUCCESS(Status))
1029 DPRINT1("Hub %p idle timeout setting unregister failed 0x%lx\n", Object, Status);
1031 }
1032
1034 {
1036 if (!NT_SUCCESS(Status))
1037 DPRINT1("Hub %p selective suspend setting unregister failed 0x%lx\n", Object, Status);
1039 }
1040
1041 if (Hub->HasFlag(HubFlag::Initialized))
1042 Hub->PostAndWait(HubEvent::DeviceCleanup, "DeviceCleanup");
1043
1044 Hub->FlushAndDeleteWorkItem(&Hub->m_WorkItem);
1045
1046 if (Hub->m_ConfigDescriptor != NULL)
1047 {
1050 }
1051
1052 if (Hub->m_HubNumber != 0)
1053 {
1054 HubReleaseHubNumber(Hub->m_HubNumber);
1055 Hub->m_HubNumber = 0;
1056 }
1057}
1058
1059/* Waits for a running timer callback */
1060VOID
1061NTAPI
1064{
1065 HubFdo* Hub = HubGetFdoContext(Object);
1066
1067 if (!Hub->HasFlag(HubFlag::Initialized))
1068 return;
1069
1070 Hub->m_Timer.Cancel();
1071 KeFlushQueuedDpcs();
1072}
1073
1074/* The IRP is completed here and never sent down */
1076NTAPI
1078 _In_ WDFDEVICE Device,
1080{
1081 HubUxdShutdownCleanup(FromDevice(Device));
1082
1083 Irp->IoStatus.Status = STATUS_SUCCESS;
1085 return STATUS_SUCCESS;
1086}
1087
1088/* The timeout path always assigns a driver managed timeout, even on the root hub */
1090NTAPI
1096{
1097 HubFdo* Hub = (HubFdo*)Context;
1098 ULONG Setting;
1100
1101 PAGED_CODE();
1102
1103 if (!Hub->HasFlag(HubFlag::S0IdleConfigured))
1104 {
1105 DPRINT1("Hub %p power setting change without idle support\n", Hub->m_Device);
1107 }
1108
1109 if (IsEqualGUID(*SettingGuid, GUID_HUB_SELECTIVE_SUSPEND_POLICY))
1110 {
1111 if (ValueLength < sizeof(ULONG) || *(PULONG)Value > 1)
1112 {
1113 DPRINT1("Hub %p bad selective suspend setting, length %lu\n", Hub->m_Device, ValueLength);
1115 }
1116
1117 if (*(PULONG)Value == 1)
1118 {
1119 if (Hub->HasFlag(HubFlag::GlobalPowerReference))
1120 {
1121 DPRINT("Hub %p selective suspend on, dropping power reference\n", Hub->m_Device);
1123 Hub->ClearFlag(HubFlag::GlobalPowerReference);
1124 }
1125 }
1126 else if (!Hub->HasFlag(HubFlag::GlobalPowerReference))
1127 {
1128 DPRINT("Hub %p selective suspend off, taking power reference\n", Hub->m_Device);
1129
1131 if (NT_SUCCESS(Status))
1132 Hub->SetFlag(HubFlag::GlobalPowerReference);
1133 else
1134 DPRINT1("Hub %p stop idle failed 0x%lx\n", Hub->m_Device, Status);
1135 }
1136
1137 return STATUS_SUCCESS;
1138 }
1139
1140 if (IsEqualGUID(*SettingGuid, GUID_HUB_IDLE_TIMEOUT_SETTING))
1141 {
1142 if (ValueLength < sizeof(ULONG))
1143 {
1144 DPRINT1("Hub %p bad idle timeout setting, length %lu\n", Hub->m_Device, ValueLength);
1146 }
1147
1148 Setting = *(PULONG)Value;
1149 if (Setting == Hub->m_IdleTimeout)
1150 return STATUS_SUCCESS;
1151
1152 DPRINT("Hub %p idle timeout now %lu ms\n", Hub->m_Device, Setting);
1153
1154 Hub->m_IdleTimeout = Setting;
1155 Status = Hub->AssignIdleSettings(DriverManagedIdleTimeout);
1156 if (!NT_SUCCESS(Status))
1157 DPRINT1("Hub %p idle timeout update failed 0x%lx\n", Hub->m_Device, Status);
1158
1159 return STATUS_SUCCESS;
1160 }
1161
1162 DPRINT1("Hub %p unknown power setting\n", Hub->m_Device);
1164}
1165
1166/* Hub machine engine hooks */
1167
1168VOID
1169NTAPI
1172{
1173 ((HubFdo*)Context)->Post(HubEvent::TimerFired);
1174}
1175
1176VOID
1177NTAPI
1182{
1185
1186 ((HubFdo*)Context)->m_Machine.SmContinueOnPassive();
1187}
1188
1189VOID
1191{
1193}
1194
1195VOID
1197{
1199}
1200
1201VOID
1203{
1205}
1206
1207/* Hub machine actions */
1208
1209VOID
1211{
1213}
1214
1215VOID
1217{
1219}
1220
1221VOID
1223{
1224 DPRINT("Hub %p PnP event done in %s\n", m_Hub->m_Device, SmCurrent()->Name);
1225
1228}
1229
1230VOID
1232{
1233 DPRINT1("Hub %p start failed in state %s, depth %lu\n",
1235
1238}
1239
1240VOID
1242{
1243 DPRINT1("Hub %p failed in state %s, message 0x%lx\n",
1245
1246 if (m_Hub->m_FailureMessageId != 0)
1247 HubReportPnpProblem(m_Hub->m_Device, m_Hub->m_FailureMessageId);
1248
1249 WdfDeviceSetFailed(m_Hub->m_Device, WdfDeviceFailedNoRestart);
1250}
1251
1252VOID
1254{
1255 DPRINT1("Boot path hub %p failed, bugchecking\n", m_Hub->m_Device);
1256
1259 (ULONG_PTR)WdfDeviceWdmGetDeviceObject(m_Hub->m_Device),
1261 0);
1262}
1263
1264/* Write failures are ignored */
1265VOID
1267{
1268 DECLARE_CONST_UNICODE_STRING(CountName, L"HardResetCount");
1269 DECLARE_CONST_UNICODE_STRING(StatusName, L"LastHubResetPortStatus");
1270 WDFKEY Key;
1271
1273
1274 DPRINT1("Hub %p reset recovery %lu, last port status 0x%lx\n",
1276
1281 &Key)))
1282 {
1283 return;
1284 }
1285
1286 WdfRegistryAssignULong(Key, &CountName, m_Hub->m_LifetimeRecoveryCount);
1287
1288 if (m_Hub->m_LastResetPortStatus != 0)
1289 {
1290 WdfRegistryAssignULong(Key, &StatusName, m_Hub->m_LastResetPortStatus);
1292 }
1293
1295}
1296
1297VOID
1299{
1300 DPRINT1("Hub %p was reset on resume\n", m_Hub->m_Device);
1301}
1302
1303BOOLEAN
1305{
1306 return m_Hub->HasFlag(HubFlag::InBootOrPagingPath);
1307}
1308
1309BOOLEAN
1311{
1312 return m_Hub->IsRootHub();
1313}
1314
1315/* Timers */
1316
1317VOID
1319{
1321}
1322
1323VOID
1325{
1327}
1328
1329VOID
1331{
1333}
1334
1335/* Counters; the hub reset and pipe reset counts are one field */
1336
1337VOID
1339{
1340 m_Hub->m_ResetCount = 0;
1341}
1342
1343VOID
1345{
1346 m_Hub->m_ResetCount = 0;
1347}
1348
1349VOID
1351{
1353}
1354
1355BOOLEAN
1357{
1359
1361 return FALSE;
1362
1363 DPRINT1("Hub %p reset failed %lu times\n", m_Hub->m_Device, (ULONG)Previous + 1);
1365 return TRUE;
1366}
1367
1368BOOLEAN
1370{
1372 return FALSE;
1373
1374 DPRINT1("Hub %p interrupt pipe reset limit reached\n", m_Hub->m_Device);
1375 return TRUE;
1376}
1377
1378/* The hub reset limit is used here too */
1379BOOLEAN
1381{
1383 return FALSE;
1384
1385 DPRINT1("Hub %p hub descriptor retries exhausted\n", m_Hub->m_Device);
1386 return TRUE;
1387}
1388
1389/* At most ten recoveries a minute; the first call always opens a new window */
1390BOOLEAN
1392{
1394
1396
1398 {
1401 return FALSE;
1402 }
1403
1405 return FALSE;
1406
1407 DPRINT1("Hub %p too many resets in a minute\n", m_Hub->m_Device);
1409 return TRUE;
1410}
#define PAGED_CODE()
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
HubFdo * Hub
Definition: bootdev.cpp:261
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
VOID NTAPI HubNoPingResponse(_In_ UCXHUB_HUB_CONTEXT HubContext, _In_ UCXHUB_DEVICE_CONTEXT DeviceContext)
Definition: childpdo.cpp:2955
_In_ DsmEvent _In_ PCSTR What
Definition: childpdo.cpp:261
WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFilePaging, TRUE)
Definition: bufpool.h:45
Definition: fdo.h:132
USB_BUS_INTERFACE_USBDI_V3 m_Usbdi
Definition: fdo.h:357
ULONG m_IdleTimeout
Definition: fdo.h:396
static EVT_WDF_DEVICE_USAGE_NOTIFICATION EvtUsageNotification
Definition: fdo.h:532
static EVT_WDF_DEVICE_RELEASE_HARDWARE EvtReleaseHardware
Definition: fdo.h:528
PUSB_CONFIGURATION_DESCRIPTOR m_ConfigDescriptor
Definition: fdo.h:425
static EVT_WDF_DRIVER_DEVICE_ADD EvtDeviceAdd
Definition: fdo.h:135
static EVT_WDF_DEVICE_D0_EXIT EvtD0Exit
Definition: fdo.h:530
static EVT_WDF_DEVICE_PREPARE_HARDWARE EvtPrepareHardware
Definition: fdo.h:527
VOID InitializeMux()
Definition: fanout.cpp:33
USHORT m_SelectedFeature
Definition: fdo.h:427
_In_ PCSTR What
Definition: fdo.h:205
BOOLEAN m_StreamsSupported
Definition: fdo.h:361
WDFDEVICE m_Device
Definition: fdo.h:349
static EVT_WDFDEVICE_WDM_IRP_PREPROCESS EvtShutdown
Definition: fdo.h:539
VOID ClearFlag(_In_ HubFlag Flag)
Definition: fdo.h:167
static EVT_WDF_DEVICE_SURPRISE_REMOVAL EvtSurpriseRemoval
Definition: fdo.h:531
HubTimer m_Timer
Definition: fdo.h:410
static EVT_WDF_DEVICE_ARM_WAKE_FROM_S0 EvtArmWakeFromS0
Definition: fdo.h:533
ULONG m_HubNumber
Definition: fdo.h:351
VOID SetFlag(_In_ HubFlag Flag)
Definition: fdo.h:160
VOID QueueSurpriseRemovalToPorts()
Definition: fanout.cpp:351
UNICODE_STRING m_SymbolicLinkName
Definition: fdo.h:441
KEVENT m_PnpEvent
Definition: fdo.h:388
WDFIOTARGET m_RootHubTarget
Definition: fdo.h:368
PDEVICE_OBJECT m_WdmPdo
Definition: fdo.h:350
static UCXHUB_WORKITEM_ROUTINE MachineWorkItem
Definition: fdo.h:541
VOID ReleasePowerReference()
Definition: fdo.cpp:123
WDFDEVICE Device() const
Definition: fdo.h:186
ULONG m_RecoveryCount
Definition: fdo.h:435
PVOID m_SelectiveSuspendSetting
Definition: fdo.h:398
USHORT m_DescriptorRetryCount
Definition: fdo.h:434
NTSTATUS m_PnpStatus
Definition: fdo.h:389
VOID AcquirePowerReference()
Definition: fdo.cpp:105
VOID Post(_In_ HubEvent Event)
Definition: fdo.h:194
HubControlRequest m_Control
Definition: fdo.h:413
PUCXHUB_WORKITEM AllocateWorkItem()
Definition: fdo.cpp:46
ULONG m_LastResetPortStatus
Definition: fdo.h:438
HubInterruptRequest m_Interrupt
Definition: fdo.h:414
static EVT_WDF_OBJECT_CONTEXT_DESTROY EvtDestroy
Definition: fdo.h:538
UCXHUB_STACK_INTERFACE m_Stack
Definition: fdo.h:356
ULONG m_LifetimeRecoveryCount
Definition: fdo.h:436
BOOLEAN HasFlag(_In_ HubFlag Flag) const
Definition: fdo.h:153
ULONG m_FailureMessageId
Definition: fdo.h:402
static HubFdo * FromDevice(_In_ WDFDEVICE Device)
Definition: fdo.cpp:37
static EVT_WDF_DEVICE_DISARM_WAKE_FROM_S0 EvtDisarmWakeFromS0
Definition: fdo.h:534
HubMachine m_Machine
Definition: fdo.h:347
static POWER_SETTING_CALLBACK PowerSettingChanged
Definition: fdo.h:540
DEVICE_CAPABILITIES m_Capabilities
Definition: fdo.h:359
static VOID NTAPI TimerFired(_In_ PVOID Context)
Definition: fdo.cpp:1170
VOID EnqueueWorkItem(_In_ PUCXHUB_WORKITEM WorkItem, _In_ PUCXHUB_WORKITEM_ROUTINE Routine, _In_ PVOID Context, _In_ BOOLEAN ForwardProgress)
Definition: fdo.cpp:54
UCXUSBDEVICE UsbDevice() const
Definition: fdo.h:180
LIST_ENTRY m_HubListEntry
Definition: fdo.h:404
PVOID m_IdleTimeoutSetting
Definition: fdo.h:397
PUCXHUB_WORKITEM m_WorkItem
Definition: fdo.h:411
HubParentInfo m_ParentInfo
Definition: fdo.h:360
volatile LONG m_Flags
Definition: fdo.h:352
ULONG m_MaxPortPower
Definition: fdo.h:384
UCXHUB_PARENT_INTERFACE m_Parent
Definition: fdo.h:355
BOOLEAN IsRootHub() const
Definition: fdo.h:174
static EVT_WDF_DEVICE_DISARM_WAKE_FROM_SX EvtDisarmWakeFromSx
Definition: fdo.h:536
WDF_POWER_DEVICE_STATE m_PowerState
Definition: fdo.h:399
ULONG m_SspIsochBurstCount
Definition: fdo.h:385
BOOLEAN m_NeedsForwardProgress
Definition: fdo.h:412
LARGE_INTEGER m_FirstRecoveryTime
Definition: fdo.h:437
static EVT_WDF_DEVICE_ARM_WAKE_FROM_SX EvtArmWakeFromSx
Definition: fdo.h:535
USHORT m_ResetCount
Definition: fdo.h:433
static EVT_WDF_OBJECT_CONTEXT_CLEANUP EvtCleanup
Definition: fdo.h:537
BOOLEAN m_OnHubList
Definition: fdo.h:405
static EVT_WDF_DEVICE_D0_ENTRY EvtD0Entry
Definition: fdo.h:529
VOID Initialize(_In_ HubFdo *Hub, _In_ HubKind Kind)
Definition: hubsm.cpp:253
VOID BugcheckBootHub()
Definition: fdo.cpp:1253
VOID SignalPnpEvent()
Definition: fdo.cpp:1222
VOID ReleasePowerReference()
Definition: fdo.cpp:1216
VOID ArmResetRetryTimer()
Definition: fdo.cpp:1318
VOID ClearPipeResetCount()
Definition: fdo.cpp:1344
VOID InitializeResetCount()
Definition: fdo.cpp:1338
VOID InitializeDescriptorRetries()
Definition: fdo.cpp:1350
BOOLEAN RecoveryLimitReached()
Definition: fdo.cpp:1391
VOID StartDescriptorRetryTimer()
Definition: fdo.cpp:1330
VOID AcquirePowerReference()
Definition: fdo.cpp:1210
HubFdo * m_Hub
Definition: hubsm.h:574
VOID LogResetRecovery()
Definition: fdo.cpp:1266
VOID ReferenceHub()
Definition: fdo.cpp:1190
BOOLEAN DescriptorRetriesExhausted()
Definition: fdo.cpp:1380
BOOLEAN IsInBootPath()
Definition: fdo.cpp:1304
VOID LogResetOnResume()
Definition: fdo.cpp:1298
VOID ReportFailureToPnp()
Definition: fdo.cpp:1241
BOOLEAN PipeResetLimitReached()
Definition: fdo.cpp:1369
BOOLEAN IsDepthZero()
Definition: fdo.cpp:1310
VOID SignalPnpFailure()
Definition: fdo.cpp:1231
BOOLEAN ResetLimitReached()
Definition: fdo.cpp:1356
VOID ArmOverCurrentTimer()
Definition: fdo.cpp:1324
VOID DereferenceHub()
Definition: fdo.cpp:1196
VOID QueuePassiveWork()
Definition: fdo.cpp:1202
HubChild * m_Child
Definition: childpdo.h:57
VOID Start(_In_ ULONG Milliseconds)
Definition: hubutil.h:104
VOID Initialize(_In_ PFN_HUB_TIMER_FIRED Fired, _In_ PVOID Context)
Definition: hubutil.h:93
BOOLEAN Cancel()
Definition: hubutil.h:115
const State * SmCurrent() const
Definition: smengine.h:130
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
LPWSTR Name
Definition: desk.c:124
#define DEVPROP_TYPE_STRING
Definition: devpropdef.h:47
_In_ ULONG Attributes
Definition: dispmprt.h:1077
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
_Check_return_ _In_ ULONG _Inout_ PDXGK_CHILD_CONTAINER_ID ContainerId
Definition: dispmprt.h:1484
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define L(x)
Definition: resources.c:13
static VOID Wake(_In_ UCHAR Csn)
Definition: hardware.c:154
#define _IRQL_requires_(irql)
Definition: driverspecs.h:229
HubDriverState HubDriver
Definition: entry.cpp:13
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define PagedPool
Definition: env_spec_w32.h:308
WdfRegistryClose(HardwareKey)
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
return pRequest Reuse(ReuseParams)
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:24
#define HUB_USB3_BOOT_DEVICE_FAILED
Definition: hubdriver.h:158
#define HUB_BUGCHECK_USB3
Definition: hubdriver.h:157
#define HUB_BOOT_DEVICE_IS_HUB
Definition: hubdriver.h:160
Previous
return WdfDeviceOpenRegistryKey(Child->m_Pdo->m_Device, PLUGPLAY_REGKEY_DEVICE, Access, WDF_NO_OBJECT_ATTRIBUTES, Key)
VOID NTAPI HubClearTtBuffer(_In_ UCXHUB_HUB_CONTEXT HubContext, _In_ UCXHUB_DEVICE_CONTEXT DeviceContext, _In_ UCXENDPOINT Endpoint, _In_ ULONG EndpointNumber, _In_ ULONG TtPortNumber)
Definition: hubreq.cpp:220
#define HUB_FEATURE_NONE
Definition: hubreq.h:14
HubKind
Definition: hubsm.h:64
HubEvent
Definition: hubsm.h:15
BOOLEAN NTAPI HubUsb4NeedsHostPower(_In_ HubChild *Child)
Definition: hubtunnel.cpp:587
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
#define UCXHUB_STACK_INTERFACE_VERSION_2
Definition: hubucx.h:418
UCXHUB_WORKITEM_ROUTINE * PUCXHUB_WORKITEM_ROUTINE
Definition: hubucx.h:228
#define UCXHUB_PARENT_INTERFACE_VERSION
Definition: hubucx.h:493
#define UCXHUB_STACK_INTERFACE_VERSION_1
Definition: hubucx.h:417
_In_opt_ PVOID _In_ PUCXHUB_WORKITEM WorkItem
Definition: hubucx.h:227
@ UcxHubWorkItemForwardProgressNotRequired
Definition: hubucx.h:217
@ UcxHubWorkItemDefault
Definition: hubucx.h:216
#define UCXHUB_WORKITEM_FLAG_NEEDS_FLUSH
Definition: hubucx.h:212
#define HUB_TAG_HUB
Definition: hubutil.h:12
#define InterlockedOr
Definition: interlocked.h:239
_In_ PIRP Irp
Definition: kse.h:79
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
_In_ UINT Bytes
Definition: mmcopy.h:9
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _Inout_
Definition: no_sal2.h:162
#define _Inout_opt_
Definition: no_sal2.h:216
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define KEY_SET_VALUE
Definition: nt_native.h:1020
#define LOCALE_NEUTRAL
WCHAR * PWCH
Definition: ntbasedef.h:422
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
@ NotificationEvent
NTSTATUS NTAPI IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1713
#define IoCompleteRequest
Definition: irp.c:1272
POWER_ACTION
Definition: ntpoapi.h:122
@ PowerActionShutdownOff
Definition: ntpoapi.h:129
@ PowerActionNone
Definition: ntpoapi.h:123
@ PowerActionHibernate
Definition: ntpoapi.h:126
@ PowerActionShutdown
Definition: ntpoapi.h:127
@ PowerActionShutdownReset
Definition: ntpoapi.h:128
@ PowerActionSleep
Definition: ntpoapi.h:125
@ PowerDeviceD2
Definition: ntpoapi.h:51
short WCHAR
Definition: pedump.c:58
unsigned short USHORT
Definition: pedump.c:61
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
@ PNPBus
Definition: restypes.h:137
struct tm * Now
Definition: output.c:19
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
static void Exit(void)
Definition: sock.c:1330
_Must_inspect_result_ NTSTATUS Create(_In_ WDFOBJECT Parent, _In_ WDFIOTARGET SizingTarget)
Definition: hubreq.cpp:22
LIST_ENTRY HubList
Definition: hubdriver.h:95
PFN_HUB_UNREGISTER_POWER_SETTING UnregisterPowerSetting
Definition: hubdriver.h:115
PFN_HUB_REGISTER_POWER_SETTING RegisterPowerSetting
Definition: hubdriver.h:114
WDFWAITLOCK HubListLock
Definition: hubdriver.h:96
WDFREQUEST Request
Definition: hubreq.h:70
PDEVICE_OBJECT RootHubPdo
Definition: fdo.h:88
ULONG Flags
Definition: fdo.h:100
PVOID Context
Definition: miniport.h:123
INTERFACE_TYPE LegacyBusType
Definition: cmtypes.h:366
PFN_UCXHUB_GET_SYMBOLIC_NAME QueryHubLinkName
Definition: hubucx.h:513
USB_DEVICE_SPEED HubSpeed
Definition: hubucx.h:504
PFN_UCXHUB_CONTROLLER_STOP_IDLE BlockControllerIdle
Definition: hubucx.h:454
UCXHUB_HUB_CONTEXT HubContext
Definition: hubucx.h:431
PFN_UCXHUB_WORKITEM_ALLOCATE WorkItemAllocate
Definition: hubucx.h:446
PFN_UCXHUB_WORKITEM_FLUSH WorkItemFlush
Definition: hubucx.h:449
PFN_UCXHUB_CLEAR_TT_BUFFER ClearTtBuffer
Definition: hubucx.h:432
PFN_UCXHUB_CONTROLLER_RESUME_IDLE AllowControllerIdle
Definition: hubucx.h:455
PFN_UCXHUB_NO_PING_RESPONSE NoPingResponse
Definition: hubucx.h:451
PFN_UCXHUB_WORKITEM_DELETE WorkItemDelete
Definition: hubucx.h:447
UCXUSBDEVICE Hub
Definition: hubucx.h:430
PFN_UCXHUB_STREAMS_SUPPORTED StreamsSupported
Definition: hubucx.h:453
PFN_UCXHUB_WORKITEM_ENQUEUE WorkItemEnqueue
Definition: hubucx.h:448
USHORT MaximumLength
Definition: env_spec_w32.h:370
WDF_TRI_STATE SurpriseRemovalOK
Definition: wdfdevice.h:1531
PFN_WDF_DEVICE_D0_ENTRY EvtDeviceD0Entry
Definition: wdfdevice.h:1164
PFN_WDF_DEVICE_D0_EXIT EvtDeviceD0Exit
Definition: wdfdevice.h:1166
PFN_WDF_DEVICE_SURPRISE_REMOVAL EvtDeviceSurpriseRemoval
Definition: wdfdevice.h:1175
PFN_WDF_DEVICE_USAGE_NOTIFICATION EvtDeviceUsageNotification
Definition: wdfdevice.h:1178
PFN_WDF_DEVICE_PREPARE_HARDWARE EvtDevicePrepareHardware
Definition: wdfdevice.h:1168
PFN_WDF_DEVICE_RELEASE_HARDWARE EvtDeviceReleaseHardware
Definition: wdfdevice.h:1169
PFN_WDF_DEVICE_ARM_WAKE_FROM_S0 EvtDeviceArmWakeFromS0
Definition: wdfdevice.h:1189
PFN_WDF_DEVICE_DISARM_WAKE_FROM_S0 EvtDeviceDisarmWakeFromS0
Definition: wdfdevice.h:1190
PFN_WDF_DEVICE_ARM_WAKE_FROM_SX EvtDeviceArmWakeFromSx
Definition: wdfdevice.h:1193
PFN_WDF_DEVICE_DISARM_WAKE_FROM_SX EvtDeviceDisarmWakeFromSx
Definition: wdfdevice.h:1194
#define MAXULONG
Definition: typedefs.h:251
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
const char * PCSTR
Definition: typedefs.h:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
int32_t * PLONG
Definition: typedefs.h:58
uint16_t * PWCHAR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG Config
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFREQUEST Request
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
@ UsbSuperSpeed
Definition: usb200.h:45
@ UsbHighSpeed
Definition: usb200.h:44
@ UsbFullSpeed
Definition: usb200.h:43
static const WCHAR HubNonFunctionalDescription[]
Definition: fdo.cpp:34
#define HUB_MSG_HUB_RESET_FAILED
Definition: fdo.cpp:27
#define HUB_RECOVERY_LIMIT
Definition: fdo.cpp:23
#define HUB_OVERCURRENT_TIME
Definition: fdo.cpp:14
#define HUB_ROOT_MAX_PORT_POWER
Definition: fdo.cpp:19
#define HUB_RESET_LIMIT
Definition: fdo.cpp:22
static const UNICODE_STRING HubSystemContainerId
Definition: fdo.cpp:30
#define HUB_DEFAULT_IDLE_TIMEOUT
Definition: fdo.cpp:18
#define HUB_RECOVERY_WINDOW
Definition: fdo.cpp:24
#define HUB_RESET_RETRY_TIME
Definition: fdo.cpp:15
#define HUB_DESCRIPTOR_RETRY_TIME
Definition: fdo.cpp:16
#define HUB_PARENT_DISABLE_LPM
Definition: fdo.h:106
EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL HubEvtIoInternalDeviceControl
Definition: fdo.h:550
EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL HubEvtIoDeviceControl
Definition: fdo.h:549
#define USB_BUSIF_USBDI_VERSION_3
Definition: usbbusif.h:76
#define USBD_CLIENT_CONTRACT_VERSION_602
Definition: usbdlib.h:100
NTSTATUS USBD_QueryUsbCapability(_In_ USBD_HANDLE USBDHandle, _In_ const GUID *CapabilityType, _In_ ULONG OutputBufferLength, _When_(OutputBufferLength==0, _Pre_null_) _When_(OutputBufferLength !=0 &&ResultLength==NULL, _Out_writes_bytes_(OutputBufferLength)) _When_(OutputBufferLength !=0 &&ResultLength !=NULL, _Out_writes_bytes_to_opt_(OutputBufferLength, *ResultLength)) PUCHAR OutputBuffer, _Out_opt_ _When_(ResultLength !=NULL, _Deref_out_range_(<=, OutputBufferLength)) PULONG ResultLength)
Definition: usbstubum.cpp:111
NTSTATUS USBD_CreateHandle(_In_ PDEVICE_OBJECT DeviceObject, _In_ PDEVICE_OBJECT TargetDeviceObject, _In_ ULONG USBDClientContractVersion, _In_ ULONG PoolTag, _Out_ USBD_HANDLE *USBDHandle)
Definition: usbstubum.cpp:90
VOID USBD_CloseHandle(_In_ USBD_HANDLE USBDHandle)
Definition: usbstubum.cpp:80
WdfObjectDelete(String)
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ PWDFDEVICE_INIT DeviceInit
Definition: wdfcontrol.h:113
_Must_inspect_result_ _In_ WDFDRIVER Driver
Definition: wdfcontrol.h:83
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
@ WakeDoNotAllowUserControl
Definition: wdfdevice.h:417
FORCEINLINE VOID WDF_DEVICE_PNP_CAPABILITIES_INIT(_Out_ PWDF_DEVICE_PNP_CAPABILITIES Caps)
Definition: wdfdevice.h:1545
_In_ WDF_POWER_DEVICE_STATE PreviousState
Definition: wdfdevice.h:829
@ WdfPowerDeviceD3Final
Definition: wdfdevice.h:427
@ WdfPowerDeviceD0
Definition: wdfdevice.h:423
enum _WDF_SPECIAL_FILE_TYPE WDF_SPECIAL_FILE_TYPE
@ WdfReleaseHardwareOrderOnFailureAfterDescendants
Definition: wdfdevice.h:476
enum _WDF_POWER_DEVICE_STATE WDF_POWER_DEVICE_STATE
_In_ WDFCMRESLIST _In_ WDFCMRESLIST ResourcesTranslated
Definition: wdfdevice.h:891
_In_ WDF_SPECIAL_FILE_TYPE _In_ BOOLEAN IsInNotificationPath
Definition: wdfdevice.h:1027
FORCEINLINE VOID WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(_Out_ PWDF_DEVICE_POWER_POLICY_IDLE_SETTINGS Settings, _In_ WDF_POWER_POLICY_S0_IDLE_CAPABILITIES IdleCaps)
Definition: wdfdevice.h:1349
_In_ WDF_SPECIAL_FILE_TYPE NotificationType
Definition: wdfdevice.h:1024
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_POWER_POLICY_IDLE_SETTINGS Settings
Definition: wdfdevice.h:2601
@ WdfDeviceFailedNoRestart
Definition: wdfdevice.h:470
@ WdfSpecialFileBoot
Definition: wdfdevice.h:445
@ WdfSpecialFileHibernation
Definition: wdfdevice.h:443
@ WdfSpecialFileDump
Definition: wdfdevice.h:444
@ WdfSpecialFilePaging
Definition: wdfdevice.h:442
#define WdfDeviceStopIdle(Device, WaitForD0)
Definition: wdfdevice.h:1977
FORCEINLINE VOID WDF_PNPPOWER_EVENT_CALLBACKS_INIT(_Out_ PWDF_PNPPOWER_EVENT_CALLBACKS Callbacks)
Definition: wdfdevice.h:1214
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3540
enum _WDF_POWER_POLICY_IDLE_TIMEOUT_TYPE WDF_POWER_POLICY_IDLE_TIMEOUT_TYPE
_In_ WDF_POWER_DEVICE_STATE TargetState
Definition: wdfdevice.h:859
@ IdleAllowUserControl
Definition: wdfdevice.h:408
_In_ WDFCMRESLIST ResourcesRaw
Definition: wdfdevice.h:888
@ SystemManagedIdleTimeoutWithHint
Definition: wdfdevice.h:1245
@ DriverManagedIdleTimeout
Definition: wdfdevice.h:1243
FORCEINLINE VOID WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(_Out_ PWDF_DEVICE_POWER_POLICY_WAKE_SETTINGS Settings)
Definition: wdfdevice.h:1437
FORCEINLINE VOID WDF_POWER_POLICY_EVENT_CALLBACKS_INIT(_Out_ PWDF_POWER_POLICY_EVENT_CALLBACKS Callbacks)
Definition: wdfdevice.h:1203
#define WdfDeviceResumeIdle(Device)
Definition: wdfdevice.h:1983
@ IdleCanWakeFromS0
Definition: wdfdevice.h:401
FORCEINLINE VOID WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(_Out_ PWDF_IO_QUEUE_CONFIG Config, _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType)
Definition: wdfio.h:443
@ WdfIoQueueDispatchSequential
Definition: wdfio.h:78
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG _In_ _Out_ WDFMEMORY * Memory
Definition: wdfmemory.h:169
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
@ WdfExecutionLevelPassive
Definition: wdfobject.h:54
#define WdfObjectReference(Handle)
Definition: wdfobject.h:803
#define WdfObjectDereference(Handle)
Definition: wdfobject.h:826
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_Must_inspect_result_ FORCEINLINE BOOLEAN WdfRequestSend(_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_opt_ PWDF_REQUEST_SEND_OPTIONS Options)
Definition: wdfrequest.h:677
FORCEINLINE VOID WDF_REQUEST_SEND_OPTIONS_INIT(_Out_ PWDF_REQUEST_SEND_OPTIONS Options, _In_ ULONG Flags)
Definition: wdfrequest.h:409
@ WDF_REQUEST_SEND_OPTION_SYNCHRONOUS
Definition: wdfrequest.h:109
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
@ WDF_REQUEST_REUSE_NO_FLAGS
Definition: wdfrequest.h:92
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
FORCEINLINE VOID WDF_REQUEST_REUSE_PARAMS_INIT(_Out_ PWDF_REQUEST_REUSE_PARAMS Params, _In_ ULONG Flags, _In_ NTSTATUS Status)
Definition: wdfrequest.h:364
@ WdfTrue
Definition: wdftypes.h:88
@ WdfUseDefault
Definition: wdftypes.h:89
@ WdfFalse
Definition: wdftypes.h:87
#define WDF_NO_HANDLE
Definition: wdftypes.h:107
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2812
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ DevicePropertyContainerID
Definition: iotypes.h:1217
#define IRP_MN_QUERY_CAPABILITIES
#define IRP_MJ_SHUTDOWN
#define PLUGPLAY_PROPERTY_PERSISTENT
Definition: iotypes.h:1026
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define MmLockPagableCodeSection(Address)
_In_ LPCGUID SettingGuid
Definition: pofuncs.h:120
#define NT_ASSERT
Definition: rtlfuncs.h:3334