Jungo WinDriver  
Official Documentation

◆ WD_DMALock

#define WD_DMALock (   h,
  pDma 
)     WD_FUNCTION(IOCTL_WD_DMA_LOCK, h, pDma, SIZE_OF_WD_DMA(pDma), FALSE)

Enables contiguous-buffer or Scatter/Gather DMA.

For contiguous-buffer DMA, the function allocates a DMA buffer and returns mappings of the allocated buffer to physical address space and to user-mode and kernel virtual address spaces.

For Scatter/Gather DMA, the function receives the address of a data buffer allocated in the usermode, locks it for DMA, and returns the corresponding physical mappings of the locked DMA pages. On Windows the function also returns a kernel-mode mapping of the buffer.

Parameters
[in]hHandle to WinDriver's kernel-mode driver as received from WD_Open().
[in,out]pDmaPointer to a DMA information structure
Returns
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise
Remarks
WinDriver supports both Scatter/Gather and contiguous-buffer DMA on Windows and Linux. On Linux, Scatter/Gather DMA is only supported for 2.4 kernels and above (since the 2.2 Linux kernels require a patch to support this type of DMA).

You should NOT use the physical memory address returned by the function (dma.Page[i].pPhysicalAddr) directly in order to access the DMA buffer from your driver. To access the memory directly from a user-mode process, use the user-mode virtual mapping of the DMA buffer dma.pUserAddr. To access the memory in the kernel, either directly from within a Kernel PlugIn driver (see the WinDriver PCI Manual) or when calling WD_Transfer() / WD_MultiTransfer(), use the kernel mapping of the DMA buffer. For contiguous-buffer DMA (dma.dwOptions | DMA_KERNEL_BUFFER_ALLOC) and for Scatter/Gather DMA on Windows, this mapping is returned by WD_DMALock() within the dma.pKernelAddr field. For Scatter/Gather DMA on other platforms, you can acquire a kernel mapping of the buffer by calling WD_CardRegister() with a card structure that contains a memory item defined with the physical DMA buffer address returned from WD_DMALock() (dma.Page[i].pPhysicalAddr). WD_CardRegister() will return a kernel mapping of the physical buffer within the pCardReg->Card.Item[i].I.Mem.pTransAddr field.

On Windows x86 and x86_64 platforms, you should normally set the DMA_ALLOW_CACHE flag in the DMA options bitmask parameter (pDma->dwOptions).

If the device supports 64-bit DMA addresses, it is recommended to set the DMA_ALLOW_64BIT_ADDRESS flag in pDma->dwOptions. Otherwise, when the physical memory on the target platform is larger than 4GB, the operating system may only allow allocation of relatively small 32-bit DMA buffers (such as 1MB buffers, or even smaller).

When using the DMA_LARGE_BUFFER flag, dwPages is an input/output parameter. As input to WD_DMALock(), dwPages should be set to the maximum number of pages that can be used for the DMA buffer (normally this would be the number of elements in the dma.Page array). As an output value of WD_DMALock(), dwPages holds the number of actual physical blocks allocated for the DMA buffer. The returned dwPages may be smaller than the input value because adjacent pages are returned as one block.

The following code demonstrates Scatter/Gather DMA allocation:
WD_DMA dma;
DWORD dwStatus;
PVOID pBuffer = malloc(20000);
BZERO(dma);
dma.dwBytes = 20000;
dma.pUserAddr = pBuffer;
/* Initialization of dma.hCard, value obtained from WD_CardRegister call: */
dma.hCard = cardReg.hCard;
dwStatus = WD_DMALock(hWD, &dma);
if (dwStatus)
{
printf("Could not lock down buffer\n");
}
else
{
/* On successful return dma.Page has the list of
physical addresses.
To access the memory from your user mode
application, use dma.pUserAddr. */
}
*****
The following code demonstrates contiguous kernel buffer DMA allocation:
WD_DMA dma;
DWORD dwStatus;
BZERO(dma);
dma.dwBytes = 20 * 4096; /* 20 pages */
/* Initialization of dma.hCard, value obtained from WD_CardRegister call: */
dma.hCard = cardReg.hCard;
dwStatus = WD_DMALock(hWD, &dma);
if (dwStatus)
{
printf("Failed allocating kernel buffer for DMA\n");
}
else
{
/* On return dma.pUserAddr holds the user mode virtual
mapping of the allocated memory and dma.pKernelAddr
holds the kernel mapping of the physical memory.
dma.Page[0].pPhysicalAddr points to the allocated
physical address. */
}
void *__cdecl malloc(unsigned long size)
DWORD dwOptions
The first three bytes refer to WD_DMA_OPTIONS The fourth byte is used for specifying the amount of DM...
Definition: windrvr.h:538
PVOID pUserAddr
User address.
Definition: windrvr.h:533
DWORD dwBytes
Size of buffer.
Definition: windrvr.h:537
DWORD hCard
Handle of relevant card as received from WD_CardRegister()
Definition: windrvr.h:542
#define WD_DMALock(h, pDma)
Enables contiguous-buffer or Scatter/Gather DMA.
Definition: windrvr.h:2024
#define BZERO(buf)
Definition: windrvr.h:1548
@ DMA_KERNEL_BUFFER_ALLOC
The system allocates a contiguous buffer.
Definition: windrvr.h:434
@ DMA_TO_DEVICE
memory pages are locked to be read by device
Definition: windrvr.h:454
@ DMA_FROM_DEVICE
memory pages are locked to be written by device
Definition: windrvr.h:451

Definition at line 2024 of file windrvr.h.