ISR の記述

割り込みを生成する物理デバイスのドライバーには、少なくとも 1 つの割り込みサービス ルーチン (ISR) が必要です。 ISR は、割り込みを無効にするために、デバイスに適した操作を行う必要があります。これには、デバイスの中断の停止が含まれる可能性があります。 次に、状態を保存し、ISR が実行されるよりも低い優先順位 (IRQL) で I/O 操作を完了するために DPC をキューに格納するために必要な処理のみを行う必要があります。

ドライバーの ISR は、SynchronizeIrql パラメーターで IoConnectInterruptEx に指定したシステム割り当て DIRQLSynchronizeIrql において、割り込みコンテキストで実行されます。

ISR は割り込み可能です。 システム割り当て DIRQL が高い別のデバイスは、いつでも割り込んだり、高 IRQL システム割り込みが発生したりする可能性があります。

システムは ISR を呼び出す前に割り込みのスピン ロックを取得するため、ISR は別のプロセッサで同時に実行できません。 ISR が戻った後、システムはスピン ロックを解放します。

ISR は比較的高い IRQL で実行され、現在のプロセッサで同等以下の IRQL を使用して割り込みをマスクするため、できるだけ早く制御を返す必要があります。 さらに、DIRQL で ISR を実行すると、ISR が呼び出すことができるサポート ルーチンのセットが制限されます。 詳細については、 「ハードウェアの優先度の管理」を参照してください。

通常、ISR は次の一般的な手順を実行します。

  • 割り込みの原因となったデバイスが ISR でサポートされていない場合、ISR はすぐに FALSE を返します。

  • それ以外の場合、ISR は必要に応じて割り込みをクリアし、必要なデバイス コンテキストを保存し、低い IRQL で I/O 操作を完了するために DPC をキューに入れます。 詳細については、 「BLOB と OLE オブジェクト」 を参照してください。 その後、ISR は TRUE を返す必要があります。

具体的には、デバイス I/O 操作と重複しないドライバーでは、ISR は次の操作を行う必要があります。

  1. 割り込みがスプリアスかどうかを判断します。 その場合は、すぐに FALSE を返して、中断したデバイスの ISR がすぐに呼び出されるようにします。 それ以外の場合は、割り込み処理を続けます。

  2. 必要に応じて、デバイスの割り込みを停止します。

  3. 現在の操作の I/O 処理を完了するために DpcForIsr (または CustomDpc) ルーチンが必要とするコンテキスト情報を収集します。

  4. このコンテキストは、 DpcForIsr ルーチンまたは CustomDpc ルーチンからアクセスできる領域に格納します。通常は、現在の I/O 要求の処理によって割り込みが発生したターゲット デバイス オブジェクトのデバイス拡張機能に格納します。

    ドライバーが I/O 操作と重複する場合、コンテキスト情報には、DPC ルーチンが各要求を完了するために必要なコンテキストと共に、DPC ルーチンが完了することが必要な未処理の要求の数を含める必要があります。 DPC が実行される前に別の割り込みを処理するために ISR が呼び出された場合は、DPC がまだ完了していない要求の保存済みコンテキストを上書きしないでください。

  5. ドライバーに DpcForIsr ルーチンがある場合は、現在の IRP、ターゲット デバイス オブジェクト、および保存済みコンテキストへのポインターを使用して IoRequestDpc を呼び出します。 IoRequestDpc は、IRQL がプロセッサの DISPATCH_LEVELを下回るとすぐに実行される DpcForIsr ルーチンをキューに入れます。

    ドライバーに CustomDpc ルーチンがある場合は、(CustomDpc ルーチンに関連付けられている) DPC オブジェクトへのポインターと、CustomDpc ルーチンが操作を完了するために必要とする保存済みコンテキストへのポインターを使用して KeInsertQueueDpc を呼び出します。 通常、ISR は、現在の IRP とターゲット デバイス オブジェクトへのポインターも渡します。 CustomDpc ルーチンは、IRQL がプロセッサのDISPATCH_LEVELを下回るとすぐに実行されます。

  6. デバイスが割り込みを生成したことを示す TRUE を返します。

一般に、ISR は IRP を満たすために実際の I/O 処理を行いません。 代わりに、デバイスの中断を停止し、必要な状態情報を設定し、デバイスの割り込みの原因となった現在の 要求を満たすために必要な I/O 処理を行うためにドライバーの DpcForIsr または CustomDpc をキューに入れます。

ISR は、可能な限り短い間隔で DIRQL で実行する必要があります。 このガイドラインに従って、DIRQL で実行すると、システムが割り当てた IRQL 値が小さいか等しい割り込みがすべてマスクされるため、マシン内のすべてのデバイスの I/O スループットが向上します。

ドライバーの割り込みオブジェクトの SynchronizeIrql は、ドライバーが IoConnectInterrupt を呼び出したときに指定され、ドライバーの ISR が実行される DIRQL を決定します。 詳細については、 「デバイス データへのアクセスの同期」 を参照してください。