Schnellreferenz

In diesem Kapitel wurden die folgenden Symbole aus dem Bereich der Speicherverwaltung eingeführt. Die Liste enthält nicht die Symbole, die im ersten Abschnitt eingeführt wurden, weil dieser Abschnitt schon selbst eine große Liste ist und die dort genannten Symbole selten für Gerätetreiber nützlich sind.

#include <linux/mm.h>

In dieser Header-Datei sind alle Funktionen und Strukturen aus dem Bereich der Speicherverwaltung definiert.

int remap_page_range(unsigned long virt_add, unsigned long phys_add, unsigned long size, pgprot_t prot);

Diese Funktion ist der Kern von mmap. Sie bildet size Bytes einer physikalischen Adresse, die bei phys_addr beginnt, auf die virtuelle Adresse virt_addr ab. Die Zugriffsbits für den virtuellen Adreßraum werden in prot angegeben.

struct page *virt_to_page(void *kaddr);, void *page_address(struct page *page);

Diese Makros konvertieren zwischen logischen Kernel-Adressen und deeren zugehörigen Speichertabellen-Einträgen. page_address funktioniert nur auf Seiten im niedrigen Speicher sowie auf Seiten im hohen Speicher, die explizit eingeblendet worden sind.

void *_ _va(unsigned long physaddr);, unsigned long _ _pa(void *kaddr);

Diese Makros konvertieren zwischen logischen Kernel-Adressen und physikalischen Adressen.

unsigned long kmap(struct page *page);, void kunmap(struct page *page);

kmap gibt eine virtuelle Kernel-Adresse zurück, die auf die angegebene Seite eingeblendet ist. Dabei wird die Einblendung bei Bedarf erzeugt. kunmap löscht die Einblendung für die angegebene Seite.

#include <linux/iobuf.h>, void kiobuf_init(struct kiobuf *iobuf);, int alloc_kiovec(int number, struct kiobuf **iobuf);, void free_kiovec(int number, struct kiobuf **iobuf);

Diese Funktionen erledigen die Allokation, Initialisierung und Freigabe von Kernel-I/O-Puffern. kiobuf_init initialisiert einen einzelnen kiobuf, wird aber nur selten verwendet. alloc_kiovec wird meistens statt dessen verwendet und alloziert und initialisiert einen Vektor von kiobufs. Ein solcher Vektor von kiobufs wird mit free_kiovec wieder freigegeben.

int lock_kiovec(int nr, struct kiobuf *iovec[], int wait);, int unlock_kiovec(int nr, struct kiobuf *iovec[]);

Diese Funktionen sperren einen kiovec im Speicher und geben ihn wieder frei. Sie sind nicht notwendig, wenn kiobufs für I/O in User Space-Speicher verwendet werden.

int map_user_kiobuf(int rw, struct kiobuf *iobuf, unsigned long address, size_t len);, void unmap_kiobuf(struct kiobuf *iobuf);

map_user_kiobuf blendet einen Puffer im User Space in den angegebenen Kernel-I/O-Puffer ein; unmap_kiobuf hebt diese Einblendung wieder auf.

#include <asm/io.h>, unsigned long virt_to_bus(volatile void * address);, void * bus_to_virt(unsigned long address);

Diese Funktionen konvertieren zwischen virtuellen Kernel-Adressen und Bus-Adressen. Bus-Adressen müssen für die Kommunikation mit Peripherie-Geräten verwendet werden.

#include <linux/pci.h>

Die Header-Datei, die die folgenden Funktionen definiert.

int pci_dma_supported(struct pci_dev *pdev, dma_addr_t mask);

Für Peripherie-Geräte, die den vollen 32-Bit-Bereich nicht adressieren können, bestimmt diese Funktion, ob DMA überhaupt auf dem Host-System unterstützt wird.

void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *bus_addr), void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpuaddr, dma_handle_t bus_addr);

Diese Funktionen allozieren konsistente DMA-Einblendungen für einen Puffer, der während der gesamten Lebensdauer des Treibers existiert, und geben sie wieder frei.

PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE, PCI_DMA_BIDIRECTIONAL, PCI_DMA_NONE

