Bagikan melalui


Menggunakan DMA Sistem Common-Buffer

Driver yang menggunakan mode inisialisasi otomatis pengontrol DMA sistem harus mengalokasikan memori untuk buffer tempat atau dari mana transfer DMA dapat dilakukan. Driver memanggil AllocateCommonBuffer untuk mendapatkan buffer ini, biasanya dari rutinitas DispatchPnP yang menangani permintaan IRP_MN_START_DEVICE . Gambar berikut menunjukkan bagaimana driver mengalokasikan buffer dan memetakan rentang alamat virtualnya ke memori fisik sistem.

diagram yang mengilustrasikan bagaimana driver mengalokasikan buffer umum untuk dma sistem.

Seperti yang ditunjukkan oleh gambar sebelumnya, driver mengambil langkah-langkah berikut untuk mengalokasikan buffer untuk DMA sistem:

  1. Driver memanggil AllocateCommonBuffer, meneruskan penunjuk ke objek adaptor yang dikembalikan oleh IoGetDmaAdapter, bersama dengan panjang byte yang diminta untuk buffer-nya. Untuk menggunakan memori secara ekonomis, nilai Panjang input untuk buffer harus kurang dari atau sama dengan PAGE_SIZE atau harus menjadi kelipatan integral PAGE_SIZE.

  2. Jika AllocateCommonBuffer mengembalikan pointerNULL , driver harus membebaskan sumber daya sistem apa pun yang telah diklaim dan mengembalikan STATUS_INSUFFICIENT_RESOURCES sebagai respons terhadap permintaan IRP_MN_START_DEVICE .

    Jika tidak, AllocateCommonBuffer mengalokasikan jumlah memori yang diminta dalam ruang alamat virtual sistem dan mengembalikan dua jenis pointer yang berbeda ke buffer tersebut:

    • LogicalAddress dari buffer (BufferLogicalAddress pada gambar sebelumnya), yang drivernya harus menyediakan penyimpanan tetapi harus diabaikan setelahnya

    • Alamat virtual buffer (BufferVirtualAddress pada gambar sebelumnya), yang juga harus disimpan driver sehingga dapat membangun MDL yang menjelaskan buffer-nya untuk operasi DMA

    Driver harus menyimpan pointer ini di ekstensi perangkat atau memori residen lain yang dialokasikan driver.

  3. Driver memanggil IoAllocateMdl untuk mengalokasikan MDL untuk buffer. Driver melewati VirtualAddress buffer yang dikembalikan oleh AllocateCommonBuffer dan Panjang buffernya untuk mengalokasikan MDL.

  4. Driver memanggil MmBuildMdlForNonPagedPool dengan pointer yang dikembalikan oleh IoAllocateMdl untuk memetakan rentang alamat virtual untuk buffer residennya ke memori fisik sistem.

Setelah mengalokasikan buffer umum dan memetakan rentang alamat virtualnya, driver perangkat bawahan dapat mulai memproses IRP yang meminta transfer DMA. Untuk melakukannya, driver memanggil urutan umum rutinitas dukungan berikut:

  1. Atas kebijakan penulis driver, RtlMoveMemory untuk menyalin data dari buffer pengguna yang terkunci ke buffer umum yang dialokasikan driver untuk transfer ke perangkat

  2. AllocateAdapterChannel ketika driver siap untuk memprogram perangkatnya untuk DMA dan membutuhkan pengontrol DMA sistem

  3. MapTransfer, dengan MDL yang menjelaskan buffer umum yang dialokasikan driver, untuk menyiapkan pengontrol DMA sistem untuk operasi transfer

    Perhatikan bahwa driver memanggil MapTransfer hanya sekali untuk menyiapkan pengontrol DMA sistem untuk menggunakan buffer umumnya. Selama transfer, driver dapat memanggil ReadDmaCounter untuk menentukan berapa banyak byte yang tetap harus ditransfer, dan jika perlu, panggil RtlMoveMemory untuk menyalin lebih banyak data ke atau dari buffer pengguna.

  4. FlushAdapterBuffers ketika driver telah menyelesaikan transfer DMA ke/dari perangkat subordinat

  5. FreeAdapterChannel segera setelah semua data yang diminta telah ditransfer atau jika driver harus gagal IRP karena kesalahan I/O perangkat

Penunjuk objek adaptor yang dikembalikan oleh IoGetDmaAdapter adalah parameter yang diperlukan untuk masing-masing rutinitas dukungan ini kecuali RtlMoveMemory.

Driver individu menyebut urutan rutinitas dukungan ini di titik yang berbeda, tergantung pada bagaimana setiap driver diimplementasikan untuk melayani perangkatnya. Misalnya, rutinitas StartIo satu driver mungkin melakukan panggilan ke AllocateAdapterChannel, driver lain mungkin melakukan panggilan ini dari rutinitas yang menghapus IRP dari antrean yang saling terhubung yang dibuat driver, dan masih ada driver lain yang mungkin melakukan panggilan ini ketika perangkat DMA bawahannya menunjukkan siap untuk mentransfer data.