ReactOS  0.4.14-dev-1332-g6db3d88
dma.c File Reference
#include <hal.h>
#include <suppress.h>
#include <debug.h>
Include dependency graph for dma.c:

Go to the source code of this file.

Classes

struct  _SCATTER_GATHER_CONTEXT
 

Macros

#define NDEBUG
 
#define MAX_SG_ELEMENTS   0x10
 
#define MAX_MAP_REGISTERS   64
 
#define TAG_DMA   ' AMD'
 

Functions

INIT_FUNCTION VOID HalpInitDma (VOID)
 
HalpGetAdapterMaximumPhysicalAddress

Get the maximum physical address acceptable by the device represented by the passed DMA adapter.

PHYSICAL_ADDRESS NTAPI HalpGetAdapterMaximumPhysicalAddress (IN PADAPTER_OBJECT AdapterObject)
 
HalpGrowMapBuffers

Allocate initial, or additional, map buffers for DMA master adapter.

Parameters
MasterAdapterDMA master adapter to allocate buffers for.
SizeOfMapBuffersSize of the map buffers to allocate (not including the size already allocated).
BOOLEAN NTAPI HalpGrowMapBuffers (IN PADAPTER_OBJECT AdapterObject, IN ULONG SizeOfMapBuffers)
 
HalpDmaAllocateMasterAdapter

Helper routine to allocate and initialize master adapter object and it's associated map register buffers.

See also
HalpInitDma
PADAPTER_OBJECT NTAPI HalpDmaAllocateMasterAdapter (VOID)
 
HalpDmaAllocateChildAdapter

Helper routine of HalGetAdapter. Allocate child adapter object and fill out some basic fields.

See also
HalGetAdapter
PADAPTER_OBJECT NTAPI HalpDmaAllocateChildAdapter (IN ULONG NumberOfMapRegisters, IN PDEVICE_DESCRIPTION DeviceDescription)
 
HalpDmaInitializeEisaAdapter

Setup DMA modes and extended modes for (E)ISA DMA adapter object.

BOOLEAN NTAPI HalpDmaInitializeEisaAdapter (IN PADAPTER_OBJECT AdapterObject, IN PDEVICE_DESCRIPTION DeviceDescription)
 
HalGetAdapter

Allocate an adapter object for DMA device.

Parameters
DeviceDescriptionStructure describing the attributes of the device.
NumberOfMapRegistersOn return filled with the maximum number of map registers the device driver can allocate for DMA transfer operations.
Returns
The DMA adapter on success, NULL otherwise.

@implemented

