Dio-Struktur verwenden

Ein Einheitentreiber kann die dio -Struktur auf viele Arten verwenden.

Er kann für folgende Zwecke verwendet werden:
  • Übergeben Sie eine Liste virtueller Adressen und Längen von Puffern an die d_map_list -und d_map_slave -Services.
  • Empfangen Sie die resultierende Liste von Busadressen (nurd_map_list ) für die Verwendung durch die Einheit bei der Datenübertragung.
    Anmerkung: Der Treiber benötigt keine dio -Busliste für Aufrufe an d_map_slave , da die Adressgenerierung für Worker ausgeblendet ist.

Normalerweise stellt ein Einheitentreiber eine dio -Struktur bereit, die nur einen virtuellen Puffer und eine Länge in der Liste enthält. Wenn die Länge des virtuellen Puffers viele Seiten umfasst, enthält die Busadressliste mehrere Einträge, die die physischen Positionen des praktisch zusammenhängenden Puffers widerspiegeln. Der Treiber kann mehrere virtuelle Puffer in der virtuellen Liste bereitstellen. Der Treiber kann dann viele Pufferanforderungen in eine E/A-Operation stellen.

Der Einheitentreiber ist für die Zuordnung des Speichers für alle benötigten dio -Listen verantwortlich. Weitere Informationen finden Sie in den Makros DIO_INIT und DIO_FREE in der Headerdatei sys/dma.h . Der Treiber muss mindestens zwei dio -Strukturen aufweisen. Eine ist für die Übergabe der virtuellen Liste erforderlich. Eine weitere ist erforderlich, um die resultierende Busliste zu akzeptieren. Der Treiber kann über viele dio -Listen verfügen, wenn er mehrere ausstehende E/A-Befehle für seine Einheit plant. Die Länge jeder Liste hängt von der Verwendung der Einheit und des Treibers ab. Die virtuelle Liste benötigt so viele Elemente, wie die Einheit gleichzeitig in einer Operation platzieren könnte. Eine Formel zur Schätzung, wie viele Elemente die Busadressliste benötigt, ist die Summe der Längen aller virtuellen Puffer dividiert durch die Seitengröße plus 2. oder

   sum [i=0 to n] ((vlist[i].length / PSIZE) + 2).  
Diese Formel behandelt eine Worst-Case-Situation. Bei einem zusammenhängenden virtuellen Puffer, der mehrere Seiten umfasst, ist jede physische Seite nicht zusammenhängend und weder die Anfangs-noch die Endadresse sind seitenausgerichtet.

Wenn der d_map_list -Service beim Ausfüllen der dio -Busliste über zu viel Speicherplatz verfügt, wird ein DMA_DIOFULL-Fehler an den Einheitentreiber zurückgegeben und das Feld bytes_done der virtuellen dio -Liste wird auf die Anzahl der Bytes gesetzt, die erfolgreich in der Busliste zugeordnet wurden. Diese Bytezahl ist garantiert ein Vielfaches des Felds minxfer , das für die d_map_list -oder d_map_slave -Services bereitgestellt wird. Außerdem wird das Feld resid_iov der virtuellen Liste auf den Index des ersten d_iovec -Eintrags gesetzt, der den Rest der iovecs darstellt, die nicht zugeordnet werden konnten.

Der Einheitentreiber kann folgende Aktionen ausführen:
  • Leiten Sie eine partielle Übertragung auf der Einheit ein und lassen Sie den Rest in der Einheitenwarteschlange.

    Wenn der Treiber entscheidet, die partielle Übertragung nicht einzuleiten, muss er dennoch einen Aufruf an d_unmap_list ausführen, um die partielle Zuordnung rückgängig zu machen.

  • Führen Sie einen weiteren Aufruf an d_map_list mit neuen dio -Listen für den Rest durch und richten Sie das Gerät für die ursprünglich vorgesehene vollständige Übertragung ein.

Wenn in d_map_list oder d_map_slave ein Zugriffsverstoß auf einer Seite in der virtuellen Liste auftritt, wird ein DMA_NOACC-Fehler an den Einheitentreiber zurückgegeben und das Feld bytes_done der virtuellen Liste dio wird auf die Anzahl der Byte gesetzt, die dem fehlerhaften Iovec vorangehen. In diesem Fall wird das Feld resid_iov auf den Index des d_iovec -Eintrags gesetzt, der den Verstoß festgestellt hat. Anhand dieser Informationen kann der Treiber bestimmen, welcher virtuelle Puffer die fehlerhafte Seite enthielt, und diese Anforderung an den Ersteller zurückgeben.

Hinweis: Wenn der Fehler DMA_NOACC zurückgegeben wird, ist die Anzahl bytes_done nicht garantiert ein Vielfaches des Felds minxfer , das für die d_map_list -oder d_map_slave -Services bereitgestellt wird, und es erfolgt keine partielle Zuordnung. Für Worker erfolgt die Konfiguration der Hardware zur Adressgenerierung nicht. Für Controller ist die Busliste nicht definiert. Wenn der Treiber eine teilweise Übertragung wünscht, muss er einen weiteren Aufruf an den Zuordnungsservice ausführen, wobei die dio -Liste so angepasst wird, dass sie den fehlerhaften Puffer nicht enthält.
Wenn für die d_map_list -oder d_map_slave -Services beim Zuordnen einer Übertragung keine Ressourcen mehr verfügbar sind, wird ein DMA_NORES-Fehler an den Einheitentreiber zurückgegeben. In diesem Fall wird das Feld bytes_done der virtuellen dio -Liste auf die Anzahl Byte gesetzt, die erfolgreich in der Busliste zugeordnet wurden. Diese Bytezahl ist garantiert ein Vielfaches des Felds minxfer , das für die d_map_list -oder d_map_slave -Services bereitgestellt wird. Außerdem wird das Feld resid_iov der virtuellen Liste auf den Index der ersten d_iovec der verbleibenden iovecs gesetzt, die nicht zugeordnet werden konnten. Der Einheitentreiber kann folgende Aktionen ausführen:
  • Eine Teilübertragung auf der Einheit einleiten und den Rest in der Einheitenwarteschlange belassen

    Wenn der Treiber entscheidet, die partielle Übertragung nicht einzuleiten, muss er trotzdem einen Aufruf an d_unmap_list oder d_unmap_slave (für Worker) ausführen, um die partielle Zuordnung rückgängig zu machen.

  • Wählen Sie diese Option aus, um die gesamte Anforderung in der Einheitenwarteschlange zu belassen und auf die Freigabe von Ressourcen zu warten (z. B. nach einer Einheitenunterbrechung durch eine vorherige Operation).
Hinweis: Wenn das Attribut DMA_ENABLE_64 im Aufruf d_map_init oder im Aufruf d_map_init_ext angegeben ist, ist das Programmiermodell mit einer Ausnahme identisch. Die Strukturen dio_64 und d_iovec_64 werden zusätzlich zu 64-Bit-Adressfeldern in d_map_page -und d_unmap_page -Aufrufen verwendet.