Fungsi WdfDmaTransactionInitialize (wdfdmatransaction.h)

[Hanya berlaku untuk KMDF]

Metode WdfDmaTransactionInitialize menginisialisasi transaksi DMA tertentu.

Sintaks

NTSTATUS WdfDmaTransactionInitialize(
  [in] WDFDMATRANSACTION   DmaTransaction,
  [in] PFN_WDF_PROGRAM_DMA EvtProgramDmaFunction,
  [in] WDF_DMA_DIRECTION   DmaDirection,
  [in] PMDL                Mdl,
  [in] PVOID               VirtualAddress,
  [in] size_t              Length
);

Parameter

[in] DmaTransaction

Handel ke objek transaksi DMA yang diperoleh driver dari panggilan sebelumnya ke WdfDmaTransactionCreate.

[in] EvtProgramDmaFunction

Penunjuk ke fungsi panggilan balik peristiwa EvtProgramDma driver.

[in] DmaDirection

Nilai yang WDF_DMA_DIRECTION ketik.

[in] Mdl

Pointer ke daftar deskriptor memori (MDL) yang menjelaskan buffer yang akan digunakan untuk transaksi DMA. Lihat informasi selengkapnya di Keterangan.

[in] VirtualAddress

Alamat virtual buffer yang akan digunakan untuk transaksi DMA.

[in] Length

Jumlah byte yang akan ditransfer.

Nilai kembali

WdfDmaTransactionInitialize mengembalikan STATUS_SUCCESS jika operasi berhasil. Jika tidak, metode mungkin mengembalikan salah satu nilai berikut.

Menampilkan kode Deskripsi
STATUS_INSUFFICIENT_RESOURCES
Daftar sebar/kumpulkan tidak dapat dialokasikan.
STATUS_INVALID_PARAMETER
Parameter yang tidak valid terdeteksi.
STATUS_WDF_TOO_FRAGMENTED
Jumlah elemen sebar/kumpulkan yang diperlukan untuk menangani transaksi lebih besar dari nilai yang ditentukan oleh panggilan driver ke WdfDmaEnablerSetMaximumScatterGatherElements .

Untuk transaksi yang ditetapkan untuk transfer tunggal, salah satu cara untuk memperbaikinya adalah dengan menyalin data ke buffer yang berdampingan secara fisik dan kemudian menginisialisasi transaksi dengan buffer tersebut. Misalnya, panggil MmAllocateContiguousMemory, salin buffer asli ke yang baru, lalu panggil WdfDmaTransactionInitialize lagi.

STATUS_WDF_NOT_ENOUGH_MAP_REGISTERS
Nilai pengembalian ini hanya berlaku untuk transaksi yang ditetapkan untuk transfer tunggal.

Jumlah register peta yang diperlukan untuk memetakan transaksi lebih besar dari angka yang telah dicadangkan adaptor DMA.

Untuk memperbaikinya, driver dapat mengurangi jumlah register peta yang diperlukan dengan menggabungkan rantai MDL ke dalam satu MDL.

Driver yang menggunakan paket dan sistem DMA dapat memanggil WdfDmaTransactionAllocateResources untuk memesan sejumlah register peta dari total yang dialokasikan ke perangkat. Misalkan driver Anda memesan 4 dari total 8 register peta, tetapi transfer DMA memerlukan 6. Dalam hal ini, WdfDmaTransactionInitialize gagal. Untuk memperbaikinya, panggil WdfDmaTransactionFreeResources lalu hubungi WdfDmaTransactionInitialize lagi.

Driver yang menggunakan DMA sebar/kumpulkan tidak dapat memesan register peta.

STATUS_WDF_TOO_MANY_TRANSFERS
Nilai pengembalian ini hanya berlaku untuk transaksi yang ditetapkan untuk transfer tunggal.

Panjang total transaksi melebihi ukuran transfer maksimum perangkat.

 

Metode ini juga dapat mengembalikan nilai NTSTATUS lainnya.

Pemeriksaan bug terjadi jika driver menyediakan handel objek yang tidak valid.

Keterangan

