Écriture d’un ISR

Les pilotes pour les appareils physiques qui génèrent des interruptions doivent avoir au moins une routine de service d’interruption (ISR). L’ISR doit faire tout ce qui est approprié pour l’appareil pour ignorer l’interruption, y compris éventuellement l’arrêt de l’appareil de l’interruption. Ensuite, il ne doit faire que ce qui est nécessaire pour enregistrer l’état et mettre en file d’attente un DPC pour terminer l’opération d’E/S à une priorité inférieure (IRQL) à celle à laquelle l’ISR s’exécute.

L’ISR d’un pilote s’exécute dans un contexte d’interruption, à un certain DIRQL attribué par le système, comme spécifié par le paramètre SynchronizeIrql à IoConnectInterruptEx.

Les ISR sont interruptibles. Un autre appareil avec un DIRQL supérieur attribué par le système peut interrompre, ou une interruption de système à IRQL élevée peut se produire, à tout moment.

Avant que le système n’appelle un ISR, il acquiert le verrou de rotation de l’interruption afin que l’ISR ne puisse pas s’exécuter simultanément sur un autre processeur. Une fois l’ISR retourné, le système libère le verrou de rotation.

Étant donné qu’un ISR s’exécute à un IRQL relativement élevé, ce qui masque les interruptions avec un IRQL équivalent ou inférieur sur le processeur actuel, il doit retourner le contrôle le plus rapidement possible. En outre, l’exécution d’un ISR au niveau de DIRQL limite l’ensemble des routines de support que l’ISR peut appeler. Pour plus d’informations, consultez Gestion des priorités matérielles.

En règle générale, un ISR effectue les étapes générales suivantes :

  • Si l’appareil à l’origine de l’interruption n’est pas pris en charge par l’ISR, l’ISR retourne immédiatement FALSE.

  • Sinon, l’ISR efface l’interruption si nécessaire, en enregistrant le contexte de l’appareil nécessaire, et met en file d’attente un DPC pour terminer l’opération d’E/S à un IRQL inférieur. Pour plus d’informations, consultez Objets DPC et PDC . L’ISR doit ensuite retourner TRUE.

Plus précisément, dans les pilotes qui ne chevauchent pas les opérations d’E/S d’appareil, l’ISR doit effectuer les opérations suivantes :

  1. Déterminez si l’interruption est fallacieuse. Si c’est le cas, retournez LA VALEUR FALSE immédiatement afin que l’ISR de l’appareil qui a été interrompu soit appelé rapidement. Sinon, continuez à interrompre le traitement.

  2. Si nécessaire, arrêtez l’appareil d’interrompre.

  3. Rassemblez les informations de contexte dont la routine DpcForIsr (ou CustomDpc) aura besoin pour terminer le traitement des E/S pour l’opération en cours.

  4. Stockez ce contexte dans une zone accessible à la routine DpcForIsr ou CustomDpc , généralement dans l’extension de l’appareil de l’objet d’appareil cible pour lequel le traitement de la demande d’E/S actuelle a provoqué l’interruption.

    Si un pilote chevauche des opérations d’E/S, les informations de contexte doivent inclure un nombre de demandes en suspens que la routine DPC doit effectuer, ainsi que le contexte dont la routine DPC a besoin pour exécuter chaque requête. Si l’ISR est appelé pour gérer une autre interruption avant l’exécution de la DPC, il ne doit pas remplacer le contexte enregistré pour une requête qui n’a pas encore été effectuée par le DPC.

  5. Si le pilote a une routine DpcForIsr , appelez IoRequestDpc avec des pointeurs vers l’IRP actuel, l’objet d’appareil cible et le contexte enregistré. IoRequestDpc met en file d’attente la routine DpcForIsr à exécuter dès que l’IRQL tombe sous DISPATCH_LEVEL sur un processeur.

    Si le pilote a une routine CustomDpc , appelez KeInsertQueueDpc avec un pointeur vers l’objet DPC (associé à la routine CustomDpc ) et des pointeurs vers n’importe quel contexte enregistré dont la routine CustomDpc aura besoin pour terminer l’opération. En règle générale, l’ISR transmet également des pointeurs vers l’IRP actuel et l’objet d’appareil cible. La routine CustomDpc est exécutée dès que l’IRQL tombe en dessous de DISPATCH_LEVEL sur un processeur.

  6. Retourne TRUE pour indiquer que son appareil a généré l’interruption.

En général, un ISR n’effectue aucun traitement d’E/S réel pour satisfaire un IRP. Au lieu de cela, il empêche son appareil d’interrompre, configure les informations d’état nécessaires et met en file d’attente le DpcForIsr ou CustomDpc du pilote pour effectuer tout traitement d’E/S nécessaire pour répondre à la demande actuelle qui a provoqué l’interruption de l’appareil.

Un ISR doit s’exécuter au niveau DIRQL pendant l’intervalle le plus court possible. Suivre cette ligne directrice augmente le débit d’E/S pour chaque appareil de la machine, car l’exécution au niveau de DIRQL masque toutes les interruptions auxquelles le système a attribué une valeur IRQL inférieure ou égale.

Le SynchronIrql des objets d’interruption du pilote, spécifié lorsque le pilote appelé IoConnectInterrupt, détermine le DIRQL auquel l’ISR du pilote s’exécute. Pour plus d’informations, consultez Synchronisation de l’accès aux données d’appareil.