Comment envoyer des structures MDL chaînées
Cet article décrit la fonctionnalité de bibliothèques mdl chaînées dans la pile de pilotes USB, et comment un pilote client peut envoyer une mémoire tampon de transfert sous la forme d’une chaîne de structures MDL .
La plupart des contrôleurs hôtes USB nécessitent que la mémoire tampon de transfert soit pratiquement contiguë. La quasi contiguïté signifie que la mémoire tampon peut démarrer et se terminer n’importe où dans une page, mais que le reste de la mémoire tampon doit démarrer et se terminer sur une limite de page. De nombreux pilotes clients USB sont en mesure de répondre à cette exigence. Toutefois, pour certains pilotes clients, en particulier ceux qui doivent ajouter ou supprimer des données supplémentaires dans ou à partir de la mémoire tampon, l’allocation de mémoire pratiquement contiguë pour la mémoire tampon de transfert n’est pas préférable.
Par exemple, considérez une pile réseau de trois pilotes, un pilote de protocole réseau, un pilote intermédiaire et un pilote miniport. Le pilote de protocole lance un transfert et envoie un paquet au pilote suivant de la pile : le pilote intermédiaire. Le pilote intermédiaire souhaite ajouter un en-tête personnalisé (contenu dans un bloc de mémoire distinct) au paquet. Le pilote intermédiaire envoie cet en-tête et le paquet reçu au pilote suivant dans la pile : le pilote miniport. Le pilote miniport s’interface avec la pile de pilotes USB et doit donc préparer une mémoire tampon de transfert pratiquement contiguë. Pour créer une telle mémoire tampon, le pilote miniport alloue une mémoire tampon volumineuse, ajoute l’en-tête personnalisé, puis copie la charge utile. Étant donné que la charge utile est généralement volumineuse, la copie de la charge utile entière peut avoir un impact significatif sur les performances.
Le pilote client peut surmonter cet impact sur les performances en envoyant la mémoire tampon de transfert sous la forme d’une chaîne de liste de descripteurs de mémoire (MDL). La nouvelle pile de pilotes USB dans Windows 8, est capable d’accepter une MDL chaînée (voir MDL) du pilote client. En fournissant une MDL chaînée, le pilote client peut référencer des pages discontiguées en mémoire au lieu d’effectuer des opérations de copie superflues. La fonctionnalité supprime les restrictions sur le nombre, la taille et l’alignement des mémoires tampons, ce qui permet à la mémoire tampon de transfert d’être segmentée dans la mémoire physique.
Pour utiliser des DLL chaînées, le pilote client doit détecter si la pile de pilotes USB sous-jacente, chargée par Windows, prend en charge la fonctionnalité, puis créer une chaîne de DLL dans un ordre approprié.
Avant de commencer
La fonctionnalité MDL chaînée est uniquement prise en charge pour les transferts en bloc, isochronous et d’interruption. Avant de rechercher la fonctionnalité MDL chaînée, assurez-vous que votre pilote client dispose d’un handle USBD pour l’inscription du pilote auprès de la pile de pilotes USB. Pour créer un handle USBD, appelez USBD_CreateHandle. En règle générale, le pilote client crée le handle USBD dans sa routine AddDevice .
Vous pouvez rechercher la fonctionnalité MDL chaînée dans le gestionnaire de IRP_MN_START_DEVICE du pilote client ou à tout moment. Le pilote client ne doit pas interroger cette fonctionnalité dans sa routine AddDevice .
Instructions
Appelez la routine USBD_QueryUsbCapability pour déterminer si la pile de pilotes USB prend en charge la fonctionnalité DEDL chaînée. Pour rechercher cette fonctionnalité, spécifiez UsbCapabilityChainedMdls comme GUID. Définissez le paramètre OutputBuffer sur NULL et le paramètre OutputBufferSize sur 0.
Vérifiez la valeur NTSTATUS retournée par USBD_QueryUsbCapability et évaluez le résultat. Si la routine se termine correctement, la fonctionnalité DEM chaînée est prise en charge. Toute autre valeur indique que la fonctionnalité n’est pas prise en charge.
Créez la chaîne de DLL. Chaque MDL a un pointeur Next qui pointe vers une autre MDL.
Le pilote peut générer une chaîne MDL en définissant manuellement le pointeur Suivant .
Dans l’exemple précédent, le pilote de protocole envoie le paquet en tant que MDL. Le pilote intermédiaire peut créer un autre MDL qui référence le bloc de mémoire avec les données d’en-tête. Pour créer une chaîne, le pilote intermédiaire peut pointer le pointeur Suivant de l’en-tête MDL vers le MDL reçu du pilote de protocole. Le pilote intermédiaire peut ensuite transférer la chaîne de deux MDL au pilote miniport, qui fournit une référence à la MDL chaînée dans l’URB pour la demande et envoie la demande à la pile de pilotes USB. Pour plus d’informations, consultez Utilisation de DLL.
Lors de la création d’un URB pour une demande d’E/S qui utilise des DLL chaînées, définissez le membre TransferBufferMDL de la structure URB associée (par exemple , _URB_BULK_OR_INTERRUPT_TRANSFER ou _URB_ISOCH_TRANSFER) sur la première MDL de la chaîne, puis définissez TransferBufferLength sur le nombre total d’octets à transférer. Les données peuvent s’étendre sur plusieurs entrées MDL dans la chaîne MDL.
Dans Windows 8, deux nouveaux types de fonctions URB ont été ajoutés pour permettre à un pilote client d’utiliser des DLL chaînées pour les transferts de données. Si vous souhaitez utiliser cette fonctionnalité, assurez-vous que le membre Function de l’en-tête URB est défini sur l’une des fonctions URB suivantes :
- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER_USING_CHAINED_MDL
- URB_FUNCTION_ISOCH_TRANSFER_USING_CHAINED_MDL
Pour plus d’informations sur ces fonctions URB, consultez _URB_HEADER.
Remarques
Pour obtenir un exemple de code qui interroge la pile de pilotes USB sous-jacente pour déterminer si la pile de pilotes peut accepter des DLL chaînées, consultez USBD_QueryUsbCapability.