ReactOS  0.4.15-dev-3207-ga415bd4
FxDmaPacketTransaction Class Reference

#include <fxdmatransaction.hpp>

Inheritance diagram for FxDmaPacketTransaction:
Collaboration diagram for FxDmaPacketTransaction:

Public Member Functions

virtual _Must_inspect_result_ NTSTATUS InitializeResources (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 ReleaseAdapter (VOID)
 
virtual _Must_inspect_result_ NTSTATUS StartTransfer (VOID)
 
virtual _Must_inspect_result_ NTSTATUS TransferCompleted (VOID)
 
virtual _Must_inspect_result_ NTSTATUS StageTransfer (VOID)
 
virtual VOID ReleaseResources (__in BOOLEAN ForceRelease)
 
VOID SetDeviceAddressOffset (__in ULONG Offset)
 
- Public Member Functions inherited from FxDmaTransactionBase
 FxDmaTransactionBase (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ObjectSize, __in USHORT ExtraSize, __in FxDmaEnabler *DmaEnabler)
 
virtual BOOLEAN Dispose (VOID)
 
_Must_inspect_result_ NTSTATUS Initialize (__in PFN_WDF_PROGRAM_DMA ProgramDmaFunction, __in WDF_DMA_DIRECTION DmaDirection, __in PMDL Mdl, __in size_t Offset, __in ULONG Length)
 
_Must_inspect_result_ NTSTATUS Execute (__in PVOID Context)
 
BOOLEAN DmaCompleted (__in size_t TransferredLength, __out NTSTATUS *ReturnStatus, __in FxDmaCompletionType CompletionType)
 
VOID ReleaseForReuse (__in BOOLEAN ForceRelease)
 
VOID GetTransferInfo (__out_opt ULONG *MapRegisterCount, __out_opt ULONG *ScatterGatherElementCount)
 
__forceinline size_t GetBytesTransferred (VOID)
 
__forceinline FxDmaEnablerGetDmaEnabler (VOID)
 
__forceinline FxRequestGetRequest (VOID)
 
__forceinline BOOLEAN IsRequestReferenced (VOID)
 
__forceinline VOID SetRequest (__in FxRequest *Request)
 
__forceinline VOID ReferenceRequest (VOID)
 
__forceinline VOID ReleaseButRetainRequest (VOID)
 
__forceinline VOID ClearRequest (VOID)
 
__forceinline size_t GetMaximumFragmentLength (VOID)
 
__forceinline VOID SetMaximumFragmentLength (size_t MaximumFragmentLength)
 
__forceinline size_t GetCurrentFragmentLength (VOID)
 
__forceinline WDFDMATRANSACTION GetHandle (VOID)
 
PVOID GetTransferContext (VOID)
 
VOID SetImmediateExecution (__in BOOLEAN Value)
 
BOOLEAN CancelResourceAllocation (VOID)
 
FxDmaTransactionState GetTransactionState (VOID)
 
- Public Member Functions inherited from FxNonPagedObject
 FxNonPagedObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
 FxNonPagedObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType ObjectType)
 
virtual ~FxNonPagedObject (VOID)
 
 _Acquires_lock_ (this->m_NPLock.m_Lock) __drv_maxIRQL(DISPATCH_LEVEL) __drv_setsIRQL(DISPATCH_LEVEL) VOID Lock(__out __drv_deref(__drv_savesIRQL) PKIRQL PreviousIrql)
 
 _Releases_lock_ (this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID Unlock(__in __drv_restoresIRQL KIRQL PreviousIrql)
 
 _Acquires_lock_ (this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) VOID LockAtDispatch(VOID)
 
 _Requires_lock_held_ (this->m_NPLock.m_Lock) _Releases_lock_(this -> m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID UnlockFromDispatch(VOID)
 
- Public Member Functions inherited from FxObject
PVOID GetCOMWrapper ()
 
void SetCOMWrapper (__drv_aliasesMem PVOID Wrapper)
 
 FxObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
virtual ~FxObject (VOID)
 
PVOID __inline operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType Type)
 
PVOID __inline operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __in USHORT ExtraSize=0)
 
VOID operator delete (__in PVOID Memory)
 
VOID SetNoContextHeader (VOID)
 
PVOID __inline GetObjectHandle (VOID)
 
__inline FxContextHeaderGetContextHeader (VOID)
 
__inline PFX_DRIVER_GLOBALS GetDriverGlobals (VOID)
 
WDFTYPE GetType (VOID)
 
USHORT GetObjectSize (VOID)
 
LONG GetRefCnt (VOID)
 
FxTagTrackerGetTagTracker (VOID)
 
CfxDeviceGetDevice (VOID)
 
CfxDeviceBaseGetDeviceBase (VOID)
 
VOID SetDeviceBase (__in CfxDeviceBase *DeviceBase)
 
__inline VOID CallCleanup (VOID)
 
