ReactOS 0.4.17-dev-1281-g065abb3
dmapool.cpp File Reference
#include "xhcidrv.h"
#include <debug.h>
Include dependency graph for dmapool.cpp:

Go to the source code of this file.

Classes

struct  _XHCI_POOL_PAGE
 
struct  _XHCI_POOL_OWNER
 

Macros

#define NDEBUG
 
#define XHCI_POOL_PAGE_BYTES   4096
 
#define XHCI_POOL_SMALL_BYTES   512
 
#define XHCI_POOL_DMA_LIMIT   0xFFFE00
 

Typedefs

typedef struct _XHCI_POOL_PAGE XHCI_POOL_PAGE
 
typedef struct _XHCI_POOL_PAGE * PXHCI_POOL_PAGE
 
typedef struct _XHCI_POOL_OWNER XHCI_POOL_OWNER
 
typedef struct _XHCI_POOL_OWNER * PXHCI_POOL_OWNER
 

Functions

 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME (XHCI_POOL_PAGE, XhciPoolPageFromBuffer)
 
 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME (XHCI_POOL_OWNER, XhciPoolOwner)
 
static VOID NTAPI XhciPoolGrowthWorkItem (_In_ WDFWORKITEM WorkItem)
 
static VOID NTAPI XhciPoolReclaimWorkItem (_In_ WDFWORKITEM WorkItem)
 
static VOID NTAPI XhciPoolEnablerCleanup (_In_ WDFOBJECT Object)
 
static VOID NTAPI XhciPoolInitClass (_Out_ PLIST_ENTRY FreeList, _Out_ PLIST_ENTRY PageList)
 
 _IRQL_requires_ (PASSIVE_LEVEL) NTSTATUS XhciCommonBuffer
 Sends a synchronous IOCTL to the specified device object.
 
 _IRQL_requires_max_ (DISPATCH_LEVEL) BOOLEAN XhciCommonBuffer
 
 _Requires_lock_held_ (m_Lock) BOOLEAN XhciCommonBuffer
 

Variables

static EVT_WDF_WORKITEM XhciPoolGrowthWorkItem
 
static EVT_WDF_WORKITEM XhciPoolReclaimWorkItem
 
static EVT_WDF_OBJECT_CONTEXT_CLEANUP XhciPoolEnablerCleanup
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 10 of file dmapool.cpp.

◆ XHCI_POOL_DMA_LIMIT

#define XHCI_POOL_DMA_LIMIT   0xFFFE00

Definition at line 16 of file dmapool.cpp.

◆ XHCI_POOL_PAGE_BYTES

#define XHCI_POOL_PAGE_BYTES   4096

Definition at line 14 of file dmapool.cpp.

◆ XHCI_POOL_SMALL_BYTES

#define XHCI_POOL_SMALL_BYTES   512

Definition at line 15 of file dmapool.cpp.

Typedef Documentation

◆ PXHCI_POOL_OWNER

◆ PXHCI_POOL_PAGE

◆ XHCI_POOL_OWNER

Context of the enabler and the pool work items.

◆ XHCI_POOL_PAGE

WDFCOMMONBUFFER context: the page header followed by its segments.

Function Documentation

◆ _IRQL_requires_()

_IRQL_requires_ ( PASSIVE_LEVEL  )

Sends a synchronous IOCTL to the specified device object.

Parameters
[in]IoControlCodeThe IOCTL to send to the device.
[in]DeviceObjectPointer to the device object that will handle the IOCTL.
[in]InputBufferOptional pointer to a buffer containing input data for the IOCTL. When specified, the buffer should be at least of InputBufferLength size.
[in]InputBufferLengthSize in bytes, of the buffer pointed by InputBuffer.
[out]OutputBufferOptional pointer to a buffer that will receive output data from the IOCTL. When specified, the buffer should be at least of OutputBufferLength size.
[in]OutputBufferLengthSize in bytes, of the buffer pointed by OutputBuffer.
[in]FileObjectOptional pointer to a file object that may be necessary for the IOCTL.
Returns
An NTSTATUS code indicating success or failure of this function.
Note
Must be called at PASSIVE_LEVEL with all APCs enabled.

