ReactOS 0.4.17-dev-1281-g065abb3
fanout.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: Fan out of hub events to the port and device machines
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/*
14 * Every fan out sets its counter before the first post, so an acknowledgement
15 * that comes back inside the post cannot reach zero early.
16 */
17
18/* Reference tags; only their addresses matter */
19static const char HubTagRegistration[] = "hub child registration";
20static const char HubTagPnpPower[] = "hub child pnp power";
21
22/* Root ports report depth 0 or nonsense above 5; both mean the deepest tier */
23static
28{
29 return (Depth == 0 || Depth > 5) ? 5 : Depth;
30}
31
32VOID
34{
35 RtlZeroMemory(&m_Mux, sizeof(m_Mux));
39}
40
44{
47
48 /* The list only changes in CreateChildPorts */
50 {
51 Port = CONTAINING_RECORD(Entry, HubPort, m_HubLink);
52 if (Port->Number() == PortNumber)
53 return Port;
54 }
55
56 return NULL;
57}
58
60static
65 _In_ const HubPortInfo* Info)
66{
67 HubPort* Port = HubPort::Create(Hub, Info);
68
69 if (Port == NULL)
70 {
71 DPRINT1("Hub %p port %u create failed\n", Hub->m_Device, Info->PortNumber);
72 return FALSE;
73 }
74
75 DPRINT("Hub %p created port %u (%p), protocol 0x%x\n",
76 Hub->m_Device, Info->PortNumber, Port, Info->Protocol);
77
78 InsertTailList(&Hub->m_Mux.Ports, &Port->m_HubLink);
80 return TRUE;
81}
82
83static
84VOID
89 _Inout_ PUSHORT Last)
90{
91 if (PortNumber < *First)
93 if (PortNumber > *Last)
94 *Last = PortNumber;
95}
96
97/* The DeviceRemovable bitmap of a hub descriptor; bit n is port n */
98static
100NTAPI
102 _In_ const UCHAR* Bitmap,
104{
105 return (Bitmap[PortNumber / 8] & (1 << (PortNumber % 8))) != 0;
106}
107
110HubFdo::CreateChildPorts()
111{
115 ULONG BitmapBytes;
116 ULONG Index;
121
122 PAGED_CODE();
123
124 if (!IsRootHub())
125 {
127 Count30 = m_HubDescriptor.Usb30.bNumberOfPorts;
128 else
129 Count20 = m_HubDescriptor.Usb20.bNumberOfPorts;
130 }
131
132 m_First20Port = 0xFFFF;
133 m_Last20Port = 0;
134
135 for (Index = 0; Index < Count20; Index++)
136 {
137 RtlZeroMemory(&Info, sizeof(Info));
138 Info.Properties = (ULONG)PortProperty::Removable;
139 Info.Protocol = 0x200;
140
141 if (IsRootHub())
142 {
144
145 Info.PortNumber = Root->PortNumber;
146 if (Root->Removable == TriStateFalse)
147 Info.Properties &= ~(ULONG)PortProperty::Removable;
148 if (Root->IntegratedHubImplemented == TriStateTrue)
149 Info.Properties |= (ULONG)PortProperty::IntegratedHub;
150 if (Root->ControllerUsb20HardwareLpmFlags.Flags.L1CapabilitySupported)
151 Info.Properties |= (ULONG)PortProperty::Usb20LpmCapable;
152 if (Root->ControllerUsb20HardwareLpmFlags.Flags.BeslLpmCapabilitySupported)
153 Info.Properties |= (ULONG)PortProperty::BeslCapable;
154 Info.TotalHubDepth = HubClampTierDepth(Root->HubDepth);
155 }
156 else
157 {
158 Info.PortNumber = (USHORT)(Index + 1);
159 if (HubDescriptorSaysFixed(&m_HubDescriptor.Usb20.bRemoveAndPowerMask[0], Info.PortNumber))
160 Info.Properties &= ~(ULONG)PortProperty::Removable;
161 Info.TotalHubDepth = m_ParentInfo.TotalHubDepth;
162 }
163
165 if (!HubAddPort(this, &Info))
166 goto Failed;
167 }
168
169 m_First30Port = 0xFFFF;
170 m_Last30Port = 0;
171
172 for (Index = 0; Index < Count30; Index++)
173 {
174 RtlZeroMemory(&Info, sizeof(Info));
175 Info.Properties = (ULONG)PortProperty::Removable;
176 Info.Protocol = 0x300;
177
178 if (IsRootHub())
179 {
181
182 Info.PortNumber = Root->Info.PortNumber;
183 if (Root->Info.Removable == TriStateFalse)
184 Info.Properties &= ~(ULONG)PortProperty::Removable;
185 if (Root->Info.DebugCapable == TriStateTrue)
186 Info.Properties |= (ULONG)PortProperty::DebugCapable;
187 Info.Properties |= (ULONG)PortProperty::EnhancedSuperSpeed;
188 if (Root->Info.MinorRevision != 0)
189 Info.SspIsochBurstCount = m_SspIsochBurstCount;
190 Info.SublinkSpeedAttr = Root->Speeds;
191 Info.SublinkSpeedAttrCount = Root->SpeedsCount;
192 Info.TotalHubDepth = HubClampTierDepth(Root->Info.HubDepth);
193 }
194 else
195 {
196 Info.PortNumber = (USHORT)(Index + 1);
197 if (HubDescriptorSaysFixed((const UCHAR*)&m_HubDescriptor.Usb30.DeviceRemovable, Info.PortNumber))
198 Info.Properties &= ~(ULONG)PortProperty::Removable;
200 {
201 Info.Properties |= (ULONG)PortProperty::EnhancedSuperSpeed;
202 Info.SspIsochBurstCount = m_SspIsochBurstCount;
203 }
204 Info.SublinkSpeedAttr = m_ParentInfo.SublinkSpeedAttr;
205 Info.SublinkSpeedAttrCount = m_ParentInfo.SublinkSpeedAttrCount;
206 Info.TotalHubDepth = m_ParentInfo.TotalHubDepth;
207 }
208
210 if (!HubAddPort(this, &Info))
211 goto Failed;
212 }
213
215 if (m_PortCount == 0)
216 DPRINT1("Hub %p reports no ports\n", m_Device);
218
219 /* External hubs read the whole interrupt packet into the bitmap; only the allocation is ULONG aligned */
220 BitmapBytes = max(2, m_PortCount / 8 + 1);
221 BitmapBytes = max(BitmapBytes, m_InterruptMaxPacket);
222
224 Attributes.ParentObject = m_Device;
225
226 Status = WdfMemoryCreate(&Attributes,
229 ALIGN_UP_BY(BitmapBytes, sizeof(ULONG)),
231 &Buffer);
232 if (!NT_SUCCESS(Status))
233 {
234 DPRINT1("Hub %p change bitmap allocation failed 0x%lx\n", m_Device, Status);
235 goto Failed;
236 }
237
239 m_Interrupt.BitmapMaxBytes = BitmapBytes;
240
241 DPRINT("Hub %p has %lu ports, bitmap %lu bytes\n", m_Device, m_PortCount, BitmapBytes);
242
243 SetFlag(HubFlag::Configured);
244 return TRUE;
245
246Failed:
247 while (!IsListEmpty(&m_Mux.Ports))
248 {
251 WdfObjectDelete(CONTAINING_RECORD(Entry, HubPort, m_HubLink)->m_Object);
252 }
253
254 return FALSE;
255}
256
257VOID
260{
262
264 CONTAINING_RECORD(Entry, HubPort, m_HubLink)->Post(Event);
265}
266
267/* Start and every kind of resume: every port owes one power acknowledgement */
268VOID
271{
273 HubPort* Port;
274
275 {
277
280 }
281
282 if (m_Mux.PortCount == 0)
283 {
284 Post(HubEvent::PortsAcquired);
285 return;
286 }
287
289
291 {
292 Port = CONTAINING_RECORD(Entry, HubPort, m_HubLink);
293 Port->SetMuxFlag(PortMuxFlag::PnpOperationPending);
294 Port->Post(Event);
295 }
296}
297
298/* Only ports holding a power reference are waited for, but all of them hear it */
299VOID
301{
303 HubPort* Port;
304 BOOLEAN NothingToWaitFor;
305
306 if (m_Mux.PortCount == 0)
307 {
308 Post(HubEvent::PortsReleased);
309 return;
310 }
311
313 NothingToWaitFor = (m_Mux.OutstandingPnpOperations == 0);
314
316 {
317 Port = CONTAINING_RECORD(Entry, HubPort, m_HubLink);
318 if (Port->HasMuxFlag(PortMuxFlag::PowerReference))
319 Port->SetMuxFlag(PortMuxFlag::PnpOperationPending);
320 Port->Post(PortEvent::HubStopping);
321 }
322
323 if (NothingToWaitFor)
324 Post(HubEvent::PortsReleased);
325}
326
327/* Every port is expected to hold a power reference while the hub is up */
328VOID
330{
332 HubPort* Port;
333
334 if (m_Mux.PortCount == 0)
335 {
336 Post(HubEvent::PortsReleased);
337 return;
338 }
339
341
343 {
344 Port = CONTAINING_RECORD(Entry, HubPort, m_HubLink);
345 Port->SetMuxFlag(PortMuxFlag::PnpOperationPending);
346 Port->Post(PortEvent::HubSuspending);
347 }
348}
349
350VOID
352{
353 PostToAllPorts(PortEvent::HubRemoved);
354
357}
358
359/* With no ports this never completes */
360VOID
362{
364 HubPort* Port;
365
366 if (m_Mux.PortCount == 0)
367 DPRINT1("Hub %p reset fan out with no ports will not finish\n", m_Device);
368
371
373 {
374 Port = CONTAINING_RECORD(Entry, HubPort, m_HubLink);
375 Port->SetMuxFlag(PortMuxFlag::ResetPending);
376 Port->Post(PortEvent::HubResetting);
377 }
378}
379
380/*
381 * Bit 0 of the change bitmap is the hub itself and was handled already.
382 * Bits for ports that do not exist are counted, then taken back.
383 */
384VOID
386{
388 HubPort* Port;
390 LONG Sent = 0;
391
393 if (Expected == 0)
394 {
396 Post(HubEvent::PortsEnableInterrupt);
397 return;
398 }
399
401
403 {
404 Port = CONTAINING_RECORD(Entry, HubPort, m_HubLink);
405 if (Port->Number() >= m_Interrupt.Bitmap.SizeOfBitMap ||
406 !RtlCheckBit(&m_Interrupt.Bitmap, Port->Number()))
407 {
408 continue;
409 }
410
411 Port->SetMuxFlag(PortMuxFlag::PortChangePending);
412 Port->Post(PortEvent::StatusChanged);
413 Sent++;
414 }
415
416 if (Sent < Expected &&
418 {
419 Post(HubEvent::PortsEnableInterrupt);
420 }
421}
422
423/* After resume from selective suspend every port rechecks; no ports never completes */
424VOID
426{
428 HubPort* Port;
429
430 if (m_Mux.PortCount == 0)
431 DPRINT1("Hub %p status recheck with no ports will not finish\n", m_Device);
432
434
436 {
437 Port = CONTAINING_RECORD(Entry, HubPort, m_HubLink);
438 Port->SetMuxFlag(PortMuxFlag::PortChangePending);
439 Port->Post(PortEvent::StatusChanged);
440 }
441}
442
443VOID
445{
448}
449
453{
455
456 {
458
461 }
462
463 if (Queue)
464 Post(HubEvent::ResetRequested);
465
466 return Queue;
467}
468
469/* Interrupt references */
470
473{
475 BOOLEAN Released = (m_Mux.InterruptReferences == 0);
476
477 if (!Released)
479
481 return Released;
482}
483
487{
489
491 return FALSE;
492
493 Port->SetMuxFlag(PortMuxFlag::InterruptReference);
495 return TRUE;
496}
497
498VOID
501{
502 BOOLEAN Released = FALSE;
503
504 {
506
507 if (!Port->HasMuxFlag(PortMuxFlag::InterruptReference))
508 DPRINT1("Port %u dropped an interrupt reference it did not hold\n", Port->Number());
509 NT_ASSERT(Port->HasMuxFlag(PortMuxFlag::InterruptReference));
510 Port->ClearMuxFlag(PortMuxFlag::InterruptReference);
511
512 if (m_Mux.InterruptReferences == 0)
513 DPRINT1("Hub %p interrupt references released too many times\n", m_Device);
515 if (m_Mux.InterruptReferences != 0)
517
519 {
521 Released = TRUE;
522 }
523 }
524
525 if (Released)
526 Post(HubEvent::PortsInterruptReleased);
527}
528
529/* Port acknowledgements, interlocked without the mux lock */
530
531VOID
534{
535 Port->ClearMuxFlag(PortMuxFlag::PnpOperationPending);
536 Port->SetMuxFlag(PortMuxFlag::PowerReference);
538
540 Post(HubEvent::PortsAcquired);
541}
542
543VOID
546{
547 Port->ClearMuxFlag(PortMuxFlag::PnpOperationPending);
548 Port->ClearMuxFlag(PortMuxFlag::PowerReference);
550
552 Post(HubEvent::PortsReleased);
553
554 /* Taken when a root port answered with an operation still pending */
555 if (Port->HasFlag(PortFlag::PendingHubPowerReference))
556 {
558 Port->ClearFlag(PortFlag::PendingHubPowerReference);
559 }
560}
561
562VOID
565{
566 Port->ClearMuxFlag(PortMuxFlag::ResetPending);
567
569 Post(HubEvent::PortsResetReleased);
570}
571
572VOID
575{
576 Port->ClearMuxFlag(PortMuxFlag::PortChangePending);
577
579 Post(HubEvent::PortsEnableInterrupt);
580}
581
582/* Devices */
583
588{
589 {
591
593 {
594 DPRINT("Hub %p refused device %p, hub is going down\n", m_Device, Child);
595 return FALSE;
596 }
597
598 Child->m_MuxFlags |= (ULONG)ChildMuxFlag::PowerReference;
600 InsertTailList(&m_Mux.Devices, &Child->m_HubLink);
601 }
602
604 return TRUE;
605}
606
607/* Posts the completion of whatever device fan out is running */
608VOID
610{
612
613 m_Mux.DeviceFanOut = HubDeviceFanOut::None;
614
615 switch (FanOut)
616 {
617 case HubDeviceFanOut::PowerUp:
618 Post(HubEvent::DevicesAcquired);
619 break;
620
621 case HubDeviceFanOut::PowerDown:
622 Post(HubEvent::DevicesReleased);
623 break;
624
625 case HubDeviceFanOut::StopWhileSuspended:
626 Post(HubEvent::DevicesStoppedAfterSuspend);
627 break;
628
629 default:
630 DPRINT1("Hub %p device fan out ended with none running\n", m_Device);
632 break;
633 }
634}
635
636/* The completion event follows the running fan out, not the device's power reference */
637VOID
640{
641 BOOLEAN Completed = FALSE;
642
643 Child->ClearState(ChildState::ActivityIdSet);
644
645 {
647
648 if (Child->m_MuxFlags & (ULONG)ChildMuxFlag::PowerReference)
649 {
651 Child->m_MuxFlags &= ~(ULONG)ChildMuxFlag::PowerReference;
652 }
653
654 if (Child->m_MuxFlags & (ULONG)ChildMuxFlag::PnpOperationPending)
655 {
656 Child->m_MuxFlags &= ~(ULONG)ChildMuxFlag::PnpOperationPending;
658 Completed = TRUE;
659 }
660
661 RemoveEntryList(&Child->m_HubLink);
662 HubClearListEntry(&Child->m_HubLink);
663 }
664
666
667 if (Completed)
669}
670
671/*
672 * Stop and suspend wait only for devices holding a power reference; every
673 * registered device still hears the event.
674 */
675VOID
678 _In_ HubDeviceFanOut FanOut)
679{
680 LIST_ENTRY FanOutList;
683 LONG Counted = 0;
684 BOOLEAN Any;
685
686 InitializeListHead(&FanOutList);
687
688 {
690
692
694 {
695 Child = CONTAINING_RECORD(Entry, HubChild, m_HubLink);
696
697 if (FanOut == HubDeviceFanOut::StopWhileSuspended ||
698 (Child->m_MuxFlags & (ULONG)ChildMuxFlag::PowerReference))
699 {
700 Child->m_MuxFlags |= (ULONG)ChildMuxFlag::PnpOperationPending;
701 Counted++;
702 }
703
705 InsertTailList(&FanOutList, &Child->m_FanOutLink);
706 }
707
709 m_Mux.DeviceFanOut = (Counted != 0) ? FanOut : HubDeviceFanOut::None;
710 }
711
712 Any = !IsListEmpty(&FanOutList);
713
714 while (!IsListEmpty(&FanOutList))
715 {
716 Entry = RemoveHeadList(&FanOutList);
718 Child = CONTAINING_RECORD(Entry, HubChild, m_FanOutLink);
719
720 Child->Post(Event);
722 }
723
724 if (!Any || Counted == 0)
725 {
726 Post(FanOut == HubDeviceFanOut::StopWhileSuspended ? HubEvent::DevicesStoppedAfterSuspend
727 : HubEvent::DevicesReleased);
728 }
729}
730
731/* Devices that registered while the hub was down are not stopped and are skipped */
732VOID
735{
736 LIST_ENTRY FanOutList;
739 LONG Counted = 0;
740
741 InitializeListHead(&FanOutList);
742
743 {
745
747 {
748 Child = CONTAINING_RECORD(Entry, HubChild, m_HubLink);
749 if (!(Child->m_MuxFlags & (ULONG)ChildMuxFlag::Stopped))
750 continue;
751
752 Child->m_MuxFlags &= ~(ULONG)ChildMuxFlag::Stopped;
753 Child->m_MuxFlags |= (ULONG)ChildMuxFlag::PnpOperationPending;
755 InsertTailList(&FanOutList, &Child->m_FanOutLink);
756 Counted++;
757 }
758
760 m_Mux.DeviceFanOut = (Counted != 0) ? HubDeviceFanOut::PowerUp : HubDeviceFanOut::None;
761 }
762
763 if (Counted == 0)
764 {
765 Post(HubEvent::DevicesAcquired);
766 return;
767 }
768
769 while (!IsListEmpty(&FanOutList))
770 {
771 Entry = RemoveHeadList(&FanOutList);
773 Child = CONTAINING_RECORD(Entry, HubChild, m_FanOutLink);
774
775 Child->Post(Event);
777 }
778}
779
780/* Device acknowledgements; the completion is posted after the lock is dropped */
781
782VOID
785{
786 BOOLEAN Completed;
787
788 {
790
791 Child->m_MuxFlags &= ~((ULONG)ChildMuxFlag::PnpOperationPending | (ULONG)ChildMuxFlag::Stopped);
792 Child->m_MuxFlags |= (ULONG)ChildMuxFlag::PowerReference;
795 }
796
797 if (Completed)
799}
800
801VOID
804{
805 BOOLEAN Completed;
806
807 {
809
810 Child->m_MuxFlags &= ~((ULONG)ChildMuxFlag::PnpOperationPending | (ULONG)ChildMuxFlag::PowerReference);
811 Child->m_MuxFlags |= (ULONG)ChildMuxFlag::Stopped;
814 }
815
816 if (Completed)
818}
819
820VOID
823{
824 BOOLEAN Completed;
825
826 {
828
829 Child->m_MuxFlags &= ~(ULONG)ChildMuxFlag::PnpOperationPending;
830 Child->m_MuxFlags |= (ULONG)ChildMuxFlag::Stopped;
832 }
833
834 if (Completed)
836}
837
838/* The controller lost every device's programming on resume or hub reset */
839VOID
841{
843
845
847 CONTAINING_RECORD(Entry, HubChild, m_HubLink)->SetState(ChildState::ReprogrammingPending);
848}
849
850/* Hub machine actions */
851
854{
855 return m_Hub->CreateChildPorts();
856}
857
860{
862}
863
864VOID
866{
868}
869
870VOID
872{
874 m_Hub->QueuePowerUpToPorts(PortEvent::HubStarted);
875}
876
877VOID
879{
880 m_Hub->QueuePowerUpToPorts(PortEvent::HubResumed);
881}
882
883VOID
885{
886 m_Hub->QueuePowerUpToPorts(PortEvent::HubResumedInS0);
887}
888
889VOID
891{
892 m_Hub->QueuePowerUpToPorts(PortEvent::HubResumedWithReset);
893}
894
895VOID
897{
899}
900
901VOID
903{
905}
906
907VOID
909{
911}
912
913VOID
915{
917}
918
919VOID
921{
923}
924
925VOID
927{
929}
930
931VOID
933{
934 m_Hub->QueuePowerDownToDevices(DsmEvent::HubStopping, HubDeviceFanOut::PowerDown);
935}
936
937VOID
939{
940 m_Hub->QueuePowerDownToDevices(DsmEvent::HubSuspending, HubDeviceFanOut::PowerDown);
941}
942
943VOID
945{
946 m_Hub->QueuePowerDownToDevices(DsmEvent::HubStoppingAfterSuspend, HubDeviceFanOut::StopWhileSuspended);
947}
948
949VOID
951{
952 m_Hub->QueuePowerUpToDevices(DsmEvent::HubStarted);
953}
954
955VOID
957{
958 m_Hub->QueuePowerUpToDevices(DsmEvent::HubResumed);
959}
960
961VOID
963{
964 m_Hub->QueuePowerUpToDevices(DsmEvent::HubResumedInS0);
965}
966
967VOID
969{
970 m_Hub->QueuePowerUpToDevices(DsmEvent::HubResumedWithReset);
971}
972
973/* Port machine actions */
974
975VOID
977{
979}
980
981VOID
983{
985}
986
987VOID
989{
991}
992
995{
997}
998
999VOID
1001{
1003}
1004
1005VOID
1007{
1009}
1010
1011VOID
1013{
1015}
1016
1017BOOLEAN
1019{
1020 return m_Port->m_Hub->HasFlag(HubFlag::ArmedForWake);
1021}
1022
1023/* Device machine actions */
1024
1025BOOLEAN
1027{
1029}
1030
1031VOID
1033{
1035}
1036
1037VOID
1039{
1041}
1042
1043VOID
1045{
1047}
1048
1049VOID
1051{
1053}
#define PAGED_CODE()
WCHAR First[]
Definition: FormatMessage.c:11
BOOLEAN Expected
#define ALIGN_UP_BY(size, align)
unsigned char BOOLEAN
Definition: actypes.h:127
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedExchange
Definition: armddk.h:54
#define InterlockedDecrement
Definition: armddk.h:52
UINT Sent
Definition: arping.c:39
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
HubFdo * Hub
Definition: bootdev.cpp:261
Definition: bufpool.h:45
HubChild * m_Device
Definition: devsm.h:1832
VOID ConfirmStopWhileSuspended()
Definition: fanout.cpp:1050
VOID ReferenceDevicePower()
Definition: fanout.cpp:1038
VOID DereferenceDevicePower()
Definition: fanout.cpp:1044
BOOLEAN RegisterWithHub()
Definition: fanout.cpp:1026
VOID UnregisterFromHub()
Definition: fanout.cpp:1032
HubFdo * m_Hub
Definition: hubchild.h:316
Definition: fdo.h:132
VOID QueuePowerUpToDevices(_In_ DsmEvent Event)
Definition: fanout.cpp:733
BOOLEAN RegisterDevice(_In_ HubChild *Child)
Definition: fanout.cpp:586
VOID DereferenceDevicePower(_In_ HubChild *Child)
Definition: fanout.cpp:802
VOID FinishDeviceFanOut()
Definition: fanout.cpp:609
VOID DropHubResetReference(_In_ HubPort *Port)
Definition: fanout.cpp:563
VOID InitializeMux()
Definition: fanout.cpp:33
VOID PostToAllPorts(_In_ PortEvent Event)
Definition: fanout.cpp:258
VOID DropPortPowerReference(_In_ HubPort *Port)
Definition: fanout.cpp:544
WDFDEVICE m_Device
Definition: fdo.h:349
USHORT m_First30Port
Definition: fdo.h:382
PROOTHUB_30PORT_INFO_EX * m_Root30Ports
Definition: fdo.h:376
VOID QueueSurpriseRemovalToPorts()
Definition: fanout.cpp:351
UCXHUB_ROOTHUB_INFO m_RootHubInfo
Definition: fdo.h:374
VOID QueuePowerUpToPorts(_In_ PortEvent Event)
Definition: fanout.cpp:269
USHORT m_First20Port
Definition: fdo.h:380
USHORT m_Last30Port
Definition: fdo.h:383
PROOTHUB_20PORT_INFO * m_Root20Ports
Definition: fdo.h:375
ULONG m_PortCount
Definition: fdo.h:379
VOID QueueSuspendToPorts()
Definition: fanout.cpp:329
BOOLEAN PortInterruptRefsReleased()
Definition: fanout.cpp:472
VOID Post(_In_ HubEvent Event)
Definition: fdo.h:194
HubInterruptRequest m_Interrupt
Definition: fdo.h:414
VOID QueueStatusChangeToPorts()
Definition: fanout.cpp:385
BOOLEAN HasFlag(_In_ HubFlag Flag) const
Definition: fdo.h:153
VOID QueueResetToPorts()
Definition: fanout.cpp:361
BOOLEAN RequestHubReset()
Definition: fanout.cpp:452
VOID UnregisterDevice(_In_ HubChild *Child)
Definition: fanout.cpp:638
USHORT m_Last20Port
Definition: fdo.h:381
VOID QueueFakeStatusChangeToPorts()
Definition: fanout.cpp:425
VOID ConfirmStopWhileSuspended(_In_ HubChild *Child)
Definition: fanout.cpp:821
USHORT m_InterruptMaxPacket
Definition: fdo.h:429
HubMux m_Mux
Definition: fdo.h:407
HubParentInfo m_ParentInfo
Definition: fdo.h:360
VOID ResumeInterruptTransfer(_In_ HubPort *Port)
Definition: fanout.cpp:573
UCXHUB_PARENT_INTERFACE m_Parent
Definition: fdo.h:355
BOOLEAN IsRootHub() const
Definition: fdo.h:174
union HubFdo::@1628 m_HubDescriptor
VOID QueueStopToPorts()
Definition: fanout.cpp:300
ULONG m_SspIsochBurstCount
Definition: fdo.h:385
VOID ReferenceDevicePower(_In_ HubChild *Child)
Definition: fanout.cpp:783
VOID AllowHubReset()
Definition: fanout.cpp:444
VOID QueuePowerDownToDevices(_In_ DsmEvent Event, _In_ HubDeviceFanOut FanOut)
Definition: fanout.cpp:676
HubPort * FindPort(_In_ ULONG PortNumber)
Definition: fanout.cpp:42
VOID TakePortPowerReference(_In_ HubPort *Port)
Definition: fanout.cpp:532
VOID MarkDevicesProgrammingLost()
Definition: fanout.cpp:840
BOOLEAN TakeInterruptReference(_In_ HubPort *Port)
Definition: fanout.cpp:485
VOID DropInterruptReference(_In_ HubPort *Port)
Definition: fanout.cpp:499
VOID QueueSuspendToDevices()
Definition: fanout.cpp:938
VOID QueueResumeInS0ToDevices()
Definition: fanout.cpp:962
BOOLEAN PortInterruptRefsReleased()
Definition: fanout.cpp:859
VOID QueueResumeToDevices()
Definition: fanout.cpp:956
VOID QueueSurpriseRemovalToPorts()
Definition: fanout.cpp:908
VOID QueueFakeStatusChangeToPorts()
Definition: fanout.cpp:926
VOID QueueSuspendToPorts()
Definition: fanout.cpp:902
VOID QueueStatusChangeToPorts()
Definition: fanout.cpp:920
VOID QueueResetToPorts()
Definition: fanout.cpp:914
HubFdo * m_Hub
Definition: hubsm.h:574
VOID QueueStopToDevices()
Definition: fanout.cpp:932
VOID QueueStartToDevices()
Definition: fanout.cpp:950
VOID QueueResumeWithResetToDevices()
Definition: fanout.cpp:968
VOID QueueResumeToPorts()
Definition: fanout.cpp:878
VOID QueueStopAfterSuspendToDevices()
Definition: fanout.cpp:944
VOID AllowHubReset()
Definition: fanout.cpp:865
BOOLEAN CreateChildPorts()
Definition: fanout.cpp:853
VOID QueueStartToPorts()
Definition: fanout.cpp:871
VOID QueueStopToPorts()
Definition: fanout.cpp:896
VOID QueueResumeInS0ToPorts()
Definition: fanout.cpp:884
VOID QueueResumeWithResetToPorts()
Definition: fanout.cpp:890
HubFdo * m_Hub
Definition: hubport.h:228
VOID DropInterruptReference()
Definition: fanout.cpp:1000
HubPort * m_Port
Definition: portsm.h:950
BOOLEAN HubArmedForWake()
Definition: fanout.cpp:1018
BOOLEAN TakeInterruptReference()
Definition: fanout.cpp:994
VOID DropHubResetReference()
Definition: fanout.cpp:988
VOID TakePortPowerReference()
Definition: fanout.cpp:976
VOID DropPortPowerReference()
Definition: fanout.cpp:982
VOID ResumeInterruptTransfer()
Definition: fanout.cpp:1012
VOID RequestHubReset()
Definition: fanout.cpp:1006
UINT Depth
Definition: d3d12.idl:4644
#define RtlNumberOfSetBits
Definition: dbgbitmap.h:343
#define RtlCheckBit
Definition: dbgbitmap.h:349
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
DsmEvent
Definition: devsm.h:15
_In_ ULONG Attributes
Definition: dispmprt.h:1077
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
#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 _IRQL_requires_(irql)
Definition: driverspecs.h:229
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
static const char HubTagPnpPower[]
Definition: fanout.cpp:20
static ULONG NTAPI HubClampTierDepth(_In_ ULONG Depth)
Definition: fanout.cpp:26
static const char HubTagRegistration[]
Definition: fanout.cpp:19
static BOOLEAN NTAPI HubDescriptorSaysFixed(_In_ const UCHAR *Bitmap, _In_ ULONG PortNumber)
Definition: fanout.cpp:101
static VOID NTAPI HubTrackPortRange(_In_ USHORT PortNumber, _Inout_ PUSHORT First, _Inout_ PUSHORT Last)
Definition: fanout.cpp:86
static BOOLEAN NTAPI HubAddPort(_In_ HubFdo *Hub, _In_ const HubPortInfo *Info)
Definition: fanout.cpp:63
Status
Definition: gdiplustypes.h:24
CPPORT Port[4]
Definition: headless.c:38
WDFKEY Root
_In_ ULONG PortNumber
Definition: hubucx.h:272
FORCEINLINE VOID NTAPI HubClearListEntry(_Out_ PLIST_ENTRY Entry)
Definition: hubutil.h:149
#define HUB_TAG_HUB
Definition: hubutil.h:12
#define InterlockedExchangeAdd
Definition: interlocked.h:196
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
PortEvent
Definition: portsm.h:15
@ Failed
Definition: arc.h:88
#define DPRINT
Definition: sndvol32.h:73
RTL_BITMAP Bitmap
Definition: hubreq.h:81
WDFMEMORY BitmapMemory
Definition: hubreq.h:77
ULONG BitmapMaxBytes
Definition: hubreq.h:79
BOOLEAN LastInterruptWasEmpty
Definition: hubreq.h:75
PUCHAR BitmapBuffer
Definition: hubreq.h:78
volatile LONG OutstandingPnpOperations
Definition: fdo.h:62
LIST_ENTRY Devices
Definition: fdo.h:73
LONG InterruptReferences
Definition: fdo.h:64
LIST_ENTRY Ports
Definition: fdo.h:69
BOOLEAN FailDeviceRegistration
Definition: fdo.h:78
volatile LONG PortPowerReferences
Definition: fdo.h:65
LONG DevicePowerReferences
Definition: fdo.h:66
BOOLEAN FailInterruptAcquire
Definition: fdo.h:76
volatile LONG OutstandingResetOperations
Definition: fdo.h:63
volatile LONG OutstandingPortChanges
Definition: fdo.h:61
BOOLEAN HubResetEnabled
Definition: fdo.h:77
BOOLEAN InterruptReleasePending
Definition: fdo.h:75
KSPIN_LOCK Lock
Definition: fdo.h:59
ULONG PortCount
Definition: fdo.h:70
HubDeviceFanOut DeviceFanOut
Definition: fdo.h:79
volatile LONG HubResetInProgress
Definition: fdo.h:82
UCHAR TotalHubDepth
Definition: fdo.h:98
PUSB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED SublinkSpeedAttr
Definition: fdo.h:101
ULONG SublinkSpeedAttrCount
Definition: fdo.h:102
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT NumberOf20Ports
Definition: ucxroothub.h:41
USHORT NumberOf30Ports
Definition: ucxroothub.h:42
ULONG SizeOfBitMap
Definition: typedefs.h:90
BOOLEAN IsEnhancedSuperSpeed
Definition: hubucx.h:506
USB_DEVICE_SPEED HubSpeed
Definition: hubucx.h:504
ROOTHUB_INFO Info
Definition: hubucx.h:119
#define max(a, b)
Definition: svc.c:63
unsigned char UCHAR
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
@ TriStateFalse
Definition: ucxroothub.h:23
@ TriStateTrue
Definition: ucxroothub.h:24
@ UsbSuperSpeed
Definition: usb200.h:45
HubDeviceFanOut
Definition: fdo.h:49
WdfObjectDelete(String)
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2231
#define WdfDeviceResumeIdle(Device)
Definition: wdfdevice.h:1983
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFDEVICE Child
Definition: wdffdo.h:536
#define WdfObjectDereferenceWithTag(Handle, Tag)
Definition: wdfobject.h:829
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
#define WdfObjectReferenceWithTag(Handle, Tag)
Definition: wdfobject.h:806
#define NT_ASSERT
Definition: rtlfuncs.h:3334