PADAPTER_OBJECT NTAPI HalGetAdapter (IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
 
HalpGetDmaAdapter

Internal routine to allocate PnP DMA adapter object. It's exported through HalDispatchTable and used by IoGetDmaAdapter.

See also
HalGetAdapter
PDMA_ADAPTER NTAPI HalpGetDmaAdapter (IN PVOID Context, IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
 
HalPutDmaAdapter

Internal routine to free DMA adapter and resources for reuse. It's exported using the DMA_OPERATIONS interface by HalGetAdapter.

See also
HalGetAdapter
VOID NTAPI HalPutDmaAdapter (IN PADAPTER_OBJECT AdapterObject)
 
HalAllocateCommonBuffer

Allocates memory that is visible to both the processor(s) and the DMA device.

Parameters
AdapterObjectAdapter object representing the bus master or system dma controller.
LengthNumber of bytes to allocate.
LogicalAddressLogical address the driver can use to access the buffer.
CacheEnabledSpecifies if the memory can be cached.
Returns
The base virtual address of the memory allocated or NULL on failure.
Remarks
On real NT x86 systems the CacheEnabled parameter is ignored, we honour it. If it proves to cause problems change it.
See also
HalFreeCommonBuffer

@implemented

PVOID NTAPI HalAllocateCommonBuffer (IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PPHYSICAL_ADDRESS LogicalAddress, IN BOOLEAN CacheEnabled)
 
HalGetScatterGatherList

Creates a scatter-gather list to be using in scatter/gather DMA

Parameters
AdapterObjectAdapter object representing the bus master or system dma controller.
DeviceObjectThe device target for DMA.
MdlThe MDL that describes the buffer to be mapped.
CurrentVaThe current VA in the buffer to be mapped for transfer.
LengthSpecifies the length of data in bytes to be mapped.
ExecutionRoutineA caller supplied AdapterListControl routine to be called when DMA is available.
ContextContext passed to the AdapterListControl routine.
WriteToDeviceIndicates direction of DMA operation.
Returns
The status of the operation.
See also
HalPutScatterGatherList

@implemented

NTSTATUS NTAPI HalGetScatterGatherList (IN PADAPTER_OBJECT AdapterObject, IN PDEVICE_OBJECT DeviceObject, IN PMDL Mdl, IN PVOID CurrentVa, IN ULONG Length, IN PDRIVER_LIST_CONTROL ExecutionRoutine, IN PVOID Context, IN BOOLEAN WriteToDevice)
 
HalPutScatterGatherList

Frees a scatter-gather list allocated from HalGetScatterGatherList

Parameters
AdapterObjectAdapter object representing the bus master or system dma controller.
ScatterGatherThe scatter/gather list to be freed.
WriteToDeviceIndicates direction of DMA operation.
Returns
None
See also
HalGetScatterGatherList

@implemented

VOID NTAPI HalPutScatterGatherList (IN PADAPTER_OBJECT AdapterObject, IN PSCATTER_GATHER_LIST ScatterGather, IN BOOLEAN WriteToDevice)
 
HalpDmaGetDmaAlignment

Internal routine to return the DMA alignment requirement. It's exported using the DMA_OPERATIONS interface by HalGetAdapter.

See also
HalGetAdapter
ULONG NTAPI HalpDmaGetDmaAlignment (IN PADAPTER_OBJECT AdapterObject)
 
ULONG NTAPI HalReadDmaCounter (IN PADAPTER_OBJECT AdapterObject)
 
HalpGrowMapBufferWorker

Helper routine of HalAllocateAdapterChannel for allocating map registers at PASSIVE_LEVEL in work item.

VOID NTAPI HalpGrowMapBufferWorker (IN PVOID DeferredContext)
 
HalAllocateAdapterChannel

Setup map registers for an adapter object.

Parameters
AdapterObjectPointer to an ADAPTER_OBJECT to set up.
WaitContextBlockContext block to be used with ExecutionRoutine.
NumberOfMapRegistersNumber of map registers requested.
ExecutionRoutineCallback to call when map registers are allocated.
Returns
If not enough map registers can be allocated then STATUS_INSUFFICIENT_RESOURCES is returned. If the function succeeds or the callback is queued for later delivering then STATUS_SUCCESS is returned.
See also
IoFreeAdapterChannel

@implemented

NTSTATUS NTAPI HalAllocateAdapterChannel (IN PADAPTER_OBJECT AdapterObject, IN PWAIT_CONTEXT_BLOCK WaitContextBlock, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine)
 
IoFreeAdapterChannel

Free DMA resources allocated by IoAllocateAdapterChannel.

Parameters
AdapterObjectAdapter object with resources to free.
Remarks
This function releases map registers registers assigned to the DMA adapter. After releasing the adapter, it checks the adapter's queue and runs each queued device object in series until the queue is empty. This is the only way the device queue is emptied.
See also
IoAllocateAdapterChannel

@implemented

VOID NTAPI IoFreeAdapterChannel (IN PADAPTER_OBJECT AdapterObject)
 
IoFreeMapRegisters

Free map registers reserved by the system for a DMA.

Parameters
AdapterObjectDMA adapter to free map registers on.
MapRegisterBaseHandle to map registers to free.
NumberOfRegistersNumber of map registers to be freed.

@implemented

VOID NTAPI IoFreeMapRegisters (IN PADAPTER_OBJECT AdapterObject, IN PVOID MapRegisterBase, IN ULONG NumberOfMapRegisters)
 
HalpCopyBufferMap

Helper function for copying data from/to map register buffers.

See also
IoFlushAdapterBuffers, IoMapTransfer
VOID NTAPI HalpCopyBufferMap (IN PMDL Mdl, IN PROS_MAP_REGISTER_ENTRY MapRegisterBase, IN PVOID CurrentVa, IN ULONG Length, IN BOOLEAN WriteToDevice)
 
IoFlushAdapterBuffers

Flush any data remaining in the DMA controller's memory into the host memory.

Parameters
AdapterObjectThe adapter object to flush.
MdlOriginal MDL to flush data into.
MapRegisterBaseMap register base that was just used by IoMapTransfer, etc.
CurrentVaOffset into Mdl to be flushed into, same as was passed to IoMapTransfer.
LengthLength of the buffer to be flushed into.
WriteToDeviceTRUE if it's a write, FALSE if it's a read.
Returns
TRUE in all cases.
Remarks
This copies data from the map register-backed buffer to the user's target buffer. Data are not in the user buffer until this function is called. For slave DMA transfers the controller channel is masked effectively stopping the current transfer.

@unimplemented.

BOOLEAN NTAPI IoFlushAdapterBuffers (IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN ULONG Length, IN BOOLEAN WriteToDevice)
 
IoMapTransfer

Map a DMA for transfer and do the DMA if it's a slave.

Parameters
AdapterObjectAdapter object to do the DMA on. Bus-master may pass NULL.
MdlLocked-down user buffer to DMA in to or out of.
MapRegisterBaseHandle to map registers to use for this dma.
CurrentVaIndex into Mdl to transfer into/out of.
LengthLength of transfer. Number of bytes actually transferred on output.
WriteToDeviceTRUE if it's an output DMA, FALSE otherwise.
Returns
A logical address that can be used to program a DMA controller, it's not meaningful for slave DMA device.
Remarks
This function does a copyover to contiguous memory <16MB represented by the map registers if needed. If the buffer described by MDL can be used as is no copyover is done. If it's a slave transfer, this function actually performs it.

@implemented

PHYSICAL_ADDRESS NTAPI IoMapTransfer (IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN OUT PULONG Length, IN BOOLEAN WriteToDevice)
 
HalFlushCommonBuffer

@implemented

BOOLEAN NTAPI HalFlushCommonBuffer (IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress)
 
PVOID NTAPI HalAllocateCrashDumpRegisters (IN PADAPTER_OBJECT AdapterObject, IN OUT PULONG NumberOfMapRegisters)
 

Variables

static KEVENT HalpDmaLock
 
static KSPIN_LOCK HalpDmaAdapterListLock
 
static LIST_ENTRY HalpDmaAdapterList
 
static PADAPTER_OBJECT HalpEisaAdapter [8]
 
static BOOLEAN HalpEisaDma
 
static PADAPTER_OBJECT HalpMasterAdapter
 
static const ULONG_PTR HalpEisaPortPage [8]
 
static DMA_OPERATIONS HalpDmaOperations
 

HalFreeCommonBuffer

Free common buffer allocated with HalAllocateCommonBuffer.

See also
HalAllocateCommonBuffer

@implemented

typedef struct _SCATTER_GATHER_CONTEXT SCATTER_GATHER_CONTEXT
 
typedef struct _SCATTER_GATHER_CONTEXTPSCATTER_GATHER_CONTEXT
 
VOID NTAPI HalFreeCommonBuffer (IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress, IN BOOLEAN CacheEnabled)
 
IO_ALLOCATION_ACTION NTAPI HalpScatterGatherAdapterControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID MapRegisterBase, IN PVOID Context)
 

Macro Definition Documentation

◆ MAX_MAP_REGISTERS

#define MAX_MAP_REGISTERS   64

Definition at line 130 of file dma.c.

◆ MAX_SG_ELEMENTS

#define MAX_SG_ELEMENTS   0x10

Definition at line 84 of file dma.c.

◆ NDEBUG

#define NDEBUG

Definition at line 77 of file dma.c.

◆ TAG_DMA

#define TAG_DMA   ' AMD'

Definition at line 132 of file dma.c.

Typedef Documentation

◆ PSCATTER_GATHER_CONTEXT

◆ SCATTER_GATHER_CONTEXT

Function Documentation

◆ HalAllocateAdapterChannel()

NTSTATUS NTAPI HalAllocateAdapterChannel ( IN PADAPTER_OBJECT  AdapterObject,
IN PWAIT_CONTEXT_BLOCK  WaitContextBlock,
IN ULONG  NumberOfMapRegisters,
IN PDRIVER_CONTROL  ExecutionRoutine 
)

Definition at line 1276 of file dma.c.

1280 {
1281  PADAPTER_OBJECT MasterAdapter;
1282  PGROW_WORK_ITEM WorkItem;
1283  ULONG Index = MAXULONG;
1284  ULONG Result;
1285  KIRQL OldIrql;
1286 
1288 
1289  /* Set up the wait context block in case we can't run right away. */
1290  WaitContextBlock->DeviceRoutine = ExecutionRoutine;
1291  WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
1292 
1293  /* Returns true if queued, else returns false and sets the queue to busy */
1294  if (KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue,
1295  &WaitContextBlock->WaitQueueEntry))
1296  {
1297  return STATUS_SUCCESS;
1298  }
1299 
1300  MasterAdapter = AdapterObject->MasterAdapter;
1301 
1302  AdapterObject->NumberOfMapRegisters = NumberOfMapRegisters;
1303  AdapterObject->CurrentWcb = WaitContextBlock;
1304 
1305  if ((NumberOfMapRegisters) && (AdapterObject->NeedsMapRegisters))
1306  {
1307  if (NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)
1308  {
1309  AdapterObject->NumberOfMapRegisters = 0;
1310  IoFreeAdapterChannel(AdapterObject);
1312  }
1313 
1314  /*
1315  * Get the map registers. This is partly complicated by the fact
1316  * that new map registers can only be allocated at PASSIVE_LEVEL
1317  * and we're currently at DISPATCH_LEVEL. The following code has
1318  * two code paths:
1319  *
1320  * - If there is no adapter queued for map register allocation,
1321  * try to see if enough contiguous map registers are present.
1322  * In case they're we can just get them and proceed further.
1323  *
1324  * - If some adapter is already present in the queue we must
1325  * respect the order of adapters asking for map registers and
1326  * so the fast case described above can't take place.
1327  * This case is also entered if not enough coniguous map
1328  * registers are present.
1329  *
1330  * A work queue item is allocated and queued, the adapter is
1331  * also queued into the master adapter queue. The worker
1332  * routine does the job of allocating the map registers at
1333  * PASSIVE_LEVEL and calling the ExecutionRoutine.
1334  */
1335 
1336  KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1337 
1338  if (IsListEmpty(&MasterAdapter->AdapterQueue))
1339  {
1340  Index = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters, NumberOfMapRegisters, 0);
1341  if (Index != MAXULONG)
1342  {
1343  AdapterObject->MapRegisterBase = MasterAdapter->MapRegisterBase + Index;
1344  if (!AdapterObject->ScatterGather)
1345  {
1346  AdapterObject->MapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
1347  }
1348  }
1349  }
1350 
1351  if (Index == MAXULONG)
1352  {
1353  InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
1354 
1356  sizeof(GROW_WORK_ITEM),
1357  TAG_DMA);
1358  if (WorkItem)
1359  {
1361  WorkItem->AdapterObject = AdapterObject;
1363 
1365  }
1366 
1367  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1368 
1369  return STATUS_SUCCESS;
1370  }
1371 
1372  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1373  }
1374  else
1375  {
1376  AdapterObject->MapRegisterBase = NULL;
1377  AdapterObject->NumberOfMapRegisters = 0;
1378  }
1379 
1380  AdapterObject->CurrentWcb = WaitContextBlock;
1381 
1382  Result = ExecutionRoutine(WaitContextBlock->DeviceObject,
1383  WaitContextBlock->CurrentIrp,
1384  AdapterObject->MapRegisterBase,
1385  WaitContextBlock->DeviceContext);
1386 
1387  /*
1388  * Possible return values:
1389  *
1390  * - KeepObject
1391  * Don't free any resources, the ADAPTER_OBJECT is still in use and
1392  * the caller will call IoFreeAdapterChannel later.
1393  *
1394  * - DeallocateObject
1395  * Deallocate the map registers and release the ADAPTER_OBJECT, so
1396  * someone else can use it.
1397  *
1398  * - DeallocateObjectKeepRegisters
1399  * Release the ADAPTER_OBJECT, but hang on to the map registers. The
1400  * client will later call IoFreeMapRegisters.
1401  *
1402  * NOTE:
1403  * IoFreeAdapterChannel runs the queue, so it must be called unless
1404  * the adapter object is not to be freed.
1405  */
1406  if (Result == DeallocateObject)
1407  {
1408  IoFreeAdapterChannel(AdapterObject);
1409  }
1411  {
1412  AdapterObject->NumberOfMapRegisters = 0;
1413  IoFreeAdapterChannel(AdapterObject);
1414  }
1415 
1416  return STATUS_SUCCESS;
1417 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Out_ PULONG NumberOfMapRegisters
Definition: halfuncs.h:209
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
WORK_QUEUE_ITEM WorkQueueItem
Definition: haldma.h:362
uint32_t ULONG_PTR
Definition: typedefs.h:64
UCHAR KIRQL
Definition: env_spec_w32.h:591
PADAPTER_OBJECT AdapterObject
Definition: haldma.h:363
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
struct _ROS_MAP_REGISTER_ENTRY * PROS_MAP_REGISTER_ENTRY
VOID NTAPI IoFreeAdapterChannel(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:103
VOID NTAPI HalpGrowMapBufferWorker(PVOID DeferredContext)
Definition: dma.c:1005
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
static const UCHAR Index[8]
Definition: usbohci.c:18
BOOLEAN NTAPI KeInsertDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
Definition: devqueue.c:41
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define TAG_DMA
Definition: dma.c:132
#define MAXULONG
Definition: typedefs.h:250
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
_In_ PDEVICE_OBJECT _In_ ULONG _In_ PDRIVER_CONTROL ExecutionRoutine
Definition: iofuncs.h:1393
unsigned int ULONG
Definition: retypes.h:1
ULONG NumberOfMapRegisters
Definition: haldma.h:364
#define MAP_BASE_SW_SG
Definition: haldma.h:367
return STATUS_SUCCESS
Definition: btrfs.c:2938

◆ HalAllocateCommonBuffer()

PVOID NTAPI HalAllocateCommonBuffer ( IN PADAPTER_OBJECT  AdapterObject,
IN ULONG  Length,
IN PPHYSICAL_ADDRESS  LogicalAddress,
IN BOOLEAN  CacheEnabled 
)

Definition at line 867 of file dma.c.

871 {
874  PHYSICAL_ADDRESS BoundryAddressMultiple;
876 
879  BoundryAddressMultiple.QuadPart = 0;
880 
881  /*
882  * For bus-master DMA devices the buffer mustn't cross 4Gb boundary. For
883  * slave DMA devices the 64Kb boundary mustn't be crossed since the
884  * controller wouldn't be able to handle it.
885  */
886  if (AdapterObject->MasterDevice)
887  {
888  BoundryAddressMultiple.HighPart = 1;
889  }
890  else
891  {
892  BoundryAddressMultiple.LowPart = 0x10000;
893  }
894 
898  BoundryAddressMultiple,
899  CacheEnabled ? MmCached :
900  MmNonCached);
901  if (VirtualAddress == NULL) return NULL;
902 
903  *LogicalAddress = MmGetPhysicalAddress(VirtualAddress);
904 
905  return VirtualAddress;
906 }
PHYSICAL_ADDRESS NTAPI HalpGetAdapterMaximumPhysicalAddress(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:167
smooth NULL
Definition: ftsmooth.c:416
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_Out_ PNDIS_HANDLE _Out_ PUINT _In_ PNDIS_STRING _In_ NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress
Definition: ndis.h:3227
ULONG LowPart
Definition: typedefs.h:105
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS LowestAcceptableAddress
Definition: mmfuncs.h:214
PHYSICAL_ADDRESS NTAPI MmGetPhysicalAddress(IN PVOID Address)
Definition: stubs.c:682
LONGLONG QuadPart
Definition: typedefs.h:113
PVOID NTAPI MmAllocateContiguousMemorySpecifyCache(IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS LowestAcceptableAddress OPTIONAL, IN PHYSICAL_ADDRESS HighestAcceptableAddress, IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, IN MEMORY_CACHING_TYPE CacheType OPTIONAL)
Definition: contmem.c:574

◆ HalAllocateCrashDumpRegisters()

PVOID NTAPI HalAllocateCrashDumpRegisters ( IN PADAPTER_OBJECT  AdapterObject,
IN OUT PULONG  NumberOfMapRegisters 
)

Definition at line 2136 of file dma.c.

2138 {
2139  PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter;
2140  ULONG MapRegisterNumber;
2141 
2142  /* Check if it needs map registers */
2143  if (AdapterObject->NeedsMapRegisters)
2144  {
2145  /* Check if we have enough */
2146  if (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)
2147  {
2148  /* We don't, fail */
2149  AdapterObject->NumberOfMapRegisters = 0;
2150  return NULL;
2151  }
2152 
2153  /* Try to find free map registers */
2154  MapRegisterNumber = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
2156  0);
2157 
2158  /* Check if nothing was found */
2159  if (MapRegisterNumber == MAXULONG)
2160  {
2161  /* No free registers found, so use the base registers */
2162  RtlSetBits(MasterAdapter->MapRegisters,
2163  0,
2165  MapRegisterNumber = 0;
2166  }
2167 
2168  /* Calculate the new base */
2169  AdapterObject->MapRegisterBase =
2170  (PROS_MAP_REGISTER_ENTRY)(MasterAdapter->MapRegisterBase +
2171  MapRegisterNumber);
2172 
2173  /* Check if scatter gather isn't supported */
2174  if (!AdapterObject->ScatterGather)
2175  {
2176  /* Set the flag */
2177  AdapterObject->MapRegisterBase =
2179  ((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
2180  }
2181  }
2182  else
2183  {
2184  AdapterObject->MapRegisterBase = NULL;
2185  AdapterObject->NumberOfMapRegisters = 0;
2186  }
2187 
2188  /* Return the base */
2189  return AdapterObject->MapRegisterBase;
2190 }
_Out_ PULONG NumberOfMapRegisters
Definition: halfuncs.h:209
uint32_t ULONG_PTR
Definition: typedefs.h:64
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
struct _ROS_MAP_REGISTER_ENTRY * PROS_MAP_REGISTER_ENTRY
#define MAXULONG
Definition: typedefs.h:250
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
unsigned int ULONG
Definition: retypes.h:1
#define MAP_BASE_SW_SG
Definition: haldma.h:367

◆ HalFlushCommonBuffer()

BOOLEAN NTAPI HalFlushCommonBuffer ( IN PADAPTER_OBJECT  AdapterObject,
IN ULONG  Length,
IN PHYSICAL_ADDRESS  LogicalAddress,
IN PVOID  VirtualAddress 
)

Definition at line 2122 of file dma.c.

2126 {
2127  /* Function always returns true */
2128  return TRUE;
2129 }
#define TRUE
Definition: types.h:120

◆ HalFreeCommonBuffer()

VOID NTAPI HalFreeCommonBuffer ( IN PADAPTER_OBJECT  AdapterObject,
IN ULONG  Length,
IN PHYSICAL_ADDRESS  LogicalAddress,
IN PVOID  VirtualAddress,
IN BOOLEAN  CacheEnabled 
)

Definition at line 919 of file dma.c.

924 {
926  Length,
927  CacheEnabled ? MmCached : MmNonCached);
928 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
VOID NTAPI MmFreeContiguousMemorySpecifyCache(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: contmem.c:666

◆ HalGetAdapter()

PADAPTER_OBJECT NTAPI HalGetAdapter ( IN PDEVICE_DESCRIPTION  DeviceDescription,
OUT PULONG  NumberOfMapRegisters 
)

Definition at line 619 of file dma.c.

621 {
622  PADAPTER_OBJECT AdapterObject = NULL;
624  ULONG MapRegisters;
626  KIRQL OldIrql;
627 
628  /* Validate parameters in device description */
630 
631  /*
632  * See if we're going to use ISA/EISA DMA adapter. These adapters are
633  * special since they're reused.
634  *
635  * Also note that we check for channel number since there are only 8 DMA
636  * channels on ISA, so any request above this requires new adapter.
637  */
638  if (((DeviceDescription->InterfaceType == Eisa) ||
640  {
641  if (((DeviceDescription->InterfaceType == Isa) ||
644  {
645  EisaAdapter = FALSE;
646  }
647  else
648  {
649  EisaAdapter = TRUE;
650  }
651  }
652  else
653  {
654  EisaAdapter = FALSE;
655  }
656 
657  /*
658  * Disallow creating adapter for ISA/EISA DMA channel 4 since it's used
659  * for cascading the controllers and it's not available for software use.
660  */
661  if ((EisaAdapter) && (DeviceDescription->DmaChannel == 4)) return NULL;
662 
663  /*
664  * Calculate the number of map registers.
665  *
666  * - For EISA and PCI scatter/gather no map registers are needed.
667  * - For ISA slave scatter/gather one map register is needed.
668  * - For all other cases the number of map registers depends on
669  * DeviceDescription->MaximumLength.
670  */
675  {
676  MapRegisters = 0;
677  }
679  {
680  MapRegisters = 1;
681  }
682  else
683  {
684  /*
685  * In the equation below the additional map register added by
686  * the "+1" accounts for the case when a transfer does not start
687  * at a page-aligned address.
688  */
689  MapRegisters = BYTES_TO_PAGES(MaximumLength) + 1;
690  if (MapRegisters > 16) MapRegisters = 16;
691  }
692 
693  /*
694  * Acquire the DMA lock that is used to protect the EISA adapter array.
695  */
697 
698  /*
699  * Now we must get ahold of the adapter object. For first eight ISA/EISA
700  * channels there are static adapter objects that are reused and updated
701  * on succesive HalGetAdapter calls. In other cases a new adapter object
702  * is always created and it's to the DMA adapter list (HalpDmaAdapterList).
703  */
704  if (EisaAdapter)
705  {
706  AdapterObject = HalpEisaAdapter[DeviceDescription->DmaChannel];
707  if (AdapterObject)
708  {
709  if ((AdapterObject->NeedsMapRegisters) &&
710  (MapRegisters > AdapterObject->MapRegistersPerChannel))
711  {
712  AdapterObject->MapRegistersPerChannel = MapRegisters;
713  }
714  }
715  }
716 
717  if (AdapterObject == NULL)
718  {
719  AdapterObject = HalpDmaAllocateChildAdapter(MapRegisters, DeviceDescription);
720  if (AdapterObject == NULL)
721  {
722  KeSetEvent(&HalpDmaLock, 0, 0);
723  return NULL;
724  }
725 
726  if (EisaAdapter)
727  {
728  HalpEisaAdapter[DeviceDescription->DmaChannel] = AdapterObject;
729  }
730 
731  if (MapRegisters > 0)
732  {
733  AdapterObject->NeedsMapRegisters = TRUE;
734  AdapterObject->MapRegistersPerChannel = MapRegisters;
735  }
736  else
737  {
738  AdapterObject->NeedsMapRegisters = FALSE;
740  {
741  AdapterObject->MapRegistersPerChannel = BYTES_TO_PAGES(MaximumLength) + 1;
742  }
743  else
744  {
745  AdapterObject->MapRegistersPerChannel = 1;
746  }
747  }
748  }
749 
750  /*
751  * Release the DMA lock. HalpEisaAdapter will no longer be touched,
752  * so we don't need it.
753  */
754  KeSetEvent(&HalpDmaLock, 0, 0);
755 
756  if (!EisaAdapter)
757  {
758  /* If it's not one of the static adapters, add it to the list */
760  InsertTailList(&HalpDmaAdapterList, &AdapterObject->AdapterList);
762  }
763 
764  /*
765  * Setup the values in the adapter object that are common for all
766  * types of buses.
767  */
769  {
770  AdapterObject->IgnoreCount = DeviceDescription->IgnoreCount;
771  }
772  else
773  {
774  AdapterObject->IgnoreCount = 0;
775  }
776 
777  AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
778  AdapterObject->Dma64BitAddresses = DeviceDescription->Dma64BitAddresses;
779  AdapterObject->ScatterGather = DeviceDescription->ScatterGather;
780  AdapterObject->MasterDevice = DeviceDescription->Master;
781  *NumberOfMapRegisters = AdapterObject->MapRegistersPerChannel;
782 
783  /*
784  * For non-(E)ISA adapters we have already done all the work. On the
785  * other hand for (E)ISA adapters we must still setup the DMA modes
786  * and prepare the controller.
787  */
788  if (EisaAdapter)
789  {
790  if (!HalpDmaInitializeEisaAdapter(AdapterObject, DeviceDescription))
791  {
792  ObDereferenceObject(AdapterObject);
793  return NULL;
794  }
795  }
796 
797  return AdapterObject;
798 }
#define TRUE
Definition: types.h:120
_Out_ PULONG NumberOfMapRegisters
Definition: halfuncs.h:209
#define MAXLONG
Definition: umtypes.h:116
static PADAPTER_OBJECT HalpEisaAdapter[8]
Definition: dma.c:90
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define InsertTailList(ListHead, Entry)
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
static KEVENT HalpDmaLock
Definition: dma.c:87
UCHAR KIRQL
Definition: env_spec_w32.h:591
BOOLEAN IgnoreCount
Definition: iotypes.h:2031
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static KSPIN_LOCK HalpDmaAdapterListLock
Definition: dma.c:88
BOOLEAN Dma32BitAddresses
Definition: iotypes.h:2030
BOOLEAN Dma64BitAddresses
Definition: iotypes.h:2033
_Must_inspect_result_ _In_ PDEVICE_DESCRIPTION DeviceDescription
Definition: iofuncs.h:1015
BOOLEAN ScatterGather
Definition: iotypes.h:2027
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define BYTES_TO_PAGES(Size)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
BOOLEAN NTAPI HalpDmaInitializeEisaAdapter(PADAPTER_OBJECT AdapterObject, PDEVICE_DESCRIPTION DeviceDescription)
Definition: dma.c:461
static LIST_ENTRY HalpDmaAdapterList
Definition: dma.c:89
UnicodeString MaximumLength
Definition: rtlfuncs.h:2982
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define DEVICE_DESCRIPTION_VERSION2
Definition: iotypes.h:2022
INTERFACE_TYPE InterfaceType
Definition: iotypes.h:2036
unsigned int ULONG
Definition: retypes.h:1
PADAPTER_OBJECT NTAPI HalpDmaAllocateChildAdapter(ULONG NumberOfMapRegisters, PDEVICE_DESCRIPTION DeviceDescription)
Definition: dma.c:391
#define DEVICE_DESCRIPTION_VERSION1
Definition: iotypes.h:2021

◆ HalGetScatterGatherList()

NTSTATUS NTAPI HalGetScatterGatherList ( IN PADAPTER_OBJECT  AdapterObject,
IN PDEVICE_OBJECT  DeviceObject,
IN PMDL  Mdl,
IN PVOID  CurrentVa,
IN ULONG  Length,
IN PDRIVER_LIST_CONTROL  ExecutionRoutine,
IN PVOID  Context,
IN BOOLEAN  WriteToDevice 
)

Definition at line 1039 of file dma.c.

1047 {
1048  PSCATTER_GATHER_CONTEXT AdapterControlContext;
1049 
1050  AdapterControlContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCATTER_GATHER_CONTEXT), TAG_DMA);
1051  if (!AdapterControlContext) return STATUS_INSUFFICIENT_RESOURCES;
1052 
1053  AdapterControlContext->AdapterObject = AdapterObject;
1054  AdapterControlContext->Mdl = Mdl;
1055  AdapterControlContext->CurrentVa = CurrentVa;
1056  AdapterControlContext->Length = Length;
1057  AdapterControlContext->MapRegisterCount = PAGE_ROUND_UP(Length) >> PAGE_SHIFT;
1058  AdapterControlContext->AdapterListControlRoutine = ExecutionRoutine;
1059  AdapterControlContext->AdapterListControlContext = Context;
1060  AdapterControlContext->WriteToDevice = WriteToDevice;
1061 
1062  AdapterControlContext->Wcb.DeviceObject = DeviceObject;
1063  AdapterControlContext->Wcb.DeviceContext = AdapterControlContext;
1064  AdapterControlContext->Wcb.CurrentIrp = DeviceObject->CurrentIrp;
1065 
1066  return HalAllocateAdapterChannel(AdapterObject,
1067  &AdapterControlContext->Wcb,
1068  AdapterControlContext->MapRegisterCount,
1070 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
PDRIVER_LIST_CONTROL AdapterListControlRoutine
Definition: dma.c:935
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG MapRegisterCount
Definition: dma.c:937
#define PAGE_ROUND_UP(x)
Definition: scsiport_int.h:13
NTSTATUS NTAPI HalAllocateAdapterChannel(IN PADAPTER_OBJECT AdapterObject, IN PWAIT_CONTEXT_BLOCK WaitContextBlock, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine)
Definition: dma.c:88
PADAPTER_OBJECT AdapterObject
Definition: dma.c:931
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define TAG_DMA
Definition: dma.c:132
WAIT_CONTEXT_BLOCK Wcb
Definition: dma.c:939
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
_In_ PDEVICE_OBJECT _In_ ULONG _In_ PDRIVER_CONTROL ExecutionRoutine
Definition: iofuncs.h:1393
PVOID AdapterListControlContext
Definition: dma.c:936
struct tagContext Context
Definition: acpixf.h:1034
IO_ALLOCATION_ACTION NTAPI HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID MapRegisterBase, IN PVOID Context)
Definition: dma.c:945
BOOLEAN WriteToDevice
Definition: dma.c:938

◆ HalpCopyBufferMap()

VOID NTAPI HalpCopyBufferMap ( IN PMDL  Mdl,
IN PROS_MAP_REGISTER_ENTRY  MapRegisterBase,
IN PVOID  CurrentVa,
IN ULONG  Length,
IN BOOLEAN  WriteToDevice 
)

Definition at line 1648 of file dma.c.

1653 {
1654  ULONG CurrentLength;
1655  ULONG_PTR CurrentAddress;
1656  ULONG ByteOffset;
1658 
1660  if (!VirtualAddress)
1661  {
1662  /*
1663  * NOTE: On real NT a mechanism with reserved pages is implemented
1664  * to handle this case in a slow, but graceful non-fatal way.
1665  */
1666  KeBugCheckEx(HAL_MEMORY_ALLOCATION, PAGE_SIZE, 0, (ULONG_PTR)__FILE__, 0);
1667  }
1668 
1669  CurrentAddress = (ULONG_PTR)VirtualAddress +
1670  (ULONG_PTR)CurrentVa -
1672 
1673  while (Length > 0)
1674  {
1675  ByteOffset = BYTE_OFFSET(CurrentAddress);
1676  CurrentLength = PAGE_SIZE - ByteOffset;
1677  if (CurrentLength > Length) CurrentLength = Length;
1678 
1679  if (WriteToDevice)
1680  {
1681  RtlCopyMemory((PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
1682  (PVOID)CurrentAddress,
1683  CurrentLength);
1684  }
1685  else
1686  {
1687  RtlCopyMemory((PVOID)CurrentAddress,
1688  (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
1689  CurrentLength);
1690  }
1691 
1692  Length -= CurrentLength;
1693  CurrentAddress += CurrentLength;
1694  MapRegisterBase++;
1695  }
1696 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define MmGetMdlVirtualAddress(_Mdl)
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
uint32_t ULONG_PTR
Definition: typedefs.h:64
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:189
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define BYTE_OFFSET(Va)
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716

◆ HalpDmaAllocateChildAdapter()

PADAPTER_OBJECT NTAPI HalpDmaAllocateChildAdapter ( IN ULONG  NumberOfMapRegisters,
IN PDEVICE_DESCRIPTION  DeviceDescription 
)

Definition at line 409 of file dma.c.

411 {
412  PADAPTER_OBJECT AdapterObject;
415  HANDLE Handle;
416 
418  NULL,
420  NULL,
421  NULL);
422 
426  KernelMode,
427  NULL,
428  sizeof(ADAPTER_OBJECT),
429  0,
430  0,
431  (PVOID)&AdapterObject);
432  if (!NT_SUCCESS(Status)) return NULL;
433 
434  Status = ObReferenceObjectByPointer(AdapterObject,
437  KernelMode);
438  if (!NT_SUCCESS(Status)) return NULL;
439 
440  RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT));
441 
442  Status = ObInsertObject(AdapterObject,
443  NULL,
445  0,
446  NULL,
447  &Handle);
448  if (!NT_SUCCESS(Status)) return NULL;
449 
450  ZwClose(Handle);
451 
452  AdapterObject->DmaHeader.Version = (USHORT)DeviceDescription->Version;
453  AdapterObject->DmaHeader.Size = sizeof(ADAPTER_OBJECT);
454  AdapterObject->DmaHeader.DmaOperations = &HalpDmaOperations;
455  AdapterObject->MapRegistersPerChannel = 1;
456  AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
457  AdapterObject->ChannelNumber = 0xFF;
458  AdapterObject->MasterAdapter = HalpMasterAdapter;
459  KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue);
460 
461  return AdapterObject;
462 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:22
USHORT Size
Definition: iotypes.h:2186
static DMA_OPERATIONS HalpDmaOperations
Definition: dma.c:109
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2187
#define FILE_READ_DATA
Definition: nt_native.h:628
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:383
#define FILE_WRITE_DATA
Definition: nt_native.h:631
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
BOOLEAN Dma32BitAddresses
Definition: iotypes.h:2030
_Must_inspect_result_ _In_ PDEVICE_DESCRIPTION DeviceDescription
Definition: iofuncs.h:1015
_In_ HANDLE Handle
Definition: extypes.h:390
USHORT Version
Definition: iotypes.h:2185
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
POBJECT_TYPE IoAdapterObjectType
Definition: adapter.c:18
#define OBJ_PERMANENT
Definition: winternl.h:226
static PADAPTER_OBJECT HalpMasterAdapter
Definition: dma.c:94
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2932
unsigned short USHORT
Definition: pedump.c:61
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106

◆ HalpDmaAllocateMasterAdapter()

PADAPTER_OBJECT NTAPI HalpDmaAllocateMasterAdapter ( VOID  )

Definition at line 352 of file dma.c.

353 {
354  PADAPTER_OBJECT MasterAdapter;
355  ULONG Size, SizeOfBitmap;
356 
357  SizeOfBitmap = MAX_MAP_REGISTERS;
358  Size = sizeof(ADAPTER_OBJECT);
359  Size += sizeof(RTL_BITMAP);
360  Size += (SizeOfBitmap + 7) >> 3;
361 
362  MasterAdapter = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_DMA);
363  if (!MasterAdapter) return NULL;
364 
365  RtlZeroMemory(MasterAdapter, Size);
366 
367  KeInitializeSpinLock(&MasterAdapter->SpinLock);
368  InitializeListHead(&MasterAdapter->AdapterQueue);
369 
370  MasterAdapter->MapRegisters = (PVOID)(MasterAdapter + 1);
371  RtlInitializeBitMap(MasterAdapter->MapRegisters,
372  (PULONG)(MasterAdapter->MapRegisters + 1),
373  SizeOfBitmap);
374  RtlSetAllBits(MasterAdapter->MapRegisters);
375  MasterAdapter->NumberOfMapRegisters = 0;
376  MasterAdapter->CommittedMapRegisters = 0;
377 
378  MasterAdapter->MapRegisterBase = ExAllocatePoolWithTag(NonPagedPool,
379  SizeOfBitmap *
380  sizeof(ROS_MAP_REGISTER_ENTRY),
381  TAG_DMA);
382  if (!MasterAdapter->MapRegisterBase)
383  {
384  ExFreePool(MasterAdapter);
385  return NULL;
386  }
387 
388  RtlZeroMemory(MasterAdapter->MapRegisterBase,
389  SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY));
390  if (!HalpGrowMapBuffers(MasterAdapter, 0x10000))
391  {
392  ExFreePool(MasterAdapter);
393  return NULL;
394  }
395 
396  return MasterAdapter;
397 }
struct _RTL_BITMAP RTL_BITMAP
struct _ADAPTER_OBJECT ADAPTER_OBJECT
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
Definition: haldma.h:312
BOOLEAN NTAPI HalpGrowMapBuffers(IN PADAPTER_OBJECT AdapterObject, IN ULONG SizeOfMapBuffers)
Definition: dma.c:203
NTSYSAPI void WINAPI RtlSetAllBits(PRTL_BITMAP)
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define TAG_DMA
Definition: dma.c:132
#define MAX_MAP_REGISTERS
Definition: dma.c:130
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ HalpDmaGetDmaAlignment()

ULONG NTAPI HalpDmaGetDmaAlignment ( IN PADAPTER_OBJECT  AdapterObject)

Definition at line 1131 of file dma.c.

1132 {
1133  return 1;
1134 }

◆ HalpDmaInitializeEisaAdapter()

BOOLEAN NTAPI HalpDmaInitializeEisaAdapter ( IN PADAPTER_OBJECT  AdapterObject,
IN PDEVICE_DESCRIPTION  DeviceDescription 
)

Definition at line 472 of file dma.c.

474 {
475  UCHAR Controller;
476  DMA_MODE DmaMode = {{0 }};
477  DMA_EXTENDED_MODE ExtendedMode = {{ 0 }};
478  PVOID AdapterBaseVa;
479 
480  Controller = (DeviceDescription->DmaChannel & 4) ? 2 : 1;
481 
482  if (Controller == 1)
483  {
484  AdapterBaseVa = UlongToPtr(FIELD_OFFSET(EISA_CONTROL, DmaController1));
485  }
486  else
487  {
488  AdapterBaseVa = UlongToPtr(FIELD_OFFSET(EISA_CONTROL, DmaController2));
489  }
490 
491  AdapterObject->AdapterNumber = Controller;
492  AdapterObject->ChannelNumber = (UCHAR)(DeviceDescription->DmaChannel & 3);
493  AdapterObject->PagePort = (PUCHAR)HalpEisaPortPage[DeviceDescription->DmaChannel];
494  AdapterObject->Width16Bits = FALSE;
495  AdapterObject->AdapterBaseVa = AdapterBaseVa;
496 
497  if (HalpEisaDma)
498  {
499  ExtendedMode.ChannelNumber = AdapterObject->ChannelNumber;
500 
501  switch (DeviceDescription->DmaSpeed)
502  {
503  case Compatible: ExtendedMode.TimingMode = COMPATIBLE_TIMING; break;
504  case TypeA: ExtendedMode.TimingMode = TYPE_A_TIMING; break;
505  case TypeB: ExtendedMode.TimingMode = TYPE_B_TIMING; break;
506  case TypeC: ExtendedMode.TimingMode = BURST_TIMING; break;
507  default:
508  return FALSE;
509  }
510 
511  switch (DeviceDescription->DmaWidth)
512  {
513  case Width8Bits: ExtendedMode.TransferSize = B_8BITS; break;
514  case Width16Bits: ExtendedMode.TransferSize = B_16BITS; break;
515  case Width32Bits: ExtendedMode.TransferSize = B_32BITS; break;
516  default:
517  return FALSE;
518  }
519 
520  if (Controller == 1)
521  {
523  ExtendedMode.Byte);
524  }
525  else
526  {
528  ExtendedMode.Byte);
529  }
530  }
531  else
532  {
533  /*
534  * Validate setup for non-busmaster DMA adapter. Secondary controller
535  * supports only 16-bit transfers and main controller supports only
536  * 8-bit transfers. Anything else is invalid.
537  */
539  {
540  if ((Controller == 2) && (DeviceDescription->DmaWidth == Width16Bits))
541  {
542  AdapterObject->Width16Bits = TRUE;
543  }
544  else if ((Controller != 1) || (DeviceDescription->DmaWidth != Width8Bits))
545  {
546  return FALSE;
547  }
548  }
549  }
550 
551  DmaMode.Channel = AdapterObject->ChannelNumber;
553 
554  /*
555  * Set the DMA request mode.
556  *
557  * For (E)ISA bus master devices just unmask (enable) the DMA channel
558  * and set it to cascade mode. Otherwise just select the right one
559  * bases on the passed device description.
560  */
562  {
564  if (Controller == 1)
565  {
566  /* Set the Request Data */
568  WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->Mode, DmaMode.Byte);
569 
570  /* Unmask DMA Channel */
571  WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->SingleMask,
572  AdapterObject->ChannelNumber | DMA_CLEARMASK);
573  }
574  else
575  {
576  /* Set the Request Data */
577  WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->Mode, DmaMode.Byte);
578 
579  /* Unmask DMA Channel */
580  WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->SingleMask,
581  AdapterObject->ChannelNumber | DMA_CLEARMASK);
582  }
583  }
584  else
585  {
587  {
589  }
590  else
591  {
593  }
594  }
595 
596  AdapterObject->AdapterMode = DmaMode;
597 
598  return TRUE;
599 }
#define TYPE_A_TIMING
Definition: haldma.h:150
UCHAR AutoInitialize
Definition: haldma.h:95
#define TRUE
Definition: types.h:120
#define B_32BITS
Definition: haldma.h:145
_In_ ULONG Mode
Definition: hubbusif.h:303
unsigned char * PUCHAR
Definition: retypes.h:3
DMA_SPEED DmaSpeed
Definition: iotypes.h:2038
#define TypeA
Definition: nslookup.h:13
#define BURST_TIMING
Definition: haldma.h:152
#define DMA_CLEARMASK
Definition: haldma.h:175
static const ULONG_PTR HalpEisaPortPage[8]
Definition: dma.c:97
UCHAR Byte
Definition: haldma.h:99
#define __WARNING_DEREF_NULL_PTR
Definition: suppress.h:32
UCHAR Channel
Definition: haldma.h:93
#define UlongToPtr(u)
Definition: config.h:106
#define B_16BITS
Definition: haldma.h:146
_Must_inspect_result_ _In_ PDEVICE_DESCRIPTION DeviceDescription
Definition: iofuncs.h:1015
#define COMPATIBLE_TIMING
Definition: haldma.h:149
if(!(yy_init))
Definition: macro.lex.yy.c:714
BOOLEAN DemandMode
Definition: iotypes.h:2028
DMA_WIDTH DmaWidth
Definition: iotypes.h:2037
unsigned char UCHAR
Definition: xmlstorage.h:181
UCHAR ChannelNumber
Definition: haldma.h:133
UCHAR RequestMode
Definition: haldma.h:97
UCHAR TransferSize
Definition: haldma.h:134
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define SINGLE_REQUEST_MODE
Definition: haldma.h:170
#define TYPE_B_TIMING
Definition: haldma.h:151
#define DEMAND_REQUEST_MODE
Definition: haldma.h:169
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532
#define B_8BITS
Definition: haldma.h:143
#define CASCADE_REQUEST_MODE
Definition: haldma.h:172
static BOOLEAN HalpEisaDma
Definition: dma.c:92
BOOLEAN AutoInitialize
Definition: iotypes.h:2029
#define _PRAGMA_WARNING_SUPPRESS(x)
Definition: suppress.h:28
UCHAR TimingMode
Definition: haldma.h:135