Nothing is found unless the PCI bus driver publishes the properties.

The root hub name without its prefix; NULL when the PDO has no name.

Grows a private buffer to what the helper asks for.

Lets KMDF handle the IRP, then hands it back here still uncompleted.

Waits for the device machine to answer a PnP or power event; returns the PnP status.

Deletes the UCX endpoints of the disabled pipes, then the interface record.

One 4 byte value; the registry type is not checked.

Reread whenever user experience settings change; the open status is returned.

Sends a synchronous IOCTL to the specified device object.

STATUS_SUCCESS when the caller's token is an administrator's.

Sends a synchronous IOCTL to the specified device object.

Reads one value of a walk. A missing value only clears Present; FALSE means stop.

Reads up to Size bytes of a value into a zeroed buffer; the type is not checked.

Writes a REG_BINARY value into the device's usbflags subkey.

Sets or clears ExtPropertiesInstalled from ExtPropDescSemaphore in the hardware key.

Fails only when a port cannot be bound to the USB4 host router its ACPI node names.

Assigns device, hardware, compatible, container and instance ids to a new child PDO.

Answers IRP_MN_QUERY_DEVICE_TEXT on a child PDO; always completes the IRP.

Takes the connector map lock, needed around HubConnectorFindCompanion.

Device hardware key values read at PDO prepare hardware.

Saves the MS OS 2.0 set info in usbflags when the set asks for alternate enumeration.

MsOs20Flags and EnumerationRetryCount, written at PDO start.

Rereads the UXD record; UpdateRequired says whether the device id changes.

Replacement PnP id of a UXD reserved device, or an empty String. Always succeeds.

Telemetry values under the device's Ceip subkey.

BootPathSurpriseRemovalCount + 1.

This machine's dual role features for a dual role partner.

Tells UCX the WDM PDO of the device; call right after the child PDO was created.

IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME: Argument1 and its length Argument2.

IOCTL_INTERNAL_USB_GET_BUS_INFO for the device: the 16 byte USB_BUS_NOTIFICATION at Argument1.

Registers the GUID_USB_WMI_NODE_INFO instance of a child PDO (not for hubs or composites).

Registers the boot device surprise removal event on an external, non hub boot PDO.

Fires the boot device surprise removal event, if one is registered.

Sends a synchronous IOCTL to the specified device object.

Publishes "<port>#<host>" for every bound port on the hub's PDO. QUIRK: with no bound port an older value is left in place.

Binds USB 3 ports to the host routers named by the USB4 DVSEC; an earlier ACPI mapping wins.

Waits on a PnP handshake event with no timeout, printing a watchdog line every minute so a stuck machine is visible in the debugger.

Copies up to Size bytes of a device property; a failed query leaves the field zero.

Only the controller name length is real; both bandwidth fields read 0.

The answer overlays a USB_HUB_NAME on TotalSize, so TotalSize comes back as the name length + 4.

Evaluates a method without arguments into Output.

Definition at line 84 of file dmapool.cpp.

