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 The handle to WinDriver's kernel-mode driver received from WD_Open() [5.2]
pDma Pointer to a DMA information structure:
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
pUserAddr Virtual user-mode mapped DMA buffer address. Input in the case of Scatter/Gather and output in the case of contiguous buffer DMA.
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.
dwBytes The size of the DMA buffer, in bytes
dwOptions DMA options bit-mask, which can be comprised 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.
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 .
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.
Page Array of DMA page structures:
pPhysicalAddr Pointer to the physical address of the beginning of the page
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