ULONG __inline AddRef (__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG Release (__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG AddRefOverride (__in WDFOBJECT_OFFSET Offset, __in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG ReleaseOverride (__in WDFOBJECT_OFFSET Offset, __in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual _Must_inspect_result_ NTSTATUS QueryInterface (__in FxQueryInterfaceParams *Params)
 
VOID MarkTraceState (VOID)
 
BOOLEAN __inline IsTraceState (VOID)
 
VOID __inline TraceDroppedEvent (__in FxObjectDroppedEvent Event)
 
VOID MarkPassiveDispose (__in FxObjectLockState State=ObjectLock)
 
VOID MarkPassiveCallbacks (__in FxObjectLockState State=ObjectLock)
 
VOID MarkForceDisposeThread (__in FxObjectLockState State=ObjectLock)
 
BOOLEAN IsPassiveCallbacks (__in BOOLEAN AcquireLock=TRUE)
 
BOOLEAN IsPassiveDispose (__in BOOLEAN AcquireLock=TRUE)
 
BOOLEAN IsForceDisposeThread (__in BOOLEAN AcquireLock=TRUE)
 
VOID MarkCommitted (VOID)
 
BOOLEAN IsCommitted (VOID)
 
VOID MarkDisposeOverride (__in FxObjectLockState State=ObjectLock)
 
VOID MarkNoDeleteDDI (__in FxObjectLockState State=ObjectLock)
 
BOOLEAN IsNoDeleteDDI (VOID)
 
_Must_inspect_result_ NTSTATUS Commit (__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
 
VOID DeleteFromFailedCreate (VOID)
 
VOID ClearEvtCallbacks (VOID)
 
BOOLEAN EarlyDispose (VOID)
 
virtual VOID DeleteObject (VOID)
 
_Must_inspect_result_ NTSTATUS AssignParentObject (__in FxObject *ParentObject)
 
_Must_inspect_result_ NTSTATUS AddContext (__in FxContextHeader *Header, __in PVOID *Context, __in PWDF_OBJECT_ATTRIBUTES Attributes)
 
_Must_inspect_result_ NTSTATUS RemoveParentAssignment (VOID)
 
_Must_inspect_result_ FxObjectGetParentObjectReferenced (__in PVOID Tag)
 
BOOLEAN IsDisposed (VOID)
 

Static Public Member Functions

static _Must_inspect_result_ NTSTATUS _Create (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in FxDmaEnabler *DmaEnabler, __out WDFDMATRANSACTION *Transaction)
 
- Static Public Member Functions inherited from FxDmaTransactionBase
static VOID _ComputeNextTransferAddress (__in PMDL CurrentMdl, __in size_t CurrentOffset, __in ULONG Transferred, __deref_out PMDL *NextMdl, __out size_t *NextOffset)
 
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 Public Member Functions inherited from FxObject
static FxObject_FromDisposeEntry (__in PSINGLE_LIST_ENTRY Entry)
 
static FxObject_GetObjectFromHandle (__in WDFOBJECT Handle, __inout PWDFOBJECT_OFFSET ObjectOffset)
 
static PVOID __inline _ToHandle (__in FxObject *Object)
 
static VOID __inline _ReferenceActual (__in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File)
 
static VOID __inline _DereferenceActual (__in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File)
 
static PVOID _GetDebugBase (__in FxObject *Object)
 
static PFX_POOL_HEADER _CleanupPointer (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject *Object)
 
static _Must_inspect_result_ NTSTATUS _GetEffectiveLock (__in FxObject *Object, __in_opt IFxHasCallbacks *Callbacks, __in BOOLEAN AutomaticLocking, __in BOOLEAN PassiveCallbacks, __out FxCallbackLock **CallbackLock, __out_opt FxObject **CallbackLockObject)
 
static _Must_inspect_result_ NTSTATUS _ObjectQuery (_In_ FxObject *Object, _In_ CONST GUID *Guid, _In_ ULONG QueryBufferLength, _Out_writes_bytes_(QueryBufferLength) PVOID QueryBuffer)
 

Protected Member Functions

 FxDmaPacketTransaction (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ObjectSize, __in USHORT ExtraSize, __in FxDmaEnabler *DmaEnabler)
 
virtual VOID Reuse (VOID)
 
void SetMapRegisterBase (__in PVOID Value)
 
void ClearMapRegisterBase (VOID)
 
BOOLEAN IsMapRegisterBaseSet (VOID)
 
PVOID GetMapRegisterBase (VOID)
 
virtual IO_ALLOCATION_ACTION GetAdapterControlReturnValue (VOID)
 
virtual BOOLEAN PreMapTransfer (VOID)
 
 _Acquires_lock_ (this) VOID __drv_raisesIRQL(DISPATCH_LEVEL) LockTransferState(__out __drv_deref(__drv_savesIRQL) KIRQL *OldIrql)
 
 _Requires_lock_held_ (this) _Releases_lock_(this) VOID UnlockTransferState(__in __drv_restoresIRQL KIRQL OldIrql)
 
virtual PDMA_COMPLETION_ROUTINE GetTransferCompletionRoutine (VOID)
 
_Must_inspect_result_ NTSTATUS AcquireDevice (VOID)
 
FORCEINLINE VOID ReleaseDevice (VOID)
 
_Must_inspect_result_ NTSTATUS AllocateAdapterChannel (__in BOOLEAN MapRegistersReserved)
 
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 FreeMapRegistersAndAdapter (VOID)
 
virtual VOID CallEvtDmaCompleted (__in DMA_COMPLETION_STATUS)
 
- Protected Member Functions inherited from FxObject
 FxObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType ObjectType)
 
FxObjectDebugExtensionGetDebugExtension (VOID)
 
BOOLEAN IsDebug (VOID)
 
VOID AllocateTagTracker (__in WDFTYPE Type)
 
virtual VOID SelfDestruct (VOID)
 
PVOID __inline GetObjectHandleUnchecked (VOID)
 
VOID __inline DestroyChildren (VOID)
 
VOID DeleteEarlyDisposedObject (VOID)
 

Static Protected Member Functions

static IO_ALLOCATION_ACTION STDCALL _AdapterControl (__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PVOID MapRegisterBase, __in PVOID Context)
 
- Static Protected Member Functions inherited from FxDmaTransactionBase
static PVOID GetStartVaFromOffset (__in PMDL Mdl, __in size_t Offset)
 
- Static Protected Member Functions inherited from FxObject
static PVOID _GetBase (__in FxObject *Object)
 

Protected Attributes

ULONG m_MapRegistersNeeded
 
PVOID m_MapRegisterBase
 
BOOLEAN m_MapRegisterBaseSet
 
ULONG m_DeviceAddressOffset
 
ULONG m_MapRegistersReserved
 
struct {
   PKTHREAD   CurrentStagingThread
 
   BOOLEAN   RerunStaging
 
   BOOLEAN   RerunCompletion
 
   DMA_COMPLETION_STATUS   CompletionStatus
 
m_TransferState
 
ULONG m_IsCancelled
 
- Protected Attributes inherited from FxDmaTransactionBase
FxDmaTransactionState m_State
 
WDF_DMA_DIRECTION m_DmaDirection
 
FxDmaEnablerm_DmaEnabler
 
FxDmaDescriptionm_AdapterInfo
 
FxRequestm_EncodedRequest
 
FxDmaTransactionProgramOrReserveDma m_DmaAcquiredFunction
 
PVOID m_DmaAcquiredContext
 
PVOID m_TransferContext
 
PMDL m_StartMdl
 
PMDL m_CurrentFragmentMdl
 
size_t m_StartOffset
 
size_t m_CurrentFragmentOffset
 
size_t m_MaxFragmentLength
 
size_t m_TransactionLength
 
size_t m_Remaining
 
size_t m_Transferred
 
size_t m_CurrentFragmentLength
 
ULONG m_Flags
 
- Protected Attributes inherited from FxObject
union {
   CfxDeviceBase *   m_DeviceBase
 
   CfxDevice *   m_Device
 
}; 
 

Detailed Description

Definition at line 731 of file fxdmatransaction.hpp.

Constructor & Destructor Documentation

◆ FxDmaPacketTransaction()

FxDmaPacketTransaction::FxDmaPacketTransaction ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in USHORT  ObjectSize,
__in USHORT  ExtraSize,
__in FxDmaEnabler DmaEnabler 
)
protected

Definition at line 1165 of file fxdmatransaction.cpp.

1170  :
1171  FxDmaTransactionBase(FxDriverGlobals, ObjectSize, ExtraSize, DmaEnabler)
1172 {
1178 
1179  m_IsCancelled = FALSE;
1180 
1181  m_TransferState.CurrentStagingThread = NULL;
1182  m_TransferState.RerunStaging = FALSE;
1183  m_TransferState.RerunCompletion = FALSE;
1185 }
struct FxDmaPacketTransaction::@4096 m_TransferState
#define FALSE
Definition: types.h:117
#define UNDEFINED_DMA_COMPLETION_STATUS
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ WDFDMAENABLER DmaEnabler
FxDmaTransactionBase(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ObjectSize, __in USHORT ExtraSize, __in FxDmaEnabler *DmaEnabler)

Referenced by _Create().

Member Function Documentation

◆ _Acquires_lock_()

FxDmaPacketTransaction::_Acquires_lock_ ( this  )
inlineprotected

Definition at line 976 of file fxdmatransaction.hpp.

979  :__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'")
981  LockTransferState(
983  )
984  {
985  Lock(OldIrql);
986  }
boolean suppress
Definition: jpeglib.h:1006
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define __out
Definition: dbghelp.h:62
#define __WARNING_FAILING_TO_ACQUIRE_MEDIUM_CONFIDENCE
Definition: suppress.h:510
__in __drv_restoresIRQL KIRQL OldIrql
Definition: fxobject.hpp:1465
#define __drv_deref(annotes)
Definition: driverspecs.h:264
#define __drv_savesIRQL
Definition: driverspecs.h:325
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
#define __WARNING_FAILING_TO_RELEASE_MEDIUM_CONFIDENCE
Definition: suppress.h:509

◆ _AdapterControl()

IO_ALLOCATION_ACTION FxDmaPacketTransaction::_AdapterControl ( __in PDEVICE_OBJECT  DeviceObject,
__in PIRP  Irp,
__in PVOID  MapRegisterBase,
__in PVOID  Context 
)
staticprotected

Definition at line 1661 of file fxdmatransaction.cpp.

1667 {
1668  FxDmaPacketTransaction * pDmaTransaction;
1671  NTSTATUS status;
1672 
1675 
1676  pDmaTransaction = (FxDmaPacketTransaction*) Context;
1677  ASSERT(pDmaTransaction);
1678 
1679  pFxDriverGlobals = pDmaTransaction->GetDriverGlobals();
1680 
1681  //
1682  // Cache the return value while we can still touch the transaction
1683  //
1684  action = pDmaTransaction->GetAdapterControlReturnValue();
1685 
1686  //
1687  // Save the MapRegister base, unless it was previously set
1688  // during a reserve.
1689  //
1690  if (pDmaTransaction->IsMapRegisterBaseSet() == FALSE) {
1691  pDmaTransaction->SetMapRegisterBase(MapRegisterBase);
1692  }
1693  else {
1694  NT_ASSERTMSG("Caller was expected to use existing map register base",
1695  MapRegisterBase == pDmaTransaction->m_MapRegisterBase);
1696  }
1697 
1700  "Map registers for WDFDMATRANSACTION %p allocated "
1701  "(base %p)",
1702  pDmaTransaction->GetHandle(),
1703  MapRegisterBase);
1704  }
1705 
1706  //
1707  // NOTE: KMDF used to call KeFlushIoBuffers() here to "ensure the
1708  // data buffers were flushed." However KeFlushIoBuffers did
1709  // nothing on x86 & amd64 (which are cache coherent WRT DMA)
1710  // and calling FlushAdapterBuffers() does any necessary
1711  // flushing anyway. Plus on non-cache-coherent architectures
1712  // (such as ARM) the flush operation has to be cache-line aligned
1713  // to avoid cache line tearing. So the flush is not necessary
1714  // and has been removed.
1715 
1716  //
1717  // Check the state of the transaction. If it's reserve then call the
1718  // reserve callback and return. Otherwise stage the first fragment.
1719  //
1720  if (pDmaTransaction->m_State == FxDmaTransactionStateReserved)
1721  {
1723 
1724  //
1725  // Save off and clear the callback before calling it.
1726  //
1727  callback = pDmaTransaction->m_DmaAcquiredFunction;
1728  pDmaTransaction->m_DmaAcquiredFunction.Clear();
1729 
1730  ASSERTMSG("Mismatch between map register counts",
1731  (pDmaTransaction->m_MapRegistersReserved ==
1732  pDmaTransaction->m_MapRegistersNeeded));
1733 
1734  //
1735  // Invoke the callback. Note that from here the driver may initialize
1736  // and execute the transaction.
1737  //
1738  callback.InvokeReserveDma(
1739  pDmaTransaction->GetHandle(),
1740  pDmaTransaction->m_DmaAcquiredContext
1741  );
1742  }
1743  else {
1744 
1745  //
1746  // Stage next fragment
1747  //
1748  status = pDmaTransaction->StageTransfer();
1749 
1750  if (!NT_SUCCESS(status)) {
1751 
1752  DMA_COMPLETION_STATUS dmaStatus =
1755 
1756  //
1757  // Map transfer failed. There will be no DMA completion callback
1758  // and no call to EvtProgramDma. And we have no way to hand this
1759  // status back directly to the driver. Fake a DMA completion with
1760  // the appropriate status.
1761  //
1762  // This should only happen for system DMA (and there most likely
1763  // only during cancelation, though we leave the possibility that
1764  // the DMA extension may fail the transfer)
1765  //
1766  ASSERTMSG("Unexpected failure of StageTransfer for packet based "
1767  "DMA",
1768  (pDmaTransaction->GetDmaEnabler()->IsBusMaster() == false));
1769 
1772  "Invoking DmaCompleted callback %p (context %p) "
1773  "for WDFDMATRANSACTION %p (status %x) "
1774  "due to staging failure (%!STATUS!)",
1777  pDmaTransaction->GetHandle(),
1778  dmaStatus,
1779  status);
1780  }
1781 
1782  pDmaTransaction->CallEvtDmaCompleted(
1784  );
1785  }
1786  }
1787 
1788  //
1789  // Indicate that MapRegs are to be kept
1790  //
1791  return action;
1792 }
enum _IO_ALLOCATION_ACTION IO_ALLOCATION_ACTION
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3311
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
virtual _Must_inspect_result_ NTSTATUS StageTransfer(VOID)
LONG NTSTATUS
Definition: precomp.h:26
FxDmaTransactionTransferComplete m_TransferCompleteFunction
BOOLEAN IsMapRegisterBaseSet(VOID)
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACINGDMA
Definition: dbgtrace.h:71
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
__forceinline WDFDMATRANSACTION GetHandle(VOID)
virtual IO_ALLOCATION_ACTION GetAdapterControlReturnValue(VOID)
PFX_DRIVER_GLOBALS pFxDriverGlobals
DMA_COMPLETION_STATUS
Definition: iotypes.h:2298
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
__forceinline FxDmaEnabler * GetDmaEnabler(VOID)
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
virtual VOID CallEvtDmaCompleted(__in DMA_COMPLETION_STATUS)
__inline BOOLEAN IsBusMaster(VOID)
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:212
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
const WCHAR * action
Definition: action.c:7783
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxDmaTransactionProgramOrReserveDma m_DmaAcquiredFunction
PFN_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE Method
FxDmaSystemTransaction * systemTransaction
FxDmaTransactionState m_State
void SetMapRegisterBase(__in PVOID Value)
static IPrintDialogCallback callback
Definition: printdlg.c:326
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by AllocateAdapterChannel().

