Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Setiap driver mungkin perlu membagi permintaan transfer dan melakukan lebih dari satu operasi transfer DMA untuk memenuhi IRP tertentu, tergantung pada hal-hal berikut:
Jumlah register peta yang dikembalikan oleh IoGetDmaAdapter
Byte data yang akan ditransfer, terkandung dalam anggota Panjang lokasi tumpukan I/O driver untuk IRP
Jumlah batas halaman, dalam memori fisik sistem, untuk buffer tempat atau dari mana driver mentransfer data
Batasan khusus perangkat pada operasi DMA driver. Misalnya, driver disk sistem "AT" harus membagi permintaan transfer untuk lebih dari 256 sektor karena keterbatasan pengontrol disk.
Driver dapat menentukan jumlah register peta yang diperlukan untuk mentransfer semua data yang ditentukan oleh IRP sebagai berikut:
Panggil MmGetMdlVirtualAddress, meneruskan penunjuk ke MDL di Irp-MdlAddress>, untuk mendapatkan alamat virtual awal untuk buffer. Perhatikan bahwa driver tidak boleh mencoba mengakses memori menggunakan alamat virtual ini. Nilai yang dikembalikan oleh MmGetMdlVirtualAddress adalah indeks ke dalam MDL, belum tentu alamat yang valid.
Teruskan indeks yang dikembalikan dan nilai Panjang di lokasi tumpukan I/O driver IRP ke makro ADDRESS_AND_SIZE_TO_SPAN_PAGES .
Jika nilai yang dikembalikan oleh ADDRESS_AND_SIZE_TO_SPAN_PAGES lebih besar dari nilai NumberOfMapRegisters yang dikembalikan oleh IoGetDmaAdapter, driver tidak dapat mentransfer semua data yang diminta untuk IRP ini dalam satu operasi DMA. Sebaliknya, ia harus melakukan hal berikut:
Bagi buffer menjadi beberapa bagian yang berukuran sesuai dengan jumlah register peta yang tersedia (dan batasan DMA khusus perangkat).
Lakukan operasi DMA sebanyak yang diperlukan untuk memenuhi permintaan transfer.
Misalnya, misalkan ADDRESS_AND_SIZE_TO_SPAN_PAGES menunjukkan bahwa dua belas register peta diperlukan untuk memenuhi permintaan transfer, tetapi nilai NumberOfMapRegisters yang dikembalikan oleh IoGetDmaAdapter hanya lima. (Asumsikan tidak ada batasan DMA khusus perangkat.) Dalam hal ini, driver harus melakukan tiga operasi transfer DMA, memanggil MapTransfer tiga kali untuk mentransfer semua data yang diminta oleh IRP.
Driver perangkat DMA sistem menggunakan berbagai teknik untuk membagi transfer DMA ketika tidak ada cukup register peta untuk memenuhi IRP dengan satu operasi I/O. Salah satu teknik yang akan digunakan adalah sebagai berikut:
Panggil IoAllocateMdl untuk mengalokasikan MDL yang menjelaskan sebagian buffer pengguna.
Panggil MmProbeAndLockPages untuk mengunci bagian buffer pengguna tersebut.
Transfer data untuk bagian buffer tersebut.
Hubungi MmUnlockPages dan lakukan salah satu hal berikut:
- Jika MDL yang dialokasikan driver di langkah 1 cukup besar untuk bagian transfer berikutnya, panggil MmPrepareMdlForReuse dan ulangi langkah 2 hingga 4.
- Jika tidak, panggil IoFreeMdl dan ulangi langkah 1 hingga 4.
Hubungi MmUnlockPages dan IoFreeMdl ketika semua data telah ditransfer.
Jika driver tingkat tertinggi tidak dapat mengunci seluruh buffer pengguna dengan MmProbeAndLockPages di komputer dengan memori terbatas, itu dapat melakukan hal berikut:
Panggil IoBuildSynchronousFsdRequest untuk mengalokasikan IRP transfer parsial dan mengunci sebagian buffer pengguna. Area terkunci biasanya berupa kelipatan PAGE_SIZE atau berukuran sesuai dengan kapasitas transfer perangkat yang mendasar.
Panggil IoCallDriver untuk IRP transfer parsial, dan panggil KeWaitForSingleObject untuk menunggu objek peristiwa yang disiapkan driver untuk dikaitkan dengan IRP transfer parsialnya, jika driver yang lebih rendah kembali STATUS_PENDING.
Ketika mendapatkan kembali kontrol, ulangi langkah 1 dan 2 hingga semua data telah ditransfer, lalu, selesaikan IRP asli.
Ketika driver kelas penyimpanan membagi permintaan transfer besar untuk driver port/miniport SCSI yang mendasar, ia mengalokasikan IRP tambahan untuk setiap bagian permintaan transfer. Ini mendaftarkan rutinitas IoCompletion untuk setiap IRP yang dialokasikan driver, untuk melacak status permintaan transfer penuh dan untuk membebaskan IRP yang dialokasikan driver. Kemudian mengirimkan IRP ini ke driver port menggunakan IoCallDriver.
Driver kelas/port lain dapat menggunakan teknik ini hanya jika driver kelas dapat menentukan berapa banyak register peta yang tersedia untuk driver port. Driver port harus menyimpan informasi konfigurasi ini di registri untuk driver kelas yang dipasangkan, atau driver yang dipasangkan harus menentukan antarmuka privat, menggunakan permintaan kontrol I/O perangkat internal, untuk meneruskan informasi konfigurasi tentang jumlah register peta yang tersedia dari driver port ke driver kelas.
Driver monolitik (yaitu, driver yang bukan bagian dari pasangan kelas/port) untuk perangkat DMA harus membagi permintaan transfer besar untuk dirinya sendiri. Driver tersebut biasanya membagi permintaan besar menjadi beberapa bagian dan melakukan urutan operasi DMA untuk memenuhi IRP.
Jika permintaan transfer terlalu besar untuk ditangani oleh driver perangkat yang mendasar, driver tingkat yang lebih tinggi dapat memanggil MmGetMdlVirtualAddress dan IoBuildPartialMdl, lalu menyiapkan urutan IRP transfer parsial untuk driver perangkat yang mendasar.