ReactOS 0.4.17-dev-1281-g065abb3
slotdev.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS xHCI Host Controller Driver
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: USB device object: slot commands, input contexts and the UCX device callbacks
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "xhcidrv.h"
9#include <acpiioct.h>
10#include <drivers/usb3/hubucx.h>
11
12#define NDEBUG
13#include <debug.h>
14
16
17/* USB _DSM {CE2EE385-00E6-48CB-9F05-2EDB927C4899}; function 10 takes a root port number */
18static const GUID XhciGuidUsbDsm =
19 { 0xce2ee385, 0x00e6, 0x48cb, { 0x9f, 0x05, 0x2e, 0xdb, 0x92, 0x7c, 0x48, 0x99 } };
20
21#define XHCI_USB_DSM_REVISION 0
22#define XHCI_USB_DSM_TUNNEL_STATE 10
23#define XHCI_USB_DSM_PORT_NATIVE 1
24#define XHCI_USB_DSM_PORT_TUNNELED 2
25
28{
32
34
35/* Reason codes for the controller's fatal error report */
36enum : ULONG
37{
44};
45
46/* Hardware verifier conditions */
48{
54};
55
57#define XHCI_DEFAULT_CONTEXT_MASK 0x00000003
58
59#define XHCI_ROUTE_TIER_MAX 15
60#define XHCI_ROUTE_TIER_BITS 4
61
62static EVT_WDF_OBJECT_CONTEXT_CLEANUP XhciEvtUsbDeviceCleanup;
63
64static
68 _In_ WDFREQUEST Request)
69{
71
73 WdfRequestGetParameters(Request, &Parameters);
74 return Parameters.Parameters.Others.Arg1;
75}
76
79static
82XhciEvaluateDsmValue(
83 _In_ WDFDEVICE Device,
84 _In_ const GUID* Uuid,
89{
90 union
91 {
93 UCHAR Bytes[32];
94 } Output;
103
105
110
112 if (Input == NULL)
113 {
114 DPRINT1("No memory for _DSM function %lu\n", Function);
115 return 0;
116 }
117
120 Input->Size = Size;
122
123 Next = &Input->Argument[0];
131
135
136 Status = WdfIoTargetSendIoctlSynchronously(WdfDeviceGetIoTarget(Device),
137 NULL,
141 NULL,
142 NULL);
144 {
145 DPRINT1("_DSM %08lx function %lu failed 0x%lx\n", Uuid->Data1, Function, Status);
146 }
147 else if (Output.Header.Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE)
148 {
149 DPRINT1("_DSM function %lu returned signature 0x%08lx\n", Function, Output.Header.Signature);
150 }
151 else if (Output.Header.Count != 0 && Output.Header.Argument[0].DataLength != 0)
152 {
153 /* QUIRK: the result type is not checked, any 1 to 8 byte value decodes */
154 Length = min(Output.Header.Argument[0].DataLength, sizeof(Value));
158 Length);
159 }
160
162 return Value;
163}
164
165static
167NTAPI
169 _In_ const XhciCommand* Command)
170{
171 return Command->Status != STATUS_NO_SUCH_DEVICE &&
173}
174
175/* Object lifetime **********************************************************/
176
179 _In_ UCXUSBDEVICE UsbDevice)
180{
181 return XhciGetUsbDeviceContext(UsbDevice);
182}
183
186XhciUsbDevice::Initialize(
188 _In_ UCXUSBDEVICE UsbDevice,
190{
191 PAGED_CODE();
192
195 RtlCopyMemory(&m_Info, Info, sizeof(m_Info));
196 m_ContextSize = Controller->m_Registers.ContextSize();
198
199 /* Allocated once so that enabling after a controller reset never needs memory */
201 if (m_Output == NULL)
202 {
203 DPRINT1("No output device context for USB device %p\n", UsbDevice);
205 }
206
208 if (m_Input == NULL)
209 {
210 DPRINT1("No input context for USB device %p\n", UsbDevice);
212 }
213
214 DPRINT("USB device %p: speed %d, root port %lu, depth %lu, TT hub %p\n",
217 return STATUS_SUCCESS;
218}
219
220VOID
223{
224 /* Creation never got far enough to own anything */
225 if (m_Handle != (UCXUSBDEVICE)Object)
226 return;
227
228 ASSERT(m_SlotId == 0);
229
230 if (m_Output != NULL)
231 {
233 m_Output = NULL;
234 }
235
236 if (m_Input != NULL)
237 {
239 m_Input = NULL;
240 }
241
243 {
246 }
247}
248
249static
250VOID
251NTAPI
254{
255 XhciGetUsbDeviceContext(Object)->Cleanup(Object);
256}
257
258/* Accessors ****************************************************************/
259
260PVOID
262 _In_ ULONG Index) const
263{
266}
267
268PVOID
270 _In_ ULONG Dci) const
271{
274}
275
278{
280}
281
282VOID
284{
286}
287
290{
292}
293
296{
298}
299
302{
303 return (const XHCI_SLOT_CONTEXT*)OutputContext(0);
304}
305
306ULONG
308 _In_ ULONG Dci) const
309{
310 return ((const XHCI_ENDPOINT_CONTEXT*)OutputContext(Dci))->EndpointState;
311}
312
315 _In_ ULONG Dci) const
316{
317 return ((const XHCI_ENDPOINT_CONTEXT*)OutputContext(Dci))->TRDequeuePointer;
318}
319
320ULONG
322{
324 ULONG Highest = 0;
325
326 ASSERT(Mask != 0);
327
328 while ((Mask >>= 1) != 0)
329 Highest++;
330
331 return Highest;
332}
333
334ULONG
336{
337 return m_SlotId;
338}
339
342{
343 return m_Info.DeviceSpeed;
344}
345
346UCXUSBDEVICE
348{
349 return m_Handle;
350}
351
354{
355 return m_Controller;
356}
357
360{
361 return m_SlotEnabled;
362}
363
366{
367 return &m_DeviceDescriptor;
368}
369
372{
373 return &m_Info.PortPath;
374}
375
376ULONG
378{
379 return m_ContextSize;
380}
381
384{
385 if (m_Info.TtHub == NULL)
386 return NULL;
387
388 return FromUcx(m_Info.TtHub);
389}
390
392VOID
393XhciUsbDevice::RingDoorbell(
394 _In_ ULONG Dci,
395 _In_ ULONG StreamId)
396{
398
399 if (SlotId == 0)
400 {
401 DPRINT("Doorbell for DCI %lu of device %p without a slot\n", Dci, this);
402 return;
403 }
404
405 /* DB Target in bits 7:0, DB Stream ID in bits 31:16 (xHCI 5.6) */
406 m_Controller->m_Registers.RingDoorbell(SlotId, (Dci & 0xFF) | (StreamId << 16));
407}
408
409/* Endpoint table ***********************************************************/
410
413XhciUsbDevice::EndpointAt(
414 _In_ ULONG Dci) const
415{
416 if (Dci > XHCI_MAX_DCI)
417 return NULL;
418
419 return m_Endpoints[Dci];
420}
421
423VOID
424XhciUsbDevice::AddEndpoint(
426{
429
430 /* The default endpoint stays in the table for the life of the device */
431 if (Endpoint->Dci() == 1)
433
435}
436
438VOID
439XhciUsbDevice::RemoveEndpoint(
441{
442 UCXUSBDEVICE UsbDevice = m_Handle;
443 ULONG Dci = Endpoint->Dci();
444
445 if (Dci <= XHCI_MAX_DCI && m_Endpoints[Dci] == Endpoint)
446 m_Endpoints[Dci] = NULL;
447
449
450 /* The device reference goes last; this object may be freed with it */
453}
454
455VOID
457{
458 if (m_Endpoints[1] != NULL)
459 m_Endpoints[1]->Disable(TRUE);
460}
461
462VOID
464 _In_ BOOLEAN ClearTable)
465{
466 ULONG Dci;
467
468 for (Dci = 2; Dci <= XHCI_MAX_DCI; Dci++)
469 {
470 if (m_Endpoints[Dci] == NULL)
471 continue;
472
473 m_Endpoints[Dci]->Disable(ClearTable);
474 if (ClearTable)
475 m_Endpoints[Dci] = NULL;
476 }
477}
478
479VOID
482 _In_reads_(Count) UCXENDPOINT* Endpoints)
483{
484 ULONG Index;
485
486 for (Index = 0; Index < Count; Index++)
487 XhciEndpoint::FromUcx(Endpoints[Index])->Disable();
488}
489
490VOID
492 _In_ const ENDPOINTS_CONFIGURE* Payload)
493{
496 ULONG Index;
497 ULONG Dci;
498
499 for (Index = 0; Index < Payload->EndpointsToEnableCount; Index++)
500 {
501 Endpoint = XhciEndpoint::FromUcx(Payload->EndpointsToEnable[Index]);
502 Dci = Endpoint->Dci();
503
504 Previous = m_Endpoints[Dci];
505 if (Previous != NULL && Previous != Endpoint)
506 {
507 DPRINT("DCI %lu of device %p moves from endpoint %p to %p\n", Dci, this, Previous, Endpoint);
508 Previous->Disable(TRUE);
509 m_Endpoints[Dci] = NULL;
510 }
511
512 m_Endpoints[Dci] = Endpoint;
513 }
514}
515
516/* Pending request and command plumbing **************************************/
517
518VOID
520 _In_ WDFREQUEST Request,
521 _In_ PVOID Payload,
522 _In_ PendingKind Kind,
523 _In_ BOOLEAN MustSucceed)
524{
525 /* UCX and the hub send one device management request at a time */
527
528 m_PendingPayload = Payload;
529 m_PendingKind = Kind;
530 m_MustSucceed = MustSucceed;
532}
533
534WDFREQUEST
536{
538}
539
540VOID
543{
544 WDFREQUEST Request = TakePending();
545
546 if (Request != NULL)
547 WdfRequestComplete(Request, Status);
548}
549
552{
554}
555
556VOID
559{
563 m_Command.Context = this;
564}
565
566VOID
567NTAPI
570{
571 XhciUsbDevice* Device = static_cast<XhciUsbDevice*>(Command->Context);
572
573 /* Controller gone or a lost slot already finished the request */
574 if (Device->m_PendingRequest == NULL)
575 {
576 DPRINT("Device %p command type %lu completed with no request left\n",
577 Device, XhciTrbType(&Command->Trb));
578 return;
579 }
580
581 switch (XhciTrbType(&Command->Trb))
582 {
583 case static_cast<ULONG>(XhciTrbType::EnableSlot):
584 Device->OnEnableSlotDone(Command);
585 break;
586
587 case static_cast<ULONG>(XhciTrbType::AddressDevice):
588 Device->OnAddressDeviceDone(Command);
589 break;
590
591 case static_cast<ULONG>(XhciTrbType::EvaluateContext):
592 Device->OnEvaluateContextDone(Command);
593 break;
594
595 case static_cast<ULONG>(XhciTrbType::ConfigureEndpoint):
596 Device->OnConfigureEndpointDone(Command);
597 break;
598
599 case static_cast<ULONG>(XhciTrbType::DisableSlot):
600 Device->OnDisableSlotDone(Command);
601 break;
602
603 case static_cast<ULONG>(XhciTrbType::ResetDevice):
604 Device->OnResetDeviceDone(Command);
605 break;
606
607 default:
608 ASSERT(FALSE);
609 break;
610 }
611}
612
613VOID
615{
616 if (m_SlotId != 0 && m_Controller->m_Slots.LookupSlot(m_SlotId) == this)
617 m_Controller->m_Slots.SetSlot(m_SlotId, this, 0);
618
620 m_SlotId = 0;
621}
622
624VOID
625XhciUsbDevice::SetDisabled()
626{
627 WDFREQUEST Request;
628
631 ForgetSlot();
632
634 if (Request != NULL)
635 WdfRequestComplete(Request, LostSlotStatus());
636}
637
638/* Enable Slot and Address Device ********************************************/
639
640VOID
642{
643 ASSERT(m_SlotId == 0);
644
645 /* QUIRK: Slot Type is always 0 */
646 PrepareCommand(static_cast<ULONG>(XhciTrbType::EnableSlot));
648}
649
652{
656 ULONG Speed;
657 ULONG Route;
658 ULONG Tier;
659
660 switch (m_Info.DeviceSpeed)
661 {
662 case UsbLowSpeed:
664 break;
665 case UsbFullSpeed:
667 break;
668 case UsbHighSpeed:
670 break;
671 case UsbSuperSpeed:
673 break;
674 default:
675 DPRINT1("Device %p has speed %d, which a slot cannot describe\n", this, m_Info.DeviceSpeed);
677 }
678
682
683 /* The root port is not part of the route string (USB 3.2 8.9) */
684 Route = 0;
685 for (Tier = 1; Tier < Path->PortPathDepth && Tier < MAX_USB_DEVICE_DEPTH; Tier++)
686 Route |= min(Path->PortPath[Tier], (ULONG)XHCI_ROUTE_TIER_MAX) << ((Tier - 1) * XHCI_ROUTE_TIER_BITS);
687
688 Slot = InputSlot();
689 Slot->RouteString = Route;
690 Slot->Speed = Speed;
691 Slot->ContextEntries = 1;
692 Slot->RootHubPortNumber = Path->PortPath[0];
693
694 Hub = TtHub();
695 if (Hub != NULL)
696 {
697 Slot->MultiTT = (Hub->m_NumberOfTTs > 1);
698 Slot->TTHubSlotId = Hub->m_SlotId;
699 }
700
701 if (Path->TTHubDepth != 0 && Path->TTHubDepth < MAX_USB_DEVICE_DEPTH)
702 Slot->TTPortNumber = Path->PortPath[Path->TTHubDepth];
703
704 /* QUIRK: Average TRB Length stays 0 for EP0 */
706 return STATUS_SUCCESS;
707}
708
711 _In_ BOOLEAN BlockSetAddress)
712{
713 ULONG64 InputAddress = InputContextAddress();
715
717 if (!NT_SUCCESS(Status))
718 return Status;
719
720 PrepareCommand(static_cast<ULONG>(XhciTrbType::AddressDevice));
721 m_Command.Trb.Dword[0] = (ULONG)InputAddress;
722 m_Command.Trb.Dword[1] = (ULONG)(InputAddress >> 32);
723 if (BlockSetAddress)
725
727 return STATUS_SUCCESS;
728}
729
730VOID
732 _In_ WDFREQUEST Request,
734{
736
737 if (m_Endpoints[1] == NULL)
738 {
739 DPRINT1("ENABLE for device %p before its default endpoint exists\n", this);
740 WdfRequestComplete(Request, STATUS_UNSUCCESSFUL);
741 return;
742 }
743
744 Status = m_Endpoints[1]->Enable();
745 if (!NT_SUCCESS(Status))
746 {
747 DPRINT1("Default endpoint of device %p failed to enable: 0x%lx\n", this, Status);
748 WdfRequestComplete(Request, Status);
749 return;
750 }
751
753 {
754 DPRINT1("ENABLE for device %p with the controller gone\n", this);
756 WdfRequestComplete(Request, STATUS_NO_SUCH_DEVICE);
757 return;
758 }
759
762}
763
764VOID
766 _In_ const XhciCommand* Command)
767{
768 ULONG Code = static_cast<ULONG>(Command->Code);
769 ULONG SlotId = XhciTrbSlotId(&Command->Completion);
771
772 if (Command->Status == STATUS_NO_SUCH_DEVICE)
773 {
776 return;
777 }
778
779 if (Command->Code != XhciCompletionCode::Success)
780 {
781 DPRINT1("Enable Slot for device %p failed with completion code %lu\n", this, Code);
782
783 /* A RESET payload has no failure flags, only ENABLE does */
784 if (Command->Code == XhciCompletionCode::NoSlotsAvailable && m_PendingKind == PendingKind::Enable)
785 ((PUSBDEVICE_ENABLE)m_PendingPayload)->FailureFlags.InsufficientHardwareResourcesForDevice = 1;
786
788
789 if (m_MustSucceed)
790 {
791 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalEnableSlot);
792
793 /* Complete the RESET here; the device holds no slot, so no reset walk will */
795 return;
796 }
797
799 return;
800 }
801
804
806
808 if (!NT_SUCCESS(Status))
809 {
810 DPRINT1("Enable Slot gave device %p slot %lu, which is already in use (0x%lx)\n",
811 this, SlotId, Status);
813 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalSlotInUse);
814
815 /* Undo the slot state and complete the request, since nothing else would */
817 m_SlotId = 0;
820 return;
821 }
822
823 DPRINT("Device %p got slot %lu\n", this, SlotId);
824
826 if (!NT_SUCCESS(Status))
827 {
828 DPRINT1("Address Device for slot %lu not built: 0x%lx\n", SlotId, Status);
830
831 if (m_MustSucceed)
832 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalAddressDefault);
833 else
835 }
836}
837
838VOID
840 _In_ WDFREQUEST Request,
842{
844
845 if (!m_SlotEnabled)
846 {
847 DPRINT1("ADDRESS for device %p without a slot\n", this);
848 WdfRequestComplete(Request, STATUS_UNSUCCESSFUL);
849 return;
850 }
851
853 {
854 DPRINT1("ADDRESS for device %p with the controller gone\n", this);
855 WdfRequestComplete(Request, STATUS_NO_SUCH_DEVICE);
856 return;
857 }
858
860
862 if (!NT_SUCCESS(Status))
863 {
864 DPRINT1("Address Device for slot %lu not built: 0x%lx\n", m_SlotId, Status);
866 }
867}
868
869VOID
871 _In_ const XhciCommand* Command)
872{
873 BOOLEAN BlockSetAddress = (Command->Trb.Dword[3] & XHCI_CMD_BLOCK_SET_ADDRESS) != 0;
874
875 if (Command->Status == STATUS_NO_SUCH_DEVICE)
876 {
877 if (BlockSetAddress)
878 SetDisabled();
879 else
881 return;
882 }
883
884 if (Command->Code == XhciCompletionCode::Success)
885 {
886 if (!BlockSetAddress && m_PendingKind == PendingKind::Address)
888
889 DPRINT("Slot %lu addressed (BSR %u), USB address %u\n",
890 m_SlotId, BlockSetAddress, OutputSlot()->UsbDeviceAddress);
892 return;
893 }
894
895 DPRINT1("Address Device (BSR %u) for slot %lu failed with completion code %lu\n",
896 BlockSetAddress, m_SlotId, static_cast<ULONG>(Command->Code));
897
898 /* The slot stays enabled until the hub sends DISABLE */
899 if (!BlockSetAddress)
900 {
902 return;
903 }
904
905 if (m_MustSucceed)
906 {
908 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalAddressDefault);
909 return;
910 }
911
913}
914
915/* Update and hub information ***********************************************/
916
917VOID
920{
921 ULONG RootPort = m_Info.PortPath.PortPath[0];
923
924 /* QUIRK: a device never stops being a hub */
925 if (Payload->Flags.UpdateIsHub && Payload->IsHub)
926 m_IsHub = TRUE;
927
928 if (Payload->Flags.UpdateDeviceDescriptor && Payload->DeviceDescriptor != NULL)
929 RtlCopyMemory(&m_DeviceDescriptor, Payload->DeviceDescriptor, sizeof(m_DeviceDescriptor));
930
931 if (Payload->Flags.Update20HardwareLpmParameters)
932 {
933 ASSERT(!m_IsHub);
934 m_LpmEnabled = (BOOLEAN)Payload->Usb20HardwareLpmParameters.HardwareLpmEnable;
935 m_Controller->m_RootHub.Update20HardwareLpm(RootPort, m_SlotId, &Payload->Usb20HardwareLpmParameters);
936 }
937
938 if (Payload->Flags.UpdateRootPortResumeTime)
939 {
940 m_Controller->m_RootHub.ArmPortResumeTimer(RootPort, Payload->RootPortResumeTime);
942 }
943
944 /* The ACPI path fills the answer before it gets here */
945 if (Payload->Flags.UpdateTunnelState && !m_Controller->HasErrata(XhciErrata::Usb4TunnelFromAcpiDsm))
946 {
947 Answer = UcxHubUpdateTunnelAnswer(Payload);
951 }
952}
953
956 _In_ const USBDEVICE_UPDATE* Payload) const
957{
958 return Payload->Flags.UpdateTunnelState && m_Controller->HasErrata(XhciErrata::Usb4TunnelFromAcpiDsm);
959}
960
965{
969 WDFWORKITEM Item;
971
973
974 /* QUIRK: the controller device has no synchronization scope, so this serializes nothing */
975 Config.AutomaticSerialization = TRUE;
976
978 Attributes.ParentObject = m_Controller->m_Device;
979
980 Status = WdfWorkItemCreate(&Config, &Attributes, &Item);
981 if (!NT_SUCCESS(Status))
982 {
983 DPRINT1("No tunnel state work item for root port %lu, 0x%lx\n", m_Info.PortPath.PortPath[0], Status);
984
985 /* QUIRK: the native link flag keeps the hub's value */
987 return FALSE;
988 }
989
990 /* Keeps this context alive even if a removal completes the request first */
992
993 Work = XhciGetTunnelDsmWork(Item);
994 Work->Device = this;
995 Work->Payload = Payload;
997 return TRUE;
998}
999
1000VOID
1001NTAPI
1003 _In_ WDFWORKITEM WorkItem)
1004{
1005 PXHCI_TUNNEL_DSM_WORK Work = XhciGetTunnelDsmWork(WorkItem);
1006 XhciUsbDevice* Device = Work->Device;
1007
1008 Device->RunTunnelStateDsm(Work->Payload);
1009 WdfObjectDereference(Device->m_Handle);
1011}
1012
1013VOID
1014XhciUsbDevice::RunTunnelStateDsm(
1015 _Inout_ PUSBDEVICE_UPDATE Payload)
1016{
1017 ULONG RootPort = m_Info.PortPath.PortPath[0];
1019 WDFREQUEST Request;
1021
1022 PAGED_CODE();
1023
1024 /* QUIRK: function 10 is used without asking function 0 whether it exists */
1025 Result = XhciEvaluateDsmValue(m_Controller->m_Device,
1029 &RootPort,
1030 sizeof(RootPort));
1031 DPRINT("Root port %lu tunnel state _DSM returned %I64u\n", RootPort, Result);
1032
1033 /* A removal may have completed the request, and the payload with it, while _DSM ran */
1034 Request = TakePending();
1035 if (Request == NULL)
1036 return;
1037
1038 Answer = UcxHubUpdateTunnelAnswer(Payload);
1040 {
1042 }
1044 {
1046 }
1047 else
1048 {
1049 DPRINT1("Root port %lu tunnel state _DSM gave %I64u, state unknown\n", RootPort, Result);
1051 }
1053
1054 ApplyUpdate(Payload);
1055 WdfRequestComplete(Request, STATUS_SUCCESS);
1056}
1057
1058VOID
1060 _In_ WDFREQUEST Request,
1061 _Inout_ PUSBDEVICE_UPDATE Payload)
1062{
1064 ULONG64 InputAddress;
1065
1066 if (!Payload->Flags.UpdateMaxExitLatency)
1067 {
1068 if (WantsTunnelStateDsm(Payload))
1069 {
1070 /* Record the request first so the work item has one to complete */
1072 if (QueueTunnelStateDsm(Payload))
1073 return;
1074
1075 TakePending();
1076 }
1077
1078 ApplyUpdate(Payload);
1079 WdfRequestComplete(Request, STATUS_SUCCESS);
1080 return;
1081 }
1082
1083 /* Evaluate Context with only the slot flagged (xHCI 4.6.7) */
1085 InputControl()->AddFlags = 1;
1086 Slot = InputSlot();
1087 Slot->MaxExitLatency = Payload->MaxExitLatency & 0xFFFF;
1088 Slot->InterrupterTarget = 0;
1089
1090 /* QUIRK: a device without a slot sends this with Slot ID 0 */
1091 InputAddress = InputContextAddress();
1092 PrepareCommand(static_cast<ULONG>(XhciTrbType::EvaluateContext));
1093 m_Command.Trb.Dword[0] = (ULONG)InputAddress;
1094 m_Command.Trb.Dword[1] = (ULONG)(InputAddress >> 32);
1095
1096 if (!m_Controller->IsAccessible())
1097 {
1098 DPRINT1("UPDATE for device %p with the controller gone\n", this);
1099 WdfRequestComplete(Request, STATUS_NO_SUCH_DEVICE);
1100 return;
1101 }
1102
1105}
1106
1107VOID
1109 _In_ const XhciCommand* Command)
1110{
1113
1114 if (Command->Status == STATUS_NO_SUCH_DEVICE)
1115 {
1117 }
1118 else if (Command->Code == XhciCompletionCode::Success)
1119 {
1120 /* The work item completes the request */
1121 if (WantsTunnelStateDsm(Payload) && QueueTunnelStateDsm(Payload))
1122 return;
1123
1124 ApplyUpdate(Payload);
1126 }
1127 else
1128 {
1129 DPRINT1("Max Exit Latency %lu for slot %lu rejected with completion code %lu\n",
1130 Payload->MaxExitLatency, m_SlotId, static_cast<ULONG>(Command->Code));
1131
1132 if (Command->Code == XhciCompletionCode::MaxExitLatencyTooLarge)
1134
1136 }
1137
1139}
1140
1141VOID
1143 _In_ WDFREQUEST Request,
1144 _In_ const USBDEVICE_HUB_INFO* Payload)
1145{
1146 /* QUIRK: accepted whether or not the device is a hub */
1147 m_NumberOfPorts = Payload->NumberOfPorts;
1148 m_NumberOfTTs = Payload->NumberOfTTs;
1149 m_TTThinkTime = Payload->TTThinkTime;
1150
1151 DPRINT("Hub %p: %lu ports, %lu TTs, think time %lu\n",
1153 WdfRequestComplete(Request, STATUS_SUCCESS);
1154}
1155
1156/* Configure Endpoint *******************************************************/
1157
1158VOID
1161 _In_ ULONG ContextSize) const
1162{
1165
1166 /* Only the hub fields; the caller zeroed the context and owns Context Entries */
1167 ASSERT(ContextSize >= sizeof(*Slot));
1169
1170 if (m_IsHub)
1171 {
1172 Slot->Hub = 1;
1173 Slot->NumberOfPorts = m_NumberOfPorts;
1174
1176 {
1177 Slot->MultiTT = (m_NumberOfTTs > 1);
1178 Slot->TTThinkTime = m_TTThinkTime;
1179 }
1180 }
1181
1182 /* Some controllers need MTT repeated for LS and FS devices behind a multi TT hub */
1183 if (m_Controller->HasErrata(XhciErrata::CfgMultiTtFromHubData) &&
1184 !m_IsHub &&
1186 {
1187 Hub = TtHub();
1188 if (Hub != NULL && Hub->m_NumberOfTTs > 1)
1189 Slot->MultiTT = 1;
1190 }
1191}
1192
1193VOID
1195 _In_ WDFREQUEST Request,
1197{
1198 XhciRequestData* Data = XhciGetRequestData(Request);
1201 ULONG EnableCount = Payload->EndpointsToEnableCount;
1202 ULONG DisableCount = Payload->EndpointsToDisableCount;
1203 ULONG64 InputAddress;
1204 ULONG AddFlags;
1205 ULONG DropFlags;
1206 ULONG Index;
1208
1209 if (Data == NULL)
1210 {
1211 DPRINT1("ENDPOINTS_CONFIGURE for device %p carries no request context\n", this);
1212 WdfRequestComplete(Request, STATUS_INVALID_DEVICE_STATE);
1213 return;
1214 }
1215
1216 Data->EndpointsConfigure.EnableFailed = FALSE;
1217 Data->EndpointsConfigure.FirstCommandFailed = FALSE;
1218
1219 /* Nothing is disabled here: the endpoints to drop never reached the hardware */
1220 if (!m_SlotEnabled)
1221 {
1222 DPRINT1("ENDPOINTS_CONFIGURE for device %p without a slot\n", this);
1223 WdfRequestComplete(Request, EnableCount != 0 ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS);
1224 return;
1225 }
1226
1227 if (!m_Controller->IsAccessible())
1228 {
1229 DPRINT1("ENDPOINTS_CONFIGURE for device %p with the controller gone\n", this);
1230 DisableEndpointList(DisableCount, Payload->EndpointsToDisable);
1231 WdfRequestComplete(Request, EnableCount != 0 ? STATUS_NO_SUCH_DEVICE : STATUS_SUCCESS);
1232 return;
1233 }
1234
1235 SetPending(Request, Payload, PendingKind::Configure, EnableCount == 0);
1236
1239
1240 for (Index = 0; Index < EnableCount; Index++)
1241 {
1242 Status = XhciEndpoint::FromUcx(Payload->EndpointsToEnable[Index])->Enable();
1243 if (NT_SUCCESS(Status))
1244 continue;
1245
1246 DPRINT1("Endpoint %lu of %lu for device %p failed to enable: 0x%lx\n",
1247 Index, EnableCount, this, Status);
1248
1249 while (Index-- > 0)
1250 XhciEndpoint::FromUcx(Payload->EndpointsToEnable[Index])->Disable();
1251
1252 if (DisableCount == 0)
1253 {
1255 return;
1256 }
1257
1258 /* The drops still have to reach the controller */
1259 Data->EndpointsConfigure.EnableFailed = TRUE;
1260 break;
1261 }
1262
1263 AddFlags = 1;
1264 if (!Data->EndpointsConfigure.EnableFailed)
1265 {
1266 for (Index = 0; Index < EnableCount; Index++)
1267 {
1268 Endpoint = XhciEndpoint::FromUcx(Payload->EndpointsToEnable[Index]);
1269 Endpoint->BuildContext(InputContext(Endpoint->Dci() + 1), m_ContextSize);
1270 AddFlags |= 1UL << Endpoint->Dci();
1271 }
1272 }
1273
1274 DropFlags = 0;
1275 for (Index = 0; Index < DisableCount; Index++)
1276 DropFlags |= 1UL << XhciEndpoint::FromUcx(Payload->EndpointsToDisable[Index])->Dci();
1277
1279 Control->AddFlags = AddFlags;
1280 Control->DropFlags = DropFlags;
1281
1282 /* QUIRK: updated before the command result is known and never rolled back */
1283 m_ContextMask = (m_ContextMask & ~DropFlags) | AddFlags;
1285
1286 InputAddress = InputContextAddress();
1287 PrepareCommand(static_cast<ULONG>(XhciTrbType::ConfigureEndpoint));
1288 m_Command.Trb.Dword[0] = (ULONG)InputAddress;
1289 m_Command.Trb.Dword[1] = (ULONG)(InputAddress >> 32);
1291}
1292
1293VOID
1295{
1297 XhciRequestData* Data = XhciGetRequestData(m_PendingRequest);
1298 ULONG64 InputAddress;
1299 ULONG DropFlags;
1300 ULONG Index;
1301
1302 Data->EndpointsConfigure.FirstCommandFailed = TRUE;
1303 DisableEndpointList(Payload->EndpointsToEnableCount, Payload->EndpointsToEnable);
1304
1305 /* QUIRK: Context Entries stays 0 in this one */
1308
1309 DropFlags = 0;
1310 for (Index = 0; Index < Payload->EndpointsToDisableCount; Index++)
1311 DropFlags |= 1UL << XhciEndpoint::FromUcx(Payload->EndpointsToDisable[Index])->Dci();
1312
1313 InputControl()->AddFlags = 1;
1314 InputControl()->DropFlags = DropFlags;
1315
1316 InputAddress = InputContextAddress();
1317 PrepareCommand(static_cast<ULONG>(XhciTrbType::ConfigureEndpoint));
1318 m_Command.Trb.Dword[0] = (ULONG)InputAddress;
1319 m_Command.Trb.Dword[1] = (ULONG)(InputAddress >> 32);
1321}
1322
1323VOID
1325 _In_ const XhciCommand* Command)
1326{
1328 XhciRequestData* Data = XhciGetRequestData(m_PendingRequest);
1329 ULONG EnableCount = Payload->EndpointsToEnableCount;
1330 ULONG DisableCount = Payload->EndpointsToDisableCount;
1331 ULONG Parameter = Command->Completion.Dword[2] & XHCI_COMPLETION_PARAMETER_MASK;
1332 BOOLEAN EarlierFailure;
1333 BOOLEAN SlotLost;
1334
1335 EarlierFailure = Data->EndpointsConfigure.EnableFailed || Data->EndpointsConfigure.FirstCommandFailed;
1336
1337 if (Command->Status != STATUS_NO_SUCH_DEVICE && Command->Code == XhciCompletionCode::Success)
1338 {
1339 DisableEndpointList(DisableCount, Payload->EndpointsToDisable);
1340 if (!EarlierFailure)
1341 RecordEnabledEndpoints(Payload);
1342
1343 Payload->ExitLatencyDelta = Parameter;
1345 return;
1346 }
1347
1348 SlotLost = (Command->Status == STATUS_NO_SUCH_DEVICE ||
1349 Command->Code == XhciCompletionCode::SlotNotEnabled);
1350
1351 if (Command->Status != STATUS_NO_SUCH_DEVICE)
1352 {
1353 DPRINT1("Configure Endpoint for slot %lu failed with completion code %lu (enable %lu, disable %lu)\n",
1354 m_SlotId, static_cast<ULONG>(Command->Code), EnableCount, DisableCount);
1355
1356 if (!SlotLost && EnableCount != 0)
1357 {
1358 switch (Command->Code)
1359 {
1360 case XhciCompletionCode::BandwidthError:
1361 case XhciCompletionCode::SecondaryBandwidthError:
1363 break;
1364 case XhciCompletionCode::ResourceError:
1366 break;
1367 case XhciCompletionCode::MaxExitLatencyTooLarge:
1369 break;
1370 default:
1371 break;
1372 }
1373 }
1374
1375 if (Command->Code == XhciCompletionCode::MaxExitLatencyTooLarge)
1376 Payload->ExitLatencyDelta = Parameter;
1377 }
1378
1379 /* Endpoints to enable that an earlier failure already disabled are not disabled again */
1380 if (SlotLost)
1381 {
1382 DisableEndpointList(DisableCount, Payload->EndpointsToDisable);
1383 if (EnableCount != 0 && !EarlierFailure)
1384 DisableEndpointList(EnableCount, Payload->EndpointsToEnable);
1385
1387 return;
1388 }
1389
1390 /* QUIRK: with nothing to enable or disable this fails although UCX expects success */
1391 if (DisableCount == 0)
1392 {
1393 DisableEndpointList(EnableCount, Payload->EndpointsToEnable);
1395 return;
1396 }
1397
1398 if (EnableCount == 0 || EarlierFailure)
1399 {
1401 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalDeconfigure);
1402 return;
1403 }
1404
1405 /* The enables failed in hardware; drop the endpoints to disable on their own */
1407}
1408
1409/* Disable Slot and Reset Device ********************************************/
1410
1411VOID
1414{
1416 PrepareCommand(static_cast<ULONG>(XhciTrbType::DisableSlot));
1418}
1419
1420VOID
1422 _In_ WDFREQUEST Request)
1423{
1424 ULONG RootPort = m_Info.PortPath.PortPath[0];
1425
1426 if (!m_SlotEnabled)
1427 {
1430 WdfRequestComplete(Request, STATUS_SUCCESS);
1431 return;
1432 }
1433
1434 /* QUIRK: neither flag is cleared afterwards */
1435 if (m_LpmEnabled)
1437 if (m_ResumeTimeSet)
1439
1440 if (!m_Controller->IsAccessible())
1441 {
1442 DPRINT("DISABLE for device %p with the controller gone\n", this);
1443 SetDisabled();
1444 WdfRequestComplete(Request, STATUS_SUCCESS);
1445 return;
1446 }
1447
1450}
1451
1452VOID
1454 _In_ const XhciCommand* Command)
1455{
1457
1458 if (Command->Status == STATUS_NO_SUCH_DEVICE)
1459 {
1460 SetDisabled();
1461 return;
1462 }
1463
1464 if (Command->Code != XhciCompletionCode::Success)
1465 {
1466 DPRINT1("Disable Slot %lu completed with code %lu\n", m_SlotId, static_cast<ULONG>(Command->Code));
1467
1468 if (Command->Code != XhciCompletionCode::SlotNotEnabled)
1469 {
1471 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalDisableSlot);
1472 return;
1473 }
1474 }
1475
1476 /* The default endpoint keeps its table entry; a re-enable follows for RESET */
1479
1481 ForgetSlot();
1482
1484 {
1486 return;
1487 }
1488
1490}
1491
1492VOID
1494 _In_ WDFREQUEST Request)
1495{
1496 ULONG Type;
1497
1498 if (!m_SlotEnabled)
1499 {
1500 WdfRequestComplete(Request, STATUS_SUCCESS);
1501 return;
1502 }
1503
1504 /* Enabled or Default: nothing to reset */
1505 if (OutputSlot()->SlotState <= XHCI_SLOT_STATE_DEFAULT)
1506 {
1507 WdfRequestComplete(Request, STATUS_SUCCESS);
1508 return;
1509 }
1510
1511 if (!m_Controller->IsAccessible())
1512 {
1513 DPRINT("RESET for device %p with the controller gone\n", this);
1516 WdfRequestComplete(Request, STATUS_SUCCESS);
1517 return;
1518 }
1519
1521
1522 if (m_Controller->HasErrata(XhciErrata::EpResetViaSlotCycle))
1523 {
1524 Type = static_cast<ULONG>(XhciTrbType::DisableSlot);
1526 }
1527 else
1528 {
1529 Type = static_cast<ULONG>(XhciTrbType::ResetDevice);
1530 }
1531
1532 /* QUIRK: the block is not cleared, so the reserved TRB fields keep the last command's bits */
1536 m_Command.Context = this;
1538}
1539
1540VOID
1542 _In_ const XhciCommand* Command)
1543{
1544 if (Command->Status != STATUS_NO_SUCH_DEVICE)
1545 {
1546 if (Command->Code != XhciCompletionCode::Success)
1547 {
1548 DPRINT1("Reset Device for slot %lu failed with completion code %lu\n",
1549 m_SlotId, static_cast<ULONG>(Command->Code));
1551 m_Controller->RaiseControllerFault(XhciRecovery::ResetHost, XhciDeviceFatalResetDevice);
1552 return;
1553 }
1554
1556 DPRINT1("Reset Device for slot %lu left the default endpoint disabled\n", m_SlotId);
1557 }
1558
1559 /* The table keeps the endpoints; the hub configures them again */
1563}
1564
1565/* Single endpoint reconfigure **********************************************/
1566
1568VOID
1569XhciUsbDevice::ReconfigureEndpoint(
1573{
1574 ReconfigureWaiter Waiter;
1575 ULONG Dci = Endpoint->Dci();
1576 KIRQL OldIrql;
1577
1578 Waiter.Endpoint = Endpoint;
1579 Waiter.Done = Done;
1580 Waiter.Context = Context;
1581
1582 /* Reconfigures run one at a time on their own command block, apart from device requests */
1585 {
1586 ASSERT((m_ReconfigureQueued & (1UL << Dci)) == 0);
1587 m_ReconfigureWaiters[Dci] = Waiter;
1588 m_ReconfigureQueued |= 1UL << Dci;
1590 return;
1591 }
1592
1595
1596 StartReconfigure(&Waiter);
1597}
1598
1599VOID
1601 _In_ const ReconfigureWaiter* Waiter)
1602{
1606 PUCHAR Base;
1607 ULONG64 InputAddress;
1608 ULONG Dci;
1609
1610 m_ReconfigureCurrent = *Waiter;
1612 Dci = Endpoint->Dci();
1613
1614 if (m_ReconfigureInput == NULL)
1615 {
1617 if (m_ReconfigureInput == NULL)
1618 {
1619 DPRINT1("No input context to reconfigure DCI %lu of slot %lu\n", Dci, m_SlotId);
1621 return;
1622 }
1623 }
1624
1627
1630
1632 Endpoint->BuildContext(Base + (Dci + 1) * m_ContextSize, m_ContextSize);
1633 Slot->ContextEntries = ContextEntries();
1634
1635 /* Drop and add of the same DCI reconfigures it in place (xHCI 4.6.6) */
1636 Control->AddFlags = 1 | (1UL << Dci);
1637 Control->DropFlags = 1UL << Dci;
1638
1641 m_ReconfigureCommand.Trb.Dword[0] = (ULONG)InputAddress;
1642 m_ReconfigureCommand.Trb.Dword[1] = (ULONG)(InputAddress >> 32);
1644 (static_cast<ULONG>(XhciTrbType::ConfigureEndpoint) << XHCI_TRB_TYPE_SHIFT) |
1649}
1650
1651VOID
1652NTAPI
1655{
1656 XhciUsbDevice* Device = static_cast<XhciUsbDevice*>(Command->Context);
1658
1660 {
1661 DPRINT1("Reconfigure of DCI %lu on slot %lu failed: status 0x%lx, code %lu\n",
1662 Device->m_ReconfigureCurrent.Endpoint->Dci(), Device->m_SlotId,
1663 Command->Status, static_cast<ULONG>(Command->Code));
1665 }
1666
1667 Device->FinishReconfigure(Status);
1668}
1669
1670VOID
1673{
1676 BOOLEAN HaveNext = FALSE;
1677 KIRQL OldIrql;
1678 ULONG Dci;
1679
1681 Finished.Done(Finished.Context, Status);
1682
1684 if (m_ReconfigureQueued != 0)
1685 {
1686 Dci = 0;
1687 while ((m_ReconfigureQueued & (1UL << Dci)) == 0)
1688 Dci++;
1689
1691 m_ReconfigureQueued &= ~(1UL << Dci);
1692 HaveNext = TRUE;
1693 }
1694 else
1695 {
1697 }
1699
1700 if (HaveNext)
1702}
1703
1704/* Events and controller walks **********************************************/
1705
1706VOID
1708 _In_ const XHCI_TRB* Event)
1709{
1711 XhciEndpoint* Endpoint = EndpointAt(Dci);
1712
1713 if (Endpoint != NULL)
1714 {
1715 Endpoint->OnTransferEvent(Event);
1716 return;
1717 }
1718
1719 /* QUIRK: isochronous leftovers after a deconfigure are dropped without a word */
1721 {
1722 DPRINT1("Transfer event for slot %lu DCI %lu code %lu has no endpoint, dropped\n",
1724 }
1725}
1726
1727VOID
1729 _In_ const XHCI_TRB* Event)
1730{
1733
1735 {
1736 DPRINT("Device notification type %lu for slot %lu ignored\n", Type, m_SlotId);
1737 return;
1738 }
1739
1741 DPRINT("Function wake from interface %lu of slot %lu\n", Interface, m_SlotId);
1742 UcxUsbDeviceRemoteWakeNotification(m_Handle, Interface);
1743}
1744
1745VOID
1747{
1748 ULONG Dci;
1749
1750 for (Dci = 1; Dci <= XHCI_MAX_DCI; Dci++)
1751 {
1752 if (m_Endpoints[Dci] != NULL)
1754 }
1755}
1756
1757VOID
1758XhciUsbDevice::ControllerResetDone()
1759{
1760 ULONG Dci;
1761
1762 PAGED_CODE();
1763
1764 /* One endpoint at a time; each may wait for its machine to acknowledge */
1765 for (Dci = 1; Dci <= XHCI_MAX_DCI; Dci++)
1766 {
1767 if (m_Endpoints[Dci] != NULL)
1768 m_Endpoints[Dci]->ControllerResetDone();
1769 }
1770}
1771
1772VOID
1774{
1775 WDFREQUEST Request;
1776 ULONG Dci;
1777
1778 for (Dci = 1; Dci <= XHCI_MAX_DCI; Dci++)
1779 {
1780 if (m_Endpoints[Dci] != NULL)
1782 }
1783
1784 Request = TakePending();
1785 if (Request != NULL)
1787}
1788
1789/* UCX callbacks ************************************************************/
1790
1792NTAPI
1794 _In_ UCXCONTROLLER UcxController,
1797{
1800 UCXUSBDEVICE UsbDevice;
1802
1803 PAGED_CODE();
1804
1815
1816 /* Suspend, resume and characteristics are not offered, so the structure ends before them */
1817 Callbacks.Size = FIELD_OFFSET(UCX_USBDEVICE_EVENT_CALLBACKS, EvtUsbDeviceSuspend);
1819
1821 Attributes.EvtCleanupCallback = XhciEvtUsbDeviceCleanup;
1822
1823 Status = UcxUsbDeviceCreate(UcxController, &UsbDeviceInit, &Attributes, &UsbDevice);
1824 if (!NT_SUCCESS(Status))
1825 {
1826 DPRINT1("UcxUsbDeviceCreate failed 0x%lx\n", Status);
1827 return Status;
1828 }
1829
1830 /* On failure UCX deletes the object and the cleanup callback frees what was acquired */
1832 UsbDevice,
1834}
1835
1836VOID
1837NTAPI
1839 _In_ UCXCONTROLLER UcxController,
1840 _In_ WDFREQUEST Request)
1841{
1843
1845 XhciUsbDevice::FromUcx(Payload->Header.UsbDevice)->EndpointsConfigure(Request, Payload);
1846}
1847
1848VOID
1849NTAPI
1851 _In_ UCXCONTROLLER UcxController,
1852 _In_ WDFREQUEST Request)
1853{
1855
1857 XhciUsbDevice::FromUcx(Payload->Header.UsbDevice)->Enable(Request, Payload);
1858}
1859
1860VOID
1861NTAPI
1863 _In_ UCXCONTROLLER UcxController,
1864 _In_ WDFREQUEST Request)
1865{
1867
1869 XhciUsbDevice::FromUcx(Payload->Header.UsbDevice)->Disable(Request);
1870}
1871
1872VOID
1873NTAPI
1875 _In_ UCXCONTROLLER UcxController,
1876 _In_ WDFREQUEST Request)
1877{
1879
1881 XhciUsbDevice::FromUcx(Payload->Header.UsbDevice)->Reset(Request);
1882}
1883
1884VOID
1885NTAPI
1887 _In_ UCXCONTROLLER UcxController,
1888 _In_ WDFREQUEST Request)
1889{
1891
1893 XhciUsbDevice::FromUcx(Payload->Header.UsbDevice)->Address(Request, Payload);
1894}
1895
1896VOID
1897NTAPI
1899 _In_ UCXCONTROLLER UcxController,
1900 _In_ WDFREQUEST Request)
1901{
1903
1905 XhciUsbDevice::FromUcx(Payload->Header.UsbDevice)->Update(Request, Payload);
1906}
1907
1908VOID
1909NTAPI
1911 _In_ UCXCONTROLLER UcxController,
1912 _In_ WDFREQUEST Request)
1913{
1915
1917 XhciUsbDevice::FromUcx(Payload->Header.UsbDevice)->HubInfo(Request, Payload);
1918}
#define PAGED_CODE()
Type
Definition: Type.h:7
struct _ACPI_EVAL_INPUT_BUFFER_COMPLEX * PACPI_EVAL_INPUT_BUFFER_COMPLEX
#define ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE
Definition: acpiioct.h:15
ACPI_METHOD_ARGUMENT UNALIGNED * PACPI_METHOD_ARGUMENT
Definition: acpiioct.h:80
#define ACPI_METHOD_NEXT_ARGUMENT(Argument)
Definition: acpiioct.h:159
#define ACPI_METHOD_ARGUMENT_LENGTH(DataLength)
Definition: acpiioct.h:153
#define ACPI_METHOD_SET_ARGUMENT_INTEGER(MethodArgument, IntData)
Definition: acpiioct.h:164
#define ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE
Definition: acpiioct.h:16
#define ACPI_METHOD_SET_ARGUMENT_BUFFER(Argument, BuffData, BuffLength)
Definition: acpiioct.h:174
#define IOCTL_ACPI_EVAL_METHOD
Definition: acpiioct.h:194
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
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
HubFdo * Hub
Definition: bootdev.cpp:261
Definition: Header.h:9
XhciSlotTable m_Slots
Definition: hc.h:93
XhciCommonBuffer m_Buffers
Definition: hc.h:92
BOOLEAN HasErrata(_In_ XhciErrata Bit) const
Definition: hc.h:58
WDFDEVICE m_Device
Definition: hc.h:85
XhciCommandRing m_Commands
Definition: hc.h:95
BOOLEAN IsAccessible() const
Definition: hc.cpp:193
XhciRootHub m_RootHub
Definition: hc.h:96
XhciRegisters m_Registers
Definition: hc.h:91
static XhciController * FromUcx(_In_ UCXCONTROLLER UcxController)
Definition: hc.cpp:176
ULONG Dci() const
Definition: epctx.cpp:257
static XhciEndpoint * FromUcx(_In_ UCXENDPOINT Endpoint)
Definition: epctx.cpp:232
VOID BuildContext(_Out_writes_bytes_(ContextSize) PVOID EndpointContext, _In_ ULONG ContextSize) const
Definition: epctx.cpp:754
VOID ControllerRemoved()
Definition: epctx.cpp:1270
VOID ControllerResetStarting()
Definition: epctx.cpp:1253
VOID RingDoorbell(_In_ ULONG Index, _In_ ULONG Value)
Definition: mmio.cpp:507
VOID Update20HardwareLpm(_In_ ULONG PortNumber, _In_ ULONG SlotId, _In_ const USBDEVICE_UPDATE_20_HARDWARE_LPM_PARAMETERS *Parameters)
Definition: rootports.cpp:1075
VOID DisableLpmForSlot(_In_ ULONG PortNumber, _In_ ULONG SlotId)
Definition: rootports.cpp:1118
VOID ArmPortResumeTimer(_In_ ULONG PortNumber, _In_ ULONG Milliseconds)
Definition: rootports.cpp:1140
UCHAR QueryTunnelState(_In_ ULONG PortNumber) const
Definition: rootports.cpp:1005
VOID DisarmPortResumeTimer(_In_ ULONG PortNumber)
Definition: rootports.cpp:1156
ULONG ContextSize() const
Definition: slotdev.cpp:377
WDFREQUEST m_PendingRequest
Definition: slotdev.h:302
VOID OnResetDeviceDone(_In_ const XhciCommand *Command)
Definition: slotdev.cpp:1541
BOOLEAN QueueTunnelStateDsm(_Inout_ PUSBDEVICE_UPDATE Payload)
Definition: slotdev.cpp:963
BOOLEAN m_MustSucceed
Definition: slotdev.h:305
VOID PrepareCommand(_In_ ULONG Type)
Definition: slotdev.cpp:557
ULONG64 InputContextAddress() const
Definition: slotdev.cpp:277
VOID ForgetSlot()
Definition: slotdev.cpp:614
VOID Cleanup(_In_ WDFOBJECT Object)
Definition: slotdev.cpp:221
_In_ UCXUSBDEVICE UsbDevice
Definition: slotdev.h:117
VOID BuildSlotContext(_Out_writes_bytes_(ContextSize) PVOID SlotContext, _In_ ULONG ContextSize) const
Definition: slotdev.cpp:1159
const XHCI_SLOT_CONTEXT * OutputSlot() const
Definition: slotdev.cpp:301
NTSTATUS LostSlotStatus() const
Definition: slotdev.cpp:551
BOOLEAN IsSlotEnabled() const
Definition: slotdev.cpp:359
PendingKind m_PendingKind
Definition: slotdev.h:304
BOOLEAN m_LpmEnabled
Definition: slotdev.h:291
VOID OnTransferEvent(_In_ const XHCI_TRB *Event)
Definition: slotdev.cpp:1707
PXHCI_SLOT_CONTEXT InputSlot() const
Definition: slotdev.cpp:295
VOID ControllerResetStarting()
Definition: slotdev.cpp:1746
XhciUsbDevice * TtHub() const
Definition: slotdev.cpp:383
VOID DisableDefaultEndpoint()
Definition: slotdev.cpp:456
_In_ ULONG StreamId
Definition: slotdev.h:51
volatile LONG m_EndpointCount
Definition: slotdev.h:298
static VOID NTAPI ReconfigureCommandDone(_In_ XhciCommand *Command)
Definition: slotdev.cpp:1653
VOID DisableConfiguredEndpoints(_In_ BOOLEAN ClearTable)
Definition: slotdev.cpp:463
VOID OnEvaluateContextDone(_In_ const XhciCommand *Command)
Definition: slotdev.cpp:1108
XhciCommand m_Command
Definition: slotdev.h:301
XhciDmaBuffer * m_ReconfigureInput
Definition: slotdev.h:315
VOID OnDisableSlotDone(_In_ const XhciCommand *Command)
Definition: slotdev.cpp:1453
ULONG SlotId() const
Definition: slotdev.cpp:335
const USB_DEVICE_DESCRIPTOR * DeviceDescriptor() const
Definition: slotdev.cpp:365
VOID FinishReconfigure(_In_ NTSTATUS Status)
Definition: slotdev.cpp:1671
BOOLEAN m_ReconfigureBusy
Definition: slotdev.h:310
VOID Address(_In_ WDFREQUEST Request, _Inout_ PUSBDEVICE_ADDRESS Payload)
Definition: slotdev.cpp:839
VOID CompletePending(_In_ NTSTATUS Status)
Definition: slotdev.cpp:541
VOID OnAddressDeviceDone(_In_ const XhciCommand *Command)
Definition: slotdev.cpp:870
PVOID InputContext(_In_ ULONG Index) const
Definition: slotdev.cpp:261
ULONG m_NumberOfTTs
Definition: slotdev.h:289
ULONG m_NumberOfPorts
Definition: slotdev.h:288
BOOLEAN WantsTunnelStateDsm(_In_ const USBDEVICE_UPDATE *Payload) const
Definition: slotdev.cpp:955
VOID Reset(_In_ WDFREQUEST Request)
Definition: slotdev.cpp:1493
VOID SubmitEnableSlot()
Definition: slotdev.cpp:641
NTSTATUS SubmitAddressDevice(_In_ BOOLEAN BlockSetAddress)
Definition: slotdev.cpp:710
ULONG m_ReconfigureQueued
Definition: slotdev.h:311
static XhciUsbDevice * FromUcx(_In_ UCXUSBDEVICE UsbDevice)
Definition: slotdev.cpp:178
static EVT_WDF_WORKITEM TunnelDsmWorker
Definition: slotdev.h:239
VOID DisableEndpointList(_In_ ULONG Count, _In_reads_(Count) UCXENDPOINT *Endpoints)
Definition: slotdev.cpp:480
PVOID OutputContext(_In_ ULONG Dci) const
Definition: slotdev.cpp:269
ULONG m_SlotId
Definition: slotdev.h:286
VOID ApplyUpdate(_Inout_ PUSBDEVICE_UPDATE Payload)
Definition: slotdev.cpp:918
ULONG64 HardwareDequeuePointer(_In_ ULONG Dci) const
Definition: slotdev.cpp:314
USB_DEVICE_SPEED Speed() const
Definition: slotdev.cpp:341
VOID ZeroInputContext()
Definition: slotdev.cpp:283
VOID Update(_In_ WDFREQUEST Request, _Inout_ PUSBDEVICE_UPDATE Payload)
Definition: slotdev.cpp:1059
XhciEndpoint * m_Endpoints[XHCI_MAX_DCI+1]
Definition: slotdev.h:297
XhciController * m_Controller
Definition: slotdev.h:278
VOID Enable(_In_ WDFREQUEST Request, _Inout_ PUSBDEVICE_ENABLE Payload)
Definition: slotdev.cpp:731
XhciDmaBuffer * m_Output
Definition: slotdev.h:281
VOID EndpointsConfigure(_In_ WDFREQUEST Request, _Inout_ PENDPOINTS_CONFIGURE Payload)
Definition: slotdev.cpp:1194
WDFREQUEST TakePending()
Definition: slotdev.cpp:535
PVOID m_PendingPayload
Definition: slotdev.h:303
BOOLEAN m_IsHub
Definition: slotdev.h:287
static VOID NTAPI CommandDone(_In_ XhciCommand *Command)
Definition: slotdev.cpp:568
UCXUSBDEVICE_INFO m_Info
Definition: slotdev.h:279
VOID SubmitSecondConfigure()
Definition: slotdev.cpp:1294
VOID SubmitDisableSlot(_In_ AfterDisable Next)
Definition: slotdev.cpp:1412
NTSTATUS BuildAddressContext()
Definition: slotdev.cpp:651
AfterDisable m_AfterDisable
Definition: slotdev.h:306
_In_ _In_ NTSTATUS _In_ PVOID Context
Definition: slotdev.h:78
BOOLEAN m_ResumeTimeSet
Definition: slotdev.h:292
KSPIN_LOCK m_ReconfigureLock
Definition: slotdev.h:309
ULONG m_ContextSize
Definition: slotdev.h:280
PXHCI_INPUT_CONTROL_CONTEXT InputControl() const
Definition: slotdev.cpp:289
XhciCommand m_ReconfigureCommand
Definition: slotdev.h:314
VOID RecordEnabledEndpoints(_In_ const ENDPOINTS_CONFIGURE *Payload)
Definition: slotdev.cpp:491
VOID OnEnableSlotDone(_In_ const XhciCommand *Command)
Definition: slotdev.cpp:765
ULONG m_ContextMask
Definition: slotdev.h:295
VOID OnHostLost()
Definition: slotdev.cpp:1773
VOID HubInfo(_In_ WDFREQUEST Request, _In_ const USBDEVICE_HUB_INFO *Payload)
Definition: slotdev.cpp:1142
XhciDmaBuffer * m_Input
Definition: slotdev.h:282
VOID SetPending(_In_ WDFREQUEST Request, _In_ PVOID Payload, _In_ PendingKind Kind, _In_ BOOLEAN MustSucceed)
Definition: slotdev.cpp:519
const USB_DEVICE_PORT_PATH * PortPath() const
Definition: slotdev.cpp:371
VOID Disable(_In_ WDFREQUEST Request)
Definition: slotdev.cpp:1421
BOOLEAN m_SlotEnabled
Definition: slotdev.h:285
VOID OnConfigureEndpointDone(_In_ const XhciCommand *Command)
Definition: slotdev.cpp:1324
_In_ _In_ NTSTATUS Status
Definition: slotdev.h:77
ReconfigureWaiter m_ReconfigureWaiters[XHCI_MAX_DCI+1]
Definition: slotdev.h:312
UCXUSBDEVICE Handle() const
Definition: slotdev.cpp:347
UCXUSBDEVICE m_Handle
Definition: slotdev.h:277
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor
Definition: slotdev.h:284
ULONG m_TTThinkTime
Definition: slotdev.h:290
VOID StartReconfigure(_In_ const ReconfigureWaiter *Waiter)
Definition: slotdev.cpp:1600
XhciController * Controller() const
Definition: slotdev.cpp:353
ULONG ContextEntries() const
Definition: slotdev.cpp:321
ReconfigureWaiter m_ReconfigureCurrent
Definition: slotdev.h:313
VOID OnDeviceNotificationEvent(_In_ const XHCI_TRB *Event)
Definition: slotdev.cpp:1728
ULONG EndpointState(_In_ ULONG Dci) const
Definition: slotdev.cpp:307
Walk Base
Definition: desccheck.cpp:2270
_Inout_ HubConfiguration ** Slot
Definition: devhcd.cpp:1260
KEVENT Done
Definition: devreq.cpp:1162
_In_ ULONG Attributes
Definition: dispmprt.h:1077
_In_ HANDLE _In_ CONST PDXGKMDT_OPM_GET_INFO_PARAMETERS Parameters
Definition: dispmprt.h:321
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG _In_ PVOID Argument
Definition: dispmprt.h:1288
_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_max_(irql)
Definition: driverspecs.h:230
#define _IRQL_requires_(irql)
Definition: driverspecs.h:229
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#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 DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define PagedPool
Definition: env_spec_w32.h:308
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T ContextSize
Definition: fltkernel.h:1444
unsigned int Mask
Definition: fpcontrol.c:82
Status
Definition: gdiplustypes.h:24
_In_ UCXUSBDEVICE UsbDevice
Definition: hostctl.h:31
Previous
UNICODE_STRING Path
WdfWorkItemEnqueue(WorkItem)
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
#define UCXHUB_TUNNEL_STATE_TUNNELED
Definition: hubucx.h:539
#define UCXHUB_TUNNEL_STATE_UNKNOWN
Definition: hubucx.h:541
_In_opt_ PVOID _In_ PUCXHUB_WORKITEM WorkItem
Definition: hubucx.h:227
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT Endpoint
Definition: hubucx.h:238
FORCEINLINE PUCXHUB_UPDATE_TUNNEL_ANSWER NTAPI UcxHubUpdateTunnelAnswer(_In_ PUSBDEVICE_UPDATE Update)
Definition: hubucx.h:556
#define UCXHUB_TUNNEL_STATE_NATIVE
Definition: hubucx.h:540
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
_In_ UINT Bytes
Definition: mmcopy.h:9
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
unsigned __int64 ULONG64
Definition: imports.h:198
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
#define min(a, b)
Definition: monoChain.cc:55
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Inout_
Definition: no_sal2.h:162
#define _Enum_is_bitflag_
Definition: no_sal2.h:404
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define _In_reads_bytes_opt_(s)
Definition: no_sal2.h:224
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:559
#define BOOLEAN
Definition: pedump.c:73
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
PACPI_EVAL_INPUT_BUFFER_COMPLEX Input
Definition: slotdev.cpp:95
@ XhciDeviceFatalAddressDefault
Definition: slotdev.cpp:39
@ XhciDeviceFatalDisableSlot
Definition: slotdev.cpp:42
@ XhciDeviceFatalDeconfigure
Definition: slotdev.cpp:41
@ XhciDeviceFatalSlotInUse
Definition: slotdev.cpp:38
@ XhciDeviceFatalEnableSlot
Definition: slotdev.cpp:40
@ XhciDeviceFatalResetDevice
Definition: slotdev.cpp:43
#define XHCI_USB_DSM_REVISION
Definition: slotdev.cpp:21
struct _XHCI_TUNNEL_DSM_WORK XHCI_TUNNEL_DSM_WORK
#define XHCI_USB_DSM_PORT_TUNNELED
Definition: slotdev.cpp:24
static BOOLEAN NTAPI XhciCommandSucceeded(_In_ const XhciCommand *Command)
Definition: slotdev.cpp:168
PACPI_METHOD_ARGUMENT Next
Definition: slotdev.cpp:96
#define XHCI_ROUTE_TIER_MAX
Definition: slotdev.cpp:59
ULONG64 Value
Definition: slotdev.cpp:99
_In_ const GUID _In_ ULONG _In_ ULONG Function
Definition: slotdev.cpp:86
ULONG Size
Definition: slotdev.cpp:101
NTSTATUS Status
Definition: slotdev.cpp:102
WDF_MEMORY_DESCRIPTOR InputDescriptor
Definition: slotdev.cpp:97
PAGED_CODE()
static const GUID XhciGuidUsbDsm
Definition: slotdev.cpp:18
#define XHCI_ROUTE_TIER_BITS
Definition: slotdev.cpp:60
#define XHCI_USB_DSM_TUNNEL_STATE
Definition: slotdev.cpp:22
_In_ const GUID * Uuid
Definition: slotdev.cpp:84
struct _XHCI_TUNNEL_DSM_WORK * PXHCI_TUNNEL_DSM_WORK
_In_ const GUID _In_ ULONG _In_ ULONG _In_ USHORT ArgumentLength
Definition: slotdev.cpp:89
@ XhciDeviceCheckAddressDefault
Definition: slotdev.cpp:50
@ XhciDeviceCheckDisableSlot
Definition: slotdev.cpp:52
@ XhciDeviceCheckDeconfigure
Definition: slotdev.cpp:51
@ XhciDeviceCheckResetDevice
Definition: slotdev.cpp:53
@ XhciDeviceCheckSlotInUse
Definition: slotdev.cpp:49
#define XHCI_USB_DSM_PORT_NATIVE
Definition: slotdev.cpp:23
ULONG Length
Definition: slotdev.cpp:100
_In_ const GUID _In_ ULONG Revision
Definition: slotdev.cpp:85
WDF_MEMORY_DESCRIPTOR OutputDescriptor
Definition: slotdev.cpp:98
static EVT_WDF_OBJECT_CONTEXT_CLEANUP XhciEvtUsbDeviceCleanup
Definition: slotdev.cpp:62
#define XHCI_DEFAULT_CONTEXT_MASK
Definition: slotdev.cpp:57
static PVOID NTAPI XhciRequestPayload(_In_ WDFREQUEST Request)
Definition: slotdev.cpp:67
#define XHCI_MAX_DCI
Definition: slotdev.h:14
#define DPRINT
Definition: sndvol32.h:73
Definition: shell.h:41
PFN_XHCI_COMMAND_DONE Done
Definition: cmdring.h:22
PVOID Context
Definition: cmdring.h:23
XHCI_TRB Trb
Definition: cmdring.h:21
PHYSICAL_ADDRESS LogicalAddress
Definition: dmapool.h:17
PVOID VirtualAddress
Definition: dmapool.h:16
PFN_RECONFIGURE_DONE Done
Definition: slotdev.h:175
ACPI_METHOD_ARGUMENT Argument[ANYSIZE_ARRAY]
Definition: acpiioct.h:90
ULONG EndpointsToDisableCount
Definition: ucxendpoint.h:32
ENDPOINTS_CONFIGURE_FAILURE_FLAGS FailureFlags
Definition: ucxendpoint.h:36
ULONG EndpointsToEnableCount
Definition: ucxendpoint.h:30
UCXUSBDEVICE TtHub
Definition: ucxusbdevice.h:177
USB_DEVICE_PORT_PATH PortPath
Definition: ucxusbdevice.h:178
USB_DEVICE_SPEED DeviceSpeed
Definition: ucxusbdevice.h:176
USBDEVICE_UPDATE_FAILURE_FLAGS FailureFlags
Definition: ucxusbdevice.h:126
ULONG PortPath[MAX_USB_DEVICE_DEPTH]
Definition: ucxusbdevice.h:170
ULONG UsbDeviceAddress
Definition: xhcihw.h:472
ULONG ContextEntries
Definition: xhcihw.h:460
ULONG Dword[4]
Definition: xhcihw.h:17
PUSBDEVICE_UPDATE Payload
Definition: slotdev.cpp:30
XhciUsbDevice * Device
Definition: slotdev.cpp:29
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
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXCONTROLLER * Controller
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG Config
_In_ PUCXUSBDEVICE_INFO UcxUsbDeviceInfo
_In_ PUCXUSBDEVICE_INFO _In_ PUCXUSBDEVICE_INIT UsbDeviceInit
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFREQUEST Request
struct _ENDPOINTS_CONFIGURE * PENDPOINTS_CONFIGURE
_In_ UCXUSBDEVICE _In_ ULONG Interface
Definition: ucxusbdevice.h:428
struct _USBDEVICE_DISABLE * PUSBDEVICE_DISABLE
struct _USBDEVICE_HUB_INFO * PUSBDEVICE_HUB_INFO
struct _USBDEVICE_RESET * PUSBDEVICE_RESET
struct _USBDEVICE_ADDRESS * PUSBDEVICE_ADDRESS
#define MAX_USB_DEVICE_DEPTH
Definition: ucxusbdevice.h:163
FORCEINLINE VOID NTAPI UcxUsbDeviceInitSetEventCallbacks(_Inout_ PUCXUSBDEVICE_INIT UsbDeviceInit, _In_ PUCX_USBDEVICE_EVENT_CALLBACKS EventCallbacks)
Definition: ucxusbdevice.h:450
struct _USBDEVICE_UPDATE * PUSBDEVICE_UPDATE
FORCEINLINE VOID NTAPI UCX_USBDEVICE_EVENT_CALLBACKS_INIT(_Out_ PUCX_USBDEVICE_EVENT_CALLBACKS Callbacks, _In_ PFN_UCX_USBDEVICE_ENDPOINTS_CONFIGURE EvtUsbDeviceEndpointsConfigure, _In_ PFN_UCX_USBDEVICE_ENABLE EvtUsbDeviceEnable, _In_ PFN_UCX_USBDEVICE_DISABLE EvtUsbDeviceDisable, _In_ PFN_UCX_USBDEVICE_RESET EvtUsbDeviceReset, _In_ PFN_UCX_USBDEVICE_ADDRESS EvtUsbDeviceAddress, _In_ PFN_UCX_USBDEVICE_UPDATE EvtUsbDeviceUpdate, _In_ PFN_UCX_USBDEVICE_HUB_INFO EvtUsbDeviceHubInfo, _In_ PFN_UCX_USBDEVICE_DEFAULT_ENDPOINT_ADD EvtUsbDeviceDefaultEndpointAdd, _In_ PFN_UCX_USBDEVICE_ENDPOINT_ADD EvtUsbDeviceEndpointAdd)
Definition: ucxusbdevice.h:364
struct _USBDEVICE_ENABLE * PUSBDEVICE_ENABLE
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
#define USB_ENDPOINT_TYPE_ISOCHRONOUS
Definition: usb100.h:63
@ UsbSuperSpeed
Definition: usb200.h:45
@ UsbHighSpeed
Definition: usb200.h:44
@ UsbLowSpeed
Definition: usb200.h:42
@ UsbFullSpeed
Definition: usb200.h:43
enum _USB_DEVICE_SPEED USB_DEVICE_SPEED
USHORT Count
Definition: userreq.cpp:200
WdfObjectDelete(String)
PUSB_ROOT_HUB_NAME Output
Definition: userreq.cpp:699
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ WDFCOLLECTION _In_ WDFOBJECT Item
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_In_ UCHAR _In_ UCHAR _In_ ULONG Code
Definition: wdfdevice.h:1707
FORCEINLINE VOID WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(_Out_ PWDF_MEMORY_DESCRIPTOR Descriptor, _In_ PVOID Buffer, _In_ ULONG BufferLength)
Definition: wdfmemory.h:102
#define WdfObjectDereferenceWithTag(Handle, Tag)
Definition: wdfobject.h:829
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
#define WdfObjectReference(Handle)
Definition: wdfobject.h:803
#define WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(_contexttype, _castingfunction)
Definition: wdfobject.h:350
#define WdfObjectReferenceWithTag(Handle, Tag)
Definition: wdfobject.h:806
#define WdfObjectDereference(Handle)
Definition: wdfobject.h:826
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
FORCEINLINE VOID WDF_REQUEST_PARAMETERS_INIT(_Out_ PWDF_REQUEST_PARAMETERS Parameters)
Definition: wdfrequest.h:211
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166
FORCEINLINE VOID WDF_WORKITEM_CONFIG_INIT(_Out_ PWDF_WORKITEM_CONFIG Config, _In_ PFN_WDF_WORKITEM EvtWorkItemFunc)
Definition: wdfworkitem.h:85
_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
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:336
EVT_UCX_USBDEVICE_ADDRESS XhciEvtUsbDeviceAddress
Definition: xhcidrv.h:49
EVT_UCX_USBDEVICE_DISABLE XhciEvtUsbDeviceDisable
Definition: xhcidrv.h:47
EVT_UCX_USBDEVICE_DEFAULT_ENDPOINT_ADD XhciEvtUsbDeviceDefaultEndpointAdd
Definition: xhcidrv.h:52
EVT_UCX_USBDEVICE_ENDPOINT_ADD XhciEvtUsbDeviceEndpointAdd
Definition: xhcidrv.h:53
EVT_UCX_USBDEVICE_ENDPOINTS_CONFIGURE XhciEvtUsbDeviceEndpointsConfigure
Definition: xhcidrv.h:45
EVT_UCX_USBDEVICE_ENABLE XhciEvtUsbDeviceEnable
Definition: xhcidrv.h:46
EVT_UCX_CONTROLLER_USBDEVICE_ADD XhciEvtControllerUsbDeviceAdd
Definition: xhcidrv.h:44
EVT_UCX_USBDEVICE_RESET XhciEvtUsbDeviceReset
Definition: xhcidrv.h:48
EVT_UCX_USBDEVICE_HUB_INFO XhciEvtUsbDeviceHubInfo
Definition: xhcidrv.h:51
EVT_UCX_USBDEVICE_UPDATE XhciEvtUsbDeviceUpdate
Definition: xhcidrv.h:50
#define XHCI_SPEED_LOW
Definition: xhcihw.h:242
struct _XHCI_INPUT_CONTROL_CONTEXT * PXHCI_INPUT_CONTROL_CONTEXT
#define XHCI_DEVICE_CONTEXT_COUNT
Definition: xhcihw.h:449
#define XHCI_CMD_BLOCK_SET_ADDRESS
Definition: xhcihw.h:572
#define XHCI_NOTIFICATION_DATA_MASK
Definition: xhcihw.h:581
#define XHCI_NOTIFICATION_TYPE_MASK
Definition: xhcihw.h:198
#define XHCI_TRB_ENDPOINT_MASK
Definition: xhcihw.h:27
#define XHCI_TRB_TYPE_SHIFT
Definition: xhcihw.h:23
struct _XHCI_SLOT_CONTEXT * PXHCI_SLOT_CONTEXT
#define XHCI_TRB_ENDPOINT_SHIFT
Definition: xhcihw.h:26
#define XHCI_NOTIFICATION_DATA_SHIFT
Definition: xhcihw.h:580
#define XHCI_SLOT_STATE_DEFAULT
Definition: xhcihw.h:491
#define XHCI_SPEED_SUPER
Definition: xhcihw.h:244
#define XHCI_TRB_SLOT_SHIFT
Definition: xhcihw.h:25
#define XHCI_SPEED_HIGH
Definition: xhcihw.h:243
#define XHCI_NOTIFICATION_FUNCTION_WAKE
Definition: xhcihw.h:579
#define XHCI_SPEED_FULL
Definition: xhcihw.h:241
#define XHCI_COMPLETION_PARAMETER_MASK
Definition: xhcihw.h:576
#define XHCI_INPUT_CONTEXT_COUNT
Definition: xhcihw.h:450
#define XHCI_NOTIFICATION_TYPE_SHIFT
Definition: xhcihw.h:197
XhciTrbType
Definition: xhcihw.h:68
#define XHCI_EVENT_DATA_TYPE_MASK
Definition: xhcihw.h:324
#define XHCI_TRB_TYPE_MASK
Definition: xhcihw.h:24
#define XHCI_ENDPOINT_STATE_DISABLED
Definition: xhcihw.h:533
FORCEINLINE ULONG NTAPI XhciTrbCompletionCode(_In_ const XHCI_TRB *Trb)
Definition: xhcihw.h:42
FORCEINLINE ULONG NTAPI XhciTrbSlotId(_In_ const XHCI_TRB *Trb)
Definition: xhcihw.h:51
#define XHCI_TAG_CONTROLLER
Definition: xhciutil.h:12