Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Ovladač, který používá režim automatické inicializace systémového řadiče DMA, musí přidělit paměť pro vyrovnávací paměť, do které nebo ze kterého lze provádět přenosy DMA. Ovladač volá Funkci AllocateCommonBuffer pro získání této vyrovnávací paměti, obvykle z rutiny DispatchPnP , která zpracovává požadavek IRP_MN_START_DEVICE . Následující obrázek ukazuje, jak ovladač přidělí vyrovnávací paměť a mapuje její virtuální rozsah adres na fyzickou paměť systému.
Jak ukazuje předchozí obrázek, ovladač provede následující kroky k přidělení vyrovnávací paměti systémovému DMA:
Ovladač volá AllocateCommonBuffer a předává ukazatel na objekt adaptéru, který vrátil IoGetDmaAdapter spolu s délkou v bajtech požadovaných pro jeho vyrovnávací paměť. Pro ekonomické využití paměti by vstupní hodnota délka vyrovnávací paměti měla být buď menší nebo rovna PAGE_SIZE, nebo by měla být integrovaným násobkem PAGE_SIZE.
Pokud Funkce AllocateCommonBuffer vrátí ukazatel NULL , ovladač by měl uvolnit všechny systémové prostředky, které již nárokoval, a vrátit STATUS_INSUFFICIENT_RESOURCES v reakci na požadavek IRP_MN_START_DEVICE .
Jinak AllocateCommonBuffer přidělí požadované množství paměti v systémovém virtuálním adresním prostoru a vrátí dva různé typy ukazatelů na danou vyrovnávací paměť:
LogicalAddress vyrovnávací paměti (BufferLogicalAddress na předchozím obrázku), pro které musí ovladač poskytovat úložiště, ale které by měl následně ignorovat
Virtuální adresa vyrovnávací paměti (BufferVirtualAddress na předchozím obrázku), kterou ovladač musí také uložit, aby mohl vytvořit MDL popisující jeho vyrovnávací paměť pro operace DMA.
Ovladač by měl tyto ukazatele uložit do rozšíření zařízení nebo jiné rezidentní paměti přidělené ovladačem.
Ovladač volá IoAllocateMdl k přidělení MDL pro vyrovnávací paměť. Ovladač předá pro přidělení MDL VirtualAddress vyrovnávací paměti, kterou vrátí AllocateCommonBuffer, a délku této vyrovnávací paměti.
Ovladač volá MmBuildMdlForNonPagedPool s ukazatelem vráceným funkcí IoAllocateMdl pro mapování rozsahu virtuálních adres jeho rezidentní vyrovnávací paměti na systémovou fyzickou paměť.
Po přidělení společné vyrovnávací paměti a mapování rozsahu virtuálních adres může ovladač podřízeného zařízení začít zpracovávat IRP, který požaduje přenos DMA. K tomu ovladač volá následující obecnou sekvenci rutin podpory:
Podle uvážení zapisovače ovladačů může použít RtlMoveMemory k kopírování dat z uzamčené a neměnné vyrovnávací paměti uživatele do společné vyrovnávací paměti alokované ovladačem pro přenos do zařízení.
AllocateAdapterChannel, když je ovladač připravený naprogramovat své zařízení pro DMA a potřebuje systémový řadič DMA
MapTransfer s MDL popisující společnou vyrovnávací paměť přidělenou ovladačem pro nastavení systémového řadiče DMA pro operaci přenosu
Všimněte si, že ovladač volá MapTransfer pouze jednou k nastavení systémového řadiče DMA pro použití jeho společné vyrovnávací paměti. Během přenosu může ovladač volat ReadDmaCounter, aby určil, kolik bajtů zbývá přenést, a v případě potřeby volat RtlMoveMemory ke zkopírování více dat do nebo z uživatelského bufferu.
FlushAdapterBuffers po dokončení přenosu DMA ovladačem do/z podřízeného zařízení
FreeAdapterChannel ihned po přenosu všech požadovaných dat nebo v případě, že ovladač musí neúspěšně dokončit IRP kvůli chybě vstupně-výstupního zařízení
Ukazatel objektu adaptéru vrácený objektem IoGetDmaAdapter je povinný parametr pro každou z těchto rutin podpory s výjimkou RtlMoveMemory.
Jednotlivé ovladače volají tuto sekvenci rutin podpory v různých bodech v závislosti na tom, jak je každý ovladač implementovaný do služby svého zařízení. Například rutina StartIo jednoho ovladače může volat AllocateAdapterChannel, jiný ovladač může toto volání provést z rutiny, která odebere IRP z mezipaměťové fronty vytvořené ovladačem, a další ovladač může toto volání provést, když jeho podřízené zařízení DMA indikuje, že je připraveno k přenosu dat.