記憶域クラス ドライバーの ReleaseQueue ルーチン
SRB_FLAGS_NO_QUEUE_FREEZE を使用して、特定の要求の記憶域クラス ドライバーの SrbFlags を除き、システム ポート ドライバーは、次のいずれかの後に特定の論理ユニットのキューを固定します。
論理ユニットが要求を実行しているときにバスのリセットが発生した。
論理ユニットが SRB の ScsiStatus メンバーでクラス ドライバーが検索できる、SCSISTAT_CHECK_CONDITIONまたはSCSISTAT_COMMAND_TERMINATED を返した。
要求がタイムアウトした。
SCSIMESS_ABORT などのバス メッセージ コマンドによって要求が終了した。
ポート ドライバーは、SrbStatus メンバー内の SRB_STATUS_QUEUE_FROZEN を含む要求を返すことによって、LU 固有のキューが固定されたことを示します。 クラス ドライバーからの新しい要求はキューに挿入できますが、キューが固定されている限り、自動センス要求のみが論理ユニットに送信されます。
これらの条件下でキューを固定すると、各記憶域クラス ドライバーは、キューに登録された他のジョブが実行される前にエラーを分析できます。 たとえば、メディアが変更された場合、キューに登録されたジョブを取り消す必要がある場合があります。 キューをフラッシュするために、ドライバーは、SRB_FLAGS_BYPASS_FROZEN_QUEUE で SrbFlags ORed を使用して要求を送信できます。
ReleaseQueue ルーチンは、固定キューを解放またはフラッシュするために IRP と SRB を割り当てて設定します。 SRB の Function メンバーは、SRB_FUNCTION_RELEASE_QUEUE または SRB_FUNCTION_FLUSH_QUEUE に設定する必要があります。このメンバーはどちらも、固定キューを解放し、ターゲット論理ユニットに対して現在キューに登録されているすべての要求を取り消します。 ポート ドライバーは、SrbStatus メンバーを SRB_STATUS_REQUEST_FLUSHED に設定して、フラッシュされたキュー内のすべての要求を完了します。
固定したキューを解放しないとデバイスにアクセスできなくなるため、ドライバーの ReleaseQueue ルーチンは、メモリ不足の状況でも成功するように設計する必要があります。 ReleaseQueue ルーチンは、まず、NonPagedPool メモリの種類で ExAllocatePool を呼び出して SRB のメモリを割り当てようとし、割り当てが失敗した場合は、ドライバーの初期化中に事前に割り当てられた SRB を使用する必要があります。 記憶域クラス ドライバーのデバイス拡張子の設定で説明されているように、記憶域クラス ドライバーのデバイス拡張子を初期化するときに予約を保持する SRB を割り当てる場合、その ReleaseQueue は、メモリ プールが少ない場合、複数の同時リリース操作が必要な場合に適切な同期メカニズムを使用して、その SRB を使用できます。
クラス ドライバーの ReleaseQueue ルーチンは、通常は IoCompletion ルーチンから非同期的に呼び出されることに注意してください。 クラス ドライバーの IoCompletion ルーチンは、固定されていないキューをフラッシュする ReleaseQueue を呼び出すことはできません。 ただし、ReleaseQueue を呼び出して固定されていないキューを解放できます。ポート ドライバーはそのような要求を単純に無視します。