Partager via


Utilisation d’un DMA de nuages de points/de collecte

Les pilotes qui effectuent une DMA basée sur le système ou le bus master peuvent utiliser des routines de prise en charge conçues spécialement pour la diffusion/la collecte de données DMA. Au lieu d’appeler la séquence de routines décrite dans Using Packet-Based System DMA et Packet-Based Bus-Master DMA, un pilote peut utiliser GetScatterGatherList et PutScatterGatherList.

Un appareil n’a pas besoin de disposer d’une prise en charge intégrée des points/regroupements pour que son pilote utilise ces routines.

Les pilotes qui utilisent la DMA basée sur les paquets appellent la séquence générale suivante de routines de prise en charge pour les opérations de diffusion/collecte :

  1. MmGetMdlVirtualAddress pour obtenir un index dans le MDL, requis en tant que paramètre dans l’appel à GetScatterGatherList

  2. GetScatterGatherList lorsque le pilote est prêt à programmer son appareil pour DMA et a besoin du contrôleur DMA système ou de l’adaptateur master bus

    GetScatterGatherList alloue le contrôleur DMA système ou l’adaptateur master bus, détermine le nombre de registres de carte requis et les alloue, remplit la liste de points/regroupements et appelle la routine AdapterListControl du pilote lorsque le contrôleur DMA ou l’adaptateur et les registres de carte sont disponibles.

  3. PutScatterGatherList dès que toutes les données demandées ont été transférées ou que le pilote échoue à l’IRP en raison d’une erreur d’E/S d’appareil

    PutScatterGatherList vide les mémoires tampons de l’adaptateur, libère les registres de carte et libère la liste de points/regroupements. Le pilote doit appeler PutScatterGatherList avant de pouvoir accéder aux données dans la mémoire tampon.

Le pointeur d’objet d’adaptateur retourné par IoGetDmaAdapter est un paramètre obligatoire pour chacune de ces routines, à l’exception de MmGetMdlVirtualAddress, qui nécessite un pointeur vers la MDL sur Irp-MdlAddress.>

La routine GetScatterGatherList inclut des appels à AllocateAdapterChannel et MapTransfer, de sorte que le pilote n’a pas à effectuer ces appels. La routine prend les paramètres suivants :

  • Pointeur vers la structure DMA_ADAPTER retournée par IoGetDmaAdapter

  • Pointeur vers l’objet d’appareil cible pour l’opération DMA

  • Pointeur vers le MDL qui décrit la mémoire tampon dans Irp-MdlAddress>

  • Pointeur vers l’adresse virtuelle actuelle dans la mémoire tampon décrite par mdl

  • Nombre d’octets à mapper

  • Pointeur vers une routine AdapterListControl qui effectue le transfert

  • Pointeur vers une zone de contexte définie par le pilote à passer à la routine AdapterListControl

  • Valeur booléenne : TRUE pour un transfert vers l’appareil ; FALSE sinon

Après avoir déterminé le nombre de registres de carte requis, alloué le canal d’adaptateur et les registres de carte, rempli la liste de points/regroupements et préparé le transfert, GetScatterGatherListlist appelle la routine AdapterListControl fournie par le pilote. La routine AdapterListControl est exécutée dans un contexte de thread arbitraire à l’emplacement IRQL = DISPATCH_LEVEL.

La routine AdapterListControl qu’un pilote fournit dans les appels à GetScatterGatherList diffère de la routine AdapterControl passée à AllocateAdapterChannel sur les points importants suivants :

  • La routine AdapterListControl n’a aucune valeur de retour, tandis que la routine AdapterControl retourne une IO_ALLOCATION_ACTION.

  • Plutôt qu’un pointeur vers MapRegisterBase pour les registres de carte alloués par le système, le troisième paramètre d’une routine AdapterListControl pointe plutôt vers une structure SCATTER_GATHER_LIST via laquelle le pilote peut effectuer des opérations DMA.

  • La routine AdapterListControl effectue un sous-ensemble des tâches requises dans une routine AdapterControl .

    La routine AdapterListControl n’appelle pas AllocateAdapterChannel ou MapTransfer. Ses seules responsabilités sont d’enregistrer le pointeur de liste de points/regroupements d’entrée, de configurer son appareil et d’utiliser la liste de points/regroupements pour effectuer une DMA.

La structure de liste de points/regroupements inclut un tableau SCATTER_GATHER_ELEMENT et le nombre d’éléments dans le tableau. Chaque élément du tableau fournit la longueur et l’adresse physique de départ d’une région de points/regroupements contiguë. Un pilote utilise la longueur et l’adresse dans les transferts de données.

Un pilote peut utiliser GetScatterGatherList , que son appareil prenne en charge ou non la diffusion/collecte DMA. Pour un appareil qui ne prend pas en charge LDMA de nuages de points/regroupements, la liste de points/regroupements ne contiendra qu’un seul élément.

L’utilisation des routines de diffusion/collecte peut améliorer les performances par rapport à l’appel d’AllocateAdapterChannel (comme décrit précédemment dans Utilisation de Packet-Based DMA système et Utilisation de Packet-Based Bus-Master DMA). Contrairement aux appels à AllocateAdapterChannel, plusieurs appels à GetScatterGatherList peuvent être mis en file d’attente pour un objet d’appareil à tout moment. Un pilote peut appeler à nouveau GetScatterGatherList pour une autre opération DMA sur le même objet de pilote avant que sa routine AdapterListControl n’ait terminé l’exécution.

Au retour de la routine AdapterListControl fournie par le pilote, GetScatterGatherList conserve les registres de carte, mais libère la structure de l’adaptateur DMA.

Lorsque le pilote a satisfait la demande de transfert de l’IRP actuelle ou doit échouer en raison d’une erreur d’E/S d’appareil ou de bus, il doit appeler PutScatterGatherList avant de pouvoir accéder aux données transférées dans la mémoire tampon. PutScatterGatherList vide les mémoires tampons de l’adaptateur et libère les registres de carte et la liste de points/regroupements.