◆ HalpGetAdapterMaximumPhysicalAddress()

PHYSICAL_ADDRESS NTAPI HalpGetAdapterMaximumPhysicalAddress ( IN PADAPTER_OBJECT  AdapterObject)

Definition at line 189 of file dma.c.

190 {
191  PHYSICAL_ADDRESS HighestAddress;
192 
193  if (AdapterObject->MasterDevice)
194  {
195  if (AdapterObject->Dma64BitAddresses)
196  {
197  HighestAddress.QuadPart = 0xFFFFFFFFFFFFFFFFULL;
198  return HighestAddress;
199  }
200  else if (AdapterObject->Dma32BitAddresses)
201  {
202  HighestAddress.QuadPart = 0xFFFFFFFF;
203  return HighestAddress;
204  }
205  }
206 
207  HighestAddress.QuadPart = 0xFFFFFF;
208  return HighestAddress;
209 }
#define ULL(a, b)
Definition: format_msg.c:27
LONGLONG QuadPart
Definition: typedefs.h:113

◆ HalpGetDmaAdapter()

PDMA_ADAPTER NTAPI HalpGetDmaAdapter ( IN PVOID  Context,
IN PDEVICE_DESCRIPTION  DeviceDescription,
OUT PULONG  NumberOfMapRegisters 
)

