Verwenden Common-Buffer Bus-Master DMA
Wie unter Verwenden Bus-Master DMA beschrieben, verwenden einige Treiber für Bus-master DMA-Geräte ausschließlich Common-Buffer-DMA, einige verwenden common-buffer DMA in Kombination mit paketbasiertem DMA.
Verwenden Sie Common-Buffer-DMA wirtschaftlich. Das Einrichten eines allgemeinen Puffers kann einige (oder alle, abhängig von der Größe des angeforderten Puffers) der Kartenregister binden, die dem Adapterobjekt zugeordnet sind, das den Bus-master-Adapter darstellt.
Durch das wirtschaftliche Einrichten von Allgemeinen Pufferbereichen, z. B. durch Die Verwendung von PAGE_SIZE Blöcken oder einer einzelnen Zuordnung, stehen mehr Kartenregister für paketbasierte DMA-Vorgänge zur Verfügung. Außerdem bleibt mehr Systemspeicher für andere Zwecke frei, was zu einer besseren Gesamtleistung von Treiber und System führt.
Um einen gemeinsamen Puffer für bus-master DMA einzurichten, muss ein Bus-master DMA-Gerätetreiber "AllocateCommonBuffer" mit dem von IoGetDmaAdapter zurückgegebenen Adapterobjektzeiger aufrufen. In der Regel führt ein Treiber diesen Aufruf aus seiner DispatchPnP-Routine für IRP_MN_START_DEVICE Anforderungen aus. Ein Treiber sollte einen gemeinsamen Puffer nur zuordnen, wenn er den Puffer wiederholt für seine DMA-Vorgänge verwendet, während der Treiber geladen bleibt. Das folgende Diagramm veranschaulicht einen solchen Aufruf von AllocateCommonBuffer.
Die angeforderte Größe für den Puffer, die im vorherigen Diagramm als LengthForBuffer dargestellt ist, bestimmt, wie viele Kartenregister verwendet werden müssen, um eine virtuelle zu logische Zuordnung für den allgemeinen Puffer bereitzustellen. Verwenden Sie das makro BYTES_TO_PAGES , um die maximal erforderliche Seitenanzahl zu bestimmen (BYTES_TO_PAGES (LengthForBuffer)). Dieser Wert darf nicht größer als der von IoGetDmaAdapter zurückgegebene NumberOfMapRegisters sein.
Darüber hinaus muss der Aufrufer Folgendes angeben:
Ein boolescher Wert, der angibt, ob die Zwischenspeicherung aktiviert werden soll
Hinweis Dieser Wert wird ignoriert. Das Betriebssystem bestimmt, ob der zwischengespeicherte Arbeitsspeicher im gemeinsamen Puffer aktiviert werden soll, der zugeordnet werden soll. Diese Entscheidung basiert auf der Prozessorarchitektur und dem Gerätebus.
Auf Computern mit x86-basierten, x64-basierten und Itanium-basierten Prozessoren ist zwischengespeicherter Arbeitsspeicher aktiviert.
Auf Computern mit Arm- oder Arm 64-basierten Prozessoren aktiviert das Betriebssystem nicht automatisch den zwischengespeicherten Arbeitsspeicher für alle Geräte. Das System verwendet die ACPI_CCA-Methode für jedes Gerät, um zu bestimmen, ob das Gerät cachekons kohärent ist.
Ein Zeiger auf eine vom Treiber definierte Variable, die die vom Gerät zugängliche logische Basisadresse für den Puffer (BufferLogicalAddress im vorherigen Diagramm) enthält, wenn sie von AllocateCommonBuffer zurückgegeben wird.
Wenn der Aufruf erfolgreich ist, gibt AllocateCommonBuffer eine vom Treiber zugängliche virtuelle Basisadresse für den Puffer (BufferVirtualAddress im vorherigen Diagramm) zurück, die der Treiber in seiner Geräteerweiterung, Controllererweiterung oder einem anderen vom Treiber zugänglichen residenten Speicherbereich speichern muss (nicht ausgelagerter Pool, der vom Treiber zugewiesen wird).
AllocateCommonBuffer gibt NULL zurück, wenn der Speicher für den Puffer nicht zugewiesen werden kann. Wenn die zurückgegebene virtuelle Basisadresse NULL ist, muss der Treiber entweder ausschließlich die paketbasierte DMA-Unterstützung des Systems verwenden, oder der Treiber muss die IRP_MN_START_DEVICE Anforderung nicht ausführen und STATUS_INSUFFICIENT_RESOURCES zurückgeben.
Andernfalls kann der Treiber den zugeordneten gemeinsamen Puffer als Treiber- und Adapterzugriffsbereich für DMA-Übertragungen verwenden.
Wenn der PnP-Manager ein IRP sendet, das das Gerät beendet oder entfernt, muss der Treiber FreeCommonBuffer aufrufen, um jeden gemeinsamen Puffer freizugeben, den er zugewiesen hat.