DMA トランザクションの開始
[KMDF にのみ適用]
ドライバーが DMA トランザクションを作成して初期化した後、ドライバーは WdfDmaTransactionExecute メソッドを呼び出してトランザクションを開始できます。 このメソッドは、トランザクションに関連付けられている最初の DMA 転送のスキャッター/ギャザー リストを作成します。 次に、このメソッドは、ドライバーがトランザクションに登録した EvtProgramDma コールバック関数を呼び出します。 コールバック関数は、DMA ハードウェアをプログラムして転送を開始します。
ドライバーが WdfDmaTransactionExecute を呼び出す前に、ドライバーは、後でドライバーがトランザクションに関連付けられている各 DMA 転送を完了したときに取得できるように、DMA トランザクション ハンドルを格納する必要があります。 トランザクション ハンドルを格納するのに適した場所は、フレームワーク オブジェクト (通常はデバイスのフレームワーク デバイス オブジェクト) のコンテキスト メモリにあります。 オブジェクト コンテキスト メモリの使用の詳細については、「フレームワーク オブジェクト コンテキスト空間」を参照してください。
PLX9x5x サンプルの次のコード例は、DMA トランザクションを初期化して実行する方法を示しています。 このコードは Read.c ファイルに表示されます。
VOID PLxEvtIoRead(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PDEVICE_EXTENSION devExt;
// Get the DevExt from the queue handle
devExt = PLxGetDeviceContext(WdfIoQueueGetDevice(Queue));
do {
// Validate the Length parameter.
if (Length > PCI9656_SRAM_SIZE) {
status = STATUS_INVALID_BUFFER_SIZE;
break;
}
// Initialize the DmaTransaction.
status =
WdfDmaTransactionInitializeUsingRequest(
devExt->ReadDmaTransaction,
Request,
PLxEvtProgramReadDma,
WdfDmaDirectionReadFromDevice
);
if(!NT_SUCCESS(status)) {
. . . //Error-handling code omitted
break;
}
// Execute this DmaTransaction.
status = WdfDmaTransactionExecute( devExt->ReadDmaTransaction,
WDF_NO_CONTEXT);
if(!NT_SUCCESS(status)) {
. . . //Error-handling code omitted
break;
}
// Indicate that the DMA transaction started successfully.
// The DPC routine will complete the request when the DMA
// transaction is complete.
status = STATUS_SUCCESS;
} while (0);
// If there are errors, clean up and complete the request.
if (!NT_SUCCESS(status )) {
WdfDmaTransactionRelease(devExt->ReadDmaTransaction);
WdfRequestComplete(Request, status);
}
return;
}