Definition at line 810 of file dma.c.

813 {
815 }
_Out_ PULONG NumberOfMapRegisters
Definition: halfuncs.h:209
_Must_inspect_result_ _In_ PDEVICE_DESCRIPTION DeviceDescription
Definition: iofuncs.h:1015
PADAPTER_OBJECT NTAPI HalGetAdapter(IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
Definition: dma.c:22

◆ HalpGrowMapBuffers()

BOOLEAN NTAPI HalpGrowMapBuffers ( IN PADAPTER_OBJECT  AdapterObject,
IN ULONG  SizeOfMapBuffers 
)

Definition at line 225 of file dma.c.

227 {
232  PHYSICAL_ADDRESS BoundryAddressMultiple;
233  KIRQL OldIrql;
234  ULONG MapRegisterCount;
235 
236  /* Check if enough map register slots are available. */
237  MapRegisterCount = BYTES_TO_PAGES(SizeOfMapBuffers);
238  if (MapRegisterCount + AdapterObject->NumberOfMapRegisters > MAX_MAP_REGISTERS)
239  {
240  DPRINT("No more map register slots available! (Current: %d | Requested: %d | Limit: %d)\n",
241  AdapterObject->NumberOfMapRegisters,
242  MapRegisterCount,
244  return FALSE;
245  }
246 
247  /*
248  * Allocate memory for the new map registers. For 32-bit adapters we use
249  * two passes in order not to waste scare resource (low memory).
250  */
253  LowestAcceptableAddress.LowPart = HighestAcceptableAddress.LowPart == 0xFFFFFFFF ? 0x1000000 : 0;
254  BoundryAddressMultiple.QuadPart = 0;
255 
259  BoundryAddressMultiple,
260  MmNonCached);
262  {
267  BoundryAddressMultiple,
268  MmNonCached);
269  }
270 
271  if (!VirtualAddress) return FALSE;
272 
274 
275  /*
276  * All the following must be done with the master adapter lock held
277  * to prevent corruption.
278  */
279  KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
280 
281  /*
282  * Setup map register entries for the buffer allocated. Each entry has
283  * a virtual and physical address and corresponds to PAGE_SIZE large
284  * buffer.
285  */
286  if (MapRegisterCount > 0)
287  {
288  PROS_MAP_REGISTER_ENTRY CurrentEntry, PreviousEntry;
289 
290  CurrentEntry = AdapterObject->MapRegisterBase + AdapterObject->NumberOfMapRegisters;
291  do
292  {
293  /*
294  * Leave one entry free for every non-contiguous memory region
295  * in the map register bitmap. This ensures that we can search
296  * using RtlFindClearBits for contiguous map register regions.
297  *
298  * Also for non-EISA DMA leave one free entry for every 64Kb
299  * break, because the DMA controller can handle only coniguous
300  * 64Kb regions.
301  */
302  if (CurrentEntry != AdapterObject->MapRegisterBase)
303  {
304  PreviousEntry = CurrentEntry - 1;
305  if ((PreviousEntry->PhysicalAddress.LowPart + PAGE_SIZE) == PhysicalAddress.LowPart)
306  {
307  if (!HalpEisaDma)
308  {
309  if ((PreviousEntry->PhysicalAddress.LowPart ^ PhysicalAddress.LowPart) & 0xFFFF0000)
310  {
311  CurrentEntry++;
312  AdapterObject->NumberOfMapRegisters++;
313  }
314  }
315  }
316  else
317  {
318  CurrentEntry++;
319  AdapterObject->NumberOfMapRegisters++;
320  }
321  }
322 
323  RtlClearBit(AdapterObject->MapRegisters,
324  (ULONG)(CurrentEntry - AdapterObject->MapRegisterBase));
325  CurrentEntry->VirtualAddress = VirtualAddress;
326  CurrentEntry->PhysicalAddress = PhysicalAddress;
327 
330 
331  CurrentEntry++;
332  AdapterObject->NumberOfMapRegisters++;
333  MapRegisterCount--;
334  } while (MapRegisterCount);
335  }
336 
337  KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
338 
339  return TRUE;
340 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define TRUE
Definition: types.h:120
Definition: haldma.h:312
PVOID VirtualAddress
Definition: haldma.h:314
uint32_t ULONG_PTR
Definition: typedefs.h:64
UCHAR KIRQL
Definition: env_spec_w32.h:591
PHYSICAL_ADDRESS NTAPI HalpGetAdapterMaximumPhysicalAddress(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:167
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
VOID NTAPI RtlClearBit(_In_ PRTL_BITMAP BitMapHeader, _In_ BITMAP_INDEX BitNumber)
Definition: bitmap.c:294
#define BYTES_TO_PAGES(Size)
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1061
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
PHYSICAL_ADDRESS PhysicalAddress
Definition: haldma.h:315
_Out_ PNDIS_HANDLE _Out_ PUINT _In_ PNDIS_STRING _In_ NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress
Definition: ndis.h:3227
ULONG LowPart
Definition: typedefs.h:105
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS LowestAcceptableAddress
Definition: mmfuncs.h:214
#define MAX_MAP_REGISTERS
Definition: dma.c:130
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
unsigned int ULONG
Definition: retypes.h:1
PHYSICAL_ADDRESS NTAPI MmGetPhysicalAddress(IN PVOID Address)
Definition: stubs.c:682
static BOOLEAN HalpEisaDma
Definition: dma.c:92
LONGLONG QuadPart
Definition: typedefs.h:113
PVOID NTAPI MmAllocateContiguousMemorySpecifyCache(IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS LowestAcceptableAddress OPTIONAL, IN PHYSICAL_ADDRESS HighestAcceptableAddress, IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, IN MEMORY_CACHING_TYPE CacheType OPTIONAL)
Definition: contmem.c:574

◆ HalpGrowMapBufferWorker()

VOID NTAPI HalpGrowMapBufferWorker ( IN PVOID  DeferredContext)

Definition at line 1217 of file dma.c.

1218 {
1220  KIRQL OldIrql;
1221  BOOLEAN Succeeded;
1222 
1223  /*
1224  * Try to allocate new map registers for the adapter.
1225  *
1226  * NOTE: The NT implementation actually tries to allocate more map
1227  * registers than needed as an optimization.
1228  */
1230  Succeeded = HalpGrowMapBuffers(WorkItem->AdapterObject->MasterAdapter,
1231  WorkItem->NumberOfMapRegisters << PAGE_SHIFT);
1232  KeSetEvent(&HalpDmaLock, 0, 0);
1233 
1234  if (Succeeded)
1235  {
1236  /*
1237  * Flush the adapter queue now that new map registers are ready. The
1238  * easiest way to do that is to call IoFreeMapRegisters to not free
1239  * any registers. Note that we use the magic (PVOID)2 map register
1240  * base to bypass the parameter checking.
1241  */
1243  IoFreeMapRegisters(WorkItem->AdapterObject, (PVOID)2, 0);
1245  }
1246 
1247  ExFreePool(WorkItem);
1248 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
VOID NTAPI IoFreeMapRegisters(IN PADAPTER_OBJECT AdapterObject, IN PVOID MapRegisterBase, IN ULONG NumberOfMapRegisters)
Definition: dma.c:114
static KEVENT HalpDmaLock
Definition: dma.c:87
UCHAR KIRQL
Definition: env_spec_w32.h:591
PADAPTER_OBJECT AdapterObject
Definition: haldma.h:363
struct _GROW_WORK_ITEM * PGROW_WORK_ITEM
BOOLEAN NTAPI HalpGrowMapBuffers(IN PADAPTER_OBJECT AdapterObject, IN ULONG SizeOfMapBuffers)
Definition: dma.c:203
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
VOID FASTCALL KfLowerIrql(IN KIRQL NewIrql)
Definition: pic.c:232
ULONG NumberOfMapRegisters
Definition: haldma.h:364
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675

◆ HalpInitDma()

INIT_FUNCTION VOID HalpInitDma ( VOID  )

Definition at line 139 of file dma.c.

140 {
141  /*
142  * Initialize the DMA Operation table
143  */
149 
151  {
152  /*
153  * Check if Extended DMA is available. We're just going to do a random
154  * read and write.
155  */
156  WRITE_PORT_UCHAR(UlongToPtr(FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2)), 0x2A);
157  if (READ_PORT_UCHAR(UlongToPtr(FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2))) == 0x2A)
158  {
159  DPRINT1("Machine supports EISA DMA. Bus type: %lu\n", HalpBusType);
160  HalpEisaDma = TRUE;
161  }
162  }
163 
164  /*
165  * Intialize all the global variables and allocate master adapter with
166  * first map buffers.
167  */
172 
173  /*
174  * Setup the HalDispatchTable callback for creating PnP DMA adapters. It's
175  * used by IoGetDmaAdapter in the kernel.
176  */
178 }
#define HalGetDmaAdapter
Definition: haltypes.h:291
#define TRUE
Definition: types.h:120
PHYSICAL_ADDRESS NTAPI IoMapTransfer(IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN OUT PULONG Length, IN BOOLEAN WriteToDevice)
Definition: dma.c:144
PFREE_MAP_REGISTERS FreeMapRegisters
Definition: iotypes.h:2317
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address)
Definition: mach.c:528
BOOLEAN(NTAPI * PFLUSH_ADAPTER_BUFFERS)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PMDL Mdl, _In_ PVOID MapRegisterBase, _In_ PVOID CurrentVa, _In_ ULONG Length, _In_ BOOLEAN WriteToDevice)
Definition: iotypes.h:2218
static DMA_OPERATIONS HalpDmaOperations
Definition: dma.c:109
VOID NTAPI IoFreeMapRegisters(IN PADAPTER_OBJECT AdapterObject, IN PVOID MapRegisterBase, IN ULONG NumberOfMapRegisters)
Definition: dma.c:114
VOID(NTAPI * PFREE_ADAPTER_CHANNEL)(_In_ PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2227
static KEVENT HalpDmaLock
Definition: dma.c:87
NTSTATUS(NTAPI * PALLOCATE_ADAPTER_CHANNEL)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PDEVICE_OBJECT DeviceObject, _In_ ULONG NumberOfMapRegisters, _In_ PDRIVER_CONTROL ExecutionRoutine, _In_ PVOID Context)
Definition: iotypes.h:2210
PMAP_TRANSFER MapTransfer
Definition: iotypes.h:2318
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
static KSPIN_LOCK HalpDmaAdapterListLock
Definition: dma.c:88
#define UlongToPtr(u)
Definition: config.h:106
VOID NTAPI IoFreeAdapterChannel(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:103
PFLUSH_ADAPTER_BUFFERS FlushAdapterBuffers
Definition: iotypes.h:2315
PHYSICAL_ADDRESS(NTAPI * PMAP_TRANSFER)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PMDL Mdl, _In_ PVOID MapRegisterBase, _In_ PVOID CurrentVa, _Inout_ PULONG Length, _In_ BOOLEAN WriteToDevice)
Definition: iotypes.h:2237
NTSTATUS NTAPI IoAllocateAdapterChannel(IN PADAPTER_OBJECT AdapterObject, IN PDEVICE_OBJECT DeviceObject, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context)
Definition: adapter.c:30
ULONG HalpBusType
Definition: bus.c:17
PFREE_ADAPTER_CHANNEL FreeAdapterChannel
Definition: iotypes.h:2316
BOOLEAN NTAPI IoFlushAdapterBuffers(IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN ULONG Length, IN BOOLEAN WriteToDevice)
Definition: dma.c:127
static PADAPTER_OBJECT HalpMasterAdapter
Definition: dma.c:94
static LIST_ENTRY HalpDmaAdapterList
Definition: dma.c:89
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
PALLOCATE_ADAPTER_CHANNEL AllocateAdapterChannel
Definition: iotypes.h:2314
PDMA_ADAPTER NTAPI HalpGetDmaAdapter(IN PVOID Context, IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
Definition: dma.c:790
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
VOID(NTAPI * PFREE_MAP_REGISTERS)(_In_ PDMA_ADAPTER DmaAdapter, PVOID MapRegisterBase, ULONG NumberOfMapRegisters)
Definition: iotypes.h:2231
#define DPRINT1
Definition: precomp.h:8
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532
static BOOLEAN HalpEisaDma
Definition: dma.c:92
#define MACHINE_TYPE_EISA
Definition: ketypes.h:53
PADAPTER_OBJECT NTAPI HalpDmaAllocateMasterAdapter(VOID)
Definition: dma.c:332

◆ HalpScatterGatherAdapterControl()

IO_ALLOCATION_ACTION NTAPI HalpScatterGatherAdapterControl ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  MapRegisterBase,
IN PVOID  Context 
)

