DMA-Kanalobjekte

Hinweis

Microsoft unterstützt eine vielfältige und inklusive Umgebung. Dieser Artikel enthält Verweise auf die Terminologie, die vom Microsoft-Stilleitfaden für eine biasfreie Kommunikation als Ausschluss erkannt wird. Das Wort oder der Ausdruck wird in diesem Artikel zur Konsistenz verwendet, da es derzeit in der Software angezeigt wird. Wenn die Software aktualisiert wird, um die Sprache zu entfernen, wird dieser Artikel so aktualisiert, dass er in Übereinstimmung steht.

Der PortCls-Systemtreiber implementiert die IDmaChannel - und IDmaChannelSlave-Schnittstellen für den Vorteil von WaveCyclic- und WavePci-Miniporttreibern. IDmaChannel stellt einen DMA-Kanal sowie die zugehörigen DMA-Puffer- und Pufferverwendungsparameter dar. Darüber hinaus verwenden WaveCyclic Miniporttreiber IDmaChannelSlave , um einen DMA-Kanal für ein untergeordnetes Gerät zu verwalten. IDmaChannelSlave erbt von IDmaChannel. Informationen zum Steuern von DMA-Vorgängen finden Sie unter Adapterobjekte und DMA.

Ein IDmaChannel-Objekt kapselt Folgendes:

  • Ein DMA-Kanal für ein Master- oder untergeordnetes Gerät

  • Der Datenpuffer, der dem Kanal zugeordnet ist

  • Informationen, die beschreiben, wie der Kanal verwendet werden soll

Port- und Miniporttreiber verwenden DMA-Kanalobjekte, um Informationen zur DMA-Kanalnutzung zu kommunizieren. In der Regel weist ein Miniporttreiber während der Initialisierung oder beim Erstellen eines Datenstroms eine Reihe von DMA-Kanälen zu. Während der Erstellung eines neuen Datenstroms teilt der Miniporttreiber dem Porttreiber mit, welches DMA-Kanalobjekt für den Datenstrom verwendet wird.

Ein DMA-Kanalobjekt kann für ein Master- oder untergeordnetes Gerät erstellt werden:

  • Ein untergeordnetes Gerät verfügt über keine integrierten DMA-Hardwarefunktionen und muss sich auf den DMA-Systemcontroller verlassen, um alle vom Gerät benötigten Datenübertragungen durchzuführen.

  • Ein Mastergerät verwendet eine eigene DMA-Hardware für busmastering, um Datenübertragungen auf dem Systembus durchzuführen.

Ein Beispiel für ein WaveCyclic-Gerät, das ein untergeordnetes DMA-Kanalobjekt verwendet, finden Sie im Sb16-Beispielaudiotreiber in früheren Versionen des Microsoft Windows Driver Kit (WDK). Ein Master-DMA-Kanalobjekt ist wenig mehr als ein Backboard zum Freigeben von Informationen über den DMA-Kanal zwischen den Port- und Miniporttreibern. Weitere Informationen zu Master- und untergeordneten Geräten finden Sie in der Einführung in Adapterobjekte.

Das DMA-Kanalobjekt für ein Master- oder untergeordnetes Gerät macht Folgendes verfügbar:

  • Ein Adapter-Objekt

  • Ein einzelner allgemeiner Puffer, den der Treiber und die DMA-Hardware gemeinsam nutzen können

  • Ein Puffergrößeswert, der abgefragt und geändert werden kann

Das Adapterobjekt ist eine DMA-Adapterstruktur für ein physisches Geräteobjekt (PDO). Das Adapterobjekt wird automatisch erstellt, wenn der Miniporttreiber das DMA-Kanalobjekt durch Aufrufen einer der folgenden Methoden erstellt:

IPortWavePci::NewMasterDmaChannel

IPortWaveCyclic::NewMasterDmaChannel

IPortWaveCyclic::NewSlaveDmaChannel

Die Methode IDmaChannel::GetAdapterObject kann verwendet werden, um einen Zeiger auf das Adapterobjekt abzurufen.

Ein Adaptertreiber kann auch die PcNewDmaChannel-Funktion aufrufen, um ein DMA-Kanalobjekt zu erstellen. Diese Funktion ist jedoch schwieriger zu verwenden als die IPortWaveXxx::NewXxx DmaChannel-Aufrufe, da der Aufrufer explizit ein Geräteobjekt und andere Kontextinformationen angeben muss.

Bei einem DMA-Kanal für ein untergeordnetes Gerät gibt die IDmaChannel::TransferCount-Methode die maximale Übertragungsgröße (den MapSize-Parameter) zurück, die im Aufruf von IDmaChannelSlave::Start angegeben wurde. Darüber hinaus stellt das Adapterobjekt einige Methoden zum Bearbeiten und Abfragen des DMA-Geräts bereit. Keine dieser Methoden ist für Master-DMA-Kanäle sinnvoll.

