次の方法で共有


ストレージ クラス ドライバーの BuildRequest ルーチン

すべての上位レベルのカーネル モード ドライバーと同様に、記憶域クラス ドライバーは、記憶域 周辺機器への要求を処理するときに、次の下位ドライバーの IRP の I/O スタックの場所を設定する必要があります。 クラス ドライバーがシステム提供のポート ドライバーの SRB を使用して設定する IRP では、ポート ドライバーの I/O スタックの場所は次のように設定されます。

  • MajorFunction にIRP_MJ_SCSIが含まれています

  • Parameters.Scsi.Srb には、SRB へのポインターが含まれています

各クラス ドライバーは、SRB のメモリを割り当てるとともに、基になる記憶域ポート ドライバーの CDB でそれらを設定する責任も負います。 クラス ドライバーは、 ExInitializeNPageLookasideList を使用してその SRB のルックアサイド リストを設定するか、非ページ メモリの ExAllocatePool を 呼び出すことができます。 ルックアサイドリストと非ページ プールの使用についてさらに詳しく知りたい方は、「ルックアサイドリストの使用」を参照してください。

プールからメモリを割り当てる場合でも、ドライバーが作成したルックアサイド リストからメモリを割り当てる場合でも、すべてのストレージ クラス ドライバーは、SRB に割り当てるメモリを解放する役割を担います。 記憶域クラス ドライバーの IoCompletion ルーチンは、 記憶域クラス ドライバーの IoCompletion ルーチンで説明されています。通常は、SRB に割り当てられたメモリをルックアサイド リストに解放します。

クラス ドライバーの BuildRequest ルーチンは、デバイスと通信するために設定した CDB の長さを含め、SRB メンバーに適切な値を設定する必要があります。 要求センス情報を返す要求や、ドライバーが再試行する必要がある可能性がある要求の場合は、IRP で IoCompletion ルーチンを設定します。 読み取り要求または書き込み要求の場合、SrbFlags をそれぞれ適切な転送方向(SRB_FLAGS_DATA_IN または SRB_FLAGS_DATA_OUT)と論理和演算します。

BuildRequest ルーチンは、SendSrbSynchronous ルーチンと SendSrbAsynchronous ルーチンのペアで SRB を設定する責任を共有する場合があります。 つまり、 BuildRequest ルーチンは、すべての要求に対して一般的に設定される SRB メンバーを設定できます。一方、 SendSrbXxx ルーチンは、各要求の種類にのみ関連する SRB 値を設定します。 IRP が SendSrbAsynchronous ルーチンからポート ドライバーに渡される場合、IRP は、ドライバーが提供する IoCompletion ルーチンを使用して設定する必要があります。

クラス ドライバーは、読み込まれた後、ほとんどの SRB を設定し、 Function メンバーを SRB_FUNCTION_EXECUTE_SCSI に設定し、バス経由で送信されるデバイス I/O 要求を示します。

システム定義 SRB メンバーとその値の詳細については、 SCSI_REQUEST_BLOCKを参照してください。

Request Sense 用の SRB の設定

クラス ドライバーは、ターゲット コントローラーがチェック条件を返すときに、ポート ドライバーが SCSI 要求センスまたは同等の情報を返すように要求できます。 これを行うために、クラス ドライバーは SRB に SenseInfoBuffer ポインターと SenseInfoBufferLength を設定し、チェック条件が発生した場合にポート ドライバーが要求検出情報を返すことができるようにします。 ポート ドライバーは、IRP を返すときに、SRB_STATUS_AUTOSENSE_VALIDを持つ SrbStatus メンバーを設定することによって要求センス情報を返したことを示します。 InterpretSenseInfo ルーチンの詳細については、「ストレージ クラス ドライバーの InterpretRequestSense ルーチン」を参照してください。

再試行

ストレージ クラス ドライバーは、ターゲット/コントローラーのエラー、バスのリセット、または要求タイムアウトのために失敗した要求を再試行する役割を担います。 そのため、多くのクラス ドライバーは、IRP の自分の I/O スタック内の場所に再試行回数を保持します。 このようなクラス ドライバーの BuildRequest ルーチンは、 IoCompletion ルーチンを設定し、IRP をポート ドライバーに送信する前に、特定の要求の再試行制限を初期化することもできます。 RetryRequest ルーチンの詳細については、「ストレージ クラス ドライバーの RetryRequest ルーチン」を参照してください。