Écriture de routines DPC
Les principales responsabilités des routines DpcForIsr et CustomDpc sont de s’assurer que l’opération d’E/S d’appareil suivante est démarrée rapidement et de terminer l’IRP actuelle.
Le travail supplémentaire effectué par une routine DpcForIsr ou CustomDpc dépend de la conception du pilote et de la nature de l’appareil. Par exemple, une routine DpcForIsr ou CustomDpc peut également effectuer l’une des opérations suivantes :
Réessayez une opération qui a expiré ou a échoué.
Appelez IoAllocateErrorLogEntry, configurez un paquet de journal d’erreurs pour signaler une erreur d’E/S d’appareil, puis appelez IoWriteErrorLogEntry.
Pour plus d’informations sur la gestion des erreurs d’E/S, consultez Erreurs de journalisation.
Si le pilote utilise des E/S mises en mémoire tampon, ou si l’IRP spécifie une opération de contrôle de périphérique, transférez les données lues de l’appareil vers la mémoire tampon système sur Irp-AssociatedIrp.SystemBuffer> avant de terminer l’IRP.
Si le pilote utilise des E/S directes et doit diviser les transferts volumineux en morceaux plus petits, enregistrez l’état de chaque opération de transfert partiel juste terminée, calculez la plage de transfert partiel suivante et utilisez une routine SynchCritSection fournie par le pilote pour programmer l’appareil en vue de la prochaine opération de transfert partiel.
Même un pilote qui utilise des E/S mises en mémoire tampon peut avoir à fractionner une demande de transfert si son appareil a des fonctionnalités de transfert limitées.
Si le pilote utilise la DMA basée sur les paquets, appelez FlushAdapterBuffers après chaque opération de transfert d’appareil, puis appelez FreeAdapterChannel ou FreeMapRegisters lorsqu’une séquence de transferts partiels est effectuée et que la demande de transfert complète est satisfaite.
Si un transfert demandé n’est satisfait qu’en partie par une seule opération DMA, la routine DpcForIsr ou CustomDpc est généralement responsable de la configuration d’une ou plusieurs opérations DMA jusqu’à ce que le nombre d’octets spécifié par l’IRP ait été entièrement transféré.
Pour plus d’informations sur l’utilisation de DMA, consultez Objets adaptateurs et DMA.
Si le pilote utilise des E/S programmées (PIO), appelez KeFlushIoBuffers à la fin de chaque opération de transfert si l’IRP actuel demande une lecture.
Si un transfert demandé n’est que partiellement satisfait par une seule opération PIO, la routine DpcForIsr ou CustomDpc est généralement responsable de la configuration d’une ou plusieurs opérations de transfert jusqu’à ce que le nombre d’octets spécifié par l’IRP ait été entièrement transféré.
Pour plus d’informations sur l’utilisation de PIO, consultez Utilisation d’E/S directes.
Si un pilote non-WDM a une routine ControllerControl , appelez IoFreeController lorsqu’une opération demandée est terminée.
Notez qu’une routine DpcForIsr ou CustomDpc effectue généralement la plupart du traitement des E/S du périphérique du pilote pour satisfaire les IRP. Ces routines partagent également une partie de la responsabilité de mettre en file d’attente les IRP sur l’appareil avec les routines de répartition du conducteur.
Tenez compte des instructions de conception générales suivantes.
Toute routine DpcForIsr ou CustomDpc doit appeler IoStartNextPacket dès qu’elle peut effectuer cet appel en toute sécurité, c’est-à-dire sans provoquer de conflit de ressources ou de condition de concurrence avec la routine StartIo du pilote ou avec toute autre routine que la routine StartIo provoque à l’exécution.
Si un pilote gère sa propre file d’attente des IRP, sa routine DpcForIsr ou CustomDpc doit le notifier dès qu’il est sûr de mettre la file d’attente à la prochaine IRP et de configurer l’appareil pour la requête suivante.
Une routine DpcForIsr ou CustomDpc doit appeler IoStartNextPacket, ou notifier la routine de pilote appropriée quand le traitement des E/S de l’appareil pour la requête suivante peut être démarré. Selon le pilote et son appareil, cela peut se produire bien avant que la routine DpcForIsr ou CustomDpc termine l’IRP actuelle avec IoCompleteRequest, ou cela peut se produire immédiatement avant que cette routine termine l’IRP actuelle et retourne le contrôle.