IDmaChannel::AllocateBuffer und IDmaChannel::FreeBuffer werden verwendet, um den einzelnen gemeinsamen Puffer zu verwalten, der dem DMA-Kanalobjekt zugeordnet ist. Auf den vom Objekt zugewiesenen Puffer kann sowohl auf den Treiber (mit Kernel-Virtual-Memory-Adressen) als auch auf das DMA-Gerät (mit physischen Speicheradressen) zugegriffen werden. Darüber hinaus ist der Puffer physisch zusammenhängend. In der Regel besteht die beste Strategie darin, den DMA-Puffer während der Miniporttreiberinitialisierung zuzuweisen, wenn physisch zusammenhängender Speicher am häufigsten vorhanden ist. IDmaChannel::AllocatedBufferSize gibt die Größe des Puffers zurück, wie er im Aufruf von IDmaChannel::AllocateBuffer angegeben wurde.

IDmaChannel::MaximumBufferSize gibt die tatsächliche maximale Puffergröße an, die verwendet werden kann. Dies kann die zugewiesene Größe überschreiten, wenn die zugeordnete Größe nicht einmal ein Vielfaches der Seitengröße ist. Möglicherweise kleiner als die zugewiesene Größe, wenn das DMA-Gerät übertragungen der zugewiesenen Größe nicht unterstützen kann. IDmaChannel::BufferSize und IDmaChannel::SetBufferSize werden verwendet, um die Größe des Puffers abzufragen und festzulegen, der für DMA-Übertragungen verwendet werden soll. Wenn der Puffer zugewiesen wird, wird die Puffergröße auf die maximale Puffergröße festgelegt. Nach der Initialisierung haben sowohl der Porttreiber als auch der Miniporttreiber die Möglichkeit, die Puffergröße zu ändern oder den aktuellen Wert zu ermitteln. Der Miniporttreiber verwendet das Ergebnis von IDmaChannel::BufferSize , um die Übertragungsgröße für DMA-Vorgänge zu bestimmen, wenn der DMA-Kanal gestartet wird. IDmaChannel::SystemAddress und IDmaChannel::P hysicalAddress werden verwendet, um die virtuellen und physischen Adressen des Puffers abzurufen.

IDmaChannel::CopyTo und IDmaChannel::CopyFrom kopieren Beispieldaten in und aus dem DMA-Puffer. Der WaveCyclic-Porttreiber ruft diese Methoden auf, um Audiodaten zwischen dem Anwendungspuffer und dem zyklischen Puffer des Miniporttreibers zu kopieren.

Der DMA-Puffer wird nicht unbedingt verwendet, um die gestreamten Daten zu übertragen. Im Falle des WavePci-Porttreibers werden die gestreamten Daten an den Miniporttreiber als Liste der XY/Gather-Zuordnungen übermittelt (oder abgerufen). Der Miniporttreiber kann jedoch weiterhin den DMA-Puffer als gemeinsam genutzten Speicherplatz für die Kommunikation mit dem Adaptertreiber verwenden.

Porttreiber bieten Miniporttreiber mit Funktionen, die sie zum Erstellen von DMA-Kanälen verwenden können. Sofern nicht anders in der Beschreibung des Porttreibers angegeben, ist es nicht unbedingt erforderlich, DMA-Objekte zu verwenden, die dem Porttreiber zugeordnet sind. Der Porttreiber erfordert einfach einen Zeiger auf eine IDmaChannel-Schnittstelle , die die benötigten Methoden unterstützt. Überprüfen Sie die Dokumentation für jeden Porttreiber für eine Liste der DMA-Kanalmethoden, die der Porttreiber benötigt.

In der Regel besteht der einfachste Ansatz darin, die DMA-Kanalzuweisungsfunktionen zu verwenden, die der Porttreiber implementiert. In seltenen Fällen müssen Miniporttreiberentwickler möglicherweise eigene DMA-Kanalobjekte implementieren, um die speziellen Anforderungen ihrer speziellen Adapter zu erfüllen. Dies erfordert manchmal die Implementierung eines neuen Objekts. Manchmal reicht es aus, dass das Streamobjekt des Miniporttreibers eine IDmaChannel-Schnittstelle verfügbar macht und die DMA-Kanalmethoden selbst implementiert.

Die IDmaChannel-Schnittstelle unterstützt die folgenden Methoden:

IDmaChannel::AllocateBuffer

IDmaChannel::AllocatedBufferSize

IDmaChannel::BufferSize

IDmaChannel::CopyFrom

IDmaChannel::CopyTo

IDmaChannel::FreeBuffer

IDmaChannel::GetAdapterObject

IDmaChannel::MaximumBufferSize

IDmaChannel::P hysicalAddress

IDmaChannel::SetBufferSize

IDmaChannel::SystemAddress

IDmaChannel::TransferCount

Die IDmaChannelSlave-Schnittstelle erweitert IDmaChannel durch Hinzufügen der folgenden Methoden:

IDmaChannelSlave::ReadCounter

IDmaChannelSlave::Start

IDmaChannelSlave::Stop

IDmaChannelSlave::WaitForTC