Diese Symbole werden dazu verwendet, den Funktionen für Streaming-Einblendungen mitzuteilen, in welche Richtung Daten vom oder zum Puffer transportiert werden.

dma_addr_t pci_map_single(struct pci_dev *pdev, void *buffer, size_t size, int direction);, void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t size, int direction);

Erzeugen und zerstören eine Streaming-DMA-Einblendung zur einmaligen Verwendung.

void pci_sync_single(struct pci_dev *pdev, dma_handle_t bus_addr, size_t size, int direction)

Synchronisieren einen Puffer, der eine Streaming-Einblendung hat. Diese Funktion muß verwendet werden, wenn der Prozessor auf einen Puffer zugreifen muß, während die Streaming-Einblendung noch besteht (also während der Puffer dem Gerät gehört).

struct scatterlist { /* ... */ };, dma_addr_t sg_dma_address(struct scatterlist *sg);, unsigned int sg_dma_len(struct scatterlist *sg);

Die Struktur scatterlist beschreibt eine I/O-Operation, die mehr als einen Puffer betrifft. Die Makros sg_dma_address und sg_dma_len können dazu verwendet werden, bei der Implementierung von Scatter-Gather-Operationen Bus-Adressen und Puffer-Längen zu extrahieren, die dann an das Gerät übergeben werden.

pci_map_sg(struct pci_dev *pdev, struct scatterlist *list, int nents, int direction);, pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *list, int nents, int direction);, pci_dma_sync_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, int direction)

pci_map_sg blendet eine Scatter-Gather-Operation ein und pci_unmap_sg hebt diese Einblendung wieder auf. Wenn auf die Puffer zugegriffen werden muß, während die Einblendung noch aktiv ist, kann pci_dma_sync_sg zum Synchronisieren verwendet werden.

/proc/dma

Diese Daten enthält einen textuellen Snapshot der allozierten Kanäle in den DMA-Controllern. PCI-basierte DmA wird hier nicht gezeigt, weil jede Karte unabhängig von den anderen arbeitet, ohne einen Kanal im DMA-Controller allozieren zu müssen.

#include <asm/dma.h>

Diese Header-Datei definiert oder deklariert alle Funktionen und Makros aus dem DMA-Bereich. Sie muß vor der Verwendung eines der folgenden Symbole eingebunden werden.

int request_dma(unsigned int channel, const char *name);, void free_dma(unsigned int channel);

Diese Funktionen greifen auf die DMA-Registry zu. Die Registrierung muß vor der Verwendung der ISA-DMA-Kanäle erfolgen.

unsigned long claim_dma_lock();, void release_dma_lock(unsigned long flags);

Diese Funktionen holen das DMA-Spinlock und geben es wieder frei. Dieses Spinlock muß gehalten werden, bevor eine der anderen ISA-DMA-Funktionen, die unten in dieser Liste beschrieben werden, aufgerufen wird. Sie schalten auch die Interrupts im lokalen Prozessor aus und wieder ein.

void set_dma_mode(unsigned int channel, char mode);, void set_dma_addr(unsigned int channel, unsigned int addr);, void set_dma_count(unsigned int channel, unsigned int count);

Diese Funktionen dienen zum Programmieren von DMA-Informationen im DMA-Controller. addr ist eine Bus-Adresse.

void disable_dma(unsigned int channel);, void enable_dma(unsigned int channel);

Ein DMA-Kanal muß während der Konfiguration abgeschaltet sein. Diese Funktionen ändern den Status des DMA-Kanals.

int get_dma_residue(unsigned int channel);

Wenn der Treiber wissen muß, wie eine DMA-Übertragung fortschreitet, kann er diese Funktion aufrufen, die die Anzahl der noch ausstehenden Datenübertragungen zurückgibt. Nach erfolgreichem Abschluß der DMA-Übertragung gibt die Funktion 0 zurück; während der Übertragung von Daten ist der Wert nicht vorhersagbar.

void clear_dma_ff(unsigned int channel)

Das DMA-Flip-Flop wird vom Controller verwendet, um 16-Bit-Werte mit Hilfe zweier 8-Bit-Operationen zu übertragen. Es muß zurückgesetzt werden, bevor irgendwelche Daten an den Controller geschickt werden.