◆ _Create()

_Must_inspect_result_ NTSTATUS FxDmaPacketTransaction::_Create ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in PWDF_OBJECT_ATTRIBUTES  Attributes,
__in FxDmaEnabler DmaEnabler,
__out WDFDMATRANSACTION *  Transaction 
)
static

Definition at line 1189 of file fxdmatransaction.cpp.

1195 {
1196  FxDmaPacketTransaction* pTransaction;
1197  WDFOBJECT hTransaction;
1198  NTSTATUS status;
1199 
1200  pTransaction = new (FxDriverGlobals, Attributes, DmaEnabler->GetTransferContextSize())
1201  FxDmaPacketTransaction(FxDriverGlobals,
1202  sizeof(FxDmaPacketTransaction),
1203  DmaEnabler->GetTransferContextSize(),
1204  DmaEnabler);
1205 
1206  if (pTransaction == NULL) {
1209  FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA,
1210  "Could not allocate memory for WDFTRANSACTION, %!STATUS!", status);
1211  return status;
1212  }
1213 
1214  //
1215  // Commit and apply the attributes
1216  //
1217  status = pTransaction->Commit(Attributes, &hTransaction, DmaEnabler);
1218  if (NT_SUCCESS(status)) {
1219  *Transaction = (WDFDMATRANSACTION)hTransaction;
1220  }
1221  else {
1222  //
1223  // This will properly clean up the target's state and free it
1224  //
1225  pTransaction->DeleteFromFailedCreate();
1226  }
1227 
1228  return status;
1229 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ NTSTATUS Commit(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
Definition: fxobject.cpp:904
LONG NTSTATUS
Definition: precomp.h:26
#define TRACINGDMA
Definition: dbgtrace.h:71
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ WDFDMAENABLER DmaEnabler
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
FxDmaPacketTransaction(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ObjectSize, __in USHORT ExtraSize, __in FxDmaEnabler *DmaEnabler)
static SERVICE_STATUS status
Definition: service.c:31
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
Definition: ps.c:97

Referenced by switch().

◆ _Requires_lock_held_()

FxDmaPacketTransaction::_Requires_lock_held_ ( this  )
inlineprotected

Definition at line 988 of file fxdmatransaction.hpp.

991  :__WARNING_FAILING_TO_RELEASE_MEDIUM_CONFIDENCE, "transferring lock name from 'this->TransferStateLock'")
992  UnlockTransferState(
994  )
995  {
996 #pragma prefast(suppress:__WARNING_CALLER_FAILING_TO_HOLD, "transferring lock name from 'this->TransferStateLock'")
997  Unlock(OldIrql);
998  }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
#define __drv_restoresIRQL
Definition: driverspecs.h:321
UCHAR KIRQL
Definition: env_spec_w32.h:591
__in __drv_restoresIRQL KIRQL OldIrql
Definition: fxobject.hpp:1465
#define __WARNING_FAILING_TO_RELEASE_MEDIUM_CONFIDENCE
Definition: suppress.h:509
#define __in
Definition: dbghelp.h:35

◆ AcquireDevice()

_Must_inspect_result_ NTSTATUS FxDmaPacketTransaction::AcquireDevice ( VOID  )
inlineprotected

Definition at line 1021 of file fxdmatransaction.hpp.

1024  {
1025  if (m_DmaEnabler->UsesDmaV3() == FALSE)
1026  {
1028  }
1029  else
1030  {
1031  return STATUS_SUCCESS;
1032  }
1033  }
BOOLEAN UsesDmaV3(VOID)
#define FALSE
Definition: types.h:117
CfxDevice * GetDevice(VOID)
Definition: fxobject.hpp:781
__inline _Must_inspect_result_ NTSTATUS AcquireDmaPacketTransaction(VOID)
Definition: fxdevice.hpp:354
#define STATUS_SUCCESS
Definition: shellext.h:65
FxDmaEnabler * m_DmaEnabler

Referenced by StartTransfer().

◆ AllocateAdapterChannel()

_Must_inspect_result_ NTSTATUS FxDmaPacketTransaction::AllocateAdapterChannel ( __in BOOLEAN  MapRegistersReserved)
inlineprotected

Definition at line 1049 of file fxdmatransaction.hpp.

1052  {
1053  NTSTATUS status;
1054  KIRQL irql;
1055 
1057 
1058  if (GetDriverGlobals()->FxVerifierOn) {
1059 
1060  if (MapRegistersReserved == FALSE) {
1063  "Allocating %d map registers for "
1064  "WDFDMATRANSACTION %p",
1066  GetHandle()
1067  );
1068  }
1069  else {
1072  "Using %d reserved map registers for "
1073  "WDFDMATRANSACTION %p",
1075  GetHandle()
1076  );
1077  }
1078  }
1079 
1080  if (m_DmaEnabler->UsesDmaV3()) {
1081  PDMA_OPERATIONS dmaOperations =
1083 
1084  if (MapRegistersReserved == FALSE)
1085  {
1086  status = dmaOperations->AllocateAdapterChannelEx(
1091  m_Flags,
1092 #pragma prefast(suppress: __WARNING_CLASS_MISMATCH_NONE, "This warning requires a wrapper class for the DRIVER_CONTROL type.")
1094  this,
1095  NULL
1096  );
1097  }
1098  else {
1099 #pragma prefast(suppress:__WARNING_PASSING_FUNCTION_UNEXPECTED_NULL, "_AdapterControl does not actually use the IRP parameter.");
1101  NULL,
1103  this);
1105  }
1106  }
1107  else {
1108 
1109  ASSERTMSG("Prereserved map registers are not compatible with DMA V2",
1110  MapRegistersReserved == FALSE);
1111 
1116 #pragma prefast(suppress: __WARNING_CLASS_MISMATCH_NONE, "This warning requires a wrapper class for the DRIVER_CONTROL type.")
1118  this);
1119  }
1120 
1121  KeLowerIrql(irql);
1122 
1123  if (!NT_SUCCESS(status))
1124  {
1127  "Allocating DMA resources (%d map registers) for WDFDMATRANSACTION %p "
1128  "returned %!STATUS!",
1130  GetHandle(),
1131  status
1132  );
1133  }
1134 
1135  return status;
1136  }
boolean suppress
Definition: jpeglib.h:1006
BOOLEAN UsesDmaV3(VOID)
LONG NTSTATUS
Definition: precomp.h:26
KIRQL irql
Definition: wave.h:1
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2295
FxDmaDescription * m_AdapterInfo
UCHAR KIRQL
Definition: env_spec_w32.h:591
static IO_ALLOCATION_ACTION STDCALL _AdapterControl(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PVOID MapRegisterBase, __in PVOID Context)
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACINGDMA
Definition: dbgtrace.h:71
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
__forceinline WDFDMATRANSACTION GetHandle(VOID)
PDEVICE_OBJECT m_FDO
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define __WARNING_CLASS_MISMATCH_NONE
Definition: suppress.h:563
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
PDMA_ADAPTER AdapterObject
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
VOID NTAPI KeRaiseIrql(KIRQL NewIrql, PKIRQL OldIrql)
Definition: spinlock.c:27
_Must_inspect_result_ NTSTATUS AllocateAdapterChannel(__in BOOLEAN MapRegistersReserved)
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID NTAPI KeLowerIrql(KIRQL NewIrql)
Definition: spinlock.c:39
static SERVICE_STATUS status
Definition: service.c:31
PALLOCATE_ADAPTER_CHANNEL_EX AllocateAdapterChannelEx
Definition: iotypes.h:2653
FxDmaEnabler * m_DmaEnabler
Definition: ps.c:97

