Memulai Transaksi DMA
[Berlaku untuk KMDF saja]
Setelah driver Anda membuat dan menginisialisasi transaksi DMA, driver dapat memanggil metode WdfDmaTransactionExecute untuk memulai transaksi. Metode ini membangun daftar sebar/kumpulkan untuk transfer DMA pertama yang terkait dengan transaksi. Selanjutnya, metode memanggil fungsi panggilan balik EvtProgramDma yang didaftarkan driver untuk transaksi. Fungsi panggilan balik memprogram perangkat keras DMA untuk memulai transfer.
Sebelum driver Anda memanggil WdfDmaTransactionExecute, driver harus menyimpan handel transaksi DMA sehingga dapat diambil nanti ketika driver menyelesaikan setiap transfer DMA yang terkait dengan transaksi. Tempat yang baik untuk menyimpan handel transaksi berada dalam memori konteks objek kerangka kerja, biasanya objek perangkat kerangka kerja perangkat. Untuk informasi selengkapnya tentang menggunakan memori konteks objek, lihat Ruang Konteks Objek Kerangka Kerja.
Contoh kode berikut dari sampel PLX9x5x menunjukkan cara menginisialisasi lalu menjalankan transaksi DMA. Kode ini muncul dalam file 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;
}