Séquences de transfert d’E/S
L’extension d’infrastructure SPB (SpbCx) prend en charge les séquences de transfert d’E/S. Une séquence de transfert d’E/S est un ensemble ordonné de transferts de bus (opérations de lecture et d’écriture) qui est effectué en tant qu’opération de bus atomique unique. Tous les transferts dans une séquence de transfert d’E/S accèdent au même appareil cible sur le bus. Pendant l’exécution d’une séquence, aucun autre appareil du bus n’est accessible, même si le pilote du contrôleur SPB peut recevoir des demandes d’E/S pour d’autres appareils avant la fin de la séquence de transfert d’E/S.
Un exemple de séquence de transfert d’E/S est une opération d’écriture-lecture, qui est une opération d’écriture de bus suivie d’une opération de lecture de bus. Un pilote de périphérique client peut utiliser ce type de séquence pour écrire dans un registre function-select dans un périphérique connecté À SPB, puis lire la valeur de la fonction de périphérique sélectionnée. Ces deux transferts peuvent être de longueurs différentes. Par exemple, l’opération d’écriture peut transférer un octet de données, et l’opération de lecture peut transférer de nombreux octets de données.
Types de séquences de transfert d’E/S
Un client peut lancer une séquence de transfert d’E/S de l’une des manières suivantes :
Le client peut spécifier la séquence entière dans une demande de contrôle d’E /S IOCTL_SPB_EXECUTE_SEQUENCE. Cette requête permet au pilote du contrôleur SPB d’utiliser toutes les optimisations des performances spécifiques au matériel disponibles pour effectuer la séquence de transfert. Pour plus d’informations, consultez Séquences de requêtes uniques.
Le client peut envoyer une demande de contrôle d’E /S IOCTL_SPB_LOCK_CONTROLLER pour verrouiller le contrôleur au début d’une séquence et envoyer une IOCTL_SPB_UNLOCK_CONTROLLER lorsque la séquence est terminée. Lorsque le contrôleur est verrouillé, le client envoie une demande d’E/S distincte (IRP_MJ_READ ou IRP_MJ_WRITE) pour chaque opération de lecture ou d’écriture dans la séquence. Pour plus d’informations, consultez Séquences implémentées par le client.
Dans la mesure du possible, un client doit utiliser la requête IOCTL_SPB_EXECUTE_SEQUENCE , qui est plus rapide, est moins sujette aux erreurs et réduit considérablement le temps pendant lequel les autres clients sont verrouillés hors du bus. Toutefois, un client peut utiliser les requêtes IOCTL_SPB_LOCK_CONTROLLER et IOCTL_SPB_UNLOCK_CONTROLLER s’il doit examiner la valeur qui est lue pendant l’un des transferts dans la séquence avant de lancer un transfert ultérieur dans la séquence. Dans ce cas, une conception minutieuse est nécessaire pour éviter de verrouiller d’autres clients hors du bus plus longtemps que nécessaire, et un pilote de périphérique mal conçu peut dégrader les performances globales du système.
séquences Single-Request
Pour améliorer les performances, votre pilote de contrôleur SPB doit implémenter une fonction de rappel EvtSpbControllerIoSequence pour gérer IOCTL_SPB_EXECUTE_SEQUENCE demandes. Cette approche ajoute une certaine complexité au pilote du contrôleur SPB, mais évite d’obliger le client à effectuer une séquence de transfert d’E/S sous la forme d’une série d’opérations de lecture et d’écriture individuelles alors que d’autres clients sont verrouillés hors du bus.
Notes
L’implémentation d’une fonction EvtSpbControllerIoSequence est fortement recommandée et peut devenir une exigence pour Windows 8.
L’implémentation d’une séquence de transfert est similaire à celle d’une simple opération de lecture ou d’écriture, mais nécessite également des mises à jour de l’état stocké de l’opération de séquence entre les transferts individuels dans la séquence. Une fois le premier transfert terminé, le pilote du contrôleur SPB met à jour l’état de la séquence pour sélectionner le transfert suivant dans la séquence. L’état de séquence est stocké dans le contexte de l’appareil et inclut le handle SPBREQUEST qui est passé au rappel EvtSpbControllerIoSequence . Le pilote de contrôleur SPB utilise ce handle pour obtenir les paramètres de mémoire tampon, de longueur, de direction et de position pour les transferts individuels dans la séquence. Pour plus d’informations sur l’obtention de ces paramètres, consultez SpbRequestGetTransferParameters.
Si le pilote du contrôleur SPB ne parvient pas à effectuer l’opération de IOCTL_SPB_EXECUTE_SEQUENCE demandée, il termine la demande avec un code d’échec. Si un tel échec se produit, le client peut, en option, verrouiller le bus, effectuer explicitement la séquence de transfert d’E/S sous la forme d’une série de demandes d’E/S simples, puis déverrouiller le bus. Pour plus d’informations, consultez Séquences implémentées par le client.
SpbCx vérifie les paramètres sur IOCTL_SPB_XXX requêtes qu’il reçoit des pilotes de périphériques. Pour les requêtes IOCTL_SPB_EXECUTE_SEQUENCE , SpbCx rejette à la fois les séquences vides et les séquences qui contiennent des pointeurs de mémoire tampon NULL ou des mémoires tampons de longueur nulle.
Le pilote du contrôleur SPB doit vérifier que la longueur de chaque transfert dans une séquence ne dépasse pas la limite spécifiée par le pilote. Par exemple, l’exemple de pilote SkeletonI2C dans le Kit de pilotes Windows (WDK) échoue à une demande de IOCTL_SPB_EXECUTE_SEQUENCE qui spécifie un transfert dépassant 4 Ko octets et définit le code d’état de cette requête sur STATUS_INVALID_PARAMETER. Avant de lancer une opération de séquence pour une demande de IOCTL_SPB_EXECUTE_SEQUENCE , le pilote doit valider les paramètres de tous les transferts dans la séquence afin de vérifier que l’opération peut être terminée avec succès.
SpbCx ne précède jamais un rappel EvtSpbControllerIoSequence avec un rappel EvtSpbControllerLock , et il ne suit jamais un rappel EvtSpbControllerIoSequence avec un rappel EvtSpbControllerUnlock .
séquences Client-Implemented
Un client d’un pilote de contrôleur SPB peut effectuer explicitement une séquence de transfert d’E/S sous la forme d’une série de lectures et d’écritures simples. Le client peut être un pilote en mode noyau ou un pilote en mode utilisateur qui contrôle un périphérique attaché au bus. Avant le premier transfert de la séquence, le client envoie une demande de IOCTL_SPB_LOCK_CONTROLLER à l’appareil cible pour empêcher d’autres accès de bus non liés entre les transferts dans la séquence. Ensuite, le client envoie IRP_MJ_READ et IRP_MJ_WRITE demandes pour effectuer les transferts dans la séquence. Enfin, le client envoie une demande de IOCTL_SPB_UNLOCK_CONTROLLER pour libérer le verrou.
Un client peut avoir besoin d’implémenter ce type de séquence de transfert d’E/S si un transfert ultérieur dans la séquence a une dépendance sur un transfert antérieur. Par exemple, la première lecture peut indiquer le nombre d’octets supplémentaires à lire ou écrire par la suite. Toutefois, s’il n’existe aucune dépendance de ce type, le client doit envoyer une demande de IOCTL_SPB_EXECUTE_SEQUENCE au pilote du contrôleur SPB, qui peut effectuer la séquence plus efficacement.
Entre la demande IOCTL_SPB_LOCK_CONTROLLER qui démarre une séquence implémentée par le client et la demande IOCTL_SPB_UNLOCK_CONTROLLER qui met fin à la séquence, les seules demandes d’E/S que le client peut envoyer à l’appareil cible sont IRP_MJ_READ et IRP_MJ_WRITE demandes. Toute violation de cette règle est une erreur.
Les verrous SPB sont utilisés uniquement pour garantir qu’une séquence de lectures et d’écritures est effectuée en tant qu’opération de bus atomique, et doivent être utilisés exclusivement à cette fin.
Pour plus d’informations, consultez Gestion des séquences Client-Implemented.