WinDriver does not impose any inherent limitation on the size of the DMA buffer
that can be allocated using its DMA APIs. However, the success of the DMA
allocation is dependent of the amount of available system resources at the time
of the attempted allocation. Therefore, the earlier your try to allocate the
buffer, the better your chances of succeeding.
Beginning with version 11.1.0 of WinDriver, you can configure your Windows
device INF file to preallocate a contiguous host-to-device and/or
device-to-host DMA buffer(s) at boot time, as outlined below, thus increasing
the odds that the allocation(s) will succeed.
To preallocate contiguous DMA buffers on Windows, follow these steps:
NOTE
You may preallocate one host-to-device buffer and/or one device-to-host buffer.
- Add the following lines to your device INF file under the
[UpdateRegistryDevice]
register key.
; 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)
NOTE
The generated DriverWizard device INF files, and relevant sample
WinDriver device INF files, already contain these lines — so you
only need to uncomment the relevant lines in these files by removing
the comment indicator (';') at the beginning of the line.
- Edit the buffer sizes and add flags to the options masks, as needed.
Note, however, that the options mask flags indicated above must be set.
- In your code, call
WDC_DMAContigBufLock() (or the
low-level WD_DMALock() function) with parameter values
that match the INF file preallocated buffers configuration:
NOTE
In the call to WDC_DMAContigBufLock(), the values are
passed as direct parameters to the function. In the call to
WD_DMALock(), the values are passed within the fields of
the WD_DMA struct whose address is passed as the function's
pDma parameter.
- For a host-to-device buffer, the
dwDMABufSize
parameter (/dwBytes WD_DMA field)
should be set to the DmaToDeviceBytes
registry key value, and the dwOptions mask
should include the flags set in the
DmaToDeviceOptions registry key value —
including DMA_TO_DEVICE and
DMA_KERNEL_BUFFER_ALLOC (see Note 2 below).
- For a device-to-host buffer, the
dwDMABufSize
parameter (/dwBytes WD_DMA field)
should be set to the DmaFromDeviceBytes
registry key value, and the dwOptions mask
should include the flags set in the
DmaFromDeviceOptions registry key value
— including DMA_FROM_DEVICE and
DMA_KERNEL_BUFFER_ALLOC (see Note 2 below).
NOTE
- When you set the
DmaToDeviceXXX values in the INF
file, the first call to WDC_DMAContigBufLock() (or
to WD_DMALock() with the
DMA_KERNEL_BUFFER_ALLOC flag) with the
DMA_TO_DEVICE flag, will use the preallocated
host-to-device buffer.
When you set the DmaFromDeviceXXX values in the INF
file, the first call to WDC_DMAContigBufLock() (or
to WD_DMALock() with the
DMA_KERNEL_BUFFER_ALLOC flag) with the
DMA_FROM_DEVICE flag, will use the preallocated
device-to-host buffer.
-
When using
WDC_DMAContigBufLock(), the
DMA_KERNEL_BUFFER_ALLOC flag is set automatically by
the function, so you do not need to set it yourself.
- The DMA option flags are defined in
WinDriver\include\windrvr.h (look for the enum that
contains the
DMA_KERNEL_BUFFER_ALLOC flag), where
you can see the related values to use in the
DmaXXXDeviceOptions registry key values in the INF
file. The flags are described in the WinDriver PCI User's Manual.
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.
|