next up previous contents
Next: 2.14 WD_DMAUnlock() Up: 2. WD_xxx PCI/PCMCIA/ISA Functions Previous: 2.12 WD_MultiTransfer()   Contents


2.13 WD_DMALock()


PURPOSE

$\bullet$Enables Contiguous Buffer or Scatter/Gather DMA.

$\bullet$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.

$\bullet$For Scatter/Gather DMA, the function receives the address of a data buffer allocated in the user-mode, locks it for DMA, and returns the corresponding physical mappings of the locked DMA pages. On Windows 98/Me/2000/XP/Server 2003/Vista the function also returns a kernel-mode mapping of the buffer.


PROTOTYPE

DWORD WD_DMALock(
    HANDLE hWD,
    WD_DMA *pDma);


PARAMETERS

Name Type Input/Output
$\bullet$hWD HANDLE Input
$\bullet$pDma WD_DMA*  
$\gg$hDma DWORD Output
$\gg$pUserAddr PVOID Input/Output
$\gg$pKernelAddr KPTR Output
$\gg$dwBytes DWORD Input
$\gg$dwOptions DWORD Input
$\gg$dwPages DWORD Input/Output
$\gg$hCard DWORD Input
$\gg$Page WD_DMA_PAGE[WD_DMA_PAGES]  
$\diamond$pPhysicalAddr DMA_ADDR Output
$\diamond$dwBytes DWORD Output


DESCRIPTION

Name Description
hWD Handle to WinDriver's kernel-mode driver as received from WD_Open() [5.2]
pDma Pointer to a DMA information structure:
$\bullet$ hDma DMA buffer handle, which should be passed to WD_DMAUnlock() [2.14] when unlocking the DMA buffer, or 0 if the DMA lock failed
$\bullet$ pUserAddr Virtual user-mode mapped DMA buffer address. Input in the case of Scatter/Gather and output in the case of contiguous buffer DMA.
$\bullet$ pKernelAddr Kernel-mode mapped DMA buffer address. Relevant only for Contiguous Buffer DMA (dwOptions | DMA_KERNEL_BUFFER_ALLOC) and for Scatter/Gather DMA on Windows 98/Me/2000/XP/Server 2003/Vista.
$\bullet$ dwBytes The size of the DMA buffer, in bytes
$\bullet$ dwOptions DMA options bit-mask, which can consist of a combination of any of the following flags:
$\bullet$DMA_FROM_DEVICE: Synchronize the DMA buffer for transfers from the device to memory.
$\bullet$DMA_TO_DEVICE: Synchronize the DMA buffer for transfers from memory to the device.
$\bullet$DMA_TO_FROM_DEVICE: Synchronize the DMA buffer for transfers in both directions - i.e. from the device to memory and from memory to the device (<=> DMA_FROM_DEVICE | DMA_TO_DEVICE).
$\bullet$DMA_KERNEL_BUFFER_ALLOC: Allocate a contiguous DMA buffer in the physical memory.
The default behavior (when this flag is not set) is to allocate a Scatter/Gather DMA buffer.
$\bullet$DMA_KBUF_BELOW_16M: Allocate the physical DMA buffer within the first 16MB of the main memory.
This flag is applicable only to Contiguous Buffer DMA, i.e. only when the DMA_KERNEL_BUFFER_ALLOC flag is also set.
$\bullet$DMA_LARGE_BUFFER: Enable locking of a large DMA buffer - dwBytes > 1MB.
This flag is applicable only to Scatter/Gather DMA (i.e. when the DMA_KERNEL_BUFFER_ALLOC flag is not set).
$\bullet$DMA_ALLOW_CACHE: Allow caching of the DMA buffer.
$\bullet$DMA_KERNEL_ONLY_MAP: Do not map the allocated DMA buffer to the user mode (i.e. map it to kernel-mode only).
This flag is applicable only in cases where the DMA_KERNEL_BUFFER_ALLOC flag is applicable - see above.
$\bullet$DMA_ALLOW_64BIT_ADDRESS: Allow allocation of 64-bit DMA addresses, if supported by the target platform. This flag is supported on Windows, Linux and Solaris.
$\bullet$ dwPages The number of pages allocated for the DMA buffer.
For Contiguous Buffer DMA this field is always set to 1.
For a large (> 1MB) Scatter/Gather DMA buffer (dwOptions | DMA_LARGE_BUFFER) this field is used both as an input and an output parameter (otherwise only output) - see Remark below for details 2.13 .
$\bullet$ hCard Handle to a card for which the DMA buffer is locked, as received from WD_CardRegister() [2.8].
This field can also be set to 0 in order to lock a kernel memory buffer without association to a specific device.
$\bullet$ Page Array of DMA page structures:
$\gg$ pPhysicalAddr Pointer to the physical address of the beginning of the page
$\gg$ dwBytes Page size, in bytes


RETURN VALUE

Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A].


REMARKS


EXAMPLES

$\bullet$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;
dma.dwOptions = fIsRead ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
/* 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. */
}

$\bullet$The following code demonstrates contiguous kernel buffer DMA allocation:

WD_DMA dma;
DWORD dwStatus;

BZERO(dma);
dma.dwBytes = 20 * 4096; /* 20 pages */
dma.dwOptions = DMA_KERNEL_BUFFER_ALLOC | 
    ( fIsRead ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
/* 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. */
}


next up previous contents
Next: 2.14 WD_DMAUnlock() Up: 2. WD_xxx PCI/PCMCIA/ISA Functions Previous: 2.12 WD_MultiTransfer()   Contents