ControllerControl ルーチンの要件
その名前が示すように、 ControllerControl ルーチンはコントローラー オブジェクトに関連付けられます。 ControllerControl ルーチンが実行されると、コントローラー オブジェクトによって表されるハードウェアは解放され、コントローラー拡張機能にドライバーの ISR と共有されるコンテキストが含まれていない限り、通常、コントローラー拡張機能は別のドライバー ルーチンによってアクセスされません。
通常、 ControllerControl ルーチンは、少なくとも次の処理を行います。
ドライバーがターゲット デバイス オブジェクトのデバイス拡張機能とコントローラー拡張機能で保持するコンテキストを更新または初期化します
ドライバーが DMA を使用する場合、その ControllerControl ルーチンは、通常、各 DMA 転送のサイズに対するシステムまたはデバイスによって課される制限のために、特定の転送要求を部分的な転送に分割する必要があるかどうかを判断する役割を担います。 このような状況では、ドライバーに AdapterControl ルーチンがある場合、ControllerControl ルーチンは AllocateAdapterChannelを呼び出す役割も担います。
ドライバーが PIO を使用する場合、その ControllerControl ルーチンは、ハードウェアで必要な場合は転送要求を部分転送範囲に分割し、MDL を Irp->MdlAddress で MDL を使用して MmGetSystemAddressForMdlSafe を呼び出す役割も担います。
要求された I/O 操作用にハードウェアをプログラムします
デバイスまたはコントローラーの拡張機能に ISR からアクセスできる場合、ControllerControl ルーチンは、KeSynchronizeExecution を呼び出すことによって呼び出される SynchCritSection ルーチンを使用する必要があります。 詳細については、「クリティカル セクションの使用」を参照してください。
ドライバーにキャンセル ルーチンがある場合、その ControllerControl ルーチンもチェックする必要があります、 Irp->キャンセル現在の IRP を取り消す必要があるかどうかを判断するフィールドと、次のいずれかの操作を行います。
Irp->CancelがTRUEに設定されている場合、ControllerControlルーチンは次のことを行う必要があります。
IRP の I/O 状態ブロックで Statusに STATUS_CANCELLED を設定し、情報に 0 を設定します。
IoFreeControllerを呼び出してコントローラー オブジェクトを解放し、次のデバイス操作をすぐに開始できるようにします。
IoStartNextPacketを呼び出すか、ドライバーが独自のキューを管理する場合は、次の IRP をキューから取り出します。
取り消された IRP をIoCompleteRequestで完了し、制御を返します。
Irp->Cancel が TRUE に設定されていない場合、ControllerControl ルーチンは代わりに次の操作を行う必要があります。
IoSetCancelRoutineを呼び出して、IRP の Cancel ルーチン エントリ ポイントをNULL にリセットします。 ドライバーがデバイス オブジェクトで I/O マネージャー提供のデバイス キューを使用する場合は、この呼び出しのキャンセル スピン ロックを取得します。
KeSynchronizeExecutionを呼び出すことによって呼び出されるSynchCritSection ルーチンを使用して、要求された I/O 操作のハードウェアをプログラムします。 詳細については、「クリティカル セクションの使用を参照してください>
キャンセル可能な IRP の処理の詳細については、「 IRP のキャンセルを参照してください。
ほとんどの割り込みドリブン I/O 操作では、物理コントローラー/アダプターに接続されている異なるデバイスで重複する操作を除き、DpcForIsr またはCustomDpc ルーチンが操作と IRP を完了するため、ControllerControl ルーチンは KeepObject を返す必要があります。
現在の要求を満たす I/O 操作が完了するとすぐに、IRP を完了するルーチンは、次の要求をできるだけ早く処理できるように、IoFreeControllerと IoStartNextPacketを呼び出す必要があります。
ControllerControl ルーチン自体が IRP を完了した場合、または別のデバイス オブジェクトの操作と重複する可能性がある 1 つのターゲット デバイス オブジェクト (ディスク) に対して、ディスク シークなどの操作を設定できる場合、ControllerControl ルーチンは DeallocateObject を返す必要があります。