ReactOS 0.4.17-dev-1281-g065abb3
devhcd.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: Device requests to the USB controller extension and endpoint programming
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "usbhub3.h"
9#include "devhcd.h"
10
11#define NDEBUG
12#include <debug.h>
13
14/* Size field of each device request: the full current layouts. UCX does not check Size. */
15#define UCX_SIZE_ADDRESS0 sizeof(ADDRESS0_OWNERSHIP_ACQUIRE)
16#define UCX_SIZE_ENABLE sizeof(USBDEVICE_ENABLE)
17#define UCX_SIZE_RESET sizeof(USBDEVICE_RESET)
18#define UCX_SIZE_ADDRESS sizeof(USBDEVICE_ADDRESS)
19#define UCX_SIZE_UPDATE sizeof(USBDEVICE_UPDATE)
20#define UCX_SIZE_DISABLE sizeof(USBDEVICE_DISABLE)
21#define UCX_SIZE_PURGE sizeof(USBDEVICE_PURGEIO)
22#define UCX_SIZE_START sizeof(USBDEVICE_STARTIO)
23#define UCX_SIZE_ABORT sizeof(USBDEVICE_ABORTIO)
24#define UCX_SIZE_CONFIGURE sizeof(ENDPOINTS_CONFIGURE)
25#define UCX_SIZE_EP0_UPDATE sizeof(DEFAULT_ENDPOINT_UPDATE)
26#define UCX_SIZE_EP_RESET sizeof(ENDPOINT_RESET)
27
28#ifndef _WIN64
31#endif
32
33/* Default endpoint packet size the controller starts with, per speed */
34#define EP0_PACKET_SUPER 512
35#define EP0_PACKET_HIGH_FULL 64
36#define EP0_PACKET_LOW 8
37
38/* How long a bandwidth failure waits before the user is told */
39#define BANDWIDTH_RETRY_DELAY_MS 1000
40
41/* Enumeration failure text for a failed SET_ADDRESS */
42#define HUB_MSG_SET_ADDRESS_FAILED 0x40010001
43
44/* Resume signaling a hub below the root port gives its downstream port, in ms */
45#define HUB_ROOT_RESUME_SIGNAL_MS 20
46
47/* USB 2.0 LPM BESL used when the device has no baseline, 400 us */
48#define LPM20_DEFAULT_BESL 4
49
50static EVT_WDF_REQUEST_COMPLETION_ROUTINE HubChildUcxIoctlComplete;
51static EVT_WDF_REQUEST_COMPLETION_ROUTINE HubChildClientRequestComplete;
52
53/* Shared helpers */
54
55static
56VOID
61{
62 PUSBDEVICE_MGMT_HEADER Header = &Child->m_UcxPayload->Header;
63
64 Header->Size = Size;
65 Header->Hub = Child->m_Hub->UsbDevice();
66 Header->UsbDevice = Child->m_UsbDevice;
67}
68
69static
75{
76 RtlZeroMemory(Child->m_UcxPayload, sizeof(*Child->m_UcxPayload));
78 return Child->m_UcxPayload;
79}
80
81static
82VOID
86{
87 WdfTimerStart(Child->m_BandwidthRetryTimer, WDF_REL_TIMEOUT_IN_MS(BANDWIDTH_RETRY_DELAY_MS));
88}
89
90static
91VOID
95{
96 WdfTimerStop(Child->m_BandwidthRetryTimer, FALSE);
97}
98
99static
100VOID
101NTAPI
104 _In_ NTSTATUS NtStatus,
106{
107 Child->m_LastNtStatus = NtStatus;
108 Child->m_LastUsbdStatus = UsbdStatus;
109}
110
111/* Appends the first list to the unchanged list, never past the shared capacity */
112static
113VOID
114NTAPI
117 _In_reads_(Count) UCXENDPOINT* Endpoints,
119{
120 ULONG Index;
121
122 for (Index = 0; Index < Count; Index++)
123 {
124 if (Child->m_UnchangedCount >= Child->m_EndpointArrayCapacity)
125 break;
126
127 Child->m_EndpointsUnchanged[Child->m_UnchangedCount++] = Endpoints[Index];
128 }
129}
130
131VOID
132NTAPI
135 _In_ PipeState From,
136 _In_ PipeState To)
137{
140 ULONG Index;
141
142 if (Config == NULL)
143 return;
144
145 for (Entry = Config->Interfaces.Flink; Entry != &Config->Interfaces; Entry = Entry->Flink)
146 {
148
149 for (Index = 0; Index < Interface->PipeCount; Index++)
150 {
151 if (Interface->Pipes[Index].State == From)
152 Interface->Pipes[Index].State = To;
153 }
154 }
155}
156
157static
158VOID
159NTAPI
162 _In_ PipeState To)
163{
164 ULONG Index;
165
166 for (Index = 0; Index < Interface->PipeCount; Index++)
167 Interface->Pipes[Index].State = To;
168}
169
170/* Request channel */
171
173NTAPI
177{
178 WDFIOTARGET Target = Child->m_Hub->m_RootHubTarget;
179 WDFREQUEST Request = Child->m_UcxRequest;
182
184 Status = WdfRequestReuse(Request, &Reuse);
185 if (!NT_SUCCESS(Status))
186 DPRINT1("Device %p UCX request reuse failed 0x%lx\n", Child, Status);
187
188 Child->m_UcxIoctl = IoControlCode;
189
190 /* The request was made on the local target; that stack is at least as deep */
191 Status = WdfIoTargetFormatRequestForInternalIoctlOthers(Target,
192 Request,
194 Child->m_UcxPayloadMemory,
195 NULL,
196 NULL,
197 NULL,
198 NULL,
199 NULL);
200 if (NT_SUCCESS(Status))
201 {
202 WdfRequestSetCompletionRoutine(Request, HubChildUcxIoctlComplete, Child);
203
205 return STATUS_SUCCESS;
206
207 Status = WdfRequestGetStatus(Request);
208 }
209
210 DPRINT1("Device %p UCX request 0x%lx not sent 0x%lx\n", Child, IoControlCode, Status);
213 return Status;
214}
215
216static
218NTAPI
222{
223 PUSBDEVICE_ENABLE Enable = &Child->m_UcxPayload->Enable;
224
225 if (Enable->FailureFlags.InsufficientHardwareResourcesForDefaultEndpoint ||
226 Enable->FailureFlags.InsufficientHardwareResourcesForDevice)
227 {
228 DPRINT("Device %p enable ran out of controller resources\n", Child);
229 Child->m_LastUsbdStatus = USBD_STATUS_NO_BANDWIDTH;
231 return STATUS_UNSUCCESSFUL;
232 }
233
234 if (NT_SUCCESS(Status))
235 {
237 return Status;
238 }
239
240 /* A generic failure is reported as out of resources */
243
244 return Status;
245}
246
248static
250NTAPI
254{
255 PENDPOINTS_CONFIGURE Configure = &Child->m_UcxPayload->Configure;
257
260 if (Child->m_OldInterface != NULL)
262
263 if (Configure->ExitLatencyDelta != 0)
264 {
265 /* The ELD exit latency is cleared either way */
266 if (Configure->FailureFlags.MaxExitLatencyTooLarge)
267 {
268 DPRINT1("Device %p exit latency delta %lu rejected, effective latency %u\n",
269 Child, Configure->ExitLatencyDelta, Child->m_EffectiveExitLatency);
270 Child->m_MaxExitLatencyFromEld = 0;
271 }
272 else if (NT_SUCCESS(*Status))
273 {
274 Child->m_MaxExitLatencyFromEld = Child->m_EffectiveExitLatency + Configure->ExitLatencyDelta;
275 DPRINT("Device %p max exit latency from delta is %lu\n", Child, Child->m_MaxExitLatencyFromEld);
276 }
277 else
278 {
279 Child->m_MaxExitLatencyFromEld = 0;
280 }
281 }
282
283 Failed = Configure->FailureFlags.InsufficientBandwidth ||
284 Configure->FailureFlags.InsufficientHardwareResourcesForEndpoints ||
285 Configure->FailureFlags.MaxExitLatencyTooLarge;
286
287 if (Failed)
288 {
289 DPRINT("Device %p endpoint configure ran out of bandwidth or resources\n", Child);
290 Child->m_LastUsbdStatus = USBD_STATUS_NO_BANDWIDTH;
292
293 /* Older controllers report a latency problem as a resource problem; retry without U1 and U2 */
294 if (Child->m_EffectiveExitLatency != 0)
295 {
296 DPRINT1("Device %p endpoint configure failed at exit latency %u, retrying without U1 and U2\n",
297 Child, Child->m_EffectiveExitLatency);
298 HubChildKeepUnchanged(Child, Child->m_EndpointsToDisable, Child->m_DisableCount);
299 Child->m_DisableCount = 0;
300
301 /* The USBD code goes into the NT status here */
304 return FALSE;
305 }
306
308 }
309
312 {
313 DPRINT1("Device %p select failed by the alternate setting filter\n", Child);
314 Child->m_LastUsbdStatus = USBD_STATUS_NO_BANDWIDTH;
317 }
318 else if (Child->m_EnableCount != 0 && NT_SUCCESS(*Status))
319 {
321 }
322 else if (*Status == STATUS_UNSUCCESSFUL)
323 {
325 }
326
327 HubConfigMovePipes(Child->m_CurrentConfig,
330
331 Child->m_DisableCount = 0;
332 Child->m_EnableCount = 0;
333 Child->m_UnchangedCount = 0;
334 return TRUE;
335}
336
337/* While any SuperSpeed device's last SET_ADDRESS failed, connects get more debounce time */
338static
339VOID
340NTAPI
344{
346
347 if (NT_SUCCESS(Status))
348 {
349 Child->m_Address = (UCHAR)Child->m_UcxPayload->Address.Address;
350
351 if (InterlockedAnd(&Child->m_StateFlags, ~Flag) & Flag)
352 {
353 DPRINT1("Device %p SET_ADDRESS works again after an earlier failure\n", Child);
355 }
356
357 return;
358 }
359
360 Child->m_EnumMessageId = HUB_MSG_SET_ADDRESS_FAILED;
361
362 if ((Child->m_Kind & DSM_KIND_PORT30) &&
363 !(InterlockedOr(&Child->m_StateFlags, Flag) & Flag))
364 {
365 DPRINT1("Device %p SET_ADDRESS failed, SuperSpeed connects now get extra debounce time\n", Child);
367 }
368}
369
370/* A controller that leaves the answer at 0 keeps the device at "unknown" */
371static
372VOID
373NTAPI
376{
377 PUSBDEVICE_UPDATE Update = &Child->m_UcxPayload->Update;
378 UCHAR State;
379
380 if (!Update->Flags.UpdateTunnelState)
381 return;
382
385 {
386 DPRINT1("Device %p controller gave no USB4 tunnel state\n", Child);
387 return;
388 }
389
390 DPRINT("Device %p USB4 tunnel state %u\n", Child, State);
391 Child->m_TunnelState = State;
392}
393
394static
395VOID
396NTAPI
398 _In_ WDFREQUEST Request,
399 _In_ WDFIOTARGET Target,
402{
404 NTSTATUS Status = Params->IoStatus.Status;
405
408
409 switch (Child->m_UcxIoctl)
410 {
413 break;
414
417 return;
418 break;
419
422 break;
423
426 break;
427
429 /* Every successful update counts as taking the target latency, even ones without it */
430 if (NT_SUCCESS(Status))
431 {
432 Child->m_EffectiveExitLatency = Child->m_TargetExitLatency;
434 }
435 else if (Child->m_UcxPayload->Update.FailureFlags.MaxExitLatencyTooLarge)
436 {
437 DPRINT1("Device %p exit latency %u too large for the controller 0x%lx\n",
438 Child, Child->m_TargetExitLatency, Status);
440 return;
441 }
442 break;
443
444 default:
445 break;
446 }
447
448 if (!NT_SUCCESS(Status))
449 {
450 DPRINT1("Device %p UCX request 0x%lx failed 0x%lx\n", Child, Child->m_UcxIoctl, Status);
451
452 /* A USBD status left over from an earlier failure wins */
453 Child->m_LastNtStatus = Status;
454 if (Child->m_LastUsbdStatus == 0)
455 Child->m_LastUsbdStatus = HubNtStatusToUsbd(Status);
456 }
457
459}
460
461VOID
463{
464 if (!WdfRequestCancelSentRequest(m_Device->m_UcxRequest))
465 DPRINT1("Device %p UCX request 0x%lx was not canceled\n", m_Device, m_Device->m_UcxIoctl);
466}
467
468/* Address zero */
469
470VOID
472{
475}
476
477VOID
479{
481
483}
484
485/* Device and default endpoint objects */
486
489{
491 HubFdo* Hub = Child->m_Hub;
492 PUCXHUB_DEVICE_CREATE_INFO Info = &Child->m_CreateInfo;
493 UCXUSBDEVICE UsbDevice;
495
496 Info->Size = sizeof(*Info);
497
498 if (Child->m_Kind & DSM_KIND_SUPER_SPEED)
499 {
500 Info->DeviceSpeed = UsbSuperSpeed;
501 Child->m_MaxPacketSize0 = EP0_PACKET_SUPER;
502 }
503 else if (Child->m_Kind & DSM_KIND_HIGH_SPEED)
504 {
505 Info->DeviceSpeed = UsbHighSpeed;
506 Child->m_MaxPacketSize0 = EP0_PACKET_HIGH_FULL;
507 }
508 else if (Child->m_Kind & DSM_KIND_LOW_SPEED)
509 {
510 Info->DeviceSpeed = UsbLowSpeed;
511 Child->m_MaxPacketSize0 = EP0_PACKET_LOW;
512 }
513 else
514 {
515 Info->DeviceSpeed = UsbFullSpeed;
516 Child->m_MaxPacketSize0 = EP0_PACKET_HIGH_FULL;
517 }
518
519 Info->PortNumber = Child->m_Port->Number();
520 Info->HubDeviceContext = (UCXHUB_DEVICE_CONTEXT)Child;
521
523 if (!NT_SUCCESS(Status))
524 {
525 DPRINT1("Port %u controller device create failed 0x%lx\n", Child->m_Port->Number(), Status);
527 return FALSE;
528 }
529
530 Child->m_UsbDevice = UsbDevice;
531 return TRUE;
532}
533
536{
538 HubFdo* Hub = Child->m_Hub;
539 UCXENDPOINT Endpoint;
541
543 Child->m_UsbDevice,
544 Child->m_MaxPacketSize0,
545 &Endpoint);
546 if (!NT_SUCCESS(Status))
547 {
548 DPRINT1("Device %p default endpoint create failed 0x%lx\n", Child, Status);
550 return FALSE;
551 }
552
553 Child->m_DefaultEndpoint = Endpoint;
554 return TRUE;
555}
556
557VOID
559{
561
564}
565
566/* The handle stays; the machine never uses it again after this */
567VOID
569{
571
573}
574
575/* Enable, disable, address, update */
576
577VOID
579{
581
584}
585
586VOID
588{
590
593}
594
595VOID
597{
599
603}
604
605/* Address 0 in the request lets the controller pick one and report it back */
606VOID
608{
610
611 Payload->Address.Address = 0;
613}
614
615/* USB 2.0 LPM attributes of the device, as the BOS validator accepts them */
617{
624};
625
626/* Combined over every USB 2.0 extension in the BOS; attributes are only ever added */
627static
628VOID
629NTAPI
633{
634 PUSB_BOS_DESCRIPTOR Bos = Child->m_Bos;
638 PUCHAR End;
639 UCHAR Baseline;
640 UCHAR Deep;
641
642 RtlZeroMemory(Lpm, sizeof(*Lpm));
643
644 if (Bos == NULL)
645 return;
646
647 Current = (PUCHAR)Bos + Bos->bLength;
648 End = (PUCHAR)Bos + Bos->wTotalLength;
649
650 for (; Current + sizeof(*Common) <= End; Current += Common->bLength)
651 {
653 if (Common->bLength == 0)
654 break;
655
657
659 Common->bLength < sizeof(*Extension) ||
660 Current + sizeof(*Extension) > End ||
661 Extension->bDevCapabilityType != USB_DEVICE_CAPABILITY_USB20_EXTENSION ||
662 !Extension->bmAttributes.LPMCapable)
663 {
664 continue;
665 }
666
667 Baseline = (UCHAR)Extension->bmAttributes.BaselineBESL;
668 Deep = (UCHAR)Extension->bmAttributes.DeepBESL;
669
670 Lpm->Capable = TRUE;
671 if (Extension->bmAttributes.BESLAndAlternateHIRDSupported)
672 Lpm->Besl = TRUE;
673
674 if (Extension->bmAttributes.BaselineBESLValid && Baseline != 0)
675 {
676 Lpm->BaselineValid = TRUE;
677 Lpm->Baseline = Baseline;
678 }
679
680 /* A deep value not above a valid baseline is ignored */
681 if (Extension->bmAttributes.DeepBESLValid && Deep != 0 &&
682 !(Extension->bmAttributes.BaselineBESLValid && Deep <= Baseline))
683 {
684 Lpm->DeepValid = TRUE;
685 Lpm->Deep = Deep;
686 }
687 }
688}
689
690/* Fills the USB 2.0 hardware LPM part of an update; TRUE when LPM is on */
691static
693NTAPI
697{
700
702
703 if (Child->HasProperty(ChildProperty::IsHub))
705 else if (Child->HasHack(ChildHack::DisableUsb20Lpm))
707 else if (Child->m_Hub->HasFlag(HubFlag::DisableUsb20Lpm))
711 else if (!Lpm.Capable)
713 else if (!Lpm.Besl)
715 else if (!Child->m_Port->HasProperty(PortProperty::Usb20LpmCapable))
717 else
719
721 {
722 Update->Flags.Update20HardwareLpmParameters = 1;
723 Update->Usb20HardwareLpmParameters.HardwareLpmEnable = 1;
724 Update->Usb20HardwareLpmParameters.L1Timeout = HubDriver.Usb20LpmTimeout;
725 Update->Usb20HardwareLpmParameters.RemoteWakeEnable =
727 Update->Usb20HardwareLpmParameters.BestEffortServiceLatency = LPM20_DEFAULT_BESL;
728 Update->Usb20HardwareLpmParameters.BestEffortServiceLatencyDeep = 0;
729 Update->Usb20HardwareLpmParameters.HostInitiatedResumeDurationMode = 0;
730
731 if (Child->m_Port->HasProperty(PortProperty::BeslCapable))
732 {
733 if (Lpm.BaselineValid)
734 Update->Usb20HardwareLpmParameters.BestEffortServiceLatency = Lpm.Baseline;
735
736 if (Lpm.DeepValid)
737 {
738 Update->Usb20HardwareLpmParameters.BestEffortServiceLatencyDeep = Lpm.Deep;
739 Update->Usb20HardwareLpmParameters.HostInitiatedResumeDurationMode = 1;
740 }
741 }
742 }
743
744 /* Diagnostic only; the parameters still go out and UCX ignores them */
746 : (ULONG)Result;
747 DPRINT("Device %p USB 2.0 LPM status %lu\n", Child, Child->m_Lpm20Status);
748
750}
751
752VOID
754{
757 PUSBDEVICE_UPDATE Update = &Payload->Update;
758 BOOLEAN IsHub = Child->HasProperty(ChildProperty::IsHub);
759
760 /* Only ports bound to a USB4 host ask; the U2 decision below sees the preset, not the answer */
761 Child->m_TunnelState = HUB_TUNNEL_STATE_NOT_USB4;
762 if (Child->m_Port->HasFlag(PortFlag::Usb4Host))
763 {
764 Child->m_TunnelState = HUB_TUNNEL_STATE_UNKNOWN;
765 Update->Flags.UpdateTunnelState = 1;
766 }
767
768 Update->Flags.UpdateDeviceDescriptor = 1;
769 Update->Flags.UpdateBosDescriptor = 1;
770 Update->Flags.UpdateMaxExitLatency = 1;
771 Update->Flags.UpdateIsHub = 1;
772 if (Child->HasHack(ChildHack::TolerateStalePipes))
773 Update->Flags.UpdateAllowIoOnInvalidPipeHandles = 1;
774
775 Update->DeviceDescriptor = &Child->m_DeviceDescriptor;
776 Update->BosDescriptor = Child->m_Bos;
777 Update->MaxExitLatency = HubChildU2ForEnumerated(Child) ? Child->m_HostU2ExitLatency : 0;
778 Update->IsHub = IsHub;
779
781
782 /* Only a root port uses the device's own resume signaling time */
783 if (Child->m_HasResumeRecoveryTime &&
784 Child->HasProperty(ChildProperty::NotRemovable) &&
785 !IsHub &&
786 Child->m_Port->m_Info.Protocol == 0x200)
787 {
788 Update->Flags.UpdateRootPortResumeTime = 1;
789 Update->RootPortResumeTime = Child->m_Hub->IsRootHub() ? Child->m_ResumeSignalingTime
791 }
792
794}
795
796/* FALSE sends nothing; TRUE means an event comes, even when the send failed */
799{
801
802 RtlZeroMemory(Child->m_UcxPayload, sizeof(*Child->m_UcxPayload));
803 if (!HubChildComputeLpm20(Child, &Child->m_UcxPayload->Update))
804 return FALSE;
805
808 return TRUE;
809}
810
811VOID
813{
815 HubUcxPayload* Payload;
816
817 if (Child->m_MaxExitLatencyFromEld != 0 &&
818 Child->m_TargetExitLatency > Child->m_MaxExitLatencyFromEld)
819 {
820 DPRINT1("Device %p exit latency %u is above the controller limit %lu\n",
821 Child, Child->m_TargetExitLatency, Child->m_MaxExitLatencyFromEld);
822 Child->Post(DsmEvent::ControllerExitLatencyTooLarge);
823 return;
824 }
825
827 Payload->Update.Flags.UpdateMaxExitLatency = 1;
828 Payload->Update.MaxExitLatency = Child->m_TargetExitLatency;
830}
831
832/*
833 * The enabled endpoints go into the request as PendingDisable; the
834 * device's own disable count is left alone.
835 */
836VOID
838{
840 HubConfiguration* Config = Child->m_CurrentConfig;
841 UCXENDPOINT* Endpoints = NULL;
842 HubUcxPayload* Payload;
845 ULONG Count = 0;
846 ULONG Index;
848
849 if (Config != NULL && Child->m_EndpointArrayCapacity != 0)
850 {
851 Endpoints = Child->m_EndpointsToDisable;
852
853 for (Entry = Config->Interfaces.Flink;
854 Entry != &Config->Interfaces && NT_SUCCESS(Status);
855 Entry = Entry->Flink)
856 {
858
859 for (Index = 0; Index < Interface->PipeCount; Index++)
860 {
861 if (Interface->Pipes[Index].State != PipeState::Enabled)
862 continue;
863
864 if (Endpoints == NULL)
865 {
867 break;
868 }
869
870 Interface->Pipes[Index].State = PipeState::PendingDisable;
871 Endpoints[Count++] = Interface->Pipes[Index].Endpoint;
872 }
873 }
874
875 /* Fails the request so the device machine does not wait forever */
876 if (!NT_SUCCESS(Status))
877 {
878 DPRINT1("Device %p reset has enabled endpoints but no disable list 0x%lx\n", Child, Status);
880 Child->Post(DsmEvent::ControllerIoctlFailed);
881 }
882 }
883
884 if (NT_SUCCESS(Status))
885 {
887 Payload->Reset.DefaultEndpoint = Child->m_DefaultEndpoint;
889 Payload->Reset.EndpointsToDisable = Endpoints;
890
892 }
893
894 if (!NT_SUCCESS(Status))
895 HubConfigMovePipes(Config, PipeState::PendingDisable, PipeState::Enabled);
896}
897
898/* I/O control */
899
900VOID
902{
905}
906
907VOID
909{
911
912 Payload->Purge.OnSuspend = FALSE;
914}
915
916VOID
918{
920
921 Payload->Purge.OnSuspend = TRUE;
923}
924
925/* The tree purge uses the plain purge size */
926VOID
928{
931}
932
933VOID
935{
938}
939
940/* Endpoint reset */
941
942static
943VOID
944NTAPI
948{
950
951 if (Child->m_TargetPipe == NULL)
952 {
953 DPRINT1("Device %p endpoint reset without a target pipe\n", Child);
956 return;
957 }
958
959 Payload->EndpointReset.Endpoint = Child->m_TargetPipe->Endpoint;
962}
963
964VOID
966{
968}
969
970VOID
972{
974}
975
976/* Endpoint programming */
977
978VOID
980{
982 BOOLEAN FailAlternate = Child->HasState(ChildState::AltSettingFiltered);
984
985 /* Selecting a zero bandwidth setting takes the bandwidth popup away */
986 if (Child->m_DisableCount == 0 && Child->m_EnableCount == 0)
987 {
988 DPRINT("Device %p has no endpoints to program\n", Child);
990 Child->Post(DsmEvent::ControllerIoctlDone);
991 return;
992 }
993
994 /* The flag stays set on this path */
995 if (Child->m_DisableCount == 0 && FailAlternate)
996 {
997 DPRINT1("Device %p select failed by the alternate setting filter\n", Child);
998 HubConfigMovePipes(Child->m_CurrentConfig, PipeState::PendingEnable, PipeState::Disabled);
1000 Child->Post(DsmEvent::ControllerIoctlFailed);
1001 return;
1002 }
1003
1005
1006 if (!FailAlternate)
1007 {
1008 Configure->EndpointsToEnableCount = Child->m_EnableCount;
1009 Configure->EndpointsToEnable = Child->m_EndpointsToEnable;
1010 }
1011
1012 Configure->EndpointsToDisableCount = Child->m_DisableCount;
1013 Configure->EndpointsToDisable = Child->m_EndpointsToDisable;
1014 Configure->EndpointsEnabledAndUnchangedCount = Child->m_UnchangedCount;
1015 Configure->EndpointsEnabledAndUnchanged = Child->m_EndpointsUnchanged;
1016
1017 if (Child->m_CurrentConfig != NULL)
1018 Configure->ConfigurationValue = Child->m_CurrentConfig->Descriptor.bConfigurationValue;
1019
1020 /* The next and new interfaces are always set together */
1021 if (Child->m_NextInterface != NULL && Child->m_NewInterface != NULL)
1022 {
1023 Configure->InterfaceNumber = Child->m_NewInterface->Descriptor->bInterfaceNumber;
1024 Configure->AlternateSetting = Child->m_NewInterface->Descriptor->bAlternateSetting;
1025 }
1026
1028}
1029
1030VOID
1032{
1034 HubConfiguration* Config = Child->m_CurrentConfig;
1036
1037 if (Config == NULL || Child->m_EndpointArrayCapacity == 0)
1038 {
1039 DPRINT("Device %p has no endpoints to disable\n", Child);
1040 Child->Post(DsmEvent::ControllerIoctlDone);
1041 return;
1042 }
1043
1044 Child->m_EnableCount = 0;
1045 Child->m_DisableCount = 0;
1046 Child->m_UnchangedCount = 0;
1047
1048 for (Entry = Config->Interfaces.Flink; Entry != &Config->Interfaces; Entry = Entry->Flink)
1050
1051 if (Child->m_DisableCount == 0)
1052 {
1053 Child->Post(DsmEvent::ControllerIoctlDone);
1054 return;
1055 }
1056
1058}
1059
1060VOID
1062{
1064
1065 if (Child->m_NewInterface == NULL)
1066 {
1067 Child->Post(DsmEvent::ControllerIoctlDone);
1068 return;
1069 }
1070
1071 Child->m_EnableCount = 0;
1072 Child->m_DisableCount = 0;
1073 Child->m_UnchangedCount = 0;
1074
1075 HubChildCollectForDisable(Child, Child->m_NewInterface);
1076
1077 if (Child->m_DisableCount == 0)
1078 {
1079 Child->Post(DsmEvent::ControllerIoctlDone);
1080 return;
1081 }
1082
1084}
1085
1086VOID
1088{
1090
1092
1093 if (Child->m_DisableCount == 0)
1094 {
1095 Child->Post(DsmEvent::ControllerIoctlDone);
1096 return;
1097 }
1098
1099 Child->m_EnableCount = 0;
1101}
1102
1103/* The caller guarantees a current configuration */
1104VOID
1106{
1107 HubConfigMovePipes(m_Device->m_CurrentConfig, PipeState::PendingEnable, PipeState::Disabled);
1108}
1109
1110BOOLEAN
1112{
1113 return m_Device->m_DisableCount != 0 || m_Device->m_EnableCount != 0;
1114}
1115
1116BOOLEAN
1118{
1120
1121 if (Child->m_EnableCount != 0 && Child->m_CurrentConfig != NULL)
1122 {
1123 HubConfigMovePipes(Child->m_CurrentConfig, PipeState::PendingEnable, PipeState::Disabled);
1124 HubChildKeepUnchanged(Child, Child->m_EndpointsToEnable, Child->m_EnableCount);
1125 Child->m_EnableCount = 0;
1126 }
1127
1128 return Child->m_DisableCount != 0;
1129}
1130
1131/*
1132 * Creates every endpoint the controller does not know yet. Zero bandwidth
1133 * endpoints made before a failure stay created as Disabled.
1134 */
1135BOOLEAN
1137{
1139 HubFdo* Hub = Child->m_Hub;
1140 HubConfiguration* Config = Child->m_CurrentConfig;
1142 HubPipe* Pipe;
1144 ULONG Index;
1146
1147 if (Child->m_EndpointArrayCapacity == 0 || Config == NULL)
1148 {
1149 DPRINT("Device %p has no endpoints to create\n", Child);
1150 return TRUE;
1151 }
1152
1153 for (Entry = Config->Interfaces.Flink;
1154 Entry != &Config->Interfaces && NT_SUCCESS(Status);
1155 Entry = Entry->Flink)
1156 {
1158
1159 for (Index = 0; Index < Interface->PipeCount; Index++)
1160 {
1161 Pipe = &Interface->Pipes[Index];
1162 if (Pipe->State != PipeState::NotCreated)
1163 continue;
1164
1165 Pipe->State = PipeState::PendingCreate;
1167 Child->m_UsbDevice,
1168 Pipe->Descriptor,
1169 Pipe->BytesToEnd,
1170 Pipe->Companion,
1171 &Pipe->Endpoint);
1172 if (!NT_SUCCESS(Status))
1173 {
1174 DPRINT1("Device %p endpoint 0x%x create failed 0x%lx\n",
1175 Child, Pipe->Descriptor->bEndpointAddress, Status);
1176 Pipe->State = PipeState::NotCreated;
1177 break;
1178 }
1179
1180 if (Pipe->ZeroBandwidth)
1181 {
1182 Pipe->State = PipeState::Disabled;
1183 Child->m_EndpointsUnchanged[Child->m_UnchangedCount++] = Pipe->Endpoint;
1184 }
1185 else
1186 {
1187 Child->m_EndpointsToEnable[Child->m_EnableCount++] = Pipe->Endpoint;
1188 }
1189 }
1190 }
1191
1192 for (Entry = Config->Interfaces.Flink; Entry != &Config->Interfaces; Entry = Entry->Flink)
1193 {
1195
1196 for (Index = 0; Index < Interface->PipeCount; Index++)
1197 {
1198 Pipe = &Interface->Pipes[Index];
1199 if (Pipe->State != PipeState::PendingCreate)
1200 continue;
1201
1202 if (NT_SUCCESS(Status))
1203 {
1204 Pipe->State = PipeState::PendingEnable;
1205 }
1206 else
1207 {
1208 Pipe->State = PipeState::NotCreated;
1209 Hub->m_Stack.EndpointDelete(Hub->UsbDevice(), Child->m_UsbDevice, Pipe->Endpoint);
1210 Pipe->Endpoint = NULL;
1211 }
1212 }
1213 }
1214
1215 if (!NT_SUCCESS(Status))
1216 {
1217 Child->m_EnableCount = 0;
1218 Child->m_UnchangedCount = 0;
1220 return FALSE;
1221 }
1222
1223 return TRUE;
1224}
1225
1226/* Deletion, all at passive level */
1227
1229VOID
1230NTAPI
1231HubChildDeleteInterface(
1234{
1235 HubFdo* Hub = Child->m_Hub;
1238
1239 for (Index = 0; Index < Interface->PipeCount; Index++)
1240 {
1241 Pipe = &Interface->Pipes[Index];
1242 if (Pipe->State != PipeState::Disabled)
1243 continue;
1244
1245 Hub->m_Stack.EndpointDelete(Hub->UsbDevice(), Child->m_UsbDevice, Pipe->Endpoint);
1246 Pipe->State = PipeState::Deleted;
1247 }
1248
1250}
1251
1252/* The FDO reads the configuration under the lock, so it is taken off before it goes */
1254static
1255VOID
1256NTAPI
1257HubChildDeleteConfiguration(
1260{
1264
1265 KeAcquireSpinLock(&Child->m_ConfigLock, &Irql);
1267 *Slot = NULL;
1268 KeReleaseSpinLock(&Child->m_ConfigLock, Irql);
1269
1270 if (Config == NULL)
1271 return;
1272
1273 while (!IsListEmpty(&Config->Interfaces))
1274 {
1275 Entry = RemoveHeadList(&Config->Interfaces);
1276 HubChildDeleteInterface(Child, CONTAINING_RECORD(Entry, HubInterface, Link));
1277 }
1278
1280}
1281
1282VOID
1284{
1285 HubChildDeleteConfiguration(m_Device, &m_Device->m_CurrentConfig);
1286}
1287
1288VOID
1290{
1291 HubChildDeleteConfiguration(m_Device, &m_Device->m_OldConfig);
1292}
1293
1294VOID
1296{
1298
1299 if (Interface == NULL)
1300 return;
1301
1303 HubChildDeleteInterface(m_Device, Interface);
1304}
1305
1306/* Enabled endpoints are not deleted; the machine disabled them before */
1307VOID
1309{
1311 HubInterface* Interface = Child->m_NewInterface;
1312 KIRQL Irql;
1313
1314 if (Interface == NULL)
1315 return;
1316
1317 KeAcquireSpinLock(&Child->m_ConfigLock, &Irql);
1318 RemoveEntryList(&Interface->Link);
1319 if (Child->m_CurrentConfig != NULL)
1320 Child->m_CurrentConfig->EndpointCount -= Interface->PipeCount;
1321 Child->m_NewInterface = NULL;
1322 KeReleaseSpinLock(&Child->m_ConfigLock, Irql);
1323
1324 if (Child->m_NextInterface == Interface)
1325 Child->m_NextInterface = NULL;
1326
1327 HubChildDeleteInterface(Child, Interface);
1328}
1329
1330/* Client request forwarding */
1331
1332static
1333VOID
1334NTAPI
1336 _In_ WDFREQUEST Request,
1337 _In_ WDFIOTARGET Target,
1340{
1342
1344
1345 WdfRequestCompleteWithInformation(Request, Params->IoStatus.Status, Params->IoStatus.Information);
1347}
1348
1349/* The request goes down as the client sent it, straight to the controller */
1350VOID
1351NTAPI
1354{
1355 WDFREQUEST Request = Child->m_ClientRequest;
1356
1357 WdfRequestFormatRequestUsingCurrentType(Request);
1358 WdfRequestSetCompletionRoutine(Request, HubChildClientRequestComplete, Child);
1359
1360 if (!WdfRequestSend(Request, Child->m_Hub->m_RootHubTarget, WDF_NO_SEND_OPTIONS))
1361 {
1362 DPRINT1("Device %p client request not sent 0x%lx\n", Child, WdfRequestGetStatus(Request));
1363 WdfRequestComplete(Request, WdfRequestGetStatus(Request));
1365 }
1366}
1367
1368VOID
1370{
1372}
1373
1374/* Services for the child PDO */
1375
1377VOID
1378NTAPI
1379HubChildSetPdo(
1382{
1383 HubFdo* Hub = Child->m_Hub;
1384
1386}
1387
1388/* Level 1 bus information, asked once more with the size the bus wants */
1390static
1392NTAPI
1393HubQueryBusInformation(
1394 _In_ HubFdo* Hub,
1397{
1399 ULONG Length = sizeof(*Buffer);
1402
1403 *Result = NULL;
1404
1406 if (Buffer == NULL)
1407 {
1408 DPRINT1("Hub %p no memory for bus information\n", Hub);
1410 }
1411
1414 {
1416
1417 Length = Actual;
1419 if (Buffer == NULL)
1420 {
1421 DPRINT1("Hub %p no memory for %lu bytes of bus information\n", Hub, Length);
1423 }
1424
1426 }
1427
1429 {
1430 DPRINT1("Hub %p bus information query failed 0x%lx\n", Hub, Status);
1432 return Status;
1433 }
1434
1435 *Result = Buffer;
1436 return Status;
1437}
1438
1439/* A short copy still succeeds; ActualLength says how much there is */
1442NTAPI
1443HubQueryControllerName(
1444 _In_ HubFdo* Hub,
1447{
1451
1452 Status = HubQueryBusInformation(Hub, Hub->m_Usbdi.BusContext, &Info);
1453 if (!NT_SUCCESS(Status))
1454 return Status;
1455
1457 {
1458 DPRINT1("Hub %p controller name buffer of %lu bytes is too small\n", Hub, Length);
1460 }
1461 else
1462 {
1463 Name->ActualLength = Info->ControllerNameLength;
1464 Copy = min(Info->ControllerNameLength, Length - FIELD_OFFSET(USB_HUB_NAME, HubName));
1465 RtlCopyMemory(Name->HubName, Info->ControllerNameUnicodeString, Copy);
1466 }
1467
1469 return Status;
1470}
1471
1472/* The device handle stands in for the bus context, which UCX accepts */
1475NTAPI
1476HubQueryDeviceBusInfo(
1479{
1482
1483 Status = HubQueryBusInformation(Child->m_Hub, Child->m_UsbDevice, &Info);
1484 if (!NT_SUCCESS(Status))
1485 return Status;
1486
1487 Notification->TotalBandwidth = Info->TotalBandwidth;
1488 Notification->ConsumedBandwidth = Info->ConsumedBandwidth;
1489 Notification->ControllerNameLength = Info->ControllerNameLength;
1490
1492 return Status;
1493}
unsigned char BOOLEAN
Definition: actypes.h:127
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
@ Update
Definition: registry.c:565
HubFdo * Hub
Definition: bootdev.cpp:261
USBD_STATUS NTAPI HubNtStatusToUsbd(_In_ NTSTATUS Status)
Definition: childpdo.cpp:190
Definition: bufpool.h:45
VOID ReleaseAddressZero()
Definition: devhcd.cpp:478
VOID AbortDeviceIo()
Definition: devhcd.cpp:901
BOOLEAN CreateDeviceInController()
Definition: devhcd.cpp:488
VOID UpdateDeviceInController()
Definition: devhcd.cpp:753
VOID DeleteDefaultEndpoint()
Definition: devhcd.cpp:558
VOID DisablePendingEndpoints()
Definition: devhcd.cpp:1087
HubChild * m_Device
Definition: devsm.h:1832
VOID ResetEndpointAndTransfers()
Definition: devhcd.cpp:971
VOID DisableDeviceInController()
Definition: devhcd.cpp:587
VOID ClaimAddressZero()
Definition: devhcd.cpp:471
BOOLEAN EndpointsNeedDisableOnFailure()
Definition: devhcd.cpp:1117
VOID DeleteDeviceInController()
Definition: devhcd.cpp:568
VOID UpdateDefaultEndpoint()
Definition: devhcd.cpp:596
VOID MarkPendingEndpointsDisabled()
Definition: devhcd.cpp:1105
VOID SetDeviceAddress()
Definition: devhcd.cpp:607
VOID DisableNewInterfaceEndpoints()
Definition: devhcd.cpp:1061
VOID DeleteOldInterfaceEndpoints()
Definition: devhcd.cpp:1295
VOID PurgeDeviceIo()
Definition: devhcd.cpp:908
VOID ProgramEndpoints()
Definition: devhcd.cpp:979
BOOLEAN CreateDefaultEndpoint()
Definition: devhcd.cpp:535
VOID UpdateExitLatency()
Definition: devhcd.cpp:812
VOID CancelControllerIoctl()
Definition: devhcd.cpp:462
BOOLEAN EndpointsNeedProgramming()
Definition: devhcd.cpp:1111
VOID NotifyDeviceReset()
Definition: devhcd.cpp:837
BOOLEAN UpdateLpm20()
Definition: devhcd.cpp:798
VOID PurgeIoForSuspend()
Definition: devhcd.cpp:917
VOID DisableAllEndpoints()
Definition: devhcd.cpp:1031
VOID DeleteOldConfigEndpoints()
Definition: devhcd.cpp:1289
VOID StartDeviceIo()
Definition: devhcd.cpp:934
VOID DeleteConfigEndpoints()
Definition: devhcd.cpp:1283
VOID EnableDeviceInController()
Definition: devhcd.cpp:578
VOID PurgeDeviceTreeIo()
Definition: devhcd.cpp:927
VOID DeleteNewInterfaceEndpoints()
Definition: devhcd.cpp:1308
VOID ResetEndpoint()
Definition: devhcd.cpp:965
VOID ForwardToController()
Definition: devhcd.cpp:1369
BOOLEAN CreateEndpoints()
Definition: devhcd.cpp:1136
Definition: Header.h:9
Header(const std::string &filename_)
Definition: Header.h:18
WDFREQUEST m_UcxRequest
Definition: hubchild.h:361
HubFdo * m_Hub
Definition: hubchild.h:316
ULONG m_DisableCount
Definition: hubchild.h:380
USHORT m_MaxPacketSize0
Definition: hubchild.h:351
UCXUSBDEVICE m_UsbDevice
Definition: hubchild.h:319
HubInterface * m_OldInterface
Definition: hubchild.h:373
ULONG m_UcxIoctl
Definition: hubchild.h:364
VOID Post(_In_ DsmEvent Event)
Definition: hubchild.h:253
HubConfiguration * m_OldConfig
Definition: hubchild.h:371
ULONG m_UnchangedCount
Definition: hubchild.h:381
ULONG m_EnableCount
Definition: hubchild.h:379
HubConfiguration * m_CurrentConfig
Definition: hubchild.h:370
BOOLEAN HasState(_In_ ChildState Flag) const
Definition: hubchild.h:260
UCXENDPOINT m_DefaultEndpoint
Definition: hubchild.h:375
Definition: fdo.h:132
USB_BUS_INTERFACE_USBDI_V3 m_Usbdi
Definition: fdo.h:357
UCXHUB_STACK_INTERFACE m_Stack
Definition: fdo.h:356
UCXUSBDEVICE UsbDevice() const
Definition: fdo.h:180
_Out_ PKIRQL Irql
Definition: csq.h:179
PUCHAR End
Definition: desccheck.cpp:2229
_In_ ULONG _Out_opt_ HubBosInfo _Out_opt_ PUSHORT _Out_opt_ PUSHORT _Inout_opt_ PBOOLEAN _Inout_opt_ HubLpmInfo * Lpm
Definition: desccheck.cpp:2221
LPWSTR Name
Definition: desk.c:124
VOID NTAPI HubChildCollectForDisable(_In_ HubChild *Child, _In_ HubInterface *Interface)
Definition: devconfig.cpp:132
static VOID NTAPI HubChildAddressDone(_In_ HubChild *Child, _In_ NTSTATUS Status)
Definition: devhcd.cpp:341
#define LPM20_DEFAULT_BESL
Definition: devhcd.cpp:48
static VOID NTAPI HubChildReadUsb20Lpm(_In_ HubChild *Child, _Out_ HubUsb20Lpm *Lpm)
Definition: devhcd.cpp:630
#define UCX_SIZE_ADDRESS
Definition: devhcd.cpp:18
Config
Definition: devhcd.cpp:1266
static VOID NTAPI HubChildResetTargetEndpoint(_In_ HubChild *Child, _In_ ULONG Flags)
Definition: devhcd.cpp:945
_In_ PVOID BusContext
Definition: devhcd.cpp:1395
#define UCX_SIZE_PURGE
Definition: devhcd.cpp:21
WdfObjectDelete(Interface->Memory)
#define UCX_SIZE_RESET
Definition: devhcd.cpp:17
_Inout_ HubConfiguration ** Slot
Definition: devhcd.cpp:1260
NTSTATUS NTAPI HubChildSubmitUcxIoctl(_In_ HubChild *Child, _In_ ULONG IoControlCode)
Definition: devhcd.cpp:174
#define EP0_PACKET_LOW
Definition: devhcd.cpp:36
static EVT_WDF_REQUEST_COMPLETION_ROUTINE HubChildUcxIoctlComplete
Definition: devhcd.cpp:50
#define UCX_SIZE_EP0_UPDATE
Definition: devhcd.cpp:25
#define HUB_ROOT_RESUME_SIGNAL_MS
Definition: devhcd.cpp:45
_In_ PVOID _Outptr_result_maybenull_ PUSB_BUS_INFORMATION_LEVEL_1 * Result
Definition: devhcd.cpp:1397
#define HUB_MSG_SET_ADDRESS_FAILED
Definition: devhcd.cpp:42
static BOOLEAN NTAPI HubChildComputeLpm20(_In_ HubChild *Child, _Inout_ PUSBDEVICE_UPDATE Update)
Definition: devhcd.cpp:694
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
static VOID NTAPI HubChildKeepUnchanged(_In_ HubChild *Child, _In_reads_(Count) UCXENDPOINT *Endpoints, _In_ ULONG Count)
Definition: devhcd.cpp:115
static VOID NTAPI HubInterfaceSetPipes(_In_ HubInterface *Interface, _In_ PipeState To)
Definition: devhcd.cpp:160
#define UCX_SIZE_START
Definition: devhcd.cpp:22
VOID NTAPI HubChildForwardToController(_In_ HubChild *Child)
Definition: devhcd.cpp:1352
HubPipe * Pipe
Definition: devhcd.cpp:1236
static NTSTATUS NTAPI HubChildEnableDone(_In_ HubChild *Child, _In_ NTSTATUS Status)
Definition: devhcd.cpp:219
#define UCX_SIZE_EP_RESET
Definition: devhcd.cpp:26
static EVT_WDF_REQUEST_COMPLETION_ROUTINE HubChildClientRequestComplete
Definition: devhcd.cpp:51
static VOID NTAPI HubChildSetPayloadHeader(_In_ HubChild *Child, _In_ ULONG Size)
Definition: devhcd.cpp:58
#define UCX_SIZE_ENABLE
Definition: devhcd.cpp:16
static VOID NTAPI HubChildFailStatus(_In_ HubChild *Child, _In_ NTSTATUS NtStatus, _In_ USBD_STATUS UsbdStatus)
Definition: devhcd.cpp:102
Buffer
Definition: devhcd.cpp:1405
ULONG Index
Definition: devhcd.cpp:1237
static VOID NTAPI HubChildStopBandwidthTimer(_In_ HubChild *Child)
Definition: devhcd.cpp:93
VOID NTAPI HubConfigMovePipes(_In_opt_ HubConfiguration *Config, _In_ PipeState From, _In_ PipeState To)
Definition: devhcd.cpp:133
#define EP0_PACKET_SUPER
Definition: devhcd.cpp:34
#define UCX_SIZE_ABORT
Definition: devhcd.cpp:23
#define EP0_PACKET_HIGH_FULL
Definition: devhcd.cpp:35
if(Length< FIELD_OFFSET(USB_HUB_NAME, HubName))
Definition: devhcd.cpp:1456
#define UCX_SIZE_UPDATE
Definition: devhcd.cpp:19
KIRQL Irql
Definition: devhcd.cpp:1263
static VOID NTAPI HubChildStartBandwidthTimer(_In_ HubChild *Child)
Definition: devhcd.cpp:84
ULONG Copy
Definition: devhcd.cpp:1449
#define BANDWIDTH_RETRY_DELAY_MS
Definition: devhcd.cpp:39
static HubUcxPayload *NTAPI HubChildNewPayload(_In_ HubChild *Child, _In_ ULONG Size)
Definition: devhcd.cpp:72
_In_ HubInterface * Interface
Definition: devhcd.cpp:1234
static VOID NTAPI HubChildTakeTunnelState(_In_ HubChild *Child)
Definition: devhcd.cpp:374
static BOOLEAN NTAPI HubChildConfigureDone(_In_ HubChild *Child, _Inout_ NTSTATUS *Status)
Definition: devhcd.cpp:251
#define UCX_SIZE_CONFIGURE
Definition: devhcd.cpp:24
NTSTATUS Status
Definition: devhcd.cpp:1401
#define UCX_SIZE_ADDRESS0
Definition: devhcd.cpp:15
ULONG Actual
Definition: devhcd.cpp:1400
#define UCX_SIZE_DISABLE
Definition: devhcd.cpp:20
BOOLEAN NTAPI HubChildU2ForEnumerated(_In_ HubChild *Child)
Definition: devlpm.cpp:135
HubLpm20Status
Definition: devhcd.h:29
#define DSM_KIND_PORT30
Definition: devsm.h:153
#define DSM_KIND_SUPER_SPEED
Definition: devsm.h:150
@ ControllerIoctlDone
@ ControllerExitLatencyTooLarge
@ ControllerRequestDone
@ ControllerIoctlFailed
#define DSM_KIND_LOW_SPEED
Definition: devsm.h:149
#define DSM_KIND_HIGH_SPEED
Definition: devsm.h:147
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
#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 NTSTATUS
Definition: precomp.h:19
#define _IRQL_requires_(irql)
Definition: driverspecs.h:229
HubDriverState HubDriver
Definition: entry.cpp:13
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define PagedPool
Definition: env_spec_w32.h:308
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
return pRequest Reuse(ReuseParams)
Status
Definition: gdiplustypes.h:24
_In_ UCXUSBDEVICE UsbDevice
Definition: hostctl.h:31
PipeState
Definition: hubchild.h:158
#define HUB_TUNNEL_STATE_UNKNOWN
Definition: hubchild.h:54
#define HUB_TUNNEL_STATE_NONE
Definition: hubchild.h:50
@ LastSetAddressFailed
@ AltSettingFiltered
@ DisableRemoteWakeForUsb20Lpm
#define HUB_TUNNEL_STATE_NOT_USB4
Definition: hubchild.h:51
@ EnableUsb20HardwareLpm
HubUxdSettings Current
#define IOCTL_UCXHUB_DEVICE_ENABLE
Definition: hubucx.h:53
#define IOCTL_UCXHUB_DEVICE_ADDRESS
Definition: hubucx.h:55
#define IOCTL_UCXHUB_ADDRESS0_OWNERSHIP_ACQUIRE
Definition: hubucx.h:49
#define IOCTL_UCXHUB_DEVICE_TREE_PURGE_IO
Definition: hubucx.h:67
#define IOCTL_UCXHUB_DEVICE_START_IO
Definition: hubucx.h:60
#define IOCTL_UCXHUB_ENDPOINT_RESET
Definition: hubucx.h:63
#define IOCTL_UCXHUB_DEVICE_UPDATE
Definition: hubucx.h:56
#define IOCTL_UCXHUB_DEVICE_DISABLE
Definition: hubucx.h:58
#define IOCTL_UCXHUB_DEVICE_RESET
Definition: hubucx.h:54
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT Endpoint
Definition: hubucx.h:238
#define IOCTL_UCXHUB_DEFAULT_ENDPOINT_UPDATE
Definition: hubucx.h:62
#define IOCTL_UCXHUB_ENDPOINTS_CONFIGURE
Definition: hubucx.h:61
FORCEINLINE PUCXHUB_UPDATE_TUNNEL_ANSWER NTAPI UcxHubUpdateTunnelAnswer(_In_ PUSBDEVICE_UPDATE Update)
Definition: hubucx.h:556
#define IOCTL_UCXHUB_DEVICE_PURGE_IO
Definition: hubucx.h:59
#define IOCTL_UCXHUB_DEVICE_ABORT_IO
Definition: hubucx.h:68
_In_ UCXUSBDEVICE _In_ PDEVICE_OBJECT Pdo
Definition: hubucx.h:280
#define HUB_TAG_HUB
Definition: hubutil.h:12
Name HubName[0]
Definition: hubwmi.cpp:470
#define InterlockedOr
Definition: interlocked.h:239
#define InterlockedAnd
Definition: interlocked.h:77
#define C_ASSERT(e)
Definition: intsafe.h:73
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define min(a, b)
Definition: monoChain.cc:55
static LRESULT Configure(const CodecInfo *pi, HWND hWnd)
Definition: msrle32.c:1192
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Inout_
Definition: no_sal2.h:162
#define _Outptr_result_maybenull_
Definition: no_sal2.h:266
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
long LONG
Definition: pedump.c:60
@ Failed
Definition: arc.h:88
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:73
Definition: xml2sdb.h:103
volatile LONG SuperSpeedDebounceVotes
Definition: hubdriver.h:108
BOOLEAN HasFlag(_In_ HubGlobal Flag) const
Definition: hubdriver.h:119
UCHAR Usb20LpmTimeout
Definition: hubdriver.h:103
UCHAR Baseline
Definition: devhcd.cpp:622
BOOLEAN BaselineValid
Definition: devhcd.cpp:620
BOOLEAN Capable
Definition: devhcd.cpp:618
BOOLEAN Besl
Definition: devhcd.cpp:619
UCHAR Deep
Definition: devhcd.cpp:623
BOOLEAN DeepValid
Definition: devhcd.cpp:621
UCXENDPOINT DefaultEndpoint
Definition: ucxendpoint.h:55
ENDPOINT_RESET_FLAGS Flags
Definition: ucxendpoint.h:49
UCXENDPOINT Endpoint
Definition: ucxendpoint.h:48
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PFN_UCXHUB_DEVICE_CREATE DeviceCreate
Definition: hubucx.h:434
PFN_UCXHUB_ENDPOINT_CREATE EndpointCreate
Definition: hubucx.h:440
PFN_UCXHUB_DEFAULT_ENDPOINT_CREATE CreateControlEndpoint
Definition: hubucx.h:438
PFN_UCXHUB_ENDPOINT_DELETE EndpointDelete
Definition: hubucx.h:441
PFN_UCXHUB_ADDRESS0_RELEASE Address0Release
Definition: hubucx.h:439
PFN_UCXHUB_DEVICE_SET_PDO DeviceSetPdo
Definition: hubucx.h:437
PFN_UCXHUB_DEVICE_DELETE DeviceDelete
Definition: hubucx.h:435
UCXENDPOINT DefaultEndpoint
Definition: ucxusbdevice.h:158
UCXENDPOINT DefaultEndpoint
Definition: ucxusbdevice.h:47
ULONG EndpointsToDisableCount
Definition: ucxusbdevice.h:55
UCXENDPOINT DefaultEndpoint
Definition: ucxusbdevice.h:54
USBDEVICE_UPDATE_FLAGS Flags
Definition: ucxusbdevice.h:121
USHORT wTotalLength
Definition: usb300.h:103
PUSB_BUSIFFN_QUERY_BUS_INFORMATION QueryBusInformation
Definition: usbbusif.h:153
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#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
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG Config
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFREQUEST Request
@ FlagEndpointResetPreserveTransferState
Definition: ucxendpoint.h:16
WDF_EXTERN_C_START enum _ENDPOINT_RESET_FLAGS ENDPOINT_RESET_FLAGS
_In_ UCXUSBDEVICE _In_ ULONG Interface
Definition: ucxusbdevice.h:428
#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
ENDPOINT_RESET EndpointReset
Definition: hubchild.h:221
USBDEVICE_ENABLE Enable
Definition: hubchild.h:209
USBDEVICE_ADDRESS Address
Definition: hubchild.h:211
USBDEVICE_UPDATE Update
Definition: hubchild.h:212
USBDEVICE_RESET Reset
Definition: hubchild.h:210
USBDEVICE_DISABLE Disable
Definition: hubchild.h:214
ENDPOINTS_CONFIGURE Configure
Definition: hubchild.h:219
DEFAULT_ENDPOINT_UPDATE DefaultEndpoint
Definition: hubchild.h:220
USBDEVICE_PURGEIO Purge
Definition: hubchild.h:215
struct _USB_COMMON_DESCRIPTOR * PUSB_COMMON_DESCRIPTOR
@ UsbSuperSpeed
Definition: usb200.h:45
@ UsbHighSpeed
Definition: usb200.h:44
@ UsbLowSpeed
Definition: usb200.h:42
@ UsbFullSpeed
Definition: usb200.h:43
struct _USB_DEVICE_CAPABILITY_USB20_EXTENSION_DESCRIPTOR * PUSB_DEVICE_CAPABILITY_USB20_EXTENSION_DESCRIPTOR
#define USB_DEVICE_CAPABILITY_DESCRIPTOR_TYPE
Definition: usb300.h:18
#define USB_DEVICE_CAPABILITY_USB20_EXTENSION
Definition: usb300.h:26
@ DisableUsb20Lpm
#define USBD_STATUS_INVALID_PIPE_HANDLE
Definition: usb.h:205
#define USBD_STATUS_NO_BANDWIDTH
Definition: usb.h:206
#define USBD_STATUS_INSUFFICIENT_RESOURCES
Definition: usb.h:215
LONG USBD_STATUS
Definition: usb.h:172
struct _USB_BUS_INFORMATION_LEVEL_1 * PUSB_BUS_INFORMATION_LEVEL_1
USHORT Count
Definition: userreq.cpp:200
WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, ActualLength)
_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
_In_ PWDFDEVICE_INIT _In_ PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION Notification
Definition: wdfcontrol.h:115
FORCEINLINE LONGLONG WDF_REL_TIMEOUT_IN_MS(_In_ ULONGLONG Time)
Definition: wdfcore.h:80
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFDEVICE Child
Definition: wdffdo.h:536
_Must_inspect_result_ FORCEINLINE BOOLEAN WdfRequestSend(_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_opt_ PWDF_REQUEST_SEND_OPTIONS Options)
Definition: wdfrequest.h:677
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
@ WDF_REQUEST_REUSE_NO_FLAGS
Definition: wdfrequest.h:92
FORCEINLINE VOID WDF_REQUEST_REUSE_PARAMS_INIT(_Out_ PWDF_REQUEST_REUSE_PARAMS Params, _In_ ULONG Flags, _In_ NTSTATUS Status)
Definition: wdfrequest.h:364
#define WDF_NO_SEND_OPTIONS
Definition: wdftypes.h:109
_In_ NTSTATUS _In_ USBD_STATUS UsbdStatus
Definition: wdfusb.h:403
_In_ WDFUSBPIPE Pipe
Definition: wdfusb.h:1741