ReactOS 0.4.17-dev-1281-g065abb3
dmapool.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: DMA enabler and the pool of zeroed common buffers
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/* Every pool page is one 4 KB common buffer split into 1 or 8 segments */
14#define XHCI_POOL_PAGE_BYTES 4096
15#define XHCI_POOL_SMALL_BYTES 512
16#define XHCI_POOL_DMA_LIMIT 0xFFFE00
17
19typedef struct _XHCI_POOL_PAGE
20{
22 WDFCOMMONBUFFER CommonBuffer;
27
29
31typedef struct _XHCI_POOL_OWNER
32{
35
37
38static EVT_WDF_WORKITEM XhciPoolGrowthWorkItem;
39static EVT_WDF_WORKITEM XhciPoolReclaimWorkItem;
40static EVT_WDF_OBJECT_CONTEXT_CLEANUP XhciPoolEnablerCleanup;
41
42static
43VOID
46 _In_ WDFWORKITEM WorkItem)
47{
48 XhciPoolOwner(WorkItem)->Pool->GrowthWork();
49}
50
51static
52VOID
55 _In_ WDFWORKITEM WorkItem)
56{
57 XhciPoolOwner(WorkItem)->Pool->ReclaimWork();
58}
59
60static
61VOID
65{
66 XhciCommonBuffer* Pool = XhciPoolOwner(Object)->Pool;
67
68 /* Creation failed before the enabler was handed to the pool */
69 if (Pool != NULL)
70 Pool->EnablerCleanup();
71}
72
73static
74VOID
78 _Out_ PLIST_ENTRY PageList)
79{
81 InitializeListHead(PageList);
82}
83
88{
89 if (!m_Initialized)
90 {
95
96 /* Pool sizing policy; the test signing overrides are not supported */
100 m_Small.GrowBy = 8;
101 m_Small.KeepAtLeast = 16;
102
105 m_Large.GrowBelow = 1;
106 m_Large.GrowBy = 1;
108
110 }
111
112 /* The enabler needs AC64, so it waits for the registers when called early */
113 if (m_Enabler == NULL && Controller->IsAccessible())
114 return CreateEnabler();
115
116 return STATUS_SUCCESS;
117}
118
122{
123 if (!m_Initialized)
124 {
125 DPRINT1("DMA pool prepared before it was created\n");
127 }
128
129 /* The enabler and its pages live as long as the WDFDEVICE */
130 if (m_Enabler != NULL)
131 return STATUS_SUCCESS;
132
133 return CreateEnabler();
134}
135
138XhciCommonBuffer::CreateEnabler()
139{
142 WDF_WORKITEM_CONFIG ItemConfig;
143 WDF_DMA_PROFILE Profile;
144 WDFDMAENABLER Enabler;
145 size_t Fragment;
147
149 {
151 }
152 else
153 {
154 m_Controller->SetErrata(XhciErrata::RegSplit64BitAccess);
156 }
157
158 /* QUIRK: the limit is a multiple of 512 but not of 1024 */
161
163 Attributes.EvtCleanupCallback = XhciPoolEnablerCleanup;
164
165 Status = WdfDmaEnablerCreate(m_Controller->m_Device, &Config, &Attributes, &Enabler);
166 if (!NT_SUCCESS(Status))
167 {
168 DPRINT1("WdfDmaEnablerCreate failed 0x%lx (64 bit %u)\n",
170 return Status;
171 }
172
173 Fragment = WdfDmaEnablerGetFragmentLength(Enabler, WdfDmaDirectionReadFromDevice);
174 m_MaxDmaSize = (ULONG)min(Fragment, (size_t)XHCI_POOL_DMA_LIMIT);
176 m_Adapter = WdfDmaEnablerWdmGetDmaAdapter(Enabler, WdfDmaDirectionReadFromDevice);
177
178 /* Both work items exist before any page so a failure only has the enabler to undo */
180 ItemConfig.AutomaticSerialization = FALSE;
182 Attributes.ParentObject = Enabler;
183
184 Status = WdfWorkItemCreate(&ItemConfig, &Attributes, &m_ReclaimItem);
185 if (NT_SUCCESS(Status))
186 {
187 XhciPoolOwner(m_ReclaimItem)->Pool = this;
188
190 ItemConfig.AutomaticSerialization = FALSE;
191 Status = WdfWorkItemCreate(&ItemConfig, &Attributes, &m_GrowthItem);
192 if (NT_SUCCESS(Status))
193 XhciPoolOwner(m_GrowthItem)->Pool = this;
194 }
195
196 /* QUIRK: the reclaim item is optional at run time, yet failing to create it fails the pool */
197 if (!NT_SUCCESS(Status))
198 {
199 DPRINT1("DMA pool work item creation failed 0x%lx\n", Status);
202 m_Adapter = NULL;
203 WdfObjectDelete(Enabler);
204 return Status;
205 }
206
207 /* The enabler cleanup reads this object, so keep the UCXCONTROLLER context alive until then */
208 if (m_Controller->m_Ucx != NULL)
209 {
212 }
213
214 m_Enabler = Enabler;
215 XhciPoolOwner(Enabler)->Pool = this;
216
217 /* Short initial lists are not fatal; acquire grows them on demand */
218 AddSegments(&m_Large, 4);
219 AddSegments(&m_Small, 8);
220
221 DPRINT("DMA pool ready: max transfer 0x%lx, %lu map registers, %lu large, %lu small\n",
223 return STATUS_SUCCESS;
224}
225
226VOID
228{
229 /* Nothing to do: the pool survives ReleaseHardware and dies with the enabler */
230}
231
233VOID
235{
236 Flush();
237}
238
240VOID
242{
243 Flush();
244}
245
247VOID
249{
250 Flush();
251}
252
254VOID
255XhciCommonBuffer::Flush()
256{
258
259 if (!m_Initialized)
260 return;
261
262 Timeout = XhciRelativeMs(60 * 1000);
263
264 /* Keep waiting, but log each time the timeout expires */
266 DPRINT1("DMA pool growth still running after 60 s, still waiting\n");
267
268 if (m_ReclaimItem != NULL)
269 WdfWorkItemFlush(m_ReclaimItem);
270}
271
275{
277 return &m_Small;
279 return &m_Large;
280 return NULL;
281}
282
284VOID
285XhciCommonBuffer::AddSegments(
286 _Inout_ SizeClass* Class,
288{
290 WDFCOMMONBUFFER CommonBuffer;
291 PHYSICAL_ADDRESS Logical;
293 PUCHAR Virtual;
294 ULONG PerPage;
295 ULONG Pages;
296 ULONG Index;
298
299 if (m_Enabler == NULL || Count == 0)
300 return;
301
302 PerPage = XHCI_POOL_PAGE_BYTES / Class->SegmentSize;
303 Pages = (Count + PerPage - 1) / PerPage;
304
305 while (Pages-- != 0)
306 {
308 Attributes.ContextSizeOverride = FIELD_OFFSET(XHCI_POOL_PAGE, Segments) +
309 PerPage * sizeof(XhciDmaBuffer);
310
311 Status = WdfCommonBufferCreate(m_Enabler, XHCI_POOL_PAGE_BYTES, &Attributes, &CommonBuffer);
312 if (!NT_SUCCESS(Status))
313 {
314 DPRINT1("WdfCommonBufferCreate failed 0x%lx, %lu byte class stays short\n",
315 Status, Class->SegmentSize);
316 return;
317 }
318
319 Logical = WdfCommonBufferGetAlignedLogicalAddress(CommonBuffer);
320 if ((Logical.QuadPart & (XHCI_POOL_PAGE_BYTES - 1)) != 0)
321 {
322 DPRINT1("Common buffer at 0x%I64x is not page aligned, dropped\n", Logical.QuadPart);
324 continue;
325 }
326
327 Virtual = (PUCHAR)WdfCommonBufferGetAlignedVirtualAddress(CommonBuffer);
328 Page = XhciPoolPageFromBuffer(CommonBuffer);
329 Page->CommonBuffer = CommonBuffer;
330 Page->SegmentCount = PerPage;
331
332 /* A page nobody used yet is a reclaim candidate right away */
333 Page->ReleaseQueued = TRUE;
334
335 for (Index = 0; Index < PerPage; Index++)
336 {
337 XhciDmaBuffer* Segment = &Page->Segments[Index];
338
339 Segment->VirtualAddress = Virtual + Index * Class->SegmentSize;
340 Segment->LogicalAddress.QuadPart = Logical.QuadPart + Index * Class->SegmentSize;
341 Segment->Size = Class->SegmentSize;
342 Segment->Page = Page;
343 Segment->Owned = FALSE;
344 }
345
347
348 m_PagesTotal++;
349 InsertTailList(&Class->PageList, &Page->Link);
350 for (Index = 0; Index < PerPage; Index++)
351 InsertTailList(&Class->FreeList, &Page->Segments[Index].Link);
352 Class->Total += PerPage;
353 Class->Available += PerPage;
354 }
355}
356
359XhciCommonBuffer::Grab(
360 _Inout_ SizeClass* Class,
362 _Out_ PLIST_ENTRY Taken,
363 _Out_ PBOOLEAN NeedGrow)
364{
366 BOOLEAN Got = FALSE;
367
369
370 {
372
373 if (Class->Available >= Count)
374 {
375 ULONG Left;
376
377 for (Left = Count; Left != 0; Left--)
378 {
381
383 Segment->Owned = TRUE;
384
386 if (Page->ReleaseQueued)
387 {
388 Page->ReleaseQueued = FALSE;
389 m_PagesInUse++;
390 }
391
393 }
394
395 Class->Available -= Count;
396 Got = TRUE;
397 }
398
399 *NeedGrow = (Class->Available < Class->GrowBelow);
400 }
401
402 /* Nobody else can reach these segments now, so zero them outside the lock */
403 for (Entry = Taken->Flink; Entry != Taken; Entry = Entry->Flink)
404 {
406 RtlZeroMemory(Segment->VirtualAddress, Segment->Size);
407 }
408
409 return Got;
410}
411
414XhciCommonBuffer::Acquire(
416{
419 SizeClass* Class;
421 BOOLEAN Got;
422
424 if (Class == NULL)
425 {
426 DPRINT1("Common buffer of %lu bytes is larger than a page\n", Size);
427 return NULL;
428 }
429
430 Got = Grab(Class, 1, &Taken, &NeedGrow);
431 if (!Got || NeedGrow)
432 {
434 {
435 AddSegments(Class, (Got ? 0 : 1) + (NeedGrow ? Class->GrowBy : 0));
436 if (!Got)
437 Got = Grab(Class, 1, &Taken, &NeedGrow);
438 }
439 else
440 {
441 QueueGrowth();
442 }
443 }
444
445 if (!Got)
446 {
447 DPRINT1("No free %lu byte common buffer\n", Class->SegmentSize);
448 return NULL;
449 }
450
453 return Buffer;
454}
455
458XhciCommonBuffer::AcquireList(
462{
464 SizeClass* Class;
466 BOOLEAN Got;
467
469 if (Class == NULL)
470 {
471 DPRINT1("Common buffer list of %lu bytes each is larger than a page\n", Size);
473 }
474
475 if (Count == 0)
476 return STATUS_SUCCESS;
477
478 Got = Grab(Class, Count, &Taken, &NeedGrow);
479 if (!Got || NeedGrow)
480 {
482 {
483 AddSegments(Class, (Got ? 0 : Count) + (NeedGrow ? Class->GrowBy : 0));
484 if (!Got)
485 Got = Grab(Class, Count, &Taken, &NeedGrow);
486 }
487 else
488 {
489 QueueGrowth();
490 }
491 }
492
493 if (!Got)
494 {
495 DPRINT1("Not enough free %lu byte common buffers for %lu\n", Class->SegmentSize, Count);
497 }
498
499 while (!IsListEmpty(&Taken))
501
502 return STATUS_SUCCESS;
503}
504
507XhciCommonBuffer::ReturnFree(
509{
510 SizeClass* Class;
511
512 if (Buffer->Size == XHCI_POOL_SMALL_BYTES)
513 Class = &m_Small;
514 else if (Buffer->Size == XHCI_POOL_PAGE_BYTES)
515 Class = &m_Large;
516 else
517 return FALSE;
518
519 if (!Buffer->Owned)
520 {
521 DPRINT1("Common buffer %p freed twice\n", Buffer);
522 return TRUE;
523 }
524
525 /* The most recently used segment goes first so it is reused while still cached */
526 Buffer->Owned = FALSE;
527 InsertHeadList(&Class->FreeList, &Buffer->Link);
528 Class->Available++;
529 return TRUE;
530}
531
533VOID
534XhciCommonBuffer::Free(
536{
538
539 if (!ReturnFree(Buffer))
540 DPRINT1("Common buffer %p has bad size %lu, dropped\n", Buffer, Buffer->Size);
541}
542
544VOID
545XhciCommonBuffer::FreeList(
547{
549
550 while (!IsListEmpty(List))
551 {
553
554 if (!ReturnFree(Buffer))
555 DPRINT1("Common buffer %p in list has bad size %lu, dropped\n", Buffer, Buffer->Size);
556 }
557}
558
560VOID
561XhciCommonBuffer::QueueGrowth()
562{
564
565 if (m_GrowthItem == NULL)
566 return;
567
568 {
570
571 /* Overlapping growth items share one idle event, so count them */
572 if (!m_GrowthQueued)
573 {
577 Enqueue = TRUE;
578 }
579 }
580
581 if (Enqueue)
583}
584
586VOID
587XhciCommonBuffer::GrowthWork()
588{
589 ULONG SmallCount;
590 ULONG LargeCount;
591
592 {
594
595 /* From here on a new request has to queue the item again */
597 SmallCount = (m_Small.Available < m_Small.GrowBelow) ? m_Small.GrowBy : 0;
598 LargeCount = (m_Large.Available < m_Large.GrowBelow) ? m_Large.GrowBy : 0;
599 }
600
601 AddSegments(&m_Small, SmallCount);
602 AddSegments(&m_Large, LargeCount);
603
605
607 if (m_GrowthOutstanding == 0)
609}
610
612VOID
613XhciCommonBuffer::ShrinkClass(
614 _Inout_ SizeClass* Class)
615{
616 PLIST_ENTRY Entry = Class->PageList.Flink;
617
618 while (Entry != &Class->PageList && Class->Available > Class->KeepAtLeast)
619 {
621 ULONG Index;
622
623 Entry = Entry->Flink;
624
625 if (Page->ReleaseQueued)
626 {
627 /* Unused since the last tick: every segment is on the free list */
628 for (Index = 0; Index < Page->SegmentCount; Index++)
629 RemoveEntryList(&Page->Segments[Index].Link);
630
631 Class->Available -= Page->SegmentCount;
632 Class->Total -= Page->SegmentCount;
633 RemoveEntryList(&Page->Link);
636 continue;
637 }
638
639 for (Index = 0; Index < Page->SegmentCount; Index++)
640 {
641 if (Page->Segments[Index].Owned)
642 break;
643 }
644
645 /* Fully free now: freed on the next tick unless somebody takes a segment first */
646 if (Index == Page->SegmentCount)
647 {
648 Page->ReleaseQueued = TRUE;
649 m_PagesInUse--;
650 }
651 }
652}
653
654VOID
656{
657 BOOLEAN Reclaim;
658
659 if (m_ReclaimItem == NULL)
660 return;
661
662 {
664
665 ShrinkClass(&m_Small);
666 ShrinkClass(&m_Large);
667 Reclaim = !IsListEmpty(&m_ReclaimList);
668 }
669
670 if (Reclaim)
672}
673
675VOID
676XhciCommonBuffer::ReclaimWork()
677{
678 LIST_ENTRY Pages;
679
680 InitializeListHead(&Pages);
681
682 {
684
685 while (!IsListEmpty(&m_ReclaimList))
687
689 m_ReclaimPages = 0;
690 }
691
692 while (!IsListEmpty(&Pages))
693 {
695
696 /* The header is the buffer's context, so it goes away with the buffer */
697 WdfObjectDelete(Page->CommonBuffer);
698 }
699}
700
701VOID
703{
705 {
706 DPRINT1("DMA pool torn down with buffers still owned: small %lu of %lu, large %lu of %lu\n",
709 ASSERT(FALSE);
710 }
711
712 /* KMDF frees the pages and work items as children of the enabler */
713 m_Enabler = NULL;
714 m_Adapter = NULL;
722
723 /* Last touch of this object; the controller context may go away right after */
725 {
728 }
729}
730
731WDFDMAENABLER
733{
734 return m_Enabler;
735}
736
739{
740 return m_Adapter;
741}
742
743ULONG
745{
746 return m_MaxDmaSize;
747}
748
749ULONG
751{
752 return m_MapRegisters;
753}
void FreeList(LOCATIONITEM *pItems)
Definition: CSearchBar.cpp:95
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
Definition: bufpool.h:50
Pool(int, int, const char *)
Definition: bufpool.cc:49
ULONG m_MaxDmaSize
Definition: dmapool.h:133
NTSTATUS Create(_In_ XhciController *Controller)
PDMA_ADAPTER m_Adapter
Definition: dmapool.h:132
PDMA_ADAPTER DmaAdapter() const
Definition: dmapool.cpp:738
VOID EnablerCleanup()
Definition: dmapool.cpp:702
_In_ ULONG _Out_ PLIST_ENTRY _Out_ PBOOLEAN NeedGrow
Definition: dmapool.h:112
NTSTATUS Prepare()
VOID Rebalance()
Definition: dmapool.cpp:655
ULONG m_PagesInUse
Definition: dmapool.h:142
WDFDMAENABLER DmaEnabler() const
Definition: dmapool.cpp:732
_In_ ULONG Count
Definition: dmapool.h:50
ULONG m_ReclaimPages
Definition: dmapool.h:145
ULONG m_PagesTotal
Definition: dmapool.h:141
WDFWORKITEM m_GrowthItem
Definition: dmapool.h:148
WDFWORKITEM m_ReclaimItem
Definition: dmapool.h:146
BOOLEAN m_Initialized
Definition: dmapool.h:135
LIST_ENTRY m_ReclaimList
Definition: dmapool.h:144
ULONG m_MapRegisters
Definition: dmapool.h:134
ULONG MaxDmaSize() const
Definition: dmapool.cpp:744
BOOLEAN m_GrowthQueued
Definition: dmapool.h:149
SizeClass m_Large
Definition: dmapool.h:140
BOOLEAN m_HoldsUcxReference
Definition: dmapool.h:136
SizeClass * ClassForSize(_In_ ULONG Size)
Definition: dmapool.cpp:273
WDFDMAENABLER m_Enabler
Definition: dmapool.h:131
ULONG m_GrowthOutstanding
Definition: dmapool.h:150
SizeClass m_Small
Definition: dmapool.h:139
ULONG MapRegisterCount() const
Definition: dmapool.cpp:750
XhciController * m_Controller
Definition: dmapool.h:130
KSPIN_LOCK m_Lock
Definition: dmapool.h:138
KEVENT m_GrowthIdle
Definition: dmapool.h:151
_In_ ULONG _Out_ PLIST_ENTRY Taken
Definition: dmapool.h:111
WDFDEVICE m_Device
Definition: hc.h:85
UCXCONTROLLER m_Ucx
Definition: hc.h:87
VOID SetErrata(_In_ XhciErrata Bit)
Definition: hc.cpp:183
XhciRegisters m_Registers
Definition: hc.h:91
BOOLEAN Addressing64() const
Definition: mmio.cpp:663
#define _Requires_lock_held_(lock)
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
_In_ ULONG Attributes
Definition: dispmprt.h:1077
#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
static EVT_WDF_WORKITEM XhciPoolGrowthWorkItem
Definition: dmapool.cpp:38
#define XHCI_POOL_SMALL_BYTES
Definition: dmapool.cpp:15
struct _XHCI_POOL_OWNER * PXHCI_POOL_OWNER
#define XHCI_POOL_PAGE_BYTES
Definition: dmapool.cpp:14
static EVT_WDF_OBJECT_CONTEXT_CLEANUP XhciPoolEnablerCleanup
Definition: dmapool.cpp:40
struct _XHCI_POOL_OWNER XHCI_POOL_OWNER
struct _XHCI_POOL_PAGE * PXHCI_POOL_PAGE
#define XHCI_POOL_DMA_LIMIT
Definition: dmapool.cpp:16
struct _XHCI_POOL_PAGE XHCI_POOL_PAGE
static EVT_WDF_WORKITEM XhciPoolReclaimWorkItem
Definition: dmapool.cpp:39
static VOID NTAPI XhciPoolInitClass(_Out_ PLIST_ENTRY FreeList, _Out_ PLIST_ENTRY PageList)
Definition: dmapool.cpp:76
#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
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#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 KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
@ Flush
Definition: fatprocs.h:1055
pFxWorkItem Enqueue()
Status
Definition: gdiplustypes.h:24
WdfWorkItemEnqueue(WorkItem)
_In_opt_ PVOID _In_ PUCXHUB_WORKITEM WorkItem
Definition: hubucx.h:227
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define min(a, b)
Definition: monoChain.cc:55
#define KernelMode
Definition: asm.h:38
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
@ NotificationEvent
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1287
static ULONG Timeout
Definition: ping.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
BOOLEAN AutomaticSerialization
Definition: wdfworkitem.h:79
XhciCommonBuffer * Pool
Definition: dmapool.cpp:33
WDFCOMMONBUFFER CommonBuffer
Definition: dmapool.cpp:22
BOOLEAN ReleaseQueued
Definition: dmapool.cpp:23
LIST_ENTRY Link
Definition: dmapool.cpp:21
XhciDmaBuffer Segments[ANYSIZE_ARRAY]
Definition: dmapool.cpp:25
ULONG SegmentCount
Definition: dmapool.cpp:24
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define ANYSIZE_ARRAY
Definition: typedefs.h:46
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXCONTROLLER * Controller
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG Config
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#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
USHORT Count
Definition: userreq.cpp:200
WdfObjectDelete(String)
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFCOMMONBUFFER * CommonBuffer
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
@ WDF_DMA_ENABLER_CONFIG_NO_SGLIST_PREALLOCATION
@ WdfDmaProfileScatterGatherDuplex
Definition: wdfdmaenabler.h:58
@ WdfDmaProfileScatterGather64Duplex
Definition: wdfdmaenabler.h:59
FORCEINLINE VOID WDF_DMA_ENABLER_CONFIG_INIT(_Out_ PWDF_DMA_ENABLER_CONFIG Config, _In_ WDF_DMA_PROFILE Profile, _In_ size_t MaximumLength)
WDF_EXTERN_C_START enum _WDF_DMA_PROFILE WDF_DMA_PROFILE
@ WdfDmaDirectionReadFromDevice
Definition: wdfdmaenabler.h:65
#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 WdfObjectDereference(Handle)
Definition: wdfobject.h:826
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
FORCEINLINE VOID WDF_WORKITEM_CONFIG_INIT(_Out_ PWDF_WORKITEM_CONFIG Config, _In_ PFN_WDF_WORKITEM EvtWorkItemFunc)
Definition: wdfworkitem.h:85
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ Executive
Definition: ketypes.h:467
#define BYTES_TO_PAGES(Size)
FORCEINLINE LARGE_INTEGER NTAPI XhciRelativeMs(_In_ ULONG Milliseconds)
Definition: xhciutil.h:137
FORCEINLINE VOID NTAPI XhciClearListEntry(_Out_ PLIST_ENTRY Entry)
Definition: xhciutil.h:117