Referenced by StartTransfer().

◆ CallEvtDmaCompleted()

virtual VOID FxDmaPacketTransaction::CallEvtDmaCompleted ( __in DMA_COMPLETION_STATUS  )
inlineprotectedvirtual

Reimplemented in FxDmaSystemTransaction.

Definition at line 1394 of file fxdmatransaction.hpp.

1397  {
1398  //
1399  // Packet mode DMA doesn't support cancellation or
1400  // completion routines. So this should never run.
1401  //
1402  ASSERTMSG("EvtDmaCompleted is not a valid callback for "
1403  "a packet-mode transaction",
1404  FALSE);
1405  return;
1406  }
#define FALSE
Definition: types.h:117
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431

Referenced by _AdapterControl(), and StageTransfer().

◆ ClearMapRegisterBase()

void FxDmaPacketTransaction::ClearMapRegisterBase ( VOID  )
inlineprotected

Definition at line 929 of file fxdmatransaction.hpp.

932  {
933  NT_ASSERTMSG("Map register base was not set",
936  }
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3311
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117

Referenced by ReleaseResources().

◆ FlushAdapterBuffers()

FORCEINLINE NTSTATUS FxDmaPacketTransaction::FlushAdapterBuffers ( VOID  )
inlineprotected

Definition at line 1266 of file fxdmatransaction.hpp.

1269  {
1270  PDMA_OPERATIONS dmaOperations =
1272 
1273  NTSTATUS status;
1274 
1275 #if DBG
1276  ULONG_PTR mapRegistersRequired;
1277 
1278  mapRegistersRequired = ADDRESS_AND_SIZE_TO_SPAN_PAGES(
1282  );
1283  NT_ASSERTMSG("Mapping requires too many map registers",
1284  mapRegistersRequired <= m_MapRegistersNeeded);
1285 #endif
1286 
1287  if (GetDriverGlobals()->FxVerifierOn) {
1289  "Flushing DMA buffers for WDFDMATRANSACTION %p. "
1290  "MDL %p, Offset %I64x, Length %I64x",
1291  GetHandle(),
1295  }
1296 
1297  if (m_DmaEnabler->UsesDmaV3()) {
1298  status = dmaOperations->FlushAdapterBuffersEx(
1305  );
1306  }
1307  else if (dmaOperations->FlushAdapterBuffers(
1314  (BOOLEAN) m_DmaDirection) == FALSE) {
1316  }
1317  else {
1319  }
1320 
1321  if (!NT_SUCCESS(status)) {
1323  "Flushing DMA buffers for WDFDMATRANSACTION %p ("
1324  "MDL %p, Offset %I64x, Length %I64x)"
1325  "completed with %!STATUS!",
1326  GetHandle(),
1330  status);
1331  }
1332 
1333  return status;
1334  }
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3311
BOOLEAN UsesDmaV3(VOID)
LONG NTSTATUS
Definition: precomp.h:26
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2295
PFLUSH_ADAPTER_BUFFERS_EX FlushAdapterBuffersEx
Definition: iotypes.h:2659
uint32_t ULONG_PTR
Definition: typedefs.h:65
FxDmaDescription * m_AdapterInfo
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACINGDMA
Definition: dbgtrace.h:71
unsigned char BOOLEAN
__forceinline WDFDMATRANSACTION GetHandle(VOID)
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
PFLUSH_ADAPTER_BUFFERS FlushAdapterBuffers
Definition: iotypes.h:2638
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static PVOID GetStartVaFromOffset(__in PMDL Mdl, __in size_t Offset)
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
WDF_DMA_DIRECTION m_DmaDirection
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
PDMA_ADAPTER AdapterObject
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
FxDmaEnabler * m_DmaEnabler
Definition: ps.c:97

Referenced by TransferCompleted().

◆ FreeMapRegistersAndAdapter()

virtual VOID FxDmaPacketTransaction::FreeMapRegistersAndAdapter ( VOID  )
inlineprotectedvirtual

Reimplemented in FxDmaSystemTransaction.

Definition at line 1338 of file fxdmatransaction.hpp.

1341  {
1342  KIRQL irql;
1343 
1344  PVOID mapRegisterBase = GetMapRegisterBase();
1345 
1346  //
1347  // It's illegal to free a NULL map register base, even if the HAL gave it
1348  // to us.
1349  //
1350  if (mapRegisterBase == NULL) {
1351  if (GetDriverGlobals()->FxVerifierOn) {
1353  "Skipping free of %d map registers for WDFDMATRANSACTION %p "
1354  "because base was NULL",
1356  GetHandle());
1357  }
1358 
1359  return;
1360  }
1361 
1362  //
1363  // Free the map registers
1364  //
1366 
1367  if (GetDriverGlobals()->FxVerifierOn) {
1369  "Freeing %d map registers for WDFDMATRANSACTION %p "
1370  "(base %p)",
1372  GetHandle(),
1373  mapRegisterBase);
1374  }
1375 
1376  //
1377  // If we pre-reserved map registers then Reserved contains
1378  // the number to free. Otherwise Needed is the number allocated
1379  // for the last transaction, which is the number to free.
1380  //
1382  FreeMapRegisters(m_AdapterInfo->AdapterObject,
1383  mapRegisterBase,
1384  (m_MapRegistersReserved > 0 ?
1387  KeLowerIrql(irql);
1388 
1389  return;
1390  }
KIRQL irql
Definition: wave.h:1
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2295
FxDmaDescription * m_AdapterInfo
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACINGDMA
Definition: dbgtrace.h:71
__forceinline WDFDMATRANSACTION GetHandle(VOID)
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
PDMA_ADAPTER AdapterObject
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
VOID NTAPI KeRaiseIrql(KIRQL NewIrql, PKIRQL OldIrql)
Definition: spinlock.c:27
VOID NTAPI KeLowerIrql(KIRQL NewIrql)
Definition: spinlock.c:39

Referenced by ReleaseResources().

◆ GetAdapterControlReturnValue()

virtual IO_ALLOCATION_ACTION FxDmaPacketTransaction::GetAdapterControlReturnValue ( VOID  )
inlineprotectedvirtual

Reimplemented in FxDmaSystemTransaction.

Definition at line 960 of file fxdmatransaction.hpp.

Referenced by _AdapterControl().

◆ GetMapRegisterBase()

PVOID FxDmaPacketTransaction::GetMapRegisterBase ( VOID  )
inlineprotected

Definition at line 949 of file fxdmatransaction.hpp.

952  {
953  NT_ASSERTMSG("Map register base is not set",
955  return m_MapRegisterBase;
956  }
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3311
#define TRUE
Definition: types.h:120

Referenced by AllocateAdapterChannel(), FlushAdapterBuffers(), FreeMapRegistersAndAdapter(), and MapTransfer().

◆ GetTransferCompletionRoutine()

virtual PDMA_COMPLETION_ROUTINE FxDmaPacketTransaction::GetTransferCompletionRoutine ( VOID  )
inlineprotectedvirtual

Reimplemented in FxDmaSystemTransaction.

Definition at line 1002 of file fxdmatransaction.hpp.

1005  {
1006  return NULL;
1007  }
#define NULL
Definition: types.h:112

Referenced by StageTransfer().

◆ InitializeResources()

_Must_inspect_result_ NTSTATUS FxDmaPacketTransaction::InitializeResources ( VOID  )
virtual

Implements FxDmaTransactionBase.

Definition at line 1233 of file fxdmatransaction.cpp.

1236 {
1237  KIRQL oldIrql;
1239  LockTransferState(&oldIrql);
1240  m_IsCancelled = FALSE;
1241  UnlockTransferState(oldIrql);
1242  return STATUS_SUCCESS;
1243 }
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by ReserveAdapter().

◆ IsMapRegisterBaseSet()

BOOLEAN FxDmaPacketTransaction::IsMapRegisterBaseSet ( VOID  )
inlineprotected

Definition at line 940 of file fxdmatransaction.hpp.

943  {
944  return m_MapRegisterBaseSet;
945  }

Referenced by _AdapterControl(), and ReleaseResources().

◆ MapTransfer()

FORCEINLINE NTSTATUS FxDmaPacketTransaction::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 
)
inlineprotected

Definition at line 1140 of file fxdmatransaction.hpp.

1148  {
1149  //
1150  // Cache globals & object handle since call to MapTransferEx could
1151  // result in a DmaComplete callback before returning.
1152  //
1154  WDFDMATRANSACTION handle = GetHandle();
1155 #if DBG
1156  ULONG_PTR mapRegistersRequired;
1157 
1158  mapRegistersRequired = ADDRESS_AND_SIZE_TO_SPAN_PAGES(
1162  );
1163  NT_ASSERTMSG("Mapping requires too many map registers",
1164  mapRegistersRequired <= m_MapRegistersNeeded);
1165 #endif
1166 
1167  NTSTATUS status;
1168 
1169  //
1170  // Assume we're going to transfer the entire current fragment.
1171  // MapTransfer may say otherwise.
1172  //
1173 
1174  *TransferLength = (ULONG) m_CurrentFragmentLength;
1175 
1176  //
1177  // Map the transfer.
1178  //
1179 
1182  "Mapping transfer for WDFDMATRANSACTION %p. "
1183  "MDL %p, Offset %I64x, Length %x, MapRegisterBase %p",
1184  handle,
1187  *TransferLength,
1188  GetMapRegisterBase());
1189  }
1190 
1191  if (m_DmaEnabler->UsesDmaV3()) {
1192 
1193  PDMA_OPERATIONS dmaOperations =
1195 
1196  status = dmaOperations->MapTransferEx(
1202  TransferLength,
1204  ScatterGatherList,
1205  ScatterGatherListCb,
1208  );
1209 
1210  NT_ASSERTMSG(
1211  "With these parameters, MapTransferEx should never fail",
1213  );
1214  }
1215  else {
1216  NT_ASSERTMSG("cannot use DMA completion routine with DMAv2",
1217  CompletionRoutine == NULL);
1218 
1219  NT_ASSERTMSG(
1220  "scatter gather list length must be large enough for at least one element",
1221  (ScatterGatherListCb >= (sizeof(SCATTER_GATHER_LIST) +
1222  sizeof(SCATTER_GATHER_ELEMENT)))
1223  );
1224 
1225  //
1226  // This matches the assertion above. There's no way to explain to
1227  // prefast that this code path requires the caller to provide a buffer
1228  // of sufficient size to store the SGL. The only case which doesn't
1229  // provide any buffer is system-mode DMA and that uses DMA v3 and so
1230  // won't go through this path.
1231  //
1232 
1233  __assume((ScatterGatherListCb >= (sizeof(SCATTER_GATHER_LIST) +
1234  sizeof(SCATTER_GATHER_ELEMENT))));
1235 
1236  ScatterGatherList->NumberOfElements = 1;
1237  ScatterGatherList->Reserved = 0;
1238  ScatterGatherList->Elements[0].Address =
1245  TransferLength,
1247  ScatterGatherList->Elements[0].Length = *TransferLength;
1248 
1250  }
1251 
1254  "MapTransfer mapped next %d bytes of "
1255  "WDFDMATRANSACTION %p - status %!STATUS!",
1256  *TransferLength,
1257  handle,
1258  status);
1259  }
1260 
1261  return status;
1262  }
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3311
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE _In_opt_ __drv_aliasesMem WDFCONTEXT CompletionContext
Definition: wdfrequest.h:893
BOOLEAN UsesDmaV3(VOID)
LONG NTSTATUS
Definition: precomp.h:26
PMAP_TRANSFER_EX MapTransferEx
Definition: iotypes.h:2656
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2295
uint32_t ULONG_PTR
Definition: typedefs.h:65
FxDmaDescription * m_AdapterInfo
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACINGDMA
Definition: dbgtrace.h:71
unsigned char BOOLEAN
struct _SCATTER_GATHER_LIST SCATTER_GATHER_LIST
Definition: iotypes.h:2204
__forceinline WDFDMATRANSACTION GetHandle(VOID)
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
static PVOID GetStartVaFromOffset(__in PMDL Mdl, __in size_t Offset)
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)
WDF_DMA_DIRECTION m_DmaDirection
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
PDMA_ADAPTER AdapterObject
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:893
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
FxDmaEnabler * m_DmaEnabler
Definition: ps.c:97

