ReactOS 0.4.17-dev-1281-g065abb3
xferring.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: Transfer ring object shared by the control, bulk and isoch transfer types
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "xhcidrv.h"
9
10#define NDEBUG
11#include <debug.h>
12
13/* Segment and buffer sizes of the two configurations */
14static const ULONG XhciRingSegmentBytes = 0x200;
15static const ULONG XhciRingWideSegmentBytes = 0x1000;
16static const ULONG XhciRingDoubleBufferBytes = 0x200;
17
20
21/* How long Disable waits for a mapping context to unwind */
22static const ULONG XhciRingIdleWaitMs = 5000;
23static const ULONG XhciRingIdleWaitUs = 100000;
24
26static const USBD_STATUS XhciRingUsbdNotSet = (USBD_STATUS)0xFFFFFFFF;
27
29
30static EVT_WDF_OBJECT_CONTEXT_CLEANUP XhciRingQueueCleanup;
31static EVT_WDF_WORKITEM XhciRingGrowthWorkItem;
32static EVT_WDF_IO_WDM_IRP_FOR_FORWARD_PROGRESS XhciRingExamineForwardProgress;
33
34/*
35 * Every ring that can receive transfer events, across all controllers. The interrupter
36 * fast path resolves its ring here from the event's slot and endpoint ids.
37 */
40
41static
45 _In_ const LIST_ENTRY* Head)
46{
47 const LIST_ENTRY* Entry;
48 ULONG Count = 0;
49
50 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
51 Count++;
52
53 return Count;
54}
55
57static
58VOID
63{
64 while (!IsListEmpty(From))
66}
67
69static
70VOID
75{
76 while (!IsListEmpty(From))
78}
79
80static
81VOID
85{
86 XhciRingContext(Object)->Cleanup();
87}
88
89static
90VOID
93 _In_ WDFWORKITEM WorkItem)
94{
95 WDFQUEUE Queue = (WDFQUEUE)WdfWorkItemGetParentObject(WorkItem);
96
97 XhciTransferRing::FromQueue(Queue)->GrowSegments();
98}
99
100static
102NTAPI
104 _In_ WDFQUEUE Queue,
105 _In_ PIRP Irp)
106{
107 PURB Urb;
108
110
111 /* Control and bulk URBs keep TransferFlags at the same offset */
113 if (Urb != NULL &&
114 (Urb->UrbBulkOrInterruptTransfer.TransferFlags & USB3_URB_RESERVED_RESOURCES))
115 {
117 }
118
120}
121
127 _In_ ULONG StreamId,
128 _Out_ XhciTransferRing** Ring)
129{
130 XhciController* Controller = Endpoint->Controller();
131 WDF_IO_QUEUE_CONFIG QueueConfig;
133 WDF_DPC_CONFIG DpcConfig;
134 PFN_WDF_DPC CompletionDpc;
135 XhciTransferRing* NewRing;
136 WDFQUEUE Queue;
137 ULONG TransferType;
139 ULONG MaxStageSize;
140 BOOLEAN NoLinkInTd;
142
143 *Ring = NULL;
144
145 TransferType = Endpoint->TransferType();
146 MaxStageSize = Controller->m_Buffers.MaxDmaSize() - PAGE_SIZE;
147 NoLinkInTd = Controller->HasErrata(XhciErrata::RingKeepTdInOneSegment);
148
149 if (TransferType == USB_ENDPOINT_TYPE_CONTROL)
150 {
154 CompletionDpc = XhciControlRing::EvtCompletionDpc;
155
156 /* A whole control transfer must fit one segment when no Link TRB may split it */
158 }
159 else if (TransferType == USB_ENDPOINT_TYPE_BULK || TransferType == USB_ENDPOINT_TYPE_INTERRUPT)
160 {
163 CompletionDpc = XhciBulkRing::EvtCompletionDpc;
165
166 if (NoLinkInTd)
167 MaxStageSize = XhciRingSingleSegmentStage;
168 }
169 else if (TransferType == USB_ENDPOINT_TYPE_ISOCHRONOUS)
170 {
173 CompletionDpc = XhciIsochRing::EvtCompletionDpc;
175 }
176 else
177 {
178 DPRINT1("Endpoint DCI %lu has transfer type %lu, no transfer ring for it\n",
179 Endpoint->Dci(), TransferType);
180 return STATUS_UNSUCCESSFUL;
181 }
182
184 Attributes.ParentObject = Parent;
185 Attributes.EvtCleanupCallback = XhciRingQueueCleanup;
186
187 Status = WdfIoQueueCreate(Controller->m_Device, &QueueConfig, &Attributes, &Queue);
188 if (!NT_SUCCESS(Status))
189 {
190 DPRINT1("Queue for DCI %lu stream %lu not created, 0x%08lx\n",
191 Endpoint->Dci(), StreamId, Status);
192 return Status;
193 }
194
195 /* The context is zeroed by WDF, so cleanup copes with any step below failing */
196 NewRing = new (XhciRingContext(Queue)) XhciTransferRing;
197 KeInitializeSpinLock(&NewRing->m_Lock);
201 NewRing->m_Device = Endpoint->Device();
202 NewRing->m_Endpoint = Endpoint;
203 NewRing->m_StreamId = StreamId;
204 NewRing->m_TransferType = TransferType;
205 NewRing->m_Queue = Queue;
206 NewRing->m_MapState = static_cast<LONG>(XhciMapState::Halted);
207 NewRing->m_SegmentSize = SegmentSize;
209 NewRing->m_MaxStageSize = MaxStageSize;
210 NewRing->m_MapRegisterCount = Controller->m_Buffers.MapRegisterCount();
211 NewRing->m_LastIndex = SegmentSize / sizeof(XHCI_TRB) - 1;
212 NewRing->m_Cycle = 1;
213 NewRing->m_Controller = Controller;
214
215 if (!NewRing->IsControl())
216 {
217 WDF_WORKITEM_CONFIG WorkConfig;
218
219 Status = WdfIoQueueReadyNotify(Queue,
222 NewRing);
223 if (!NT_SUCCESS(Status))
224 {
225 DPRINT1("Ready notification for DCI %lu stream %lu not registered, 0x%08lx\n",
226 Endpoint->Dci(), StreamId, Status);
227 return Status;
228 }
229
231 WorkConfig.AutomaticSerialization = FALSE;
233 Attributes.ParentObject = Queue;
234
235 Status = WdfWorkItemCreate(&WorkConfig, &Attributes, &NewRing->m_GrowthItem);
236 if (!NT_SUCCESS(Status))
237 {
238 DPRINT1("Segment growth work item for DCI %lu stream %lu not created, 0x%08lx\n",
239 Endpoint->Dci(), StreamId, Status);
240 return Status;
241 }
242 }
243
244 WDF_DPC_CONFIG_INIT(&DpcConfig, CompletionDpc);
245 DpcConfig.AutomaticSerialization = TRUE;
247 Attributes.ParentObject = Queue;
248
249 Status = WdfDpcCreate(&DpcConfig, &Attributes, &NewRing->m_CompletionDpc);
250 if (!NT_SUCCESS(Status))
251 {
252 DPRINT1("Completion DPC for DCI %lu stream %lu not created, 0x%08lx\n",
253 Endpoint->Dci(), StreamId, Status);
254 return Status;
255 }
256
257 /* Take the first segment now so a later enable at DISPATCH_LEVEL never allocates */
258 Status = NewRing->EnsureFreeSegments(1, FALSE);
259 if (NT_SUCCESS(Status))
260 {
261 XhciSpinLockGuard Guard(&NewRing->m_Lock);
262
263 if (IsListEmpty(&NewRing->m_FreeSegments))
264 {
266 }
267 else
268 {
272 NewRing->m_Trbs = (PXHCI_TRB)NewRing->m_Segment->VirtualAddress;
273 }
274 }
275
276 if (!NT_SUCCESS(Status))
277 {
278 DPRINT1("No initial segment for DCI %lu stream %lu, 0x%08lx\n",
279 Endpoint->Dci(), StreamId, Status);
280 return Status;
281 }
282
283 if (NewRing->IsControl())
285 else if (NewRing->IsIsoch())
287 else
289
290 if (!NT_SUCCESS(Status))
291 {
292 DPRINT1("Type setup for DCI %lu stream %lu failed, 0x%08lx\n",
293 Endpoint->Dci(), StreamId, Status);
294 return Status;
295 }
296
297 NewRing->m_TypeReady = TRUE;
298 NewRing->MakeLive();
299
300 DPRINT("Ring %p for DCI %lu stream %lu type %lu, segment 0x%lx, stage max 0x%lx\n",
301 NewRing, Endpoint->Dci(), StreamId, TransferType, SegmentSize, MaxStageSize);
302
303 *Ring = NewRing;
304 return STATUS_SUCCESS;
305}
306
309 _In_ WDFQUEUE Queue)
310{
311 return XhciRingContext(Queue);
312}
313
314WDFQUEUE
316{
317 return m_Queue;
318}
319
322{
324}
325
328{
331}
332
335{
337}
338
339VOID
341{
342 LIST_ENTRY Leftover;
343
344 /* The queue failed before the ring was filled in */
345 if (m_Controller == NULL)
346 return;
347
348 RetireLive();
349
350 InitializeListHead(&Leftover);
351 {
353
356 }
357
358 if (!IsListEmpty(&Leftover))
359 {
360 DPRINT1("Ring for DCI %lu stream %lu still pooled %lu buffers at cleanup\n",
362 m_Controller->m_Buffers.FreeList(&Leftover);
363 }
364
365 if (m_Segment != NULL)
366 {
368 m_Segment = NULL;
369 m_Trbs = NULL;
370 }
371
372 if (m_ReservedMdl != NULL)
373 {
376 }
377
378 if (!m_TypeReady)
379 return;
380
382 if (IsControl())
384 else if (IsIsoch())
386 else
388}
389
390VOID
392{
394
396 m_Live = TRUE;
397}
398
399VOID
401{
402 {
404
405 if (!m_Live)
406 return;
407
410 m_Live = FALSE;
411 }
412
413 /* Nobody can find the ring anymore; let an event handler already inside it finish */
414 while (InterlockedCompareExchange(&m_EventUsers, 0, 0) != 0)
416}
417
422 _In_ ULONG Dci)
423{
427
429 {
431
432 if (Ring->m_Controller != Controller ||
433 Ring->m_Device != Device ||
434 Ring->m_Endpoint->Dci() != Dci)
435 {
436 continue;
437 }
438
439 /* The event does not say which stream it belongs to; the endpoint sorts that out */
440 if (Ring->m_StreamId != 0)
441 return NULL;
442
443 Found = Ring;
444 }
445
446 if (Found != NULL)
447 InterlockedIncrement(&Found->m_EventUsers);
448
449 return Found;
450}
451
452VOID
454{
456}
457
460XhciTransferRing::Enable()
461{
462 ASSERT(m_MapState == static_cast<LONG>(XhciMapState::Halted));
463
464 if (m_Segment == NULL)
465 {
466 DPRINT1("Ring for DCI %lu stream %lu has no segment to enable\n",
469 }
470
472
473 if (IsControl())
475 else if (IsIsoch())
477 else
479
480 DPRINT("Ring for DCI %lu stream %lu enabled\n", m_Endpoint->Dci(), m_StreamId);
481 return STATUS_SUCCESS;
482}
483
485VOID
486XhciTransferRing::WaitForMappingIdle()
487{
489 ULONGLONG Deadline = KeQueryInterruptTime() +
490 10000ULL * (Passive ? XhciRingIdleWaitMs : XhciRingIdleWaitUs / 1000);
491
492 for (;;)
493 {
495
496 if (State != static_cast<LONG>(XhciMapState::Filling) &&
497 State != static_cast<LONG>(XhciMapState::Halting))
498 {
499 return;
500 }
501
502 if (KeQueryInterruptTime() >= Deadline)
503 {
504 DPRINT1("Ring for DCI %lu stream %lu still in map state %ld, disabling anyway\n",
506
507 /* The late mapping context can no longer acknowledge the stop, so do it here once */
509 static_cast<LONG>(XhciMapState::Halted),
510 static_cast<LONG>(XhciMapState::Halting)) ==
511 static_cast<LONG>(XhciMapState::Halting))
512 {
514 }
515 return;
516 }
517
518 if (Passive)
519 {
522 }
523 else
524 {
526 }
527 }
528}
529
531VOID
532XhciTransferRing::Disable(
534{
535 LIST_ENTRY Segments;
536 LIST_ENTRY DoubleBuffers;
538
539 /* The idle wait is bounded so it cannot hang a single processor at DISPATCH_LEVEL */
540 if (IsIsoch())
542 else if (!IsControl())
544 WaitForMappingIdle();
545
546 if (IsControl())
548 else if (IsIsoch())
550 else
552
553 Previous = InterlockedExchange(&m_MapState, static_cast<LONG>(XhciMapState::Halted));
554 ASSERT(Previous == static_cast<LONG>(XhciMapState::Halted) ||
555 Previous == static_cast<LONG>(XhciMapState::PausedFill));
557
558 if (!FreeResources)
559 return;
560
561 InitializeListHead(&Segments);
562 InitializeListHead(&DoubleBuffers);
563 {
565
567 XhciRingAppendList(&DoubleBuffers, &m_DoubleBuffers);
568 }
569
570 if (!IsListEmpty(&Segments))
571 m_Controller->m_Buffers.FreeList(&Segments);
572
573 if (!IsListEmpty(&DoubleBuffers))
574 m_Controller->m_Buffers.FreeList(&DoubleBuffers);
575
576 if (m_ReservedMdl != NULL)
577 {
580 }
581}
582
585XhciTransferRing::EnableForwardProgress(
587{
589 PMDL Mdl;
590 PMDL Old;
592
593 if (IsIsoch())
594 {
595 DPRINT1("Forward progress asked for isoch DCI %lu, not supported\n", m_Endpoint->Dci());
597 }
598
599 if (IsControl())
601 else
603
604 if (!NT_SUCCESS(Status))
605 {
606 DPRINT1("Forward progress setup for DCI %lu stream %lu failed, 0x%08lx\n",
608 return Status;
609 }
610
612 if (Mdl == NULL)
613 {
614 DPRINT1("No forward progress MDL of %lu bytes for DCI %lu stream %lu\n",
617 }
618
619 /* KMDF refuses a second policy on the same queue, and the policy never changes */
621 {
623
624 Status = WdfIoQueueAssignForwardProgressPolicy(m_Queue, &Policy);
625 if (!NT_SUCCESS(Status))
626 {
627 DPRINT1("Forward progress policy for DCI %lu stream %lu refused, 0x%08lx\n",
629 IoFreeMdl(Mdl);
630 return Status;
631 }
632
634 }
635
636 /* A changed maximum size replaces the previous MDL */
637 Old = m_ReservedMdl;
639 if (Old != NULL)
640 IoFreeMdl(Old);
641
642 DPRINT("Forward progress on DCI %lu stream %lu for %lu bytes\n",
644 return STATUS_SUCCESS;
645}
646
647VOID
649{
652 m_EnqueueIndex = 0;
653 m_LastIndex = m_SegmentSize / sizeof(XHCI_TRB) - 1;
654 m_Cycle = 1;
655}
656
659{
661}
662
665{
666 return SegmentBase() + (ULONG64)m_EnqueueIndex * sizeof(XHCI_TRB);
667}
668
671{
673
674 if (m_Cycle & 1)
676
677 if (m_StreamId != 0)
679
680 return Value;
681}
682
683VOID
685{
686 if (IsControl())
688 else if (IsIsoch())
690 else
692}
693
694VOID
696{
697 if (IsControl())
699 else if (IsIsoch())
701 else
703}
704
705VOID
707{
708 /* A halted control ring waits for its reset and an isoch ring never reports a halt */
709 if (IsBulkOrInterrupt())
711}
712
713VOID
715{
716 /* Only an isoch ring cares: its next ASAP URB starts a new stream */
717 if (IsIsoch())
719}
720
721VOID
723{
724 /* An isoch ring already tracks the stop through its own events */
725 if (IsBulkOrInterrupt())
727}
728
729VOID
731{
732 if (IsControl())
734 else if (IsIsoch())
736 else
738}
739
740VOID
742{
743 if (IsControl())
745 else if (IsIsoch())
747 else
749}
750
751VOID
753{
754 if (IsControl())
756 else if (IsIsoch())
758 else
760}
761
764{
765 if (IsControl())
767
768 if (IsIsoch())
770
772}
773
776{
777 if (IsControl())
779
780 if (IsIsoch())
781 return XhciIsochRing::HasQueuedWork(this);
782
783 return XhciBulkRing::HasQueuedWork(this);
784}
785
788 _In_ const XHCI_TRB* Event)
789{
790 if (IsControl())
792
793 if (IsBulkOrInterrupt())
795
796 if (IsIsoch())
798
799 return FALSE;
800}
801
805 _In_ const XHCI_TRB* Event)
806{
808 ULONG SlotId = XhciTrbSlotId(Event);
810 XhciTransferRing* Ring;
811 BOOLEAN SameType;
812
814 return FALSE;
815
816 /* Find the ring by slot and endpoint id so the type handler can check the pointer before using it */
818 static_cast<const XhciUsbDevice*>(Controller->m_Slots.LookupSlot(SlotId)),
819 Dci);
820 if (Ring == NULL)
821 return FALSE;
822
824 SameType = Ring->IsControl();
825 else
826 SameType = Ring->IsBulkOrInterrupt();
827
828 if (SameType)
829 {
830 Ring->OnTransferEvent(Event);
831 }
832 else
833 {
834 DPRINT1("Stale Event Data 0x%I64x for slot %lu DCI %lu type %lu, dropped\n",
835 XhciTrbPointer(Event), SlotId, Dci, Ring->m_TransferType);
836 }
837
838 Ring->DereferenceLive();
839 return TRUE;
840}
841
844 _In_ const XHCI_TRB* Event) const
845{
846 if (IsBulkOrInterrupt())
848
849 return FALSE;
850}
851
855 _In_ BOOLEAN Async)
856{
857 LIST_ENTRY Taken;
858 ULONG Have;
859 ULONG Missing;
862
863 {
865
867 }
868
869 if (Have >= Count)
870 return STATUS_SUCCESS;
871
872 Missing = Count - Have;
873 InitializeListHead(&Taken);
874
875 Status = m_Controller->m_Buffers.AcquireList(m_SegmentSize, Missing, &Taken);
876 if (NT_SUCCESS(Status))
877 {
879
881 return STATUS_SUCCESS;
882 }
883
884 /* At PASSIVE_LEVEL the pool already grew synchronously, so the failure is final */
885 if (Async && m_GrowthItem != NULL && KeGetCurrentIrql() > PASSIVE_LEVEL)
886 {
887 {
889
890 if (m_GrowthWanted < Missing)
891 m_GrowthWanted = Missing;
892
893 if (!m_GrowthQueued)
894 {
896 Enqueue = TRUE;
897 }
898 }
899
900 if (Enqueue)
902
903 return STATUS_PENDING;
904 }
905
906 DPRINT1("Ring for DCI %lu stream %lu could not get %lu segments, 0x%08lx\n",
907 m_Endpoint->Dci(), m_StreamId, Missing, Status);
908 return Status;
909}
910
912VOID
913XhciTransferRing::GrowSegments()
914{
915 LIST_ENTRY Taken;
916 ULONG Count;
918
919 {
921
923 m_GrowthWanted = 0;
925 }
926
927 InitializeListHead(&Taken);
928 if (Count != 0)
929 Status = m_Controller->m_Buffers.AcquireList(m_SegmentSize, Count, &Taken);
930
931 if (NT_SUCCESS(Status))
932 {
934
936 }
937 else
938 {
939 DPRINT1("Ring for DCI %lu stream %lu could not grow by %lu segments, 0x%08lx\n",
941 }
942
943 if (IsIsoch())
945 else
947}
948
953{
954 LIST_ENTRY Moved;
955 ULONG Index;
957
959 if (Status != STATUS_SUCCESS)
960 return Status;
961
962 InitializeListHead(&Moved);
963 {
965
967 {
969 }
970 else
971 {
972 for (Index = 0; Index < Count; Index++)
974
975 XhciRingPrependList(List, &Moved);
976 }
977 }
978
979 if (!NT_SUCCESS(Status))
980 {
981 DPRINT1("Ring for DCI %lu stream %lu lost its reserved segments\n",
983 }
984
985 return Status;
986}
987
988VOID
991 _In_ BOOLEAN ToHead)
992{
993 if (IsListEmpty(List))
994 return;
995
996 if (m_Controller->HasErrata(XhciErrata::RingClearNewSegments))
997 {
999
1000 for (Entry = List->Flink; Entry != List; Entry = Entry->Flink)
1001 {
1003 RtlZeroMemory(Segment->VirtualAddress, Segment->Size);
1004 }
1005 }
1006
1007 if (ToHead)
1009 else
1011}
1012
1015{
1017
1018 /* Forward progress rings never double buffer */
1019 if (m_DoubleBufferSize == 0)
1020 return NULL;
1021
1022 {
1023 XhciSpinLockGuard Guard(&m_Lock);
1024
1026 {
1028 XhciClearListEntry(&Buffer->Link);
1029 }
1030 }
1031
1032 if (Buffer == NULL)
1034
1035 return Buffer;
1036}
1037
1038VOID
1041{
1042 XhciSpinLockGuard Guard(&m_Lock);
1043
1045}
1046
1049 _In_ BOOLEAN FromAny,
1050 _In_ XhciMapState From,
1051 _In_ XhciMapState To)
1052{
1053 LONG Old;
1054 BOOLEAN Changed;
1055
1056 if (FromAny)
1057 {
1058 Old = InterlockedExchange(&m_MapState, static_cast<LONG>(To));
1059 Changed = TRUE;
1060 }
1061 else
1062 {
1063 Old = InterlockedCompareExchange(&m_MapState, static_cast<LONG>(To), static_cast<LONG>(From));
1064 Changed = (Old == static_cast<LONG>(From));
1065 }
1066
1067 if (Changed)
1068 {
1069 if (To == XhciMapState::Halted)
1071 }
1072 else if (From == XhciMapState::Filling)
1073 {
1074 /* A stop arrived while this context was mapping; it acknowledges the stop itself */
1075 ASSERT(Old == static_cast<LONG>(XhciMapState::Halting));
1076
1078 static_cast<LONG>(XhciMapState::Halted),
1079 static_cast<LONG>(XhciMapState::Halting)) ==
1080 static_cast<LONG>(XhciMapState::Halting))
1081 {
1083 }
1084 }
1085
1086 return static_cast<XhciMapState>(Old);
1087}
1088
1089VOID
1091 _Out_ PXHCI_TRB Trb,
1092 _In_ BOOLEAN FirstOfTd,
1093 _In_ BOOLEAN InDataStage) const
1094{
1095 ULONG Control;
1096
1097 RtlZeroMemory(Trb, sizeof(*Trb));
1098
1099 /* A TD's first TRB stays invalid until the whole TD is written */
1100 Control = static_cast<ULONG>(XhciTrbType::Link) << XHCI_TRB_TYPE_SHIFT;
1101 Control |= FirstOfTd ? (m_Cycle ^ 1) & XHCI_TRB_CYCLE : m_Cycle & XHCI_TRB_CYCLE;
1102
1103 if (m_Controller->HasErrata(XhciErrata::RingLinkTrbChain))
1105 else if (!FirstOfTd && InDataStage)
1107
1109 Trb->Dword[3] = Control;
1110}
1111
1112ULONG
1114 _In_ ULONG Bytes) const
1115{
1116 ULONG MaxPacket = m_Endpoint->MaxPacketSize();
1117
1118 /* xHCI 0.96 parts take no TD Size, so the count is not needed */
1119 if (m_Controller->m_Registers.VersionMajor() < 1 || MaxPacket == 0)
1120 return 0;
1121
1122 return (Bytes + MaxPacket - 1) / MaxPacket;
1123}
1124
1125ULONG
1127 _In_ ULONG PacketCount,
1128 _In_ ULONG BytesMappedSoFar,
1129 _In_ BOOLEAN LastTrbOfTd) const
1130{
1131 ULONG MaxPacket = m_Endpoint->MaxPacketSize();
1132 ULONG Sent;
1133 ULONG Remaining;
1134
1135 if (LastTrbOfTd || MaxPacket == 0 || m_Controller->m_Registers.VersionMajor() < 1)
1136 return 0;
1137
1138 Sent = BytesMappedSoFar / MaxPacket;
1139 if (Sent >= PacketCount)
1140 return 0;
1141
1142 Remaining = PacketCount - Sent;
1143 return min(Remaining, 31);
1144}
1145
1146VOID
1148{
1151}
1152
1153VOID
1155 _In_ ULONG ProcessorIndex)
1156{
1157 if (ProcessorIndex == XHCI_URB_NO_PROCESSOR)
1158 {
1160 return;
1161 }
1162
1165}
1166
1167ULONG
1169 _In_ PURB Urb)
1170{
1171 return *(PULONG)&Urb->UrbControlTransfer.hca;
1172}
1173
1174VOID
1176{
1177 /* The cycle bit flip must be visible before the controller is told to look */
1179 m_Device->RingDoorbell(m_Endpoint->Dci(), m_StreamId);
1180}
1181
1185 _In_ ULONG CompletionCode)
1186{
1187 switch (static_cast<XhciCompletionCode>(CompletionCode))
1188 {
1189 case XhciCompletionCode::Invalid:
1190 return XhciRingUsbdNotSet;
1191
1192 /* QUIRK: short packets always succeed, USBD_SHORT_TRANSFER_OK is not consulted */
1193 case XhciCompletionCode::Success:
1194 case XhciCompletionCode::ShortPacket:
1195 case XhciCompletionCode::Stopped:
1196 case XhciCompletionCode::StoppedShortPacket:
1197 return USBD_STATUS_SUCCESS;
1198
1199 case XhciCompletionCode::DataBufferError:
1201
1202 case XhciCompletionCode::BabbleDetected:
1203 case XhciCompletionCode::IsochBufferOverrun:
1205
1206 case XhciCompletionCode::StallError:
1207 return USBD_STATUS_STALL_PID;
1208
1209 case XhciCompletionCode::UsbTransactionError:
1210 case XhciCompletionCode::SplitTransactionError:
1212
1213 case XhciCompletionCode::MissedService:
1215
1216 case XhciCompletionCode::NoPingResponse:
1218
1219 case XhciCompletionCode::StoppedLengthInvalid:
1221
1222 case XhciCompletionCode::InvalidStreamType:
1224
1225 case XhciCompletionCode::InvalidStreamId:
1227
1228 default:
1229 /* QUIRK: any other code is reported as a transaction error */
1230 DPRINT1("Unexpected completion code %lu reported as a transaction error\n",
1231 CompletionCode);
1233 }
1234}
1235
1239{
1240 switch (UsbdStatus)
1241 {
1244 return STATUS_SUCCESS;
1245
1248
1254
1256 return STATUS_NOT_SUPPORTED;
1257
1259 return STATUS_NO_SUCH_DEVICE;
1260
1262 return STATUS_CANCELLED;
1263
1264 default:
1265 return STATUS_UNSUCCESSFUL;
1266 }
1267}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
unsigned char BOOLEAN
Definition: actypes.h:127
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedExchange
Definition: armddk.h:54
#define InterlockedDecrement
Definition: armddk.h:52
UINT Sent
Definition: arping.c:39
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
return Found
Definition: dirsup.c:1270
Definition: bufpool.h:45
static VOID Cleanup(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:502
static NTSTATUS EnableForwardProgress(_In_ XhciTransferRing *Ring, _In_ ULONG MaxTransferSize)
Definition: bulkio.cpp:466
static VOID RecoverTransfers(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:724
static VOID ResumeRingFill(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:606
static NTSTATUS Initialize(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:357
static EVT_WDF_DPC EvtCompletionDpc
Definition: bulkio.h:115
static BOOLEAN DoorbellRungSinceFill(_In_ const XhciTransferRing *Ring)
Definition: bulkio.cpp:740
static BOOLEAN OnTransferEvent(_In_opt_ XhciTransferRing *Ring, _In_ XhciController *Controller, _In_ const XHCI_TRB *Event)
Definition: bulkio.cpp:779
static EVT_WDF_IO_QUEUE_STATE ReadyNotification
Definition: bulkio.h:113
static VOID SegmentsArrived(_In_ XhciTransferRing *Ring, _In_ NTSTATUS Status)
Definition: bulkio.cpp:799
static EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE EvtIoCanceledOnQueue
Definition: bulkio.h:114
static BOOLEAN IsLikelyDuplicate(_In_ const XhciTransferRing *Ring, _In_ const XHCI_TRB *Event)
Definition: bulkio.cpp:762
static VOID Enable(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:401
static BOOLEAN HasQueuedWork(_In_ const XhciTransferRing *Ring)
Definition: bulkio.cpp:747
static VOID ConsumePendingEvents(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:705
static VOID Disable(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:422
static VOID SuspendRingFill(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:632
static VOID OnPipeHalted(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:666
static VOID AllowReclaimOnCancel(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:680
static VOID StoppedEventReceived(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:673
static VOID ReleaseParkedMapping(_In_ XhciTransferRing *Ring)
Definition: bulkio.cpp:443
static VOID Enable(_In_ XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:230
static VOID RecoverTransfers(_In_ XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:1258
static BOOLEAN HasQueuedWork(_In_ const XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:1295
static BOOLEAN OnTransferEvent(_In_opt_ XhciTransferRing *Ring, _In_ XhciController *Controller, _In_ const XHCI_TRB *Event)
Definition: ctrlxfer.cpp:1338
static VOID Disable(_In_ XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:237
static BOOLEAN DoorbellRungSinceFill(_In_ const XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:1278
static EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE EvtIoCanceledOnQueue
Definition: ctrlxfer.h:36
static EVT_WDF_IO_QUEUE_IO_DEFAULT EvtIoDefault
Definition: ctrlxfer.h:35
static NTSTATUS Initialize(_In_ XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:178
static VOID SuspendRingFill(_In_ XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:1194
static VOID ResumeRingFill(_In_ XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:1145
static VOID Cleanup(_In_ XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:286
static EVT_WDF_DPC EvtCompletionDpc
Definition: ctrlxfer.h:37
static NTSTATUS EnableForwardProgress(_In_ XhciTransferRing *Ring, _In_ ULONG MaxTransferSize)
Definition: ctrlxfer.cpp:260
static VOID AllowReclaimOnCancel(_In_ XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:1221
static VOID ConsumePendingEvents(_In_ XhciTransferRing *Ring)
Definition: ctrlxfer.cpp:1240
XhciCommonBuffer m_Buffers
Definition: hc.h:92
BOOLEAN HasErrata(_In_ XhciErrata Bit) const
Definition: hc.h:58
XhciInterrupters m_Interrupters
Definition: hc.h:94
XhciRegisters m_Registers
Definition: hc.h:91
ULONG Dci() const
Definition: epctx.cpp:257
VOID OnMappingStopped()
Definition: epctx.cpp:1237
USHORT MaxPacketSize() const
Definition: epctx.cpp:275
ULONG TargetForProcessor(_In_ ULONG ProcessorIndex) const
Definition: intr.cpp:1419
ULONG TargetForCurrentProcessor() const
Definition: intr.cpp:1413
static VOID AllowReclaimOnCancel(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:702
static VOID SuspendRingFill(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:661
static EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE EvtIoCanceledOnQueue
Definition: isoxfer.h:102
static BOOLEAN OnTransferEvent(_In_ XhciTransferRing *Ring, _In_ const XHCI_TRB *Event)
Definition: isoxfer.cpp:772
static VOID ReleaseParkedMapping(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:495
static VOID Enable(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:468
static VOID RecoverTransfers(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:734
static EVT_WDF_DPC EvtCompletionDpc
Definition: isoxfer.h:103
static NTSTATUS Initialize(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:422
static BOOLEAN HasQueuedWork(_In_ const XhciTransferRing *Ring)
Definition: isoxfer.cpp:757
static VOID OnClientPipeReset(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:691
static VOID Disable(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:479
static VOID ConsumePendingEvents(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:726
static BOOLEAN DoorbellRungSinceFill(_In_ const XhciTransferRing *Ring)
Definition: isoxfer.cpp:750
static VOID Cleanup(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:518
static VOID SegmentsArrived(_In_ XhciTransferRing *Ring, _In_ NTSTATUS Status)
Definition: isoxfer.cpp:785
static EVT_WDF_IO_QUEUE_STATE ReadyNotification
Definition: isoxfer.h:101
static VOID ResumeRingFill(_In_ XhciTransferRing *Ring)
Definition: isoxfer.cpp:636
UCHAR VersionMajor() const
Definition: mmio.cpp:615
XhciDmaBuffer * BorrowBounceBuffer()
Definition: xferring.cpp:1014
static XhciTransferRing * FromQueue(_In_ WDFQUEUE Queue)
Definition: xferring.cpp:308
BOOLEAN HasQueuedWork() const
Definition: xferring.cpp:775
XhciMapState ChangeMapState(_In_ BOOLEAN FromAny, _In_ XhciMapState From, _In_ XhciMapState To)
Definition: xferring.cpp:1048
VOID AllowReclaimOnCancel()
Definition: xferring.cpp:730
static XhciTransferRing * ReferenceLiveRing(_In_ XhciController *Controller, _In_ const XhciUsbDevice *Device, _In_ ULONG Dci)
Definition: xferring.cpp:419
ULONG m_InterrupterTarget
Definition: xferring.h:179
BOOLEAN IsControl() const
Definition: xferring.cpp:321
static ULONG UrbProcessorIndex(_In_ PURB Urb)
Definition: xferring.cpp:1168
WDFDPC m_CompletionDpc
Definition: xferring.h:176
KSPIN_LOCK m_Lock
Definition: xferring.h:177
WDFQUEUE m_Queue
Definition: xferring.h:175
ULONG64 DequeuePointerValue() const
Definition: xferring.cpp:670
static NTSTATUS NtStatusFromUsbdStatus(_In_ USBD_STATUS UsbdStatus)
Definition: xferring.cpp:1237
XhciController * m_Controller
Definition: xferring.h:170
BOOLEAN OnTransferEvent(_In_ const XHCI_TRB *Event)
Definition: xferring.cpp:787
ULONG64 EnqueuePointer() const
Definition: xferring.cpp:664
ULONG m_DoubleBufferSize
Definition: xferring.h:184
static NTSTATUS Create(_In_ XhciEndpoint *Endpoint, _In_ WDFOBJECT Parent, _In_ ULONG StreamId, _Out_ XhciTransferRing **Ring)
VOID ReturnBounceBuffer(_In_ XhciDmaBuffer *Buffer)
Definition: xferring.cpp:1039
BOOLEAN IsIsoch() const
Definition: xferring.cpp:334
LIST_ENTRY m_LiveLink
Definition: xferring.h:226
ULONG m_LastIndex
Definition: xferring.h:191
VOID ConsumePendingEvents()
Definition: xferring.cpp:741
ULONG m_MapRegisterCount
Definition: xferring.h:186
ULONG m_EnqueueIndex
Definition: xferring.h:190
WDFWORKITEM m_GrowthItem
Definition: xferring.h:233
VOID OnClientPipeReset()
Definition: xferring.cpp:714
ULONG TdSize(_In_ ULONG PacketCount, _In_ ULONG BytesMappedSoFar, _In_ BOOLEAN LastTrbOfTd) const
Definition: xferring.cpp:1126
VOID ReturnSegments(_Inout_ PLIST_ENTRY List, _In_ BOOLEAN ToHead)
Definition: xferring.cpp:989
ULONG64 SegmentBase() const
Definition: xferring.cpp:658
ULONG m_StreamId
Definition: xferring.h:173
NTSTATUS TakeSegments(_In_ ULONG Count, _Inout_ PLIST_ENTRY List)
Definition: xferring.cpp:950
PMDL m_ReservedMdl
Definition: xferring.h:181
VOID SuspendRingFill()
Definition: xferring.cpp:695
VOID DereferenceLive()
Definition: xferring.cpp:453
BOOLEAN m_Live
Definition: xferring.h:228
ULONG m_GrowthWanted
Definition: xferring.h:232
BOOLEAN IsLikelyDuplicate(_In_ const XHCI_TRB *Event) const
Definition: xferring.cpp:843
XhciUsbDevice * m_Device
Definition: xferring.h:171
ULONG PacketCount(_In_ ULONG Bytes) const
Definition: xferring.cpp:1113
BOOLEAN m_ForwardProgressQueue
Definition: xferring.h:231
ULONG m_SegmentSize
Definition: xferring.h:183
NTSTATUS EnsureFreeSegments(_In_ ULONG Count, _In_ BOOLEAN Async)
Definition: xferring.cpp:853
BOOLEAN DoorbellRungSinceFill() const
Definition: xferring.cpp:763
XhciControlRing Control
Definition: xferring.h:198
LIST_ENTRY m_FreeSegments
Definition: xferring.h:193
LIST_ENTRY m_DoubleBuffers
Definition: xferring.h:194
VOID InitializeRing()
Definition: xferring.cpp:648
PXHCI_TRB m_Trbs
Definition: xferring.h:189
VOID OnPipeHalted()
Definition: xferring.cpp:706
WDFQUEUE Queue() const
Definition: xferring.cpp:315
BOOLEAN m_GrowthQueued
Definition: xferring.h:230
static USBD_STATUS UsbdStatusFromCompletionCode(_In_ ULONG CompletionCode)
Definition: xferring.cpp:1184
VOID ResumeRingFill()
Definition: xferring.cpp:684
VOID StoppedEventReceived()
Definition: xferring.cpp:722
VOID RecoverTransfers()
Definition: xferring.cpp:752
XhciDmaBuffer * m_Segment
Definition: xferring.h:188
BOOLEAN IsBulkOrInterrupt() const
Definition: xferring.cpp:327
volatile LONG m_MapState
Definition: xferring.h:178
XhciEndpoint * m_Endpoint
Definition: xferring.h:172
ULONG m_MaxStageSize
Definition: xferring.h:185
VOID UpdateInterrupterTarget()
Definition: xferring.cpp:1147
BOOLEAN m_TypeReady
Definition: xferring.h:229
static BOOLEAN OnUntargetedTransferEvent(_In_ XhciController *Controller, _In_ const XHCI_TRB *Event)
Definition: xferring.cpp:803
VOID BuildLinkTrb(_Out_ PXHCI_TRB Trb, _In_ BOOLEAN FirstOfTd, _In_ BOOLEAN InDataStage) const
Definition: xferring.cpp:1090
volatile LONG m_EventUsers
Definition: xferring.h:227
ULONG m_TransferType
Definition: xferring.h:174
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
_In_ ULONG Attributes
Definition: dispmprt.h:1077
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define _IRQL_requires_max_(irql)
Definition: driverspecs.h:230
#define _IRQL_requires_(irql)
Definition: driverspecs.h:229
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define RemoveTailList(ListHead)
Definition: env_spec_w32.h:975
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
pFxWorkItem Enqueue()
Status
Definition: gdiplustypes.h:24
Previous
#define USB3_URB_RESERVED_RESOURCES
Definition: hubreq.cpp:15
WdfWorkItemEnqueue(WorkItem)
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
_In_opt_ PVOID _In_ PUCXHUB_WORKITEM WorkItem
Definition: hubucx.h:227
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT Endpoint
Definition: hubucx.h:238
#define InterlockedCompareExchange
Definition: interlocked.h:119
_In_ PIRP Irp
Definition: kse.h:79
_In_ UINT Bytes
Definition: mmcopy.h:9
#define ASSERT(a)
Definition: mode.c:44
static int Passive(const FTPCIPtr cip, struct sockaddr_in *saddr, int *weird)
Definition: ftp.c:939
unsigned __int64 ULONG64
Definition: imports.h:198
#define KeStallExecutionProcessor(MicroSeconds)
Definition: precomp.h:27
#define min(a, b)
Definition: monoChain.cc:55
#define KernelMode
Definition: asm.h:38
DWORD Interval
Definition: netstat.c:28
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
long LONG
Definition: pedump.c:60
_In_ ULONG MaxTransferSize
Definition: pipe.h:72
#define YieldProcessor
Definition: ke.h:48
#define KeQueryInterruptTime()
Definition: ke.h:37
FORCEINLINE VOID KeMemoryBarrier(VOID)
Definition: ke.h:58
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
LIST_ENTRY Link
Definition: dmapool.h:15
ULONG Size
Definition: dmapool.h:18
PHYSICAL_ADDRESS LogicalAddress
Definition: dmapool.h:17
PVOID VirtualAddress
Definition: dmapool.h:16
struct _IO_STACK_LOCATION::@5100::@5139 Others
union _IO_STACK_LOCATION::@1823 Parameters
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: usb.h:565
BOOLEAN AutomaticSerialization
Definition: wdfdpc.h:77
PFN_WDF_IO_QUEUE_IO_DEFAULT EvtIoDefault
Definition: wdfio.h:399
PFN_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE EvtIoCanceledOnQueue
Definition: wdfio.h:413
BOOLEAN AutomaticSerialization
Definition: wdfworkitem.h:79
#define STATUS_PENDING
Definition: telnetd.h:14
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
uint64_t ULONGLONG
Definition: typedefs.h:67
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXCONTROLLER * Controller
#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
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
LONGLONG QuadPart
Definition: typedefs.h:114
#define USB_ENDPOINT_TYPE_INTERRUPT
Definition: usb100.h:65
#define USB_ENDPOINT_TYPE_CONTROL
Definition: usb100.h:62
#define USB_ENDPOINT_TYPE_ISOCHRONOUS
Definition: usb100.h:63
#define USB_ENDPOINT_TYPE_BULK
Definition: usb100.h:64
#define USBD_STATUS_DATA_BUFFER_ERROR
Definition: usb.h:197
#define USBD_STATUS_DEVICE_GONE
Definition: usb.h:222
struct _URB * PURB
#define USBD_STATUS_ISO_NOT_ACCESSED_BY_HW
Definition: usb.h:226
#define USBD_STATUS_INVALID_STREAM_ID
Definition: usb.h:200
#define USBD_STATUS_INVALID_PIPE_HANDLE
Definition: usb.h:205
#define USBD_STATUS_CANCELED
Definition: usb.h:225
#define USBD_STATUS_STALL_PID
Definition: usb.h:183
#define USBD_STATUS_ISO_TD_ERROR
Definition: usb.h:227
#define USBD_STATUS_SUCCESS
Definition: usb.h:177
#define USBD_STATUS_INVALID_STREAM_TYPE
Definition: usb.h:199
#define USBD_STATUS_NOT_SUPPORTED
Definition: usb.h:213
#define USBD_STATUS_INSUFFICIENT_RESOURCES
Definition: usb.h:215
#define USBD_STATUS_NO_PING_RESPONSE
Definition: usb.h:198
#define USBD_STATUS_INVALID_PARAMETER
Definition: usb.h:203
#define USBD_STATUS_PORT_OPERATION_PENDING
Definition: usb.h:178
#define USBD_STATUS_XACT_ERROR
Definition: usb.h:195
LONG USBD_STATUS
Definition: usb.h:172
#define USBD_STATUS_INVALID_URB_FUNCTION
Definition: usb.h:202
#define USBD_STATUS_BABBLE_DETECTED
Definition: usb.h:196
#define USBD_STATUS_BAD_START_FRAME
Definition: usb.h:209
#define USBD_STATUS(Status)
Definition: usbdi.h:52
_In_ UCHAR EndpointType
Definition: usbdlib.h:252
_In_opt_ PUSB_CONFIGURATION_DESCRIPTOR _Inout_ PUSBD_INTERFACE_LIST_ENTRY _Outptr_ PURB * Urb
Definition: usbdlib.h:333
USHORT Count
Definition: userreq.cpp:200
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2231
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
FORCEINLINE VOID WDF_DPC_CONFIG_INIT(_Out_ PWDF_DPC_CONFIG Config, _In_ PFN_WDF_DPC EvtDpcFunc)
Definition: wdfdpc.h:83
EVT_WDF_DPC * PFN_WDF_DPC
Definition: wdfdpc.h:64
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY Policy
Definition: wdfinterrupt.h:653
@ WdfIoForwardProgressActionUseReservedRequest
Definition: wdfio.h:462
@ WdfIoForwardProgressActionFailRequest
Definition: wdfio.h:461
FORCEINLINE VOID WDF_IO_QUEUE_FORWARD_PROGRESS_POLICY_EXAMINE_INIT(_Out_ PWDF_IO_QUEUE_FORWARD_PROGRESS_POLICY Policy, _In_ ULONG TotalForwardProgressRequests, _In_ PFN_WDF_IO_WDM_IRP_FOR_FORWARD_PROGRESS EvtIoWdmIrpForForwardProgress)
Definition: wdfio.h:571
FORCEINLINE VOID WDF_IO_QUEUE_CONFIG_INIT(_Out_ PWDF_IO_QUEUE_CONFIG Config, _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType)
Definition: wdfio.h:426
@ WdfIoQueueDispatchSequential
Definition: wdfio.h:78
@ WdfIoQueueDispatchManual
Definition: wdfio.h:80
enum _WDF_IO_FORWARD_PROGRESS_ACTION WDF_IO_FORWARD_PROGRESS_ACTION
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
#define WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(_contexttype, _castingfunction)
Definition: wdfobject.h:350
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
_In_ NTSTATUS _In_ USBD_STATUS UsbdStatus
Definition: wdfusb.h:403
_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
static VOID FreeResources(VOID)
Definition: welcome.c:710
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
_Inout_ PVOID _In_ ULONG SegmentSize
Definition: exfuncs.h:1102
static EVT_WDF_OBJECT_CONTEXT_CLEANUP XhciRingQueueCleanup
Definition: xferring.cpp:30
static VOID NTAPI XhciRingPrependList(_Inout_ PLIST_ENTRY To, _Inout_ PLIST_ENTRY From)
Definition: xferring.cpp:72
static const ULONG XhciRingSegmentBytes
Definition: xferring.cpp:14
static EVT_WDF_WORKITEM XhciRingGrowthWorkItem
Definition: xferring.cpp:31
static LIST_ENTRY XhciLiveRings
Definition: xferring.cpp:39
static const ULONG XhciRingSingleSegmentStage
Definition: xferring.cpp:19
static const ULONG XhciRingDoubleBufferBytes
Definition: xferring.cpp:16
static EVT_WDF_IO_WDM_IRP_FOR_FORWARD_PROGRESS XhciRingExamineForwardProgress
Definition: xferring.cpp:32
static const ULONG XhciRingIdleWaitUs
Definition: xferring.cpp:23
static ULONG NTAPI XhciRingCountList(_In_ const LIST_ENTRY *Head)
Definition: xferring.cpp:44
static KSPIN_LOCK XhciLiveRingLock
Definition: xferring.cpp:38
static const ULONG XhciRingWideSegmentBytes
Definition: xferring.cpp:15
static VOID NTAPI XhciRingAppendList(_Inout_ PLIST_ENTRY To, _Inout_ PLIST_ENTRY From)
Definition: xferring.cpp:60
static const USBD_STATUS XhciRingUsbdNotSet
Definition: xferring.cpp:26
static const ULONG XhciRingIdleWaitMs
Definition: xferring.cpp:22
#define XHCI_URB_NO_PROCESSOR
Definition: xferring.h:15
XhciMapState
Definition: xferring.h:19
#define XHCI_SCT_PRIMARY_RING
Definition: xhcihw.h:613
#define XHCI_TRB_ENDPOINT_MASK
Definition: xhcihw.h:27
#define XHCI_TRB_TYPE_SHIFT
Definition: xhcihw.h:23
FORCEINLINE ULONG64 NTAPI XhciTrbPointer(_In_ const XHCI_TRB *Trb)
Definition: xhcihw.h:60
#define XHCI_TRB_ENDPOINT_SHIFT
Definition: xhcihw.h:26
#define XHCI_TRB_INTERRUPTER_MASK
Definition: xhcihw.h:611
struct _XHCI_TRB * PXHCI_TRB
#define XHCI_TRB_INTERRUPTER_SHIFT
Definition: xhcihw.h:610
#define XHCI_DEQUEUE_CYCLE
Definition: xhcihw.h:593
#define XHCI_DEQUEUE_SCT_SHIFT
Definition: xhcihw.h:612
#define XHCI_EVENT_DATA_TYPE_MASK
Definition: xhcihw.h:324
#define XHCI_TRB_CYCLE
Definition: xhcihw.h:22
struct _XHCI_TRB XHCI_TRB
#define XHCI_TRB_CHAIN
Definition: xhcihw.h:609
XhciCompletionCode
Definition: xhcihw.h:110
FORCEINLINE ULONG NTAPI XhciTrbSlotId(_In_ const XHCI_TRB *Trb)
Definition: xhcihw.h:51
FORCEINLINE LARGE_INTEGER NTAPI XhciRelativeMs(_In_ ULONG Milliseconds)
Definition: xhciutil.h:137
FORCEINLINE VOID NTAPI XhciClearListEntry(_Out_ PLIST_ENTRY Entry)
Definition: xhciutil.h:117