Using Common Buffers

[Applies to KMDF only]

Drivers for DMA devices sometimes must allocate buffer space that both a device and the driver can access. For example, a device might write transfer information, such as byte counts, into this buffer space and the driver can read it to determine the number of bytes that were transferred. This type of buffer space is called a common buffer.

To allocate a common buffer, your driver's EvtDriverDeviceAdd callback function:

The following code example is taken from the Init.c file of the PLX9x5x sample. This code shows how a KMDF driver allocates common buffer space.

// Allocate common buffer for building writes
DevExt->WriteCommonBufferSize = 
         sizeof( DMA_TRANSFER_ELEMENT) * DevExt->WriteTransferElements;
status = WdfCommonBufferCreate( DevExt->DmaEnabler,
                                DevExt->WriteCommonBufferSize,
                                WDF_NO_OBJECT_ATTRIBUTES, 
                                &DevExt->WriteCommonBuffer );
if (!NT_SUCCESS(status)) {
    . . . //Error-handling code omitted 
    }
DevExt->WriteCommonBufferBase = 
             WdfCommonBufferGetAlignedVirtualAddress(
                      DevExt->WriteCommonBuffer);
DevExt->WriteCommonBufferBaseLA = 
             WdfCommonBufferGetAlignedLogicalAddress(
                      DevExt->WriteCommonBuffer);
RtlZeroMemory( DevExt->WriteCommonBufferBase, DevExt->WriteCommonBufferSize);

If your driver calls WdfDeviceSetAlignmentRequirement before calling WdfDmaEnablerCreate, the buffers that WdfDmaEnablerCreate creates are aligned to the memory address boundary that the driver specified to WdfDeviceSetAlignmentRequirement. Otherwise, common buffers are aligned to word address boundaries. Alternatively, the driver can call WdfCommonBufferCreateWithConfig to specify an alignment for a single buffer.

To obtain the length of a common buffer that your driver has allocated, the driver can call WdfCommonBufferGetLength.

When the driver is finished using a common buffer, the driver calls WdfObjectDelete.