Sdílet prostřednictvím


Základní model volání pro rutiny DMA verze 3

Chcete-li provést přenos DMA, který používá rutiny ve verzi 3 operačního rozhraní DMA, ovladač by měl postupovat podle kroků popsaných v následujícím seznamu. Tyto kroky jsou společné pro podřízená zařízení i zařízení hlavní sběrnice. Verze 3 tohoto rozhraní je k dispozici od systému Windows 8. Další informace o rutinách v tomto rozhraní najdete v tématu DMA_OPERATIONS.

Krok 1: Získání objektu adaptéru DMA

Při přípravě na přenos DMA ovladač volá rutinu IoGetDmaAdapter pro získání objektu adaptéru DMA. Objekt adaptéru DMA je softwarový objekt, který představuje buď hlavní zařízení sběrnice, nebo řádek požadavku na systémovém řadiči DMA. Tento objekt obsahuje rozhraní operací DMA pro sběrnici, která se používá k přenosu dat do nebo ze zařízení. Kromě toho tento objekt synchronizuje přístup ovladače ke sdíleným prostředkům, které jsou nutné k provedení přenosu. Další informace naleznete v tématu Úvod k objektům adaptéru.

Krok 2: Získání popisu požadovaných prostředků DMA

Ovladač volá rutinu GetDmaTransferInfo , aby získal popis prostředků DMA, které potřebuje k provedení přenosu.

Vstupní parametry tohoto volání popisují vyrovnávací paměť, která se má použít pro přenos, a směr přenosu (čtení nebo zápis).

Požadavky na prostředky získané z tohoto volání zahrnují počet registrů mapování a velikost scatter/gather seznamu potřebného k popisu vyrovnávací paměti dat pro přenos. V následném volání rutiny AllocateAdapterChannelEx (viz krok 3) ovladač poskytuje počet registrů mapování jako vstupní parametr.

Krok 3: Vyžádání požadovaných prostředků DMA

Ovladač volá rutinu AllocateAdapterChannelEx , která přiděluje prostředky pro přiřazení k objektu adaptéru DMA. Mezi tyto prostředky patří kanál DMA a registrace map.

Volání AllocateAdapterChannelEx může být asynchronní nebo synchronní.

Pokud není příznak DMA_SYNCHRONOUS_CALLBACK nastaven, volání je asynchronní. V tomto případě parametr ExecutionRoutine odkazuje na rutinu provádění zadanou volajícím, která se volá, když jsou k dispozici požadované prostředky. V případě úspěchu asynchronní volání AllocateAdapterChannelEx vrátí STATUS_SUCCESS bez čekání na spuštění rutiny provádění.

Pokud je nastaven příznak DMA_SYNCHRONOUS_CALLBACK, volání AllocateAdapterChannelEx je synchronní. V tomto případě je parametr ExecutionRoutine ve volání volitelný a AllocateAdapterChannelEx se chová takto:

  • Pokud ExecutionRoutine není NULL a prostředky DMA lze přidělit okamžitě, AllocateAdapterChannelEx volá prováděcí rutinu v kontextu volajícího vlákna. Jakmile se rutina provádění dokončí, funkce AllocateAdapterChannelEx vrátí STATUS_SUCCESS. Pokud prostředky nejsou okamžitě dostupné, Funkce AllocateAdapterChannelEx selže a vrátí stavový kód chyby STATUS_INSUFFICIENT_RESOURCES.

  • Pokud executionRoutine je NULL a AllocateAdapterChannelEx může okamžitě přidělit prostředky DMA, AllocateAdapterChannelEx vrátí STATUS_SUCCESS. Pokud všechny prostředky nejsou okamžitě dostupné, volání selže se stavovým kódem chyby STATUS_INSUFFICIENT_RESOURCES.

Pro synchronní volání, která vracejí STATUS_SUCCESS, pokud je parametr MapRegisterBase pro AllocateAdapterChannelEx nenullový, funkce AllocateAdapterChannelEx zapíše základní adresu přidělených mapových registrů na adresu, na kterou odkazuje parametr MapRegisterBase. Pokud executionRoutine má hodnotu NULL, mapRegisterBase musí mít hodnotu non-NULL. Pokud ExecutionRoutine není NULL, je parametr MapRegisterBasepro AllocateAdapterChannelEx nepovinný a rutina provádění obdrží základní adresu registru mapování jako vstupní parametr.

Asynchronní volání AllocateAdapterChannelEx vyžadují, aby ExecutionRoutine byla nenulová, a rutina provádění přijímá základní adresu mapovacího registru jako vstupní parametr.

V následných voláních rutiny MapTransferEx (viz krok 5) ovladač dodává základní adresu registru mapování jako vstupní parametr.

Pokud ExecutionRoutine není null, rutina provádění vrátí hodnotu stavu označující dispozici přidělených prostředků. Pro systémové přenosy DMA musí být tato návratová hodnota KeepObject. Tato hodnota informuje operační systém, že se objekt adaptéru (a všechny jeho přidělené prostředky) používá a neměl by být uvolněn. Pokud není zadána žádná rutina provádění, ovladač musí místo toho volat FreeAdapterObject rutinu a zadat KeepObject jako AllocationOption parametr.