Referenced by StageTransfer().

◆ PreMapTransfer()

virtual BOOLEAN FxDmaPacketTransaction::PreMapTransfer ( VOID  )
inlineprotectedvirtual

Reimplemented in FxDmaSystemTransaction.

Definition at line 969 of file fxdmatransaction.hpp.

972  {
973  return TRUE;
974  }
#define TRUE
Definition: types.h:120

Referenced by StageTransfer().

◆ ReleaseAdapter()

VOID FxDmaPacketTransaction::ReleaseAdapter ( VOID  )

Definition at line 1465 of file fxdmatransaction.cpp.

1468 {
1470  WDFDMATRANSACTION dmaTransaction = GetHandle();
1471 
1474  "Enter WDFDMATRANSACTION %p", dmaTransaction);
1475  }
1476 
1477  //
1478  // Must not be in invalid, created, transfer or deleted state
1479  //
1484 
1486  "WDFDMATRANSACTION %p state %!FxDmaTransactionState! "
1487  "is invalid", dmaTransaction, m_State);
1488 
1490  WDF_DMA_FATAL_ERROR, // specific type
1491  (ULONG_PTR) GetObjectHandle(), // parm 2
1492  (ULONG_PTR) m_State); // parm 3
1493  }
1494 
1495  //
1496  // The caller wants to free the reserved map registers, so force their
1497  // release.
1498  //
1500 
1503  "Exit WDFDMATRANSACTION %p",
1504  dmaTransaction);
1505  }
1506 
1507  return;
1508 }
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
#define TRUE
Definition: types.h:120
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACINGDMA
Definition: dbgtrace.h:71
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
__forceinline WDFDMATRANSACTION GetHandle(VOID)
PFX_DRIVER_GLOBALS pFxDriverGlobals
VOID ReleaseForReuse(__in BOOLEAN ForceRelease)
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxDmaTransactionState m_State

◆ ReleaseDevice()

FORCEINLINE VOID FxDmaPacketTransaction::ReleaseDevice ( VOID  )
inlineprotected

Definition at line 1037 of file fxdmatransaction.hpp.

1040  {
1041  if (m_DmaEnabler->UsesDmaV3() == FALSE)
1042  {
1044  }
1045  }
BOOLEAN UsesDmaV3(VOID)
#define FALSE
Definition: types.h:117
CfxDevice * GetDevice(VOID)
Definition: fxobject.hpp:781
__inline VOID ReleaseDmaPacketTransaction(VOID)
Definition: fxdevice.hpp:373
FxDmaEnabler * m_DmaEnabler

Referenced by ReleaseResources(), and StartTransfer().

◆ ReleaseResources()

VOID FxDmaPacketTransaction::ReleaseResources ( __in BOOLEAN  ForceRelease)
virtual

Implements FxDmaTransactionBase.

Definition at line 1246 of file fxdmatransaction.cpp.

1249 {
1250  //
1251  // If the map register base hasn't been assigned, then just
1252  // skip this.
1253  //
1254 
1255  if (IsMapRegisterBaseSet() == FALSE) {
1256  return;
1257  }
1258 
1259  //
1260  // Map registers are reserved. Unless the caller is forcing
1261  // us to free them, just return. Otherwise updated the
1262  // number of map registers that FreeMapRegistersAndAdapter
1263  // is going to look at.
1264  //
1265  if ((m_MapRegistersReserved > 0) && (ForceRelease == FALSE))
1266  {
1267  return;
1268  }
1269 
1270  //
1271  // Free the map registers and release the device.
1272  //
1274 
1276 
1277  ReleaseDevice();
1278 
1279  m_AdapterInfo = NULL;
1281 }
FORCEINLINE VOID ReleaseDevice(VOID)
BOOLEAN IsMapRegisterBaseSet(VOID)
FxDmaDescription * m_AdapterInfo
#define FALSE
Definition: types.h:117
#define NULL
Definition: types.h:112
virtual VOID FreeMapRegistersAndAdapter(VOID)

◆ ReserveAdapter()

_Must_inspect_result_ NTSTATUS FxDmaPacketTransaction::ReserveAdapter ( __in ULONG  NumberOfMapRegisters,
__in WDF_DMA_DIRECTION  Direction,
__in PFN_WDF_RESERVE_DMA  Callback,
__in_opt PVOID  Context 
)

Definition at line 1285 of file fxdmatransaction.cpp.

