3.3.5.2 Common-Buffer Busmaster DMA

To set up a common buffer for busmaster DMA, a busmaster DMA device driver’s DriverEntry routine must call HalAllocateCommonBuffer with the adapter object pointer returned by HalGetAdapter. An NT driver should allocate a common buffer only if it will use the buffer repeatedly for its DMA operations while the driver remains loaded. Figure 3.12 illustrates such a call to HalAllocateCommonBuffer.

Figure 3.12 Allocating a Common Buffer for Busmaster DMA

The requested size for the buffer, shown in Figure 3.12 as LengthForBuffer, determines how many map registers must be used to provide a virtual-to-logical mapping for the common buffer. At most, the number of map registers can be the value of (BYTES_TO_PAGES (LengthForBuffer)). This value cannot be greater than the NumberOfMapRegisters returned by HalGetAdapter. For more information about system-supplied macros, such as BYTES_TO_PAGES, that NT drivers can use, see the Kernel-Mode Driver Reference.

In addition, the caller must supply the following:

If the call succeeds, HalAllocateCommonBuffer returns a driver-accessible base virtual address for the buffer (BuffVirtualAddress in Figure 3.12), which the driver must save in its device extension, controller extension, or other driver-accessible resident storage area (nonpaged pool allocated by the driver).

HalAllocateCommonBuffer returns NULL if it cannot allocate memory for the buffer. If the returned base virtual address is NULL, such a driver either must use the system’s packet-based DMA support exclusively or the DriverEntry routine must fail initialization and return STATUS_INSUFFICIENT_RESOURCES.

Otherwise, the driver can use the allocated common buffer as a driver- and adapter-accessible storage area for DMA transfers.

When (or if) such a driver unloads, it must call HalFreeCommonBuffer to release each common buffer it has allocated.

For more information about requirements for DriverEntry and Unload routines, see Chapters 5 and 15, respectively.