The WinDriver DMA APIs do not limit the size of allocated DMA buffers. However, the success of the DMA allocation is dependent on the
amount of available system resources at the time of the allocation. Therefore,
the earlier you try to allocate the buffer, the better your chances of
succeeding.
Beginning with version 11.1.0 of WinDriver for Windows, you can configure your
device INF file to preallocate at boot time a contiguous host-to-device DMA buffer and/or a device-to-host DMA buffer, thus increasing the odds that the
allocation(s) will succeed. Beginning with version 11.4.0 of WinDriver for
Windows, you can, alternatively, configure the device INF file to preallocate
up to two bidirectional DMA buffers at boot time.
NOTE
You may currently preallocate a maximum of either two unidirectional buffers
— one host-to-device buffer and/or one
device-to-host buffer — or two bidirectional buffers.
To preallocate contiguous DMA buffers on Windows, follow these steps:
- Add the required configuration under the
[UpdateRegistryDevice]
registry key in your device INF file, as shown below.
NOTE
- The examples are for configuring preallocation of two DMA
buffers (either
unidirectional or
bidirectional), but you
may, of-course, select to preallocate just one buffer (or none
at all).
- The wizard-generated and relevant sample WinDriver device INF
files already contain the unidirectional buffers configuration
lines, so you only need to remove the comment indicator (';')
at the start of each line. For bidirectional buffers, you should also
edit the title comments and DMA direction flag (see
below).
- To preallocate unidirectional
buffers, add these lines:
; Host-to-device DMA buffer:
HKR,, "DmaToDeviceBytes",0x00010001,0x100000 ; Buffer size, in bytes
HKR,, "DmaToDeviceOptions",0x00010001,0x41 ; DMA flags (0x40=DMA_TO_DEVICE
; + 0x1=DMA_KERNEL_BUFFER_ALLOC)
; Device-to-host DMA buffer:
HKR,, "DmaFromDeviceBytes",0x00010001,0x100000 ; Buffer size, in bytes
HKR,, "DmaFromDeviceOptions",0x00010001,0x21 ; DMA flags (0x20=DMA_FROM_DEVICE
; + 0x1=DMA_KERNEL_BUFFER_ALLOC)
- To preallocate bidirectional
buffers, add these lines:
; Bidirectional DMA buffer:
HKR,, "DmaToDeviceBytes",0x00010001,0x100000 ; Buffer size, in bytes
HKR,, "DmaToDeviceOptions",0x00010001,0x61 ; DMA flags (0x60=DMA_TO_FROM_DEVICE
; + 0x1=DMA_KERNEL_BUFFER_ALLOC)
; Second Bidirectional DMA buffer:
HKR,, "DmaFromDeviceBytes",0x00010001,0x100000 ; Buffer size, in bytes
HKR,, "DmaFromDeviceOptions",0x00010001,0x61 ; DMA flags (0x60=DMA_TO_FROM_DEVICE
; + 0x1=DMA_KERNEL_BUFFER_ALLOC)
NOTE
The INF-file configuration for bidirectional buffers uses the
same registry keys as for unidirectional buffers
(DmaToDeviceXXX and DmaFromDeviceXXX ),
but the DMA-options key value (DmaToDeviceOptions /
DmaFromDeviceOptions ) should contain the
DMA_TO_FROM_DEVICE flag (0x60) instead of
the unidirectional DMA_TO_DEVICE (0x40) or
DMA_FROM_DEVICE (0x20) flag, as shown above.
- Edit the buffer sizes and add flags to
the options masks in the INF file, as needed.
Note, however, that the direction flags and the
DMA_KERNEL_BUFFER_ALLOC flag must be set as shown in
Step 1.
NOTE
The supported WinDriver DMA flags are documented in the
WinDriver PCI User's Manual. To locate the relevant flag values to set
in the INF file, look for the flag definitions in the
<WinDriver directory>\include\windrvr.h file;
(look for the enum that contains the
DMA_KERNEL_BUFFER_ALLOC flag).
- In your code, the first call or the
first two calls (if you configured the INF file to preallocate two DMA
buffers) to the contiguous-DMA-lock function —
WDC_DMAContigBufLock() or the low-level
WD_DMALock() function — should set parameter values
that match the buffer configurations in the INF file:
- For a device-to-host buffer or the first
allocation of a bidirectional buffer, the DMA-options mask
parameter (
dwOptions /
pDma->dwOptions ) should contain the same
DMA flags set in the DmaFromDeviceOptions
registry key value, and the buffer-size parameter
(dwDMABufSize /
pDma->dwBytes ) should be set to the value
of the DmaFromDeviceBytes registry key
value.
-
For a host-to-device buffer or the
second allocation of a bidirectional buffer, the
DMA-options mask parameter (
dwOptions /
pDma->dwOptions ) should contain the same
flags set in the DmaToDeviceOptions
registry key value, and the buffer-size parameter
(dwDMABufSize /
pDma->dwBytes ) should be set to the value
of the DmaToDeviceBytes registry key value.
NOTE
- In calls to
WDC_DMAContigBufLock() , the DMA
configuration information is provided via dedicated function
parameters — dwDMABufSize and
dwOptions .
In calls to WD_DMALock() , the information is
provided within the fields of the WD_DMA struct
pointed to by the pDma parameter —
pDma->dwBytes and
pDma->dwOptions .
- When using
WDC_DMAContigBufLock() , the
DMA_KERNEL_BUFFER_ALLOC flag is automatically
set by the function, so you do not need to set it explicitly in the
DMA-options mask parameter (as you do when using the low-level
WD_DMALock() function), even though it is set in
the INF-file configuration.
- If the buffer preallocation fails due to insufficient
resources, you may need to increase the size of the non-paged
pool (from which the memory is allocated), as explained in
Technical Document #58.
|