1291 {
1292  NTSTATUS status;
1294  WDFDMATRANSACTION dmaTransaction = GetHandle();
1295 
1298  "Enter WDFDMATRANSACTION %p", dmaTransaction);
1299  }
1300 
1301  //
1302  // If caller doesn't supply a map register count then we get the count
1303  // out of the transaction. So the transaction must be initialized.
1304  //
1305  // Otherwise the transaction can't be executing.
1306  //
1307  if (NumberOfMapRegisters == 0) {
1310 
1312  "RequiredMapRegisters cannot be 0 because "
1313  "WDFDMATRANSACTION %p is not initialized ("
1314  "state is %!FxDmaTransactionState!) - %!STATUS!",
1315  GetHandle(),
1316  m_State,
1317  status);
1319  WDF_DMA_FATAL_ERROR, // specific type
1320  (ULONG_PTR) GetObjectHandle(), // parm 2
1321  (ULONG_PTR) m_State); // parm 3
1322  }
1323  }
1324  else if (m_State != FxDmaTransactionStateCreated &&
1327 
1329  "WDFDMATRANSACTION %p state %!FxDmaTransactionState! "
1330  "is invalid", dmaTransaction, m_State);
1331 
1333  WDF_DMA_FATAL_ERROR, // specific type
1334  (ULONG_PTR) GetObjectHandle(), // parm 2
1335  (ULONG_PTR) m_State); // parm 3
1336  }
1337 
1338  //
1339  // Must not already have reserved map registers
1340  //
1341  if (m_MapRegistersReserved != 0)
1342  {
1344  "WDFDMATRANSACTION %p already has allocated map registers.",
1345  dmaTransaction);
1346 
1348  WDF_DMA_FATAL_ERROR, // specific type
1349  (ULONG_PTR) GetObjectHandle(), // parm 2
1350  (ULONG_PTR) m_State); // parm 3
1351  }
1352 
1353  //
1354  // Get the adapter
1355  //
1358  } else {
1360  }
1361 
1362  //
1363  // Save the number of map registers being reserved.
1364  //
1365  if (NumberOfMapRegisters != 0) {
1366 
1367  //
1368  // Use the number the caller passed us
1369  //
1371  }
1372  else if (m_DmaEnabler->IsBusMaster() == FALSE) {
1373 
1374  //
1375  // For system DMA use all the map registers we have
1376  //
1378 
1379  } else {
1380 
1381  //
1382  // Compute the number of map registers required based on
1383  // the MDL and length passed in
1384  //
1386  m_StartMdl,
1387  m_StartOffset,
1390  NULL,
1392  );
1393 
1394  if (!NT_SUCCESS(status)) {
1396  goto End;
1397  }
1398  }
1399 
1400  //
1401  // Initialize the DmaTransaction object with enough data to
1402  // trick StartTransfer into allocating the adapter channel for us.
1403  //
1405  m_StartMdl = NULL;
1406  m_StartOffset = 0;
1409  m_Remaining = 0;
1410  m_TransactionLength = 0;
1411 
1412  //
1413  // Save the callback and context
1414  //
1417 
1418  //
1419  // If needed, initialize the transfer context.
1420  //
1421  if (m_DmaEnabler->UsesDmaV3()) {
1423  m_DmaDirection);
1424  }
1425 
1427  if (NT_SUCCESS(status)) {
1428  //
1429  // Set the state to reserved so _AdapterControl knows which
1430  // callback to invoke.
1431  //
1433  } else {
1435  goto End;
1436  }
1437 
1438  //
1439  // Start the adapter channel allocation through StartTransfer
1440  //
1441  status = StartTransfer();
1442 
1443 End:
1444  if (!NT_SUCCESS(status)) {
1449 
1450  if (m_EncodedRequest != NULL) {
1452  }
1453  }
1454 
1457  "Exit WDFDMATRANSACTION %p, %!STATUS!",
1458  dmaTransaction, status);
1459  }
1460 
1461  return status;
1462 }
__inline FxDmaDescription * GetReadDmaDescription(VOID)
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
_Out_ PULONG NumberOfMapRegisters
Definition: halfuncs.h:209
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
BOOLEAN UsesDmaV3(VOID)
LONG NTSTATUS
Definition: precomp.h:26
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
FxDmaDescription * m_AdapterInfo
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACINGDMA
Definition: dbgtrace.h:71
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
union FxDmaTransactionProgramOrReserveDma::@4097 Method
__forceinline WDFDMATRANSACTION GetHandle(VOID)
_In_ WDFDMAENABLER _In_ WDF_DMA_DIRECTION DmaDirection
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID ReleaseForReuse(__in BOOLEAN ForceRelease)
__forceinline VOID ReleaseButRetainRequest(VOID)
__inline FxDmaDescription * GetWriteDmaDescription(VOID)
virtual _Must_inspect_result_ NTSTATUS InitializeResources(VOID)
__inline BOOLEAN IsBusMaster(VOID)
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
WDF_DMA_DIRECTION m_DmaDirection
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
virtual _Must_inspect_result_ NTSTATUS StartTransfer(VOID)
VOID InitializeTransferContext(__out PVOID Context, __in WDF_DMA_DIRECTION Direction)
#define NULL
Definition: types.h:112
FxDmaTransactionProgramOrReserveDma m_DmaAcquiredFunction
struct tagContext Context
Definition: acpixf.h:1034
FxDmaTransactionState m_State
unsigned int ULONG
Definition: retypes.h:1
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 SERVICE_STATUS status
Definition: service.c:31
FxDmaEnabler * m_DmaEnabler
Definition: ps.c:97

◆ Reuse()

virtual VOID FxDmaPacketTransaction::Reuse ( VOID  )
inlineprotectedvirtual

Reimplemented from FxDmaTransactionBase.

Reimplemented in FxDmaSystemTransaction.

Definition at line 905 of file fxdmatransaction.hpp.

908  {
909  return;
910  }

Referenced by FxDmaSystemTransaction::Reuse().

◆ SetDeviceAddressOffset()

VOID FxDmaPacketTransaction::SetDeviceAddressOffset ( __in ULONG  Offset)
inline

Definition at line 802 of file fxdmatransaction.hpp.

805  {
807  }
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101

◆ SetMapRegisterBase()

void FxDmaPacketTransaction::SetMapRegisterBase ( __in PVOID  Value)
inlineprotected

Definition at line 916 of file fxdmatransaction.hpp.

