Uso de búferes comunes
[Solo se aplica a KMDF]
A veces, los controladores para dispositivos DMA deben asignar espacio en búfer al que puede acceder un dispositivo y el controlador. Por ejemplo, un dispositivo podría escribir información de transferencia, como recuentos de bytes, en este espacio de búfer y el controlador puede leerla para determinar el número de bytes transferidos. Este tipo de espacio de búfer se denomina búfer común.
Para asignar un búfer común, la función de devolución de llamada EvtDriverDeviceAdd del controlador:
Llama a WdfDmaEnablerCreate para crear un objeto de habilitador DMA.
Llama a WdfCommonBufferCreate o WdfCommonBufferCreateWithConfig para crear el búfer.
Llama a WdfCommonBufferGetAlignedLogicalAddress para obtener la dirección lógica del búfer, a la que puede acceder el dispositivo.
Llama a WdfCommonBufferGetAlignedVirtualAddress para obtener la dirección virtual del búfer, a la que puede acceder el controlador.
El ejemplo de código siguiente se toma del archivo Init.c del ejemplo PLX9x5x . En este código se muestra cómo un controlador KMDF asigna espacio de búfer común.
// 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);
Si el controlador llama a WdfDeviceSetAlignmentRequirement antes de llamar a WdfDmaEnablerCreate, los búferes que WdfDmaEnablerCreate crea se alinean con el límite de dirección de memoria que el controlador especificó en WdfDeviceSetAlignmentRequirement. De lo contrario, los búferes comunes se alinean con los límites de dirección de palabra. Como alternativa, el controlador puede llamar a WdfCommonBufferCreateWithConfig para especificar una alineación para un único búfer.
Para obtener la longitud de un búfer común que ha asignado el controlador, el controlador puede llamar a WdfCommonBufferGetLength.
Cuando el controlador termine de usar un búfer común, el controlador llama a WdfObjectDelete.