Definition at line 945 of file dma.c.

949 {
950  PSCATTER_GATHER_CONTEXT AdapterControlContext = Context;
951  PADAPTER_OBJECT AdapterObject = AdapterControlContext->AdapterObject;
952  PSCATTER_GATHER_LIST ScatterGatherList;
954  ULONG ElementCount = 0, RemainingLength = AdapterControlContext->Length;
955  PUCHAR CurrentVa = AdapterControlContext->CurrentVa;
956 
957  /* Store the map register base for later in HalPutScatterGatherList */
958  AdapterControlContext->MapRegisterBase = MapRegisterBase;
959 
960  while (RemainingLength > 0 && ElementCount < MAX_SG_ELEMENTS)
961  {
962  TempElements[ElementCount].Length = RemainingLength;
963  TempElements[ElementCount].Reserved = 0;
964  TempElements[ElementCount].Address = IoMapTransfer(AdapterObject,
965  AdapterControlContext->Mdl,
967  CurrentVa + (AdapterControlContext->Length - RemainingLength),
968  &TempElements[ElementCount].Length,
969  AdapterControlContext->WriteToDevice);
970  if (TempElements[ElementCount].Length == 0)
971  break;
972 
973  DPRINT("Allocated one S/G element: 0x%I64u with length: 0x%x\n",
974  TempElements[ElementCount].Address.QuadPart,
975  TempElements[ElementCount].Length);
976 
977  ASSERT(TempElements[ElementCount].Length <= RemainingLength);
978  RemainingLength -= TempElements[ElementCount].Length;
979  ElementCount++;
980  }
981 
982  if (RemainingLength > 0)
983  {
984  DPRINT1("Scatter/gather list construction failed!\n");
985  return DeallocateObject;
986  }
987 
988  ScatterGatherList = ExAllocatePoolWithTag(NonPagedPool,
989  sizeof(SCATTER_GATHER_LIST) + sizeof(SCATTER_GATHER_ELEMENT) * ElementCount,
990  TAG_DMA);
991  ASSERT(ScatterGatherList);
992 
993  ScatterGatherList->NumberOfElements = ElementCount;
994  ScatterGatherList->Reserved = (ULONG_PTR)AdapterControlContext;
995  RtlCopyMemory(ScatterGatherList->Elements,
996  TempElements,
997  sizeof(SCATTER_GATHER_ELEMENT) * ElementCount);
998 
999  DPRINT("Initiating S/G DMA with %d element(s)\n", ElementCount);
1000 
1001  AdapterControlContext->AdapterListControlRoutine(DeviceObject,
1002  Irp,
1003  ScatterGatherList,
1004  AdapterControlContext->AdapterListControlContext);
1005 
1007 }
PDRIVER_LIST_CONTROL AdapterListControlRoutine
Definition: dma.c:935
#define MAX_SG_ELEMENTS
Definition: dma.c:84
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_In_ PIRP Irp
Definition: csq.h:116
PHYSICAL_ADDRESS NTAPI IoMapTransfer(IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN OUT PULONG Length, IN BOOLEAN WriteToDevice)
Definition: dma.c:144
unsigned char * PUCHAR
Definition: retypes.h:3
PHYSICAL_ADDRESS Address
Definition: iotypes.h:2065
static WCHAR Address[46]
Definition: ping.c:68
void DPRINT(...)
Definition: polytest.cpp:61
struct _SCATTER_GATHER_LIST SCATTER_GATHER_LIST
Definition: iotypes.h:2096
PADAPTER_OBJECT AdapterObject
Definition: dma.c:931
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define TAG_DMA
Definition: dma.c:132
PVOID MapRegisterBase
Definition: dma.c:936
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:189
#define DPRINT1
Definition: precomp.h:8
PVOID AdapterListControlContext
Definition: dma.c:936
struct _SCATTER_GATHER_LIST * PSCATTER_GATHER_LIST
Definition: iotypes.h:2096
struct tagContext Context
Definition: acpixf.h:1034
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
BOOLEAN WriteToDevice
Definition: dma.c:938