Metode WdfDmaTransactionInitialize menyiapkan operasi DMA untuk eksekusi, dengan melakukan operasi inisialisasi seperti mengalokasikan daftar sebar/kumpulkan transaksi. Setelah driver Anda memanggil WdfDmaTransactionInitialize, driver harus memanggil WdfDmaTransactionExecute untuk mulai menjalankan transaksi.

Driver berbasis kerangka kerja biasanya memanggil WdfDmaTransactionInitialize dari dalam fungsi panggilan balik peristiwa antrean I/O.

Jika Anda membuat transaksi DMA yang didasarkan pada informasi yang dimuat objek permintaan kerangka kerja, driver Anda harus memanggil WdfDmaTransactionInitializeUsingRequest. Jika Anda membuat transaksi DMA yang tidak didasarkan pada objek permintaan, gunakan WdfDmaTransactionInitialize atau WdfDmaTransactionInitializeUsingOffset.

Driver dapat menentukan rantai MDL dalam parameter Mdl dari metode ini. Rantai MDL adalah urutan struktur MDL yang dirangkai driver bersama-sama menggunakan anggota berikutnya dari struktur MDL. Dalam versi kerangka kerja sebelum 1.11, hanya transfer DMA sebar/kumpulkan yang dapat menggunakan rantai MDL. Mulai versi 1.11, jika driver menggunakan DMA versi 3, transfer paket tunggal juga dapat menggunakan MDL berantai.

Jika buffer yang ditentukan driver lebih besar dari panjang transfer maksimum yang ditentukan driver Anda ketika disebut WdfDmaEnablerCreate atau WdfDmaTransactionSetMaximumLength, kerangka kerja memecah transaksi menjadi beberapa transfer.

Untuk informasi selengkapnya tentang transaksi DMA, lihat Membuat dan Menginisialisasi Transaksi DMA.

Contoh

Contoh kode berikut berasal dari driver sampel PLX9x5x . Pertama, contoh menginisialisasi struktur WDF_OBJECT_ATTRIBUTES dan membuat objek transaksi DMA. Selanjutnya, ia mendapatkan MDL yang mewakili buffer input permintaan I/O yang diterima, dan mendapatkan alamat virtual dan panjang buffer. Terakhir, contoh memanggil WdfDmaTransactionInitialize untuk menginisialisasi transaksi.

WDF_OBJECT_ATTRIBUTES  attributes;
PMDL  mdl;
PVOID  virtualAddress;
ULONG  length;
NTSTATUS  status;

WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
                                        &attributes,
                                        TRANSACTION_CONTEXT
                                        );

status = WdfDmaTransactionCreate(
                                 devExt->DmaEnabler,
                                 &attributes,
                                 &dmaTransaction
                                 );
if(!NT_SUCCESS(status)) {
    goto CleanUp;
}

status = WdfRequestRetrieveInputWdmMdl(
                                       Request,
                                       &mdl
                                       );
if (!NT_SUCCESS(status)) {
    goto CleanUp;
}

virtualAddress = MmGetMdlVirtualAddress(mdl);
length = MmGetMdlByteCount(mdl);

status = WdfDmaTransactionInitialize(
                                     dmaTransaction,
                                     PLxEvtProgramWriteDma,
                                     WdfDmaDirectionWriteToDevice,
                                     mdl,
                                     virtualAddress,
                                     length
                                     );
if(!NT_SUCCESS(status)) {
    goto CleanUp;
}

Persyaratan

Persyaratan Nilai
Target Platform Universal
Versi KMDF minimum 1,0
Header wdfdmatransaction.h (termasuk Wdf.h)
Pustaka Wdf01000.sys (lihat Penerapan Versi Pustaka Kerangka Kerja.)
IRQL <=DISPATCH_LEVEL
Aturan kepatuhan DDI DeferredRequestCompleted(kmdf), DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MdlAfterReqCompletedIntIoctlA(kmdf), MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf)

Lihat juga

EvtProgramDma

MmGetMdlByteCount

MmGetMdlVirtualAddress

WDF_DMA_DIRECTION

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionExecute

WdfDmaTransactionInitializeUsingRequest