Krok 4: V případě potřeby zrušte čekající žádost o prostředek.

Po volání AllocateAdapterChannelEx, které zařadí adaptér DMA do fronty k čekání na prostředky DMA, může ovladač v případě potřeby volat rutinu CancelAdapterChannel, aby zrušil čekající požadavek na prostředky.

Pokud CancelAdapterChannel vrátí hodnotu TRUE, požadavek na prostředek se úspěšně zruší. Pokud byla rutina provádění zadána ve volání AllocateAdapterChannelEx , tato rutina se nespustí.

Pokud CancelAdapterChannel vrátí hodnotu FALSE, požadavek na prostředek nelze zrušit, protože již byl udělen. Pokud byla rutina provádění zadána ve volání AllocateAdapterChannelEx , bude volána tato rutina.

Krok 5: Inicializace prostředků DMA a spuštění přenosu DMA

Ovladač volá MapTransferEx pro inicializaci prostředků DMA a spuštění přenosu DMA. K tomuto volání může dojít ve stejném vlákně ovladače, které volá AllocateAdapterChannelEx, nebo může dojít v rutině provádění, kterou ovladač dodává funkci AllocateAdapterChannelEx. Pokud je pro přenos celé vyrovnávací paměti dat DMA vyžadováno více než jedno volání MapTransferEx, může v rutině dokončení předchozího volání MapTransferEx dojít k pozdějšímu volání MapTransferEx.

MapTransferEx podporuje zřetězené MDLs jako vstupní parametry. Každý MDL popisuje oblast vyrovnávací paměti DMA, která je souvislá ve virtuální paměti. Když MapTransferEx sestaví scatter/gather seznam, automaticky zpracovává přechody z jedné prakticky spojité oblasti virtuální paměti na další bez zásahu ovladače. Další informace naleznete v tématu Použití rutiny MapTransferEx.

Pro systémový přenos DMA lze ukazatel na rutinu dokončení DMA předat MapTransferEx v volitelném parametru DmaCompletionRoutine . Tato rutina je naplánovaná tak, aby běžela na úrovni odeslání v reakci na přerušení ze systémového kontroleru DMA, který indikuje, že je přenos DMA dokončený.

Pokud MapTransferEx nemůže mapovat celou požadovanou velikost přenosu, nastaví výstupní parametr *Length na délku, která byla namapována, a vrátí STATUS_SUCCESS.

Krok 6: V případě potřeby proveďte operace specifické pro hardware

MapTransferEx vrátí STATUS_SUCCESS označující, že přenos DMA je úspěšně zahájen. Na některých platformách může ovladač muset provést nějakou další akci mimo volání MapTransferEx , aby mohl zahájit přenos, ale tento typ zpožděného spuštění není vyžadován pro všechny platformy. Ovladače by se neměly rozhodovat o používání a uvolnění přidělených prostředků na základě zpoždění.

Rutiny v provozním rozhraní DMA udržují aktuálnost mezipaměti pro přenosy DMA způsobem, který je transparentní pro ovladače, které tyto rutiny používají. Na platformách, které nevynucují koherenci mezipaměti v hardwaru, MapTransferEx zajistí vyprázdnění mezipamětí dat procesoru před přenosy (z paměti do zařízení). U přenosů typu čtení (zařízení-paměť) jsou mezipaměti během volání rutiny FlushAdapterBuffersEx neplatné (viz krok 8), které následují za každým voláním MapTransferEx .

Krok 7: Příjem oznámení po dokončení přenosu DMA

Po dokončení přenosu DMA je ovladač upozorněn jedním z těchto dvou způsobů:

  • Přerušení ovladače zařízení u hlavního zařízení sběrnice
  • Provádění rutiny dokončení dodaného ovladačem pro podřízené zařízení, které používá systémový řadič DMA

Pro systémový přenos DMA může ovladač poskytnout rutinu dokončení MapTransferEx jako vstupní parametr.

Krok 8: Vyprázdnění všech dat, která zůstávají v mezipaměti

Po dokončení přenosu DMA musí ovladač zavolat rutinu FlushAdapterBuffersEx, aby vyprázdnil všechna data, která zůstávají v mezipaměti. Ovladač musí po každém volání MapTransferEx volat FlushAdapterBuffersEx.

Pokud volání MapTransferEx mapuje pouze část vyrovnávací paměti dat DMA, ovladač musí znovu volat MapTransferEx pro mapování zbývajících dat. Složitý přenos může vyžadovat několik volání MapTransferEx . Pro každé další volání MapTransferEx opakujte kroky 5 až 8.

Krok 9: Uvolnění kanálu DMA a mapovacích registrů

Po úspěšném namapování celé datové vyrovnávací paměti DMA a dokončení konečného přenosu musí ovladač volat rutinu FreeAdapterChannel , aby uvolnil kanál DMA a všechny dříve přidělené mapové registry.

Krok 10: Uvolnění objektu adaptéru DMA

Po dokončení všech přenosů DMA jsou všechny dříve přidělené mapovací registry uvolněny, ovladač volá rutinu PutDmaAdapter k uvolnění objektu adaptéru.