Referenced by HalGetScatterGatherList().

◆ HalPutDmaAdapter()

VOID NTAPI HalPutDmaAdapter ( IN PADAPTER_OBJECT  AdapterObject)

Definition at line 827 of file dma.c.

828 {
829  KIRQL OldIrql;
830  if (AdapterObject->ChannelNumber == 0xFF)
831  {
833  RemoveEntryList(&AdapterObject->AdapterList);
835  }
836 
837  ObDereferenceObject(AdapterObject);
838 }
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
static KSPIN_LOCK HalpDmaAdapterListLock
Definition: dma.c:88
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627

◆ HalPutScatterGatherList()

VOID NTAPI HalPutScatterGatherList ( IN PADAPTER_OBJECT  AdapterObject,
IN PSCATTER_GATHER_LIST  ScatterGather,
IN BOOLEAN  WriteToDevice 
)

Definition at line 1092 of file dma.c.

1095 {
1096  PSCATTER_GATHER_CONTEXT AdapterControlContext = (PSCATTER_GATHER_CONTEXT)ScatterGather->Reserved;
1097  ULONG i;
1098 
1099  for (i = 0; i < ScatterGather->NumberOfElements; i++)
1100  {
1101  IoFlushAdapterBuffers(AdapterObject,
1102  AdapterControlContext->Mdl,
1103  AdapterControlContext->MapRegisterBase,
1104  AdapterControlContext->CurrentVa,
1105  ScatterGather->Elements[i].Length,
1106  AdapterControlContext->WriteToDevice);
1107  AdapterControlContext->CurrentVa += ScatterGather->Elements[i].Length;
1108  }
1109 
1110  IoFreeMapRegisters(AdapterObject,
1111  AdapterControlContext->MapRegisterBase,
1112  AdapterControlContext->MapRegisterCount);
1113 
1114  DPRINT("S/G DMA has finished!\n");
1115 
1116  ExFreePoolWithTag(AdapterControlContext, TAG_DMA);
1118 }
ULONG MapRegisterCount
Definition: dma.c:937
VOID NTAPI IoFreeMapRegisters(IN PADAPTER_OBJECT AdapterObject, IN PVOID MapRegisterBase, IN ULONG NumberOfMapRegisters)
Definition: dma.c:114
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void DPRINT(...)
Definition: polytest.cpp:61
#define for
Definition: utility.h:88
BOOLEAN NTAPI IoFlushAdapterBuffers(IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN ULONG Length, IN BOOLEAN WriteToDevice)
Definition: dma.c:127
#define TAG_DMA
Definition: dma.c:132
PVOID MapRegisterBase
Definition: dma.c:936
_In_ struct _IRP _In_ struct _SCATTER_GATHER_LIST * ScatterGather
Definition: iotypes.h:2259
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _SCATTER_GATHER_CONTEXT * PSCATTER_GATHER_CONTEXT
BOOLEAN WriteToDevice
Definition: dma.c:938

◆ HalReadDmaCounter()

ULONG NTAPI HalReadDmaCounter ( IN PADAPTER_OBJECT  AdapterObject)

Definition at line 1145 of file dma.c.

1146 {
1147  KIRQL OldIrql;
1148  ULONG Count, OldCount;
1149 
1150  ASSERT(!AdapterObject->MasterDevice);
1151 
1152  /*
1153  * Acquire the master adapter lock since we're going to mess with the
1154  * system DMA controller registers and we really don't want anyone
1155  * to do the same at the same time.
1156  */
1157  KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
1158 
1159  /* Send the request to the specific controller. */
1160  if (AdapterObject->AdapterNumber == 1)
1161  {
1162  PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
1163 
1164  Count = 0xffff00;
1165  do
1166  {
1167  OldCount = Count;
1168 
1169  /* Send Reset */
1170  WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
1171 
1172  /* Read Count */
1173  Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
1174  [AdapterObject->ChannelNumber].DmaBaseCount);
1175  Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
1176  [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
1177  } while (0xffff00 & (OldCount ^ Count));
1178  }
1179  else
1180  {
1181  PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
1182 
1183  Count = 0xffff00;
1184  do
1185  {
1186  OldCount = Count;
1187 
1188  /* Send Reset */
1189  WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
1190 
1191  /* Read Count */
1192  Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
1193  [AdapterObject->ChannelNumber].DmaBaseCount);
1194  Count |= READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
1195  [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
1196  } while (0xffff00 & (OldCount ^ Count));
1197  }
1198 
1199  KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
1200 
1201  Count++;
1202  Count &= 0xffff;
1203  if (AdapterObject->Width16Bits) Count *= 2;
1204 
1205  return Count;
1206 }
UCHAR DmaBaseCount
Definition: haldma.h:184
DMA1_ADDRESS_COUNT DmaAddressCount[4]
Definition: haldma.h:197
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address)
Definition: mach.c:528
DMA2_ADDRESS_COUNT DmaAddressCount[4]
Definition: haldma.h:210
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
UCHAR KIRQL
Definition: env_spec_w32.h:591
UCHAR ClearBytePointer
Definition: haldma.h:219
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
UCHAR DmaBaseCount
Definition: haldma.h:191
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
unsigned int ULONG
Definition: retypes.h:1
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532
UCHAR ClearBytePointer
Definition: haldma.h:202

◆ IoFlushAdapterBuffers()

BOOLEAN NTAPI IoFlushAdapterBuffers ( IN PADAPTER_OBJECT  AdapterObject,
IN PMDL  Mdl,
IN PVOID  MapRegisterBase,
IN PVOID  CurrentVa,
IN ULONG  Length,
IN BOOLEAN  WriteToDevice 
)

Definition at line 1731 of file dma.c.

