14#define XHCI_POOL_PAGE_BYTES 4096
15#define XHCI_POOL_SMALL_BYTES 512
16#define XHCI_POOL_DMA_LIMIT 0xFFFE00
48 XhciPoolOwner(
WorkItem)->Pool->GrowthWork();
57 XhciPoolOwner(
WorkItem)->Pool->ReclaimWork();
70 Pool->EnablerCleanup();
114 return CreateEnabler();
125 DPRINT1(
"DMA pool prepared before it was created\n");
133 return CreateEnabler();
138XhciCommonBuffer::CreateEnabler()
144 WDFDMAENABLER Enabler;
168 DPRINT1(
"WdfDmaEnablerCreate failed 0x%lx (64 bit %u)\n",
199 DPRINT1(
"DMA pool work item creation failed 0x%lx\n",
Status);
215 XhciPoolOwner(Enabler)->Pool =
this;
221 DPRINT(
"DMA pool ready: max transfer 0x%lx, %lu map registers, %lu large, %lu small\n",
255XhciCommonBuffer::Flush()
266 DPRINT1(
"DMA pool growth still running after 60 s, still waiting\n");
285XhciCommonBuffer::AddSegments(
303 Pages = (
Count + PerPage - 1) / PerPage;
314 DPRINT1(
"WdfCommonBufferCreate failed 0x%lx, %lu byte class stays short\n",
319 Logical = WdfCommonBufferGetAlignedLogicalAddress(
CommonBuffer);
322 DPRINT1(
"Common buffer at 0x%I64x is not page aligned, dropped\n", Logical.
QuadPart);
330 Page->SegmentCount = PerPage;
352 Class->Total += PerPage;
353 Class->Available += PerPage;
359XhciCommonBuffer::Grab(
377 for (Left =
Count; Left != 0; Left--)
414XhciCommonBuffer::Acquire(
426 DPRINT1(
"Common buffer of %lu bytes is larger than a page\n",
Size);
447 DPRINT1(
"No free %lu byte common buffer\n",
Class->SegmentSize);
458XhciCommonBuffer::AcquireList(
471 DPRINT1(
"Common buffer list of %lu bytes each is larger than a page\n",
Size);
495 DPRINT1(
"Not enough free %lu byte common buffers for %lu\n",
Class->SegmentSize,
Count);
507XhciCommonBuffer::ReturnFree(
534XhciCommonBuffer::Free(
545XhciCommonBuffer::FreeList(
561XhciCommonBuffer::QueueGrowth()
587XhciCommonBuffer::GrowthWork()
601 AddSegments(&
m_Small, SmallCount);
602 AddSegments(&
m_Large, LargeCount);
613XhciCommonBuffer::ShrinkClass(
625 if (
Page->ReleaseQueued)
676XhciCommonBuffer::ReclaimWork()
706 DPRINT1(
"DMA pool torn down with buffers still owned: small %lu of %lu, large %lu of %lu\n",
void FreeList(LOCATIONITEM *pItems)
Pool(int, int, const char *)
NTSTATUS Create(_In_ XhciController *Controller)
PDMA_ADAPTER DmaAdapter() const
_In_ ULONG _Out_ PLIST_ENTRY _Out_ PBOOLEAN NeedGrow
WDFDMAENABLER DmaEnabler() const
WDFWORKITEM m_ReclaimItem
BOOLEAN m_HoldsUcxReference
SizeClass * ClassForSize(_In_ ULONG Size)
ULONG m_GrowthOutstanding
ULONG MapRegisterCount() const
XhciController * m_Controller
_In_ ULONG _Out_ PLIST_ENTRY Taken
VOID SetErrata(_In_ XhciErrata Bit)
XhciRegisters m_Registers
BOOLEAN Addressing64() const
#define _Requires_lock_held_(lock)
#define NT_SUCCESS(StatCode)
static EVT_WDF_WORKITEM XhciPoolGrowthWorkItem
#define XHCI_POOL_SMALL_BYTES
struct _XHCI_POOL_OWNER * PXHCI_POOL_OWNER
#define XHCI_POOL_PAGE_BYTES
static EVT_WDF_OBJECT_CONTEXT_CLEANUP XhciPoolEnablerCleanup
struct _XHCI_POOL_OWNER XHCI_POOL_OWNER
struct _XHCI_POOL_PAGE * PXHCI_POOL_PAGE
#define XHCI_POOL_DMA_LIMIT
struct _XHCI_POOL_PAGE XHCI_POOL_PAGE
static EVT_WDF_WORKITEM XhciPoolReclaimWorkItem
static VOID NTAPI XhciPoolInitClass(_Out_ PLIST_ENTRY FreeList, _Out_ PLIST_ENTRY PageList)
#define _IRQL_requires_max_(irql)
#define _IRQL_requires_(irql)
#define RemoveEntryList(Entry)
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
#define KeInitializeEvent(pEvt, foo, foo2)
#define KeSetEvent(pEvt, foo, foo2)
#define KeGetCurrentIrql()
#define RemoveHeadList(ListHead)
#define InitializeListHead(ListHead)
#define KeInitializeSpinLock(sl)
VOID NTAPI KeClearEvent(IN PKEVENT Event)
WdfWorkItemEnqueue(WorkItem)
_In_opt_ PVOID _In_ PUCXHUB_WORKITEM WorkItem
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
struct _LIST_ENTRY * Flink
BOOLEAN AutomaticSerialization
WDFCOMMONBUFFER CommonBuffer
XhciDmaBuffer Segments[ANYSIZE_ARRAY]
#define FIELD_OFFSET(t, f)
#define RtlZeroMemory(Destination, Length)
#define CONTAINING_RECORD(address, type, field)
_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
#define STATUS_INVALID_DEVICE_STATE
#define STATUS_INSUFFICIENT_RESOURCES
_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
@ WDF_DMA_ENABLER_CONFIG_NO_SGLIST_PREALLOCATION
@ WdfDmaProfileScatterGatherDuplex
@ WdfDmaProfileScatterGather64Duplex
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
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
#define WdfObjectReference(Handle)
#define WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(_contexttype, _castingfunction)
#define WdfObjectDereference(Handle)
_Must_inspect_result_ _In_ WDFCMRESLIST List
FORCEINLINE VOID WDF_WORKITEM_CONFIG_INIT(_Out_ PWDF_WORKITEM_CONFIG Config, _In_ PFN_WDF_WORKITEM EvtWorkItemFunc)
#define BYTES_TO_PAGES(Size)
FORCEINLINE LARGE_INTEGER NTAPI XhciRelativeMs(_In_ ULONG Milliseconds)
FORCEINLINE VOID NTAPI XhciClearListEntry(_Out_ PLIST_ENTRY Entry)