88{
89 if (!m_Initialized)
90 {
91 m_Controller = Controller;
92 KeInitializeSpinLock(&m_Lock);
93 InitializeListHead(&m_ReclaimList);
95
96 /* Pool sizing policy; the test signing overrides are not supported */
97 XhciPoolInitClass(&m_Small.FreeList, &m_Small.PageList);
98 m_Small.SegmentSize = XHCI_POOL_SMALL_BYTES;
99 m_Small.GrowBelow = 4;
100 m_Small.GrowBy = 8;
101 m_Small.KeepAtLeast = 16;
102
103 XhciPoolInitClass(&m_Large.FreeList, &m_Large.PageList);
104 m_Large.SegmentSize = XHCI_POOL_PAGE_BYTES;
105 m_Large.GrowBelow = 1;
106 m_Large.GrowBy = 1;
107 m_Large.KeepAtLeast = 2;
108
109 m_Initialized = TRUE;
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}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define XHCI_POOL_SMALL_BYTES
Definition: dmapool.cpp:15
#define XHCI_POOL_PAGE_BYTES
Definition: dmapool.cpp:14
static VOID NTAPI XhciPoolInitClass(_Out_ PLIST_ENTRY FreeList, _Out_ PLIST_ENTRY PageList)
Definition: dmapool.cpp:76
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
@ NotificationEvent
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXCONTROLLER * Controller

◆ _IRQL_requires_max_()

_IRQL_requires_max_ ( DISPATCH_LEVEL  )

IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION; the idle machine owns the IRP afterwards.

Records hub over current in the hub hardware key, once per devnode.

First selective suspend of the device; the registry write runs in a work item.

"USB device not recognized" popup for a port.

A hub was attached beyond the allowed tier depth.

The selected configuration draws more power than the port can give.

The controller ran out of bandwidth for the device; fired by the out of bandwidth timer.

Definition at line 357 of file dmapool.cpp.

364{
366 BOOLEAN Got = FALSE;
367
368 InitializeListHead(Taken);
369
370 {
371 XhciSpinLockGuard Guard(&m_Lock);
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
392 InsertTailList(Taken, &Segment->Link);
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}
unsigned char BOOLEAN
Definition: actypes.h:127
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
#define FALSE
Definition: types.h:117
struct _XHCI_POOL_PAGE * PXHCI_POOL_PAGE
#define InsertTailList(ListHead, Entry)
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
if(dx< 0)
Definition: linetemp.h:194
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1287
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#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
USHORT Count
Definition: userreq.cpp:200
_Inout_ PVOID Segment
Definition: exfuncs.h:1101

◆ _Requires_lock_held_()

_Requires_lock_held_ ( m_Lock  )

Definition at line 505 of file dmapool.cpp.

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}
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
#define InsertHeadList(ListHead, Entry)

◆ WDF_DECLARE_CONTEXT_TYPE_WITH_NAME() [1/2]

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME ( XHCI_POOL_OWNER  ,
XhciPoolOwner   
)

◆ WDF_DECLARE_CONTEXT_TYPE_WITH_NAME() [2/2]

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME ( XHCI_POOL_PAGE  ,
XhciPoolPageFromBuffer   
)

◆ XhciPoolEnablerCleanup()

static VOID NTAPI XhciPoolEnablerCleanup ( _In_ WDFOBJECT  Object)
static

Definition at line 63 of file dmapool.cpp.

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}
Definition: bufpool.h:50
Pool(int, int, const char *)
Definition: bufpool.cc:49
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object

◆ XhciPoolGrowthWorkItem()

static VOID NTAPI XhciPoolGrowthWorkItem ( _In_ WDFWORKITEM  WorkItem)
static

Definition at line 45 of file dmapool.cpp.

47{
48 XhciPoolOwner(WorkItem)->Pool->GrowthWork();
49}
_In_opt_ PVOID _In_ PUCXHUB_WORKITEM WorkItem
Definition: hubucx.h:227

◆ XhciPoolInitClass()

static VOID NTAPI XhciPoolInitClass ( _Out_ PLIST_ENTRY  FreeList,
_Out_ PLIST_ENTRY  PageList 
)
static

Definition at line 76 of file dmapool.cpp.

79{
81 InitializeListHead(PageList);
82}
void FreeList(LOCATIONITEM *pItems)
Definition: CSearchBar.cpp:95

Referenced by _IRQL_requires_(), and XhciCommonBuffer::EnablerCleanup().

◆ XhciPoolReclaimWorkItem()

static VOID NTAPI XhciPoolReclaimWorkItem ( _In_ WDFWORKITEM  WorkItem)
static

Definition at line 54 of file dmapool.cpp.

56{
57 XhciPoolOwner(WorkItem)->Pool->ReclaimWork();
58}

Variable Documentation

◆ XhciPoolEnablerCleanup

EVT_WDF_OBJECT_CONTEXT_CLEANUP XhciPoolEnablerCleanup
static

Definition at line 40 of file dmapool.cpp.

◆ XhciPoolGrowthWorkItem

EVT_WDF_WORKITEM XhciPoolGrowthWorkItem
static

Definition at line 38 of file dmapool.cpp.

◆ XhciPoolReclaimWorkItem

EVT_WDF_WORKITEM XhciPoolReclaimWorkItem
static

Definition at line 39 of file dmapool.cpp.