1737 {
1738  BOOLEAN SlaveDma = FALSE;
1739  PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
1742  PPFN_NUMBER MdlPagesPtr;
1743 
1744  /* Sanity checks */
1746  ASSERT(AdapterObject);
1747 
1748  if (!AdapterObject->MasterDevice)
1749  {
1750  /* Mask out (disable) the DMA channel. */
1751  if (AdapterObject->AdapterNumber == 1)
1752  {
1753  PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
1754  WRITE_PORT_UCHAR(&DmaControl1->SingleMask,
1755  AdapterObject->ChannelNumber | DMA_SETMASK);
1756  }
1757  else
1758  {
1759  PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
1760  WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
1761  AdapterObject->ChannelNumber | DMA_SETMASK);
1762  }
1763  SlaveDma = TRUE;
1764  }
1765 
1766  /* This can happen if the device supports hardware scatter/gather. */
1767  if (MapRegisterBase == NULL) return TRUE;
1768 
1769  RealMapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
1770 
1771  if (!WriteToDevice)
1772  {
1774  {
1775  if (RealMapRegisterBase->Counter != MAXULONG)
1776  {
1777  if ((SlaveDma) && !(AdapterObject->IgnoreCount))
1778  {
1779  Length -= HalReadDmaCounter(AdapterObject);
1780  }
1781  }
1782  HalpCopyBufferMap(Mdl,
1783  RealMapRegisterBase,
1784  CurrentVa,
1785  Length,
1786  FALSE);
1787  }
1788  else
1789  {
1790  MdlPagesPtr = MmGetMdlPfnArray(Mdl);
1791  MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
1792 
1793  PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
1794  PhysicalAddress.QuadPart += BYTE_OFFSET(CurrentVa);
1795 
1798  {
1799  HalpCopyBufferMap(Mdl,
1800  RealMapRegisterBase,
1801  CurrentVa,
1802  Length,
1803  FALSE);
1804  }
1805  }
1806  }
1807 
1808  RealMapRegisterBase->Counter = 0;
1809 
1810  return TRUE;
1811 }
#define DMA_SETMASK
Definition: haldma.h:174
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define TRUE
Definition: types.h:120
ULONG NTAPI HalReadDmaCounter(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:76
#define MmGetMdlPfnArray(_Mdl)
UCHAR SingleMask
Definition: haldma.h:215
Definition: haldma.h:312
VOID NTAPI HalpCopyBufferMap(PMDL Mdl, PROS_MAP_REGISTER_ENTRY MapRegisterBase, PVOID CurrentVa, ULONG Length, BOOLEAN WriteToDevice)
Definition: dma.c:1468
uint32_t ULONG_PTR
Definition: typedefs.h:64
ULONG * PPFN_NUMBER
Definition: ke.h:8
UCHAR SingleMask
Definition: haldma.h:200
PHYSICAL_ADDRESS NTAPI HalpGetAdapterMaximumPhysicalAddress(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:167
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _ROS_MAP_REGISTER_ENTRY * PROS_MAP_REGISTER_ENTRY
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1061
_Out_ PNDIS_HANDLE _Out_ PUINT _In_ PNDIS_STRING _In_ NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress
Definition: ndis.h:3227
#define MAXULONG
Definition: typedefs.h:250
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:189
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532
#define ULONG_PTR
Definition: config.h:101
#define MAP_BASE_SW_SG
Definition: haldma.h:367
#define BYTE_OFFSET(Va)
LONGLONG QuadPart
Definition: typedefs.h:113
ULONG Counter
Definition: haldma.h:316

◆ IoFreeAdapterChannel()

VOID NTAPI IoFreeAdapterChannel ( IN PADAPTER_OBJECT  AdapterObject)

Definition at line 1439 of file dma.c.

1440 {
1441  PADAPTER_OBJECT MasterAdapter;
1443  PWAIT_CONTEXT_BLOCK WaitContextBlock;
1444  ULONG Index = MAXULONG;
1445  ULONG Result;
1446  KIRQL OldIrql;
1447 
1448  MasterAdapter = AdapterObject->MasterAdapter;
1449 
1450  for (;;)
1451  {
1452  /*
1453  * To keep map registers, call here with AdapterObject->
1454  * NumberOfMapRegisters set to zero. This trick is used in
1455  * HalAllocateAdapterChannel for example.
1456  */
1457  if (AdapterObject->NumberOfMapRegisters)
1458  {
1459  IoFreeMapRegisters(AdapterObject,
1460  AdapterObject->MapRegisterBase,
1461  AdapterObject->NumberOfMapRegisters);
1462  }
1463 
1464  DeviceQueueEntry = KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue);
1465  if (!DeviceQueueEntry) break;
1466 
1467  WaitContextBlock = CONTAINING_RECORD(DeviceQueueEntry,
1469  WaitQueueEntry);
1470 
1471  AdapterObject->CurrentWcb = WaitContextBlock;
1472  AdapterObject->NumberOfMapRegisters = WaitContextBlock->NumberOfMapRegisters;
1473 
1474  if ((WaitContextBlock->NumberOfMapRegisters) && (AdapterObject->MasterAdapter))
1475  {
1476  KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1477 
1478  if (IsListEmpty(&MasterAdapter->AdapterQueue))
1479  {
1480  Index = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
1481  WaitContextBlock->NumberOfMapRegisters,
1482  0);
1483  if (Index != MAXULONG)
1484  {
1485  AdapterObject->MapRegisterBase = MasterAdapter->MapRegisterBase + Index;
1486  if (!AdapterObject->ScatterGather)
1487  {
1488  AdapterObject->MapRegisterBase =(PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
1489  }
1490  }
1491  }
1492 
1493  if (Index == MAXULONG)
1494  {
1495  InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
1496  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1497  break;
1498  }
1499 
1500  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1501  }
1502  else
1503  {
1504  AdapterObject->MapRegisterBase = NULL;
1505  AdapterObject->NumberOfMapRegisters = 0;
1506  }
1507 
1508  /* Call the adapter control routine. */
1509  Result = ((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)(WaitContextBlock->DeviceObject,
1510  WaitContextBlock->CurrentIrp,
1511  AdapterObject->MapRegisterBase,
1512  WaitContextBlock->DeviceContext);
1513  switch (Result)
1514  {
1515  case KeepObject:
1516  /*
1517  * We're done until the caller manually calls IoFreeAdapterChannel
1518  * or IoFreeMapRegisters.
1519  */
1520  return;
1521 
1523  /*
1524  * Hide the map registers so they aren't deallocated next time
1525  * around.
1526  */
1527  AdapterObject->NumberOfMapRegisters = 0;
1528  break;
1529 
1530  default:
1531  break;
1532  }
1533  }
1534 }
PDRIVER_CONTROL DeviceRoutine
Definition: iotypes.h:196
#define InsertTailList(ListHead, Entry)
VOID NTAPI IoFreeMapRegisters(IN PADAPTER_OBJECT AdapterObject, IN PVOID MapRegisterBase, IN ULONG NumberOfMapRegisters)
Definition: dma.c:114
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:64
UCHAR KIRQL
Definition: env_spec_w32.h:591
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
struct _ROS_MAP_REGISTER_ENTRY * PROS_MAP_REGISTER_ENTRY
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
static const UCHAR Index[8]
Definition: usbohci.c:18
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define MAXULONG
Definition: typedefs.h:250
Definition: ketypes.h:566
PKDEVICE_QUEUE_ENTRY NTAPI KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:153
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
unsigned int ULONG
Definition: retypes.h:1
DRIVER_CONTROL * PDRIVER_CONTROL
Definition: iotypes.h:192
_Inout_ PKDEVICE_QUEUE_ENTRY DeviceQueueEntry
Definition: kefuncs.h:339
#define MAP_BASE_SW_SG
Definition: haldma.h:367
ULONG NumberOfMapRegisters
Definition: iotypes.h:198

◆ IoFreeMapRegisters()

VOID NTAPI IoFreeMapRegisters ( IN PADAPTER_OBJECT  AdapterObject,
IN PVOID  MapRegisterBase,
IN ULONG  NumberOfMapRegisters 
)

Definition at line 1552 of file dma.c.

1555 {
1556  PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter;
1557  PLIST_ENTRY ListEntry;
1558  KIRQL OldIrql;
1559  ULONG Index;
1560  ULONG Result;
1561 
1563 
1564  if (!(MasterAdapter) || !(MapRegisterBase)) return;
1565 
1566  KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1567 
1568  if (NumberOfMapRegisters != 0)
1569  {
1570  PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
1571 
1572  RealMapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
1573  RtlClearBits(MasterAdapter->MapRegisters,
1574  (ULONG)(RealMapRegisterBase - MasterAdapter->MapRegisterBase),
1576  }
1577 
1578  /*
1579  * Now that we freed few map registers it's time to look at the master
1580  * adapter queue and see if there is someone waiting for map registers.
1581  */
1582  while (!IsListEmpty(&MasterAdapter->AdapterQueue))
1583  {
1584  ListEntry = RemoveHeadList(&MasterAdapter->AdapterQueue);
1585  AdapterObject = CONTAINING_RECORD(ListEntry, struct _ADAPTER_OBJECT, AdapterQueue);
1586 
1587  Index = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
1588  AdapterObject->NumberOfMapRegisters,
1589  0);
1590  if (Index == MAXULONG)
1591  {
1592  InsertHeadList(&MasterAdapter->AdapterQueue, ListEntry);
1593  break;
1594  }
1595 
1596  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1597 
1598  AdapterObject->MapRegisterBase = MasterAdapter->MapRegisterBase + Index;
1599  if (!AdapterObject->ScatterGather)
1600  {
1601  AdapterObject->MapRegisterBase =
1602  (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
1603  }
1604 
1605  Result = ((PDRIVER_CONTROL)AdapterObject->CurrentWcb->DeviceRoutine)(AdapterObject->CurrentWcb->DeviceObject,
1606  AdapterObject->CurrentWcb->CurrentIrp,
1607  AdapterObject->MapRegisterBase,
1608  AdapterObject->CurrentWcb->DeviceContext);
1609  switch (Result)
1610  {
1612  AdapterObject->NumberOfMapRegisters = 0;
1613  /* fall through */
1614 
1615  case DeallocateObject:
1616  if (AdapterObject->NumberOfMapRegisters)
1617  {
1618  KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1619  RtlClearBits(MasterAdapter->MapRegisters,
1620  (ULONG)(AdapterObject->MapRegisterBase -
1621  MasterAdapter->MapRegisterBase),
1622  AdapterObject->NumberOfMapRegisters);
1623  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1624  }
1625 
1626  IoFreeAdapterChannel(AdapterObject);
1627  break;
1628 
1629  default:
1630  break;
1631  }
1632 
1633  KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1634  }
1635 
1636  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1637 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
_Out_ PULONG NumberOfMapRegisters
Definition: halfuncs.h:209
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
Definition: haldma.h:312
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:64
UCHAR KIRQL
Definition: env_spec_w32.h:591
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
struct _ROS_MAP_REGISTER_ENTRY * PROS_MAP_REGISTER_ENTRY
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
VOID NTAPI IoFreeAdapterChannel(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:103
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
static const UCHAR Index[8]
Definition: usbohci.c:18
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: typedefs.h:118
#define MAXULONG
Definition: typedefs.h:250
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:189
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
unsigned int ULONG
Definition: retypes.h:1
DRIVER_CONTROL * PDRIVER_CONTROL
Definition: iotypes.h:192
#define MAP_BASE_SW_SG
Definition: haldma.h:367

◆ IoMapTransfer()

PHYSICAL_ADDRESS NTAPI IoMapTransfer ( IN PADAPTER_OBJECT  AdapterObject,
IN PMDL  Mdl,
IN PVOID  MapRegisterBase,
IN PVOID  CurrentVa,
IN OUT PULONG  Length,
IN BOOLEAN  WriteToDevice 
)

Definition at line 1846 of file dma.c.

1852 {
1853  PPFN_NUMBER MdlPagesPtr;
1854  PFN_NUMBER MdlPage1, MdlPage2;
1855  ULONG ByteOffset;
1856  ULONG TransferOffset;
1857  ULONG TransferLength;
1858  BOOLEAN UseMapRegisters;
1859  PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
1862  ULONG Counter;
1863  DMA_MODE AdapterMode;
1864  KIRQL OldIrql;
1865 
1866  /*
1867  * Precalculate some values that are used in all cases.
1868  *
1869  * ByteOffset is offset inside the page at which the transfer starts.
1870  * MdlPagesPtr is pointer inside the MDL page chain at the page where the
1871  * transfer start.
1872  * PhysicalAddress is physical address corresponding to the transfer
1873  * start page and offset.
1874  * TransferLength is the initial length of the transfer, which is reminder
1875  * of the first page. The actual value is calculated below.
1876  *
1877  * Note that all the variables can change during the processing which
1878  * takes place below. These are just initial values.
1879  */
1880  ByteOffset = BYTE_OFFSET(CurrentVa);
1881 
1882  MdlPagesPtr = MmGetMdlPfnArray(Mdl);
1883  MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
1884 
1885  PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
1887 
1888  TransferLength = PAGE_SIZE - ByteOffset;
1889 
1890  /*
1891  * Special case for bus master adapters with S/G support. We can directly
1892  * use the buffer specified by the MDL, so not much work has to be done.
1893  *
1894  * Just return the passed VA's corresponding physical address and update
1895  * length to the number of physically contiguous bytes found. Also
1896  * pages crossing the 4Gb boundary aren't considered physically contiguous.
1897  */
1898  if (MapRegisterBase == NULL)
1899  {
1900  while (TransferLength < *Length)
1901  {
1902  MdlPage1 = *MdlPagesPtr;
1903  MdlPage2 = *(MdlPagesPtr + 1);
1904  if (MdlPage1 + 1 != MdlPage2) break;
1905  if ((MdlPage1 ^ MdlPage2) & ~0xFFFFF) break;
1906  TransferLength += PAGE_SIZE;
1907  MdlPagesPtr++;
1908  }
1909 
1910  if (TransferLength < *Length) *Length = TransferLength;
1911 
1912  return PhysicalAddress;
1913  }
1914 
1915  /*
1916  * The code below applies to slave DMA adapters and bus master adapters
1917  * without hardward S/G support.
1918  */
1919  RealMapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
1920 
1921  /*
1922  * Try to calculate the size of the transfer. We can only transfer
1923  * pages that are physically contiguous and that don't cross the
1924  * 64Kb boundary (this limitation applies only for ISA controllers).
1925  */
1926  while (TransferLength < *Length)
1927  {
1928  MdlPage1 = *MdlPagesPtr;
1929  MdlPage2 = *(MdlPagesPtr + 1);
1930  if (MdlPage1 + 1 != MdlPage2) break;
1931  if (!HalpEisaDma && ((MdlPage1 ^ MdlPage2) & ~0xF)) break;
1932  TransferLength += PAGE_SIZE;
1933  MdlPagesPtr++;
1934  }
1935 
1936  if (TransferLength > *Length) TransferLength = *Length;
1937 
1938  /*
1939  * If we're about to simulate software S/G and not all the pages are
1940  * physically contiguous then we must use the map registers to store
1941  * the data and allow the whole transfer to proceed at once.
1942  */
1943  if (((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG) && (TransferLength < *Length))
1944  {
1945  UseMapRegisters = TRUE;
1946  PhysicalAddress = RealMapRegisterBase->PhysicalAddress;
1948  TransferLength = *Length;
1949  RealMapRegisterBase->Counter = MAXULONG;
1950  Counter = 0;
1951  }
1952  else
1953  {
1954  /*
1955  * This is ordinary DMA transfer, so just update the progress
1956  * counters. These are used by IoFlushAdapterBuffers to track
1957  * the transfer progress.
1958  */
1959  UseMapRegisters = FALSE;
1960  Counter = RealMapRegisterBase->Counter;
1961  RealMapRegisterBase->Counter += BYTES_TO_PAGES(ByteOffset + TransferLength);
1962 
1963  /*
1964  * Check if the buffer doesn't exceed the highest physical address
1965  * limit of the device. In that case we must use the map registers to
1966  * store the data.
1967  */
1969  if ((PhysicalAddress.QuadPart + TransferLength) > HighestAcceptableAddress.QuadPart)
1970  {
1971  UseMapRegisters = TRUE;
1972  PhysicalAddress = RealMapRegisterBase[Counter].PhysicalAddress;
1975  {
1976  RealMapRegisterBase->Counter = MAXULONG;
1977  Counter = 0;
1978  }
1979  }
1980  }
1981 
1982  /*
1983  * If we decided to use the map registers (see above) and we're about
1984  * to transfer data to the device then copy the buffers into the map
1985  * register memory.
1986  */
1987  if ((UseMapRegisters) && (WriteToDevice))
1988  {
1989  HalpCopyBufferMap(Mdl,
1990  RealMapRegisterBase + Counter,
1991  CurrentVa,
1992  TransferLength,
1993  WriteToDevice);
1994  }
1995 
1996  /*
1997  * Return the length of transfer that actually takes place.
1998  */
1999  *Length = TransferLength;
2000 
2001  /*
2002  * If we're doing slave (system) DMA then program the (E)ISA controller
2003  * to actually start the transfer.
2004  */
2005  if ((AdapterObject) && !(AdapterObject->MasterDevice))
2006  {
2007  AdapterMode = AdapterObject->AdapterMode;
2008 
2009  if (WriteToDevice)
2010  {
2011  AdapterMode.TransferType = WRITE_TRANSFER;
2012  }
2013  else
2014  {
2015  AdapterMode.TransferType = READ_TRANSFER;
2016  if (AdapterObject->IgnoreCount)
2017  {
2018  RtlZeroMemory((PUCHAR)RealMapRegisterBase[Counter].VirtualAddress + ByteOffset,
2019  TransferLength);
2020  }
2021  }
2022 
2023  TransferOffset = PhysicalAddress.LowPart & 0xFFFF;
2024  if (AdapterObject->Width16Bits)
2025  {
2026  TransferLength >>= 1;
2027  TransferOffset >>= 1;
2028  }
2029 
2030  KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
2031 
2032  if (AdapterObject->AdapterNumber == 1)
2033  {
2034  PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
2035 
2036  /* Reset Register */
2037  WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
2038 
2039  /* Set the Mode */
2040  WRITE_PORT_UCHAR(&DmaControl1->Mode, AdapterMode.Byte);
2041 
2042  /* Set the Offset Register */
2043  WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
2044  (UCHAR)(TransferOffset));
2045  WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
2046  (UCHAR)(TransferOffset >> 8));
2047 
2048  /* Set the Page Register */
2049  WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
2050  (UCHAR)(PhysicalAddress.LowPart >> 16));
2051  if (HalpEisaDma)
2052  {
2053  WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
2054  0);
2055  }
2056 
2057  /* Set the Length */
2058  WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
2059  (UCHAR)(TransferLength - 1));
2060  WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
2061  (UCHAR)((TransferLength - 1) >> 8));
2062 
2063  /* Unmask the Channel */
2064  WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
2065  }
2066  else
2067  {
2068  PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
2069 
2070  /* Reset Register */
2071  WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
2072 
2073  /* Set the Mode */
2074  WRITE_PORT_UCHAR(&DmaControl2->Mode, AdapterMode.Byte);
2075 
2076  /* Set the Offset Register */
2077  WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
2078  (UCHAR)(TransferOffset));
2079  WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
2080  (UCHAR)(TransferOffset >> 8));
2081 
2082  /* Set the Page Register */
2083  WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
2084  (UCHAR)(PhysicalAddress.u.LowPart >> 16));
2085  if (HalpEisaDma)
2086  {
2087  WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
2088  0);
2089  }
2090 
2091  /* Set the Length */
2092  WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
2093  (UCHAR)(TransferLength - 1));
2094  WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
2095  (UCHAR)((TransferLength - 1) >> 8));
2096 
2097  /* Unmask the Channel */
2098  WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
2099  AdapterObject->ChannelNumber | DMA_CLEARMASK);
2100  }
2101 
2102  KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
2103  }
2104 
2105  /*
2106  * Return physical address of the buffer with data that is used for the
2107  * transfer. It can either point inside the Mdl that was passed by the
2108  * caller or into the map registers if the Mdl buffer can't be used
2109  * directly.
2110  */
2111  return PhysicalAddress;
2112 }
UCHAR DmaBaseCount
Definition: haldma.h:184
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
UCHAR DmaBaseAddress
Definition: haldma.h:183
DMA1_ADDRESS_COUNT DmaAddressCount[4]
Definition: haldma.h:197
#define TRUE
Definition: types.h:120
#define MmGetMdlPfnArray(_Mdl)
UCHAR SingleMask
Definition: haldma.h:215
UCHAR Mode
Definition: haldma.h:217
unsigned char * PUCHAR
Definition: retypes.h:3
UCHAR DmaBaseAddress
Definition: haldma.h:189
Definition: haldma.h:312
DMA2_ADDRESS_COUNT DmaAddressCount[4]
Definition: haldma.h:210
#define DMA_CLEARMASK
Definition: haldma.h:175
UCHAR Byte
Definition: haldma.h:99
VOID NTAPI HalpCopyBufferMap(PMDL Mdl, PROS_MAP_REGISTER_ENTRY MapRegisterBase, PVOID CurrentVa, ULONG Length, BOOLEAN WriteToDevice)
Definition: dma.c:1468
uint32_t ULONG_PTR
Definition: typedefs.h:64
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG * PPFN_NUMBER
Definition: ke.h:8
UCHAR SingleMask
Definition: haldma.h:200
ULONG PFN_NUMBER
Definition: ke.h:8
PHYSICAL_ADDRESS NTAPI HalpGetAdapterMaximumPhysicalAddress(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:167
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _ROS_MAP_REGISTER_ENTRY * PROS_MAP_REGISTER_ENTRY
UCHAR ClearBytePointer
Definition: haldma.h:219
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define BYTES_TO_PAGES(Size)
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1061
unsigned char UCHAR
Definition: xmlstorage.h:181
UCHAR TransferType
Definition: haldma.h:94
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
UCHAR DmaBaseCount
Definition: haldma.h:191
PHYSICAL_ADDRESS PhysicalAddress
Definition: haldma.h:315
_Out_ PNDIS_HANDLE _Out_ PUINT _In_ PNDIS_STRING _In_ NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress
Definition: ndis.h:3227
ULONG LowPart
Definition: typedefs.h:105
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
#define READ_TRANSFER
Definition: haldma.h:165
#define MAXULONG
Definition: typedefs.h:250
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:189
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
struct _LARGE_INTEGER::@2225 u
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
static LARGE_INTEGER Counter
Definition: clock.c:43
unsigned int ULONG
Definition: retypes.h:1
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
UCHAR Mode
Definition: haldma.h:201
#define WRITE_TRANSFER
Definition: haldma.h:166
#define MAP_BASE_SW_SG
Definition: haldma.h:367
static BOOLEAN HalpEisaDma
Definition: dma.c:92
UCHAR ClearBytePointer
Definition: haldma.h:202
#define BYTE_OFFSET(Va)
LONGLONG QuadPart
Definition: typedefs.h:113
ULONG Counter
Definition: haldma.h:316
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716

Variable Documentation

◆ HalpDmaAdapterList

LIST_ENTRY HalpDmaAdapterList
static

Definition at line 89 of file dma.c.

Referenced by HalGetAdapter(), and HalpInitDma().

◆ HalpDmaAdapterListLock

KSPIN_LOCK HalpDmaAdapterListLock
static

Definition at line 88 of file dma.c.

Referenced by HalGetAdapter(), HalpInitDma(), and HalPutDmaAdapter().

◆ HalpDmaLock

KEVENT HalpDmaLock
static

Definition at line 87 of file dma.c.

Referenced by HalGetAdapter(), HalpGrowMapBufferWorker(), and HalpInitDma().

◆ HalpDmaOperations

DMA_OPERATIONS HalpDmaOperations
static
Initial value:
= {
sizeof(DMA_OPERATIONS),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL ,
NULL ,
}
PVOID(NTAPI * PALLOCATE_COMMON_BUFFER)(_In_ PDMA_ADAPTER DmaAdapter, _In_ ULONG Length, _Out_ PPHYSICAL_ADDRESS LogicalAddress, _In_ BOOLEAN CacheEnabled)
Definition: iotypes.h:2195
ULONG NTAPI HalReadDmaCounter(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:76
VOID(NTAPI * PPUT_SCATTER_GATHER_LIST)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PSCATTER_GATHER_LIST ScatterGather, _In_ BOOLEAN WriteToDevice)
Definition: iotypes.h:2275
ULONG NTAPI HalpDmaGetDmaAlignment(PADAPTER_OBJECT AdapterObject)
Definition: dma.c:918
VOID NTAPI HalPutScatterGatherList(IN PADAPTER_OBJECT AdapterObject, IN PSCATTER_GATHER_LIST ScatterGather, IN BOOLEAN WriteToDevice)
Definition: dma.c:1092
ULONG(NTAPI * PGET_DMA_ALIGNMENT)(_In_ PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2246
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI HalGetScatterGatherList(IN PADAPTER_OBJECT AdapterObject, IN PDEVICE_OBJECT DeviceObject, IN PMDL Mdl, IN PVOID CurrentVa, IN ULONG Length, IN PDRIVER_LIST_CONTROL ExecutionRoutine, IN PVOID Context, IN BOOLEAN WriteToDevice)
Definition: dma.c:1039
VOID(NTAPI * PFREE_COMMON_BUFFER)(_In_ PDMA_ADAPTER DmaAdapter, _In_ ULONG Length, _In_ PHYSICAL_ADDRESS LogicalAddress, _In_ PVOID VirtualAddress, _In_ BOOLEAN CacheEnabled)
Definition: iotypes.h:2202
VOID(NTAPI * PPUT_DMA_ADAPTER)(PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2191
struct _DMA_OPERATIONS DMA_OPERATIONS
VOID NTAPI HalPutDmaAdapter(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:35
ULONG(NTAPI * PREAD_DMA_COUNTER)(_In_ PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2250
PVOID NTAPI HalAllocateCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PPHYSICAL_ADDRESS LogicalAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:46
VOID NTAPI HalFreeCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:61
NTSTATUS(NTAPI * PGET_SCATTER_GATHER_LIST)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PDEVICE_OBJECT DeviceObject, _In_ PMDL Mdl, _In_ PVOID CurrentVa, _In_ ULONG Length, _In_ PDRIVER_LIST_CONTROL ExecutionRoutine, _In_ PVOID Context, _In_ BOOLEAN WriteToDevice)
Definition: iotypes.h:2264

Definition at line 109 of file dma.c.

Referenced by HalpDmaAllocateChildAdapter(), and HalpInitDma().

◆ HalpEisaAdapter

PADAPTER_OBJECT HalpEisaAdapter[8]
static

Definition at line 90 of file dma.c.

Referenced by HalGetAdapter().

◆ HalpEisaDma

BOOLEAN HalpEisaDma
static

Definition at line 92 of file dma.c.

Referenced by HalpDmaInitializeEisaAdapter(), HalpGrowMapBuffers(), HalpInitDma(), and IoMapTransfer().

◆ HalpEisaPortPage

const ULONG_PTR HalpEisaPortPage[8]
static
Initial value:
= {
FIELD_OFFSET(DMA_PAGE, Channel0),
FIELD_OFFSET(DMA_PAGE, Channel1),
FIELD_OFFSET(DMA_PAGE, Channel2),
FIELD_OFFSET(DMA_PAGE, Channel3),
0,
FIELD_OFFSET(DMA_PAGE, Channel5),
FIELD_OFFSET(DMA_PAGE, Channel6),
}
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254

Definition at line 97 of file dma.c.

Referenced by HalpDmaInitializeEisaAdapter().

◆ HalpMasterAdapter

PADAPTER_OBJECT HalpMasterAdapter
static

Definition at line 94 of file dma.c.

Referenced by HalpDmaAllocateChildAdapter(), and HalpInitDma().