919  {
920  NT_ASSERTMSG("Map register base is already set",
922 
925  }
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3311
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406

Referenced by _AdapterControl().

◆ StageTransfer()

_Must_inspect_result_ NTSTATUS FxDmaPacketTransaction::StageTransfer ( VOID  )
virtual

Implements FxDmaTransactionBase.

Definition at line 1796 of file fxdmatransaction.cpp.

1799 {
1800  PSCATTER_GATHER_LIST sgList;
1801 
1803  UCHAR_MEMORY_ALIGNED sgListBuffer[sizeof(SCATTER_GATHER_LIST)
1804  + sizeof(SCATTER_GATHER_ELEMENT)];
1805  WDFDMATRANSACTION dmaTransaction;
1806 
1807  KIRQL oldIrql;
1808  BOOLEAN stagingNeeded;
1809 
1811 
1812  //
1813  // Client driver could complete and delete the object in
1814  // EvtProgramDmaFunction. So, save the handle because we need it
1815  // for tracing after we invoke the callback.
1816  //
1818  dmaTransaction = GetHandle();
1819 
1822  "Enter WDFDMATRANSACTION %p ", dmaTransaction);
1823  }
1824 
1825  //
1826  // For packet base DMA, current and startMDL will always be
1827  // same. For V2 DMA we don't support MDL chains. For V3 DMA
1828  // we use the HAL's support for MDL chains and don't walk through
1829  // the MDL chain on our own.
1830  //
1832 
1833  LockTransferState(&oldIrql);
1834 
1835  if (m_TransferState.CurrentStagingThread != NULL) {
1836 
1837  //
1838  // Staging in progress. Indicate that another staging will
1839  // be needed.
1840  //
1841  m_TransferState.RerunStaging = TRUE;
1842 
1843  stagingNeeded = FALSE;
1844 
1848  "Staging next fragment of WDFDMATRANSACTION %p "
1849  "deferred",
1850  dmaTransaction
1851  );
1852  }
1853  }
1854  else {
1855  //
1856  // Staging isn't in progress anyplace else. Indicate that it's
1857  // running now so that any parallel attempt is blocked.
1858  //
1859  m_TransferState.CurrentStagingThread = KeGetCurrentThread();
1860 
1861  ASSERTMSG("The thread which was staging didn't clear "
1862  "RerunStaging",
1863  (m_TransferState.RerunStaging == FALSE));
1864 
1865  stagingNeeded = TRUE;
1866  }
1867 
1868  UnlockTransferState(oldIrql);
1869 
1870  //
1871  // Take a reference on the transaction so that we can safely
1872  // manipulate the transfer state even after it's destroyed.
1873  //
1875 
1876  //
1877  // Loop for as long as staging is required
1878  //
1879  while (stagingNeeded) {
1880 
1881  //
1882  // Calculate length for this packet.
1883  //
1885 
1886  //
1887  // Calculate address for this packet.
1888  //
1890 
1891  //
1892  // Adjust the fragment length for the number of reserved map registers.
1893  //
1894  if ((m_MapRegistersReserved > 0) &&
1896  {
1897  size_t currentOffset = m_CurrentFragmentOffset;
1898  size_t currentPageOffset;
1899  PMDL mdl;
1900 
1901  for (mdl = m_CurrentFragmentMdl; mdl != NULL; mdl = mdl->Next)
1902  {
1903  //
1904  // For packet/system transfers of chained MDLs, m_CurrentFragmentMdl
1905  // is never adjusted, and m_CurrentFragmentOFfset is the offset
1906  // into the entire chain.
1907  //
1908  // Locate the MDL which contains the current fragment.
1909  //
1910  ULONG mdlBytes = MmGetMdlByteCount(mdl);
1911  if (mdlBytes >= currentOffset)
1912  {
1913  //
1914  // This MDL is larger than the remaining offset, so it
1915  // contains the start address.
1916  //
1917  break;
1918  }
1919 
1920  currentOffset -= mdlBytes;
1921  }
1922 
1923  ASSERT(mdl != NULL);
1924 
1925  //
1926  // Compute page offset from current MDL's initial page offset
1927  // and the offset into that MDL
1928  //
1929 
1930  currentPageOffset = BYTE_OFFSET(MmGetMdlByteOffset(mdl) +
1931  currentOffset);
1932 
1933  //
1934  // Compute the maximum number of bytes we can transfer with
1935  // the number of map registers we have reserved, taking into
1936  // account the offset of the first page.
1937  //
1938  size_t l = ((PAGE_SIZE * (m_MapRegistersReserved - 1)) +
1939  (PAGE_SIZE - currentPageOffset));
1940 
1942  }
1943 
1945 
1948  "Initiating %s transfer for WDFDMATRANSACTION %p. "
1949  "Mdl %p, Offset %I64x, Length %I64x",
1950  m_Transferred == 0 ? "first" : "next",
1951  GetHandle(),
1953  m_Transferred,
1955  }
1956 
1957  //
1958  // Check for a pending cancellation. This can happen if the cancel
1959  // occurred between DMA completion and FlushAdapterBuffers -
1960  // FlushAdapterBuffers will clear the canceled bit in the transfer
1961  // context (TC), which would allow MapTransfer to succeed.
1962  //
1963  // An unprotected check of IsCancelled here is safe. A concurrent
1964  // cancel at this point would mark the TC cancelled such that
1965  // MapTransfer will fail.
1966  //
1967  if (m_IsCancelled == TRUE) {
1969  goto End;
1970  }
1971 
1972  //
1973  // Profile specific work before mapping the transfer. if this
1974  // fails consider 'this' invalid.
1975  //
1976  if (PreMapTransfer() == FALSE) {
1978  goto End;
1979  }
1980 
1981  //
1982  // Map this packet for transfer.
1983  //
1984 
1985  //
1986  // For packet based DMA we use a single entry on-stack SGL. This
1987  // allows us to map multiple packet-based requests concurrently and
1988  // we know packet base DMA only requires a single SGL
1989  //
1990  // NOTE: It turns out the HAL doesn't handle chained MDLs in packet
1991  // mode correctly. It makes each MDL continguous, but returns
1992  // a list of SG elements - one for each MDL. That's scatter
1993  // gather DMA, not packet DMA.
1994  //
1995  // So it's actually very important in Win8 that we only use a
1996  // single entry SGL when calling MapTransferEx. This ensures
1997  // we only map the first MDL in the chain and thus get a
1998  // contiguous buffer
1999  //
2000  // For system DMA we use the SystemSGList stored in the DMA enabler
2001  // We can use a shared one in that case because we won't be mapping
2002  // multiple system DMA requests concurrently (HAL doesn't allow it)
2003  //
2004  FxDmaEnabler* enabler = GetDmaEnabler();
2005  size_t sgListSize;
2006 
2007  if (enabler->IsBusMaster()) {
2008  sgList = (PSCATTER_GATHER_LIST)sgListBuffer;
2009  sgListSize = sizeof(sgListBuffer);
2010  } else {
2011  sgList = enabler->m_SGList.SystemProfile.List;
2012  sgListSize = enabler->m_SGListSize;
2013  }
2014 
2015  ULONG mappedBytes;
2016 
2017  status = MapTransfer(sgList,
2018  (ULONG) sgListSize,
2020  this,
2021  &mappedBytes);
2022 
2023  NT_ASSERTMSG("Unexpected failure of MapTransfer",
2024  ((NT_SUCCESS(status) == TRUE) ||
2025  (status == STATUS_CANCELLED)));
2026 
2027  if (NT_SUCCESS(status)) {
2028 
2029  NT_ASSERTMSG("unexpected number of mapped bytes",
2030  ((mappedBytes > 0) &&
2031  (mappedBytes <= m_CurrentFragmentLength)));
2032 
2033  //
2034  // Adjust the remaining byte count if the HAL mapped less data than we
2035  // requested.
2036  //
2037  if (mappedBytes < m_CurrentFragmentLength) {
2038  m_Remaining += m_CurrentFragmentLength - mappedBytes;
2039  m_CurrentFragmentLength = mappedBytes;
2040  }
2041 
2042  //
2043  // Do client PFN_WDF_PROGRAM_DMA callback.
2044  //
2046 
2049  "Invoking ProgramDma callback %p (context %p) for "
2050  "WDFDMATRANSACTION %p.",
2053  GetHandle()
2054  );
2055  }
2056 
2057  //
2058  // Call program DMA
2059  //
2061  GetHandle(),
2065  sgList
2066  );
2067  }
2068  }
2069 
2070 End:
2071  //
2072  // Process any pending completion or nested staging.
2073  //
2074  {
2075  LockTransferState(&oldIrql);
2076 
2077  //
2078  // While staging we could either have deferred a call to the
2079  // completion routine or deferred another call to stage the
2080  // next fragment. We should not ever have to do both - this
2081  // would imply that the driver didn't wait for its DMA completion
2082  // routine to run when calling TransferComplete*.
2083  //
2084  ASSERTMSG("driver called TransferComplete with pending DMA "
2085  "completion callback",
2086  !((m_TransferState.RerunCompletion == TRUE) &&
2087  (m_TransferState.RerunStaging == TRUE)));
2088 
2089  //
2090  // Check for pending completion. save the status away and clear it
2091  // before dropping the lock.
2092  //
2093  if (m_TransferState.RerunCompletion == TRUE) {
2094  DMA_COMPLETION_STATUS completionStatus;
2096 
2097  //
2098  // Save the completion status for when we drop the lock.
2099  //
2100  completionStatus = m_TransferState.CompletionStatus;
2101 
2102  ASSERTMSG("completion needed, but status was not set or was "
2103  "already cleared",
2104  completionStatus != UNDEFINED_DMA_COMPLETION_STATUS);
2105 
2106  ASSERTMSG("completion needed, but mapping failed so there shouldn't "
2107  "be any parallel work going on",
2108  NT_SUCCESS(status));
2109 
2110  //
2111  // Clear the completion needed state.
2112  //
2113  m_TransferState.RerunCompletion = FALSE;
2115 
2116  //
2117  // Drop the lock, call the completion routine, then take the
2118  // lock again.
2119  //
2120  UnlockTransferState(oldIrql);
2123  "Invoking DmaCompleted callback %p (context %p) "
2124  "for WDFDMATRANSACTION %p (status %x) "
2125  "after deferral",
2128  GetHandle(),
2129  completionStatus);
2130  }
2131  CallEvtDmaCompleted(completionStatus);
2132  LockTransferState(&oldIrql);
2133 
2134  //
2135  // Staging is blocked, which means we aren't starting up the
2136  // next transfer. Therefore we cannot have a queued completion.
2137  //
2138  ASSERTMSG("RerunCompletion should not be set on an unstaged "
2139  "transaction",
2140  m_TransferState.RerunCompletion == FALSE);
2141  }
2142 
2143  //
2144  // Capture whether another staging is needed. If none is needed
2145  // then we can clear staging in progress.
2146  //
2147  if (m_TransferState.RerunStaging == TRUE) {
2148  stagingNeeded = TRUE;
2149  m_TransferState.RerunStaging = FALSE;
2150  }
2151  else {
2152  m_TransferState.CurrentStagingThread = NULL;
2153  stagingNeeded = FALSE;
2154  }
2155 
2156  UnlockTransferState(oldIrql);
2157  }
2158 
2159 #if DBG
2160  if (!NT_SUCCESS(status)) {
2161  ASSERTMSG("MapTransfer returned an error - there should not be any "
2162  "deferred work.",
2163  (stagingNeeded == FALSE));
2164  }
2165 #endif
2166 
2167  } // while(stagingNeeded)
2168 
2170 
2173  "Exit WDFDMATRANSACTION %p, "
2174  "%!STATUS!", dmaTransaction,
2175  status);
2176  }
2177 
2178  return status;
2179 }
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3311
virtual ULONG Release(__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxobject.hpp:853
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
#define TRUE
Definition: types.h:120
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
LONG NTSTATUS
Definition: precomp.h:26
virtual PDMA_COMPLETION_ROUTINE GetTransferCompletionRoutine(VOID)
BOOLEAN InvokeProgramDma(__in WDFDMATRANSACTION Transaction, __in WDFDEVICE Device, __in PVOID Context, __in WDF_DMA_DIRECTION Direction, __in PSCATTER_GATHER_LIST SgList)
struct FxDmaPacketTransaction::@4096 m_TransferState
FxDmaTransactionTransferComplete m_TransferCompleteFunction
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACINGDMA
Definition: dbgtrace.h:71
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
union FxDmaTransactionProgramOrReserveDma::@4097 Method
unsigned char BOOLEAN
struct _SCATTER_GATHER_LIST SCATTER_GATHER_LIST
Definition: iotypes.h:2204
__forceinline WDFDMATRANSACTION GetHandle(VOID)
r l[0]
Definition: byte_order.h:167
#define UNDEFINED_DMA_COMPLETION_STATUS
PFX_DRIVER_GLOBALS pFxDriverGlobals
DMA_COMPLETION_STATUS
Definition: iotypes.h:2298
#define ASSERT(a)
Definition: mode.c:44
size_t m_SGListSize
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
__forceinline FxDmaEnabler * GetDmaEnabler(VOID)
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
union FxDmaEnabler::@4583 m_SGList
CfxDeviceBase * m_DeviceBase
Definition: fxobject.hpp:328
#define VOID
Definition: acefi.h:82
#define PAGE_SIZE
Definition: env_spec_w32.h:49
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)
MDL * mdl
virtual VOID CallEvtDmaCompleted(__in DMA_COMPLETION_STATUS)
__inline size_t FxSizeTMin(__in size_t A, __in size_t B)
Definition: fxglobals.h:997
__inline BOOLEAN IsBusMaster(VOID)
WDF_DMA_DIRECTION m_DmaDirection
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define MmGetMdlByteCount(_Mdl)
#define NULL
Definition: types.h:112
FxDmaTransactionProgramOrReserveDma m_DmaAcquiredFunction
ULONG __inline AddRef(__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxobject.hpp:826
PFN_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE Method
virtual BOOLEAN PreMapTransfer(VOID)
FxDmaSystemTransaction * systemTransaction
struct _SCATTER_GATHER_LIST * PSCATTER_GATHER_LIST
Definition: iotypes.h:2204
unsigned int ULONG
Definition: retypes.h:1
#define MmGetMdlByteOffset(_Mdl)
#define STATUS_SUCCESS
Definition: shellext.h:65
struct FxDmaEnabler::@4583::@4585 SystemProfile
#define KeGetCurrentThread
Definition: hal.h:55
static SERVICE_STATUS status
Definition: service.c:31
#define BYTE_OFFSET(Va)
FxDmaEnabler * m_DmaEnabler
Definition: ps.c:97

Referenced by _AdapterControl().

◆ StartTransfer()

_Must_inspect_result_ NTSTATUS FxDmaPacketTransaction::StartTransfer ( VOID  )
virtual

Implements FxDmaTransactionBase.

Definition at line 1512 of file fxdmatransaction.cpp.

1515 {
1516  NTSTATUS status;
1518  WDFDMATRANSACTION dmaTransaction;
1519 
1520  //
1521  // Client driver could complete and delete the object in
1522  // EvtProgramDmaFunction. So, save the handle because we need it
1523  // for tracing after we invoke the callback.
1524  //
1525  dmaTransaction = GetHandle();
1526 
1529  "Enter WDFDMATRANSACTION %p",
1530  dmaTransaction);
1531 
1533  "Starting WDFDMATRANSACTION %p - MDL %#p, "
1534  "offset %I64x, length %I64x",
1535  dmaTransaction,
1536  m_StartMdl,
1537  m_StartOffset,
1539  }
1540 
1541  //
1542  // Reference the device when using DMA v2. For DMA v3 we can support
1543  // concurrent attempts to allocate the channel.
1544  //
1545  status = AcquireDevice();
1546  if (!NT_SUCCESS(status)) {
1547 
1548  NT_ASSERTMSG("AcquireDevice should never fail when DMAv3 is in use",
1549  m_DmaEnabler->UsesDmaV3());
1550 
1552  "Only one transaction can be queued "
1553  "at one time on a packet based WDFDMAENABLER %p "
1554  "%!STATUS!", m_DmaEnabler->GetHandle(),
1555  status);
1557  return status;
1558  }
1559 
1560  //
1561  // Calculate the initial DMA transfer length.
1562  //
1564 
1566 
1568  //
1569  // Caller is simply reserving the DMA adapter for later use. Ask for
1570  // as many map registers as the driver requested.
1571  //
1573 
1574  ASSERT(m_MapRegistersNeeded <= m_AdapterInfo->NumberOfMapRegisters);
1575 
1577 
1578  }
1579  else {
1580 
1581  if (m_DmaEnabler->IsBusMaster() == FALSE) {
1582 
1583  //
1584  // Use as many map registers as we were granted.
1585  //
1587  } else {
1588 
1589  //
1590  // If the transfer is the size of the transaction then use the offset
1591  // to determine the number of map registers needed. If it's smaller
1592  // then use the worst-case offset to make sure we ask for enough MR's
1593  // to account for a bigger offset in one of the later transfers.
1594  //
1595  // Example:
1596  // Transaction is 8 KB and is page aligned
1597  // if max transfer is >= 8KB then this will be one transfer and only
1598  // requires two map registers. Even if the driver completes a partial
1599  // transfer and we have to do the rest in a second transfer it will
1600  // fit within two map registers becuase the overall transaction does
1601  // (and a partial transfer can't take more map registers than the
1602  // whole transaction would).
1603  //
1604  // If max transfer is 2KB then this nominally requires 4 2KB transfers.
1605  // In this case however, a partial completion of one of those transfers
1606  // would leave us attempting a second 2KB transfer starting on an
1607  // unaligned address. For example, we might transfer 2KB, then 1KB
1608  // then 2KB. Even though the first transfer was page aligned, the
1609  // 3rd transfer isn't and could cross a page boundary, requiring two
1610  // map registers rather than one.
1611  //
1612  // To account for this second case, ignore the actual MDL offset and
1613  // instead compute the maximum number of map registers than an N byte
1614  // transfer could take (with worst-case alignment).
1615  //
1616  //
1622  (PVOID)(ULONG_PTR) (PAGE_SIZE -1)),
1624  );
1625 
1626 
1627  ASSERT(m_MapRegistersNeeded <= m_AdapterInfo->NumberOfMapRegisters);
1628  }
1629 
1630  //
1631  // NOTE: the number of map registers needed for this transfer may
1632  // exceed the number that we've reserved. StageTransfer will
1633  // take care of fragmenting the transaction accordingly.
1634  //
1636  }
1637 
1638  if (!NT_SUCCESS(status)) {
1640  "AllocateAdapterChannel failed for "
1641  "WDFDMATRANSACTION %p, %!STATUS!",
1642  dmaTransaction, status);
1643  ReleaseDevice();
1644  }
1645 
1646  //
1647  // Before AllocateAdapterChannel returns, _AdapterControl can get called
1648  // on another thread and the driver could delete the transaction object.
1649  // So don't touch the object after this point.
1650  //
1653  "Exit WDFDMATRANSACTION %p, "
1654  "%!STATUS!", dmaTransaction, status);
1655  }
1656 
1657  return status;
1658 }
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3311
FORCEINLINE VOID ReleaseDevice(VOID)
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
_Out_ PULONG NumberOfMapRegisters
Definition: halfuncs.h:209
BOOLEAN UsesDmaV3(VOID)
LONG NTSTATUS
Definition: precomp.h:26
uint32_t ULONG_PTR
Definition: typedefs.h:65
FxDmaDescription * m_AdapterInfo
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACINGDMA
Definition: dbgtrace.h:71
__inline WDFDMAENABLER GetHandle(VOID)
__forceinline WDFDMATRANSACTION GetHandle(VOID)
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static PVOID GetStartVaFromOffset(__in PMDL Mdl, __in size_t Offset)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
__inline size_t FxSizeTMin(__in size_t A, __in size_t B)
Definition: fxglobals.h:997
__inline BOOLEAN IsBusMaster(VOID)
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxDmaTransactionState m_State
unsigned int ULONG
Definition: retypes.h:1
_Must_inspect_result_ NTSTATUS AllocateAdapterChannel(__in BOOLEAN MapRegistersReserved)
static SERVICE_STATUS status
Definition: service.c:31
_Must_inspect_result_ NTSTATUS AcquireDevice(VOID)
FxVerifierDbgBreakPoint(pFxDriverGlobals)
FxDmaEnabler * m_DmaEnabler
Definition: ps.c:97

Referenced by ReserveAdapter().

◆ TransferCompleted()

_Must_inspect_result_ NTSTATUS FxDmaPacketTransaction::TransferCompleted ( VOID  )
virtual

Implements FxDmaTransactionBase.

Definition at line 2183 of file fxdmatransaction.cpp.

2186 {
2187  NTSTATUS status;
2189 
2190  //
2191  // Flush the buffers
2192  //
2194 
2195  if (!NT_SUCCESS(status)) {
2197  "FlushAdapterBuffers on WDFDMATRANSACTION %p "
2198  "failed, %!STATUS!",
2199  GetHandle(), status);
2201  }
2202 
2203  return status;
2204 }
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE NTSTATUS FlushAdapterBuffers(VOID)
#define TRACINGDMA
Definition: dbgtrace.h:71
__forceinline WDFDMATRANSACTION GetHandle(VOID)
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
static SERVICE_STATUS status
Definition: service.c:31
FxVerifierDbgBreakPoint(pFxDriverGlobals)
Definition: ps.c:97

Member Data Documentation

◆ CompletionStatus

DMA_COMPLETION_STATUS FxDmaPacketTransaction::CompletionStatus

Definition at line 884 of file fxdmatransaction.hpp.

◆ CurrentStagingThread

PKTHREAD FxDmaPacketTransaction::CurrentStagingThread

Definition at line 868 of file fxdmatransaction.hpp.

◆ m_DeviceAddressOffset

ULONG FxDmaPacketTransaction::m_DeviceAddressOffset
protected

◆ m_IsCancelled

ULONG FxDmaPacketTransaction::m_IsCancelled
protected

◆ m_MapRegisterBase

PVOID FxDmaPacketTransaction::m_MapRegisterBase
protected

◆ m_MapRegisterBaseSet

BOOLEAN FxDmaPacketTransaction::m_MapRegisterBaseSet
protected

◆ m_MapRegistersNeeded

◆ m_MapRegistersReserved

ULONG FxDmaPacketTransaction::m_MapRegistersReserved
protected

◆ m_TransferState

struct { ... } FxDmaPacketTransaction::m_TransferState

◆ RerunCompletion

BOOLEAN FxDmaPacketTransaction::RerunCompletion

Definition at line 883 of file fxdmatransaction.hpp.

◆ RerunStaging

BOOLEAN FxDmaPacketTransaction::RerunStaging

Definition at line 875 of file fxdmatransaction.hpp.


The documentation for this class was generated from the following files: