Technical Document #3

Technical Document #3        [Product Version: 11.1.0 and above]
Preallocating contiguous DMA buffers on Windows

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.

  1. 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.

  2. 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.

  3. 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
    1. 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.

    2. 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.

    3. 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.