4#ifndef _FXDMATRANSACTION_HPP_
5#define _FXDMATRANSACTION_HPP_
71#define FX_STRONG_REF_TAG 0x1
76#define FX_ENCODE_POINTER(T,p,tag) ((T*) ((ULONG_PTR) p | (ULONG_PTR) tag))
77#define FX_DECODE_POINTER(T,p,tag) ((T*) ((ULONG_PTR) p & ~(ULONG_PTR) tag))
78#define FX_IS_POINTER_ENCODED(p,tag) ((((ULONG_PTR) p & (ULONG_PTR) tag) == tag) ? TRUE : FALSE)
84#define UNDEFINED_DMA_COMPLETION_STATUS ((DMA_COMPLETION_STATUS) -1)
103 __in size_t CurrentOffset,
106 __out size_t *NextOffset
114 __in size_t CurrentOffset,
330 size_t MaximumFragmentLength
333 if (MaximumFragmentLength < m_AdapterInfo->MaximumFragmentLength) {
589 __in size_t CurrentOffset,
661 __in size_t CurrentOffset,
703 ScatterGatherBufferLength,
721 ScatterGatherBufferLength);
979#pragma prefast(suppress:__WARNING_FAILING_TO_ACQUIRE_MEDIUM_CONFIDENCE, "transferring lock name to 'this->TransferStateLock'")
980#pragma prefast(suppress:__WARNING_FAILING_TO_RELEASE_MEDIUM_CONFIDENCE, "transferring lock name to 'this->TransferStateLock'")
991#pragma prefast(suppress:__WARNING_FAILING_TO_RELEASE_MEDIUM_CONFIDENCE, "transferring lock name from 'this->TransferStateLock'")
996#pragma prefast(suppress:__WARNING_CALLER_FAILING_TO_HOLD, "transferring lock name from 'this->TransferStateLock'")
1060 if (MapRegistersReserved ==
FALSE) {
1063 "Allocating %d map registers for "
1064 "WDFDMATRANSACTION %p",
1072 "Using %d reserved map registers for "
1073 "WDFDMATRANSACTION %p",
1084 if (MapRegistersReserved ==
FALSE)
1099#pragma prefast(suppress:__WARNING_PASSING_FUNCTION_UNEXPECTED_NULL, "_AdapterControl does not actually use the IRP parameter.");
1109 ASSERTMSG(
"Prereserved map registers are not compatible with DMA V2",
1110 MapRegistersReserved ==
FALSE);
1127 "Allocating DMA resources (%d map registers) for WDFDMATRANSACTION %p "
1128 "returned %!STATUS!",
1163 NT_ASSERTMSG(
"Mapping requires too many map registers",
1182 "Mapping transfer for WDFDMATRANSACTION %p. "
1183 "MDL %p, Offset %I64x, Length %x, MapRegisterBase %p",
1205 ScatterGatherListCb,
1211 "With these parameters, MapTransferEx should never fail",
1216 NT_ASSERTMSG(
"cannot use DMA completion routine with DMAv2",
1220 "scatter gather list length must be large enough for at least one element",
1236 ScatterGatherList->NumberOfElements = 1;
1237 ScatterGatherList->Reserved = 0;
1238 ScatterGatherList->Elements[0].Address =
1247 ScatterGatherList->Elements[0].Length = *TransferLength;
1254 "MapTransfer mapped next %d bytes of "
1255 "WDFDMATRANSACTION %p - status %!STATUS!",
1283 NT_ASSERTMSG(
"Mapping requires too many map registers",
1289 "Flushing DMA buffers for WDFDMATRANSACTION %p. "
1290 "MDL %p, Offset %I64x, Length %I64x",
1323 "Flushing DMA buffers for WDFDMATRANSACTION %p ("
1324 "MDL %p, Offset %I64x, Length %I64x)"
1325 "completed with %!STATUS!",
1350 if (mapRegisterBase ==
NULL) {
1353 "Skipping free of %d map registers for WDFDMATRANSACTION %p "
1354 "because base was NULL",
1369 "Freeing %d map registers for WDFDMATRANSACTION %p "
1402 ASSERTMSG(
"EvtDmaCompleted is not a valid callback for "
1403 "a packet-mode transaction",
1491 "Freeing adapter channel for WDFDMATRANSACTION %p",
1523 "Stopping WDFDMATRANSACTION %p returned status %!STATUS!",
__inline _Must_inspect_result_ NTSTATUS AcquireDmaPacketTransaction(VOID)
__inline VOID ReleaseDmaPacketTransaction(VOID)
ULONG m_MapRegistersNeeded
struct FxDmaPacketTransaction::@4336 m_TransferState
BOOLEAN m_MapRegisterBaseSet
VOID SetDeviceAddressOffset(__in ULONG Offset)
void SetMapRegisterBase(__in PVOID Value)
virtual VOID FreeMapRegistersAndAdapter(VOID)
FORCEINLINE NTSTATUS MapTransfer(__out_bcount_opt(ScatterGatherListCb) PSCATTER_GATHER_LIST ScatterGatherList, __in ULONG ScatterGatherListCb, __in_opt PDMA_COMPLETION_ROUTINE CompletionRoutine, __in_opt PVOID CompletionContext, __out ULONG *TransferLength)
FORCEINLINE NTSTATUS FlushAdapterBuffers(VOID)
virtual VOID CallEvtDmaCompleted(__in DMA_COMPLETION_STATUS)
_Acquires_lock_(this) VOID __drv_raisesIRQL(DISPATCH_LEVEL) LockTransferState(__out __drv_deref(__drv_savesIRQL) KIRQL *OldIrql)
static IO_ALLOCATION_ACTION STDCALL _AdapterControl(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PVOID MapRegisterBase, __in PVOID Context)
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in FxDmaEnabler *DmaEnabler, __out WDFDMATRANSACTION *Transaction)
ULONG m_MapRegistersReserved
_Requires_lock_held_(this) _Releases_lock_(this) VOID UnlockTransferState(__in __drv_restoresIRQL KIRQL OldIrql)
FORCEINLINE VOID ReleaseDevice(VOID)
DMA_COMPLETION_STATUS CompletionStatus
_Must_inspect_result_ NTSTATUS AllocateAdapterChannel(__in BOOLEAN MapRegistersReserved)
BOOLEAN IsMapRegisterBaseSet(VOID)
virtual BOOLEAN PreMapTransfer(VOID)
_Must_inspect_result_ NTSTATUS ReserveAdapter(__in ULONG NumberOfMapRegisters, __in WDF_DMA_DIRECTION Direction, __in PFN_WDF_RESERVE_DMA Callback, __in_opt PVOID Context)
void ClearMapRegisterBase(VOID)
virtual _Must_inspect_result_ NTSTATUS TransferCompleted(VOID)
_Must_inspect_result_ NTSTATUS AcquireDevice(VOID)
virtual _Must_inspect_result_ NTSTATUS StartTransfer(VOID)
virtual VOID ReleaseResources(__in BOOLEAN ForceRelease)
virtual _Must_inspect_result_ NTSTATUS StageTransfer(VOID)
PVOID GetMapRegisterBase(VOID)
PKTHREAD CurrentStagingThread
virtual PDMA_COMPLETION_ROUTINE GetTransferCompletionRoutine(VOID)
ULONG m_DeviceAddressOffset
virtual _Must_inspect_result_ NTSTATUS InitializeResources(VOID)
virtual IO_ALLOCATION_ACTION GetAdapterControlReturnValue(VOID)
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in FxDmaEnabler *DmaEnabler, __out WDFDMATRANSACTION *Transaction)
virtual _Must_inspect_result_ NTSTATUS InitializeResources(VOID)
static VOID _AdapterListControl(__in DEVICE_OBJECT *DeviceObject, __in IRP *Irp, __in SCATTER_GATHER_LIST *SgList, __in VOID *Context)
virtual _Must_inspect_result_ NTSTATUS StartTransfer(VOID)
_Must_inspect_result_ NTSTATUS BuildScatterGatherList(__in PMDL Mdl, __in size_t CurrentOffset, __in ULONG Length, __in PDRIVER_LIST_CONTROL ExecutionRoutine, __in PVOID Context, __in PVOID ScatterGatherBuffer, __in ULONG ScatterGatherBufferLength)
virtual _Must_inspect_result_ NTSTATUS TransferCompleted(VOID)
_Must_inspect_result_ NTSTATUS GetScatterGatherList(__in PMDL Mdl, __in size_t CurrentOffset, __in ULONG Length, __in PDRIVER_LIST_CONTROL ExecutionRoutine, __in PVOID Context)
virtual _Must_inspect_result_ NTSTATUS StageTransfer(VOID)
virtual BOOLEAN Dispose(VOID)
VOID PutScatterGatherList(__in PSCATTER_GATHER_LIST ScatterGather)
virtual VOID ReleaseResources(__in BOOLEAN ForceRelease)
PSCATTER_GATHER_LIST m_SGList
static DMA_COMPLETION_ROUTINE _SystemDmaCompletion
PVOID m_ConfigureChannelContext
PVOID m_TransferCompleteContext
BOOLEAN CancelMappedTransfer(VOID)
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in FxDmaEnabler *DmaEnabler, __out WDFDMATRANSACTION *Transaction)
IO_ALLOCATION_ACTION GetAdapterControlReturnValue(VOID)
VOID CallEvtDmaCompleted(__in DMA_COMPLETION_STATUS Status)
VOID SetConfigureChannelCallback(__in_opt PFN_WDF_DMA_TRANSACTION_CONFIGURE_DMA_CHANNEL Callback, __in_opt PVOID Context)
FxDmaTransactionConfigureChannel m_ConfigureChannelFunction
virtual PDMA_COMPLETION_ROUTINE GetTransferCompletionRoutine(VOID)
VOID SetTransferCompleteCallback(__in_opt PFN_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE Callback, __in_opt PVOID Context)
virtual BOOLEAN PreMapTransfer(VOID)
FxDmaTransactionTransferComplete m_TransferCompleteFunction
VOID FreeMapRegistersAndAdapter(VOID)
friend FxDmaPacketTransaction
__forceinline size_t GetMaximumFragmentLength(VOID)
__forceinline VOID SetMaximumFragmentLength(size_t MaximumFragmentLength)
__forceinline size_t GetCurrentFragmentLength(VOID)
FxRequest * m_EncodedRequest
__forceinline BOOLEAN IsRequestReferenced(VOID)
__forceinline VOID ReleaseButRetainRequest(VOID)
VOID SetImmediateExecution(__in BOOLEAN Value)
size_t m_MaxFragmentLength
static PVOID GetStartVaFromOffset(__in PMDL Mdl, __in size_t Offset)
__forceinline FxRequest * GetRequest(VOID)
virtual _Must_inspect_result_ NTSTATUS TransferCompleted(VOID)=0
virtual VOID ReleaseResources(__in BOOLEAN ForceRelease)=0
FxDmaTransactionProgramOrReserveDma m_DmaAcquiredFunction
PVOID m_DmaAcquiredContext
FxDmaDescription * m_AdapterInfo
virtual _Must_inspect_result_ NTSTATUS StartTransfer(VOID)=0
__forceinline VOID SetRequest(__in FxRequest *Request)
FxDmaEnabler * m_DmaEnabler
VOID ReleaseForReuse(__in BOOLEAN ForceRelease)
__forceinline size_t GetBytesTransferred(VOID)
virtual _Must_inspect_result_ NTSTATUS StageTransfer(VOID)=0
FxDmaTransactionState GetTransactionState(VOID)
PVOID GetTransferContext(VOID)
PMDL m_CurrentFragmentMdl
__forceinline VOID ReferenceRequest(VOID)
WDF_DMA_DIRECTION m_DmaDirection
__forceinline FxDmaEnabler * GetDmaEnabler(VOID)
size_t m_TransactionLength
__forceinline VOID ClearRequest(VOID)
size_t m_CurrentFragmentOffset
_Must_inspect_result_ NTSTATUS Execute(__in PVOID Context)
FxDmaTransactionState m_State
VOID GetTransferInfo(__out_opt ULONG *MapRegisterCount, __out_opt ULONG *ScatterGatherElementCount)
virtual _Must_inspect_result_ NTSTATUS InitializeResources(VOID)=0
size_t m_CurrentFragmentLength
virtual BOOLEAN Dispose(VOID)
static _Must_inspect_result_ NTSTATUS _CalculateRequiredMapRegisters(__in PMDL Mdl, __in size_t CurrentOffset, __in ULONG Length, __in ULONG AvailableMapRegisters, __out_opt PULONG PossibleTransferLength, __out PULONG MapRegistersRequired)
static VOID _ComputeNextTransferAddress(__in PMDL CurrentMdl, __in size_t CurrentOffset, __in ULONG Transferred, __deref_out PMDL *NextMdl, __out size_t *NextOffset)
BOOLEAN DmaCompleted(__in size_t TransferredLength, __out NTSTATUS *ReturnStatus, __in FxDmaCompletionType CompletionType)
__forceinline WDFDMATRANSACTION GetHandle(VOID)
PFN_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE Method
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
CfxDevice * GetDevice(VOID)
__in __drv_restoresIRQL KIRQL OldIrql
VOID ReleaseIrpReference(VOID)
VOID AddIrpReference(VOID)
#define _Releases_lock_(lock)
#define __out_bcount_opt(x)
#define NT_SUCCESS(StatCode)
#define __drv_deref(annotes)
#define __drv_restoresIRQL
#define __drv_raisesIRQL(irql)
#define KeRaiseIrql(irql, oldIrql)
#define KeLowerIrql(oldIrql)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFX_DRIVER_GLOBALS pFxDriverGlobals
return pObject GetObjectHandle()
#define FX_DECODE_POINTER(T, p, tag)
#define FX_STRONG_REF_TAG
#define FX_IS_POINTER_ENCODED(p, tag)
@ FxDmaTransactionStateDeleted
@ FxDmaTransactionStateInitialized
@ FxDmaTransactionStateTransferCompleted
@ FxDmaTransactionStateInvalid
@ FxDmaTransactionStateReleased
@ FxDmaTransactionStateReserved
@ FxDmaTransactionStateTransfer
@ FxDmaTransactionStateCreated
@ FxDmaTransactionStateTransferFailed
#define FX_ENCODE_POINTER(T, p, tag)
@ FxDmaCompletionTypeAbort
@ FxDmaCompletionTypePartial
@ FxDmaCompletionTypeFull
systemTransaction StopTransfer()
return pDmaTrans CancelResourceAllocation()
pDmaTrans ReleaseAdapter()
return pDmaTrans GetTransferContext()
#define _Must_inspect_result_
#define ASSERTMSG(msg, exp)
#define DECLSPEC_ALIGN(x)
#define MEMORY_ALLOCATION_ALIGNMENT
_In_ ULONG _In_ ULONG Offset
_In_ ULONG _In_ ULONG _In_ ULONG Length
#define TRACE_LEVEL_VERBOSE
#define TRACE_LEVEL_ERROR
struct _DMA_OPERATIONS * DmaOperations
PFLUSH_ADAPTER_BUFFERS_EX FlushAdapterBuffersEx
PMAP_TRANSFER_EX MapTransferEx
PALLOCATE_ADAPTER_CHANNEL_EX AllocateAdapterChannelEx
PFLUSH_ADAPTER_BUFFERS FlushAdapterBuffers
PGET_SCATTER_GATHER_LIST_EX GetScatterGatherListEx
PBUILD_SCATTER_GATHER_LIST_EX BuildScatterGatherListEx
PDMA_ADAPTER AdapterObject
#define __WARNING_CLASS_MISMATCH_NONE
#define STATUS_UNSUCCESSFUL
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Must_inspect_result_ _In_ WDFDMAENABLER DmaEnabler
_In_ PDEVICE_OBJECT DeviceObject
_In_ WDFDMAENABLER _In_ WDF_DMA_DIRECTION DmaDirection
enum _WDF_DMA_DIRECTION WDF_DMA_DIRECTION
EVT_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE * PFN_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE
EVT_WDF_PROGRAM_DMA * PFN_WDF_PROGRAM_DMA
EVT_WDF_RESERVE_DMA * PFN_WDF_RESERVE_DMA
WDF_EXTERN_C_START typedef _In_ WDFDEVICE _In_ WDFCONTEXT _In_ WDF_DMA_DIRECTION _In_ PSCATTER_GATHER_LIST SgList
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
WDF_EXTERN_C_START typedef _In_ WDFDEVICE _In_ WDFCONTEXT _In_ WDF_DMA_DIRECTION Direction
_In_ WDFDMATRANSACTION _Out_opt_ ULONG * MapRegisterCount
_In_ WDFDMATRANSACTION _In_ size_t TransferredLength
EVT_WDF_DMA_TRANSACTION_CONFIGURE_DMA_CHANNEL * PFN_WDF_DMA_TRANSACTION_CONFIGURE_DMA_CHANNEL
_In_ WDFDMATRANSACTION _Out_opt_ ULONG _Out_opt_ ULONG * ScatterGatherElementCount
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE _In_opt_ __drv_aliasesMem WDFCONTEXT CompletionContext
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
_Out_ PULONG NumberOfMapRegisters
_In_ PDEVICE_OBJECT _In_ ULONG _In_ PDRIVER_CONTROL ExecutionRoutine
struct _SCATTER_GATHER_LIST SCATTER_GATHER_LIST
struct _SCATTER_GATHER_LIST * PSCATTER_GATHER_LIST
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
enum _IO_ALLOCATION_ACTION IO_ALLOCATION_ACTION
@ DeallocateObjectKeepRegisters
DRIVER_LIST_CONTROL * PDRIVER_LIST_CONTROL
_In_ struct _IRP _In_ struct _SCATTER_GATHER_LIST * ScatterGather
DMA_COMPLETION_ROUTINE * PDMA_COMPLETION_ROUTINE
#define MmGetMdlVirtualAddress(_Mdl)
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)