reactos/sdk/lib/drivers/wdf/shared/inc/private/km/fxdmaenabler.hpp
Victor Perevertkin 1f377076d7
[WDF] Fix KMDF so it can compile with ReactOS SDK
Not all files are included, but these are necessary to compile cdrom driver.
So far it can only be statically linked with drivers, a proper
implementation requires wdfldr helper driver
2020-11-03 00:06:27 +03:00

479 lines
11 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Module Name:
FxDmaEnabler.hpp
Abstract:
WDF DMA Enabler support
Environment:
Kernel mode only.
Notes:
Revision History:
--*/
#ifndef __FX_DMA_ENABLER_HPP__
#define __FX_DMA_ENABLER_HPP__
#include "fxdmaenablercallbacks.hpp"
//
// Dma Description structure
//
typedef struct _FxDmaDescription {
DEVICE_DESCRIPTION DeviceDescription;
PDMA_ADAPTER AdapterObject;
//
// The size of a preallocated lookaside list for this DMA adapter
//
size_t PreallocatedSGListSize;
size_t MaximumFragmentLength;
ULONG NumberOfMapRegisters;
} FxDmaDescription;
enum FxDuplexDmaDescriptionType {
FxDuplexDmaDescriptionTypeRead = 0,
FxDuplexDmaDescriptionTypeWrite,
FxDuplexDmaDescriptionTypeMax,
};
//
// Make sure the two enums which match to the channels in the enabler match
// corresponding values.
//
C_ASSERT(((ULONG) FxDuplexDmaDescriptionTypeRead) == ((ULONG) WdfDmaDirectionReadFromDevice));
C_ASSERT(((ULONG) FxDuplexDmaDescriptionTypeWrite) == ((ULONG) WdfDmaDirectionWriteToDevice));
//
// Declare the FxDmaEnabler class
//
class FxDmaEnabler : public FxNonPagedObject {
friend class FxDmaTransactionBase;
friend class FxDmaPacketTransaction;
friend class FxDmaScatterGatherTransaction;
friend class FxDmaSystemTransaction;
public:
FxDmaEnabler(
__in PFX_DRIVER_GLOBALS FxDriverGlobals
);
~FxDmaEnabler();
virtual
BOOLEAN
Dispose(
VOID
);
_Must_inspect_result_
NTSTATUS
Initialize(
__in PWDF_DMA_ENABLER_CONFIG Config,
__inout FxDeviceBase *Device
);
_Must_inspect_result_
NTSTATUS
ConfigureSystemAdapter(
__in PWDF_DMA_SYSTEM_PROFILE_CONFIG Config,
__in WDF_DMA_DIRECTION ConfigDirection
);
VOID
AllocateCommonBuffer(
__in size_t Length,
__deref_out_opt PVOID * BufferVA,
__out PHYSICAL_ADDRESS * BufferPA
);
VOID
FreeCommonBuffer(
__in size_t Length,
__in PVOID BufferVA,
__in PHYSICAL_ADDRESS BufferPA
);
_Must_inspect_result_
NTSTATUS
PowerUp(
VOID
);
_Must_inspect_result_
NTSTATUS
PowerDown(
VOID
);
VOID
RevokeResources(
VOID
);
VOID
InitializeTransferContext(
__out PVOID Context,
__in WDF_DMA_DIRECTION Direction
);
__inline
size_t
GetMaximumLength(
VOID
)
{
//
// This value is same for all the channels and equal to the value
// provided in the DMA_ENABLER_CONFIG.
//
return GetReadDmaDescription()->DeviceDescription.MaximumLength;
}
__inline
size_t
GetAlignment(
VOID
)
{
return m_CommonBufferAlignment;
}
__inline
WDFDMAENABLER
GetHandle(
VOID
)
{
return (WDFDMAENABLER) GetObjectHandle();
}
__inline
WDFDEVICE
GetDeviceHandle(
VOID
)
{
return m_DeviceBase->GetHandle();
}
__inline
size_t
GetMaxSGElements(
VOID
)
{
return m_MaxSGElements;
}
__inline
VOID
SetMaxSGElements(
__in size_t MaximumSGElements
)
{
m_MaxSGElements = (ULONG) MaximumSGElements;
}
__inline
WDF_DMA_PROFILE
GetProfile(
VOID
)
{
return m_Profile;
}
__inline
BOOLEAN
SupportsChainedMdls(
VOID
)
{
//
// The only case where we don't support chained MDLS is DMAV2
// with packet mode.
//
if ((UsesDmaV3() == false) &&
(m_IsBusMaster == TRUE) &&
(m_IsScatterGather == FALSE)) {
return false;
} else {
return true;
}
}
__inline
BOOLEAN
IsBusMaster(
VOID
)
{
return m_IsBusMaster;
}
__inline
BOOLEAN
IsPacketBased(
)
{
return m_IsScatterGather ? FALSE : TRUE ;
}
__inline
FxDmaDescription*
GetDmaDescription(
__in WDF_DMA_DIRECTION Direction
)
{
if (m_IsDuplexTransfer) {
return &m_DuplexAdapterInfo[Direction];
}
else {
return &m_SimplexAdapterInfo;
}
}
__inline
FxDmaDescription*
GetWriteDmaDescription(
VOID
)
{
if (m_IsDuplexTransfer) {
return &m_DuplexAdapterInfo[FxDuplexDmaDescriptionTypeWrite];
} else {
return &m_SimplexAdapterInfo;
}
}
__inline
FxDmaDescription*
GetReadDmaDescription(
VOID
)
{
if (m_IsDuplexTransfer) {
return &m_DuplexAdapterInfo[FxDuplexDmaDescriptionTypeRead];
} else {
return &m_SimplexAdapterInfo;
}
}
BOOLEAN
UsesDmaV3(
VOID
)
{
FxDmaDescription* description;
//
// It doesn't matter which direction we use below. Direction is
// ignored for the simplex enabler, and will be the same for both
// channels in a duplex enabler.
//
description = GetDmaDescription(WdfDmaDirectionReadFromDevice);
return description->DeviceDescription.Version == DEVICE_DESCRIPTION_VERSION3;
}
USHORT
GetTransferContextSize(
VOID
)
{
return UsesDmaV3() ? DMA_TRANSFER_CONTEXT_SIZE_V1 : 0;
}
public:
//
// Link into list of FxDmaEnabler pointers maintained by the pnp package.
//
FxTransactionedEntry m_TransactionLink;
protected:
PDEVICE_OBJECT m_FDO;
PDEVICE_OBJECT m_PDO;
union {
//
// Used if the dma profile is not duplex. Common for both read & write.
// All the information specific to the channel are stored in the struct.
//
FxDmaDescription m_SimplexAdapterInfo;
//
// Used if the dma profile is duplex.
//
FxDmaDescription m_DuplexAdapterInfo[FxDuplexDmaDescriptionTypeMax];
};
//
// The profile of the DMA enabler.
//
WDF_DMA_PROFILE m_Profile;
//
// Whether the enabler object is added to the device enabler list.
//
BOOLEAN m_IsAdded : 1;
//
// Whether the DMA enabler has been configured with DMA resources & has its
// adapters.
//
BOOLEAN m_IsConfigured : 1;
//
// The DMA profile broken out into individual flags.
//
BOOLEAN m_IsBusMaster : 1;
BOOLEAN m_IsScatterGather : 1;
BOOLEAN m_IsDuplexTransfer : 1;
//
// Has the preallocated scatter gather list (single list or lookaside,
// depending on profile) been allocated. Indicates initialization state
// of m_SGList below.
//
BOOLEAN m_IsSGListAllocated: 1;
//
// This value is larger of aligment value returned by HAL(which is always 1)
// and the alignment value set on the device by WdfDeviceSetAlignmentRequirement.
//
ULONG m_CommonBufferAlignment;
//
// The maximum DMA transfer the enabler should support (saved from the enabler
// config)
//
ULONG m_MaximumLength;
ULONG m_MaxSGElements;
//
// The size of the preallocated SGList entries, in bytes. This is for entries
// on the lookaside list or the single entry list.
//
size_t m_SGListSize;
//
// Storage for scatter gather lists. Whether the lookaside or the single entry
// the size in bytes is described by m_SGListSize
//
// The m_IsSGListAllocated bit above indicates whether we've
// initialized this structure or not.
//
union {
//
// For the scatter gather profile we have a lookaside list of SGLists
// We allocate these dynamically because (a) we can be mapping
// multiple transactions in parallel and (b) the number of map registers
// for SG DMA may be very large and we don't necessarily need one per
// transaction at all times
//
// For duplex channels, the entry size is larger of read & write channels.
//
struct {
NPAGED_LOOKASIDE_LIST Lookaside;
} ScatterGatherProfile;
//
// A single SGList for use with system DMA transfers. We can use a single
// list because (a) there is only one system DMA transaction being mapped
// at any given time (for this adapter) and (b) we don't use the physical
// addresses or give them to the driver so they don't need to be preserved
// very long (the list is only so the HAL has enough scratch space to tell
// the HAL DMA extension which PA's comprise the transfer)
//
struct {
PSCATTER_GATHER_LIST List;
} SystemProfile;
//
// NOTE: there is no preallocated entry for packet based bus mastering DMA
// because we could be mapping multiple transactions in parallel but
// the size of the SGList is static and can be allocated on the stack
//
} m_SGList;
private:
//
// Power-related callbacks.
//
FxEvtDmaEnablerFillCallback m_EvtDmaEnablerFill;
FxEvtDmaEnablerFlushCallback m_EvtDmaEnablerFlush;
FxEvtDmaEnablerEnableCallback m_EvtDmaEnablerEnable;
FxEvtDmaEnablerDisableCallback m_EvtDmaEnablerDisable;
FxEvtDmaEnablerSelfManagedIoStartCallback m_EvtDmaEnablerSelfManagedIoStart;
FxEvtDmaEnablerSelfManagedIoStopCallback m_EvtDmaEnablerSelfManagedIoStop;
//
// Note that these fields form an informal state engine.
//
BOOLEAN m_DmaEnablerFillFailed;
BOOLEAN m_DmaEnablerEnableFailed;
BOOLEAN m_DmaEnablerSelfManagedIoStartFailed;
_Must_inspect_result_
NTSTATUS
ConfigureBusMasterAdapters(
__in PDEVICE_DESCRIPTION DeviceDescription,
__in PWDF_DMA_ENABLER_CONFIG Config
);
_Must_inspect_result_
NTSTATUS
ConfigureDmaAdapter(
__in PDEVICE_DESCRIPTION DeviceDescription,
__in WDF_DMA_DIRECTION ConfigDirection
);
_Must_inspect_result_
NTSTATUS
InitializeResources(
__inout FxDmaDescription *AdapterInfo
);
VOID
ReleaseResources(
VOID
);
VOID
FreeResources(
__inout FxDmaDescription *AdapterInfo
);
}; // end of class
#endif // _FXDMAENABLER_HPP_