SPB の I/O 要求

I/O 制御コードの定義」で説明されているシステム提供の CTL_CODE マクロは、spb.h で IOCTL_SPB_* 制御コードを定義するのに使用されます。

IOCTL_SPB_EXECUTE_SEQUENCE 制御コード

IOCTL_SPB_EXECUTE_SEQUENCE I/O 制御コードを使用すると、SPB コントローラー ドライバーのクライアント (周辺機器ドライバー) は、1 つの I/O 要求で 1 つのアトミック操作として一連の転送 (読み取りと書き込み) を実行できます。 バス上の指定されたデバイスは、シーケンス内のすべての転送のターゲットです。

固定長転送のシーケンスを単一のアトミック操作として指定することで、OCTL_SPB_EXECUTE_SEQUENCE I/O 制御要求により、コントローラー ドライバーは I/O 転送を最適化し、パフォーマンスを向上させることができます。

クライアントは、この I/O 制御要求をターゲット デバイスのファイル オブジェクトに送信します。

SPB コントローラー ドライバーは、I/O 転送シーケンスのバス転送を実行する EvtSpbControllerIoSequence コールバック関数を登録します。 SPB フレームワーク拡張機能 (SpbCx) は、この関数を呼び出して、IIOCTL_SPB_EXECUTE_SEQUENCE 要求を SPB コントローラー ドライバーに渡して処理します。

IOCTL_SPB_EXECUTE_SEQUENCE 入力バッファー

入力バッファーは、クライアントのデータ バッファーへのポインターの一覧を含む SPB_TRANSFER_LIST 構造体です。 このリストには、I/O 転送シーケンス内の各転送 (読み取りまたは書き込み) のデータ バッファーが含まれています。

IOCTL_SPB_EXECUTE_SEQUENCE 入力バッファーの長さ

SPB_TRANSFER_LIST 構造体のサイズ。

IOCTL_SPB_EXECUTE_SEQUENCE ステータス ブロック

操作が成功した場合、コントローラー ドライバーは状態メンバーを STATUS_SUCCESS に設定し、情報メンバーをシーケンス中に転送された合計バイト数に設定します。

この操作は、リソース不足、無効なクライアント入力、デバイスの誤動作など、さまざまな理由で失敗する可能性があります。

コントローラー ドライバーが I/O 要求の処理を開始したが、シーケンス内のいずれかの転送中にエラーが発生した場合 (たとえば、ターゲット デバイスが NACK に転送を拒否するよう通知するなど)、コントローラー ドライバーはシーケンス内の転送メインを中止します。 その後、ドライバーは完了状態を STATUS_SUCCESS に設定し、エラーが発生する前に正常に転送されたバイト数に情報メンバーを設定して要求を完了します。

IOCTL_SPB_FULL_DUPLEX 制御コード

IOCTL_SPB_FULL_DUPLEX 制御コードは、全二重 I/O 操作を要求するためにクライアント (周辺機器ドライバー) によって使用されます。 全二重 I/O 操作は、データの読み取りと書き込みを同時に実行できる SPI などのバス向けのコントローラーでサポートされます。 「I/O 制御コードの定義」で説明されているシステム提供の CTL_CODE マクロは、次のように IOCTL_SPB_FULL_DUPLEX を定義するのに使用されます。

バス上のデバイスのユーザー モード ドライバーまたはカーネル モード ドライバーは、ターゲット デバイスのファイル オブジェクトにこの I/O コントロール要求を送信します。

この IOCTL は、データの読み取りと書き込みを同時に行うことができる、SPI などのバス用の SPB コントローラー ドライバーでのみサポートされます。

全二重転送の書き込みバッファーと読み取りバッファーは、SPB_TRANSFER_LIST 構造体によって記述されます。 この構造体では、次の形式を使用しなければなりません。

  • SPB_TRANSFER_LIST_ENTRY 構造体の配列には、ちょうど 2 つの要素が含まれています。 最初の要素は、書き込みバッファーを記述します (Direction = SpbTransferDirectionToDevice)。 2 番目の要素は、読み取りバッファーを記述します (Direction = SpbTransferDirectionFromDevice)。

  • 2 つの SPB_TRANSFER_LIST_ENTRY 構造体の DelayInUs メンバーは 0 である必要があります。 書き込みバッファーと読み取りバッファーのバッファー形式は、次のいずれかになります。

    • SpbTransferBufferFormatSimple
    • SpbTransferBufferFormatList
    • SpbTransferBufferFormatSimpleNonPaged
    • SpbTransferBufferFormatMdl

    上記の一覧の最後の 2 つの形式は、カーネル モード クライアントでのみ使用できます。 書き込みバッファーと読み取りバッファーの形式は同じである必要はありません。 これらのバッファー形式の詳細については、SPB_TRANSFER_BUFFER_FORMAT を参照してください。

成功した操作では、Information メンバーを書き込みバッファーと読み取りバッファーのサイズの合計より小さい値に設定する場合があり、要求が取り消された場合、操作が書き込みバッファーの完全な内容をデバイスに書き込むことができない場合、または読み取りバッファーにデバイスから読み取られたデータを完全に入力できない場合に発生する可能性があります。

書き込みバッファー サイズと読み取りバッファー サイズが同じである必要はありません。 書き込みバッファーが読み取りバッファーより大きい場合、読み取りバッファーがいっぱいになった後も、操作は書き込みバッファーからデータを書き込み続けます。 読み取りバッファーが書き込みバッファーよりも大きい場合、書き込みバッファーが空になった後も、操作は読み取りバッファーを埋め続けます。

SPB コントローラー ドライバーが EvtSpbControllerIoOther コールバック関数を登録する場合、SPB フレームワーク拡張機能 (SpbCx) はこの関数を呼び出して、処理するために IOCTL_SPB_FULL_DUPLEX 要求を SPB コントローラー ドライバーに渡します。 SpbCx は、IOCTL_SPB_FULL_DUPLEX 要求に対してパラメーターのチェック、転送リストの検証、またはその他の処理を実行しません。

SPB コントローラー ドライバーがこの IOCTL のサポートを実装する方法の詳細については、「IOCTL_SPB_FULL_DUPLEX 要求の処理」を参照してください。

IOCTL_SPB_FULL_DUPLEX 入力バッファー

クライアントの入力および出力データ バッファーへのポインターを含む SPB_TRANSFER_LIST 構造体へのポインター。 この構造体には、厳密に 2 つの要素の Transfers 配列が含まれています。 最初の要素は、デバイスに書き込むデータを含むバッファーを記述します。 2 番目の要素は、デバイスから読み取られたデータを保持するのに使用されるバッファーを記述します。 SPB コントローラー ドライバーが、SPB_TRANSFER_LIST 構造体を使用してバッファーを記述するカスタム I/O コントロール (IOCTL) 要求を実装する方法の詳細については、「カスタム IOCTL のSPB_TRANSFER_LIST 構造体の使用」を参照してください。

IOCTL_SPB_FULL_DUPLEX 入力バッファーの長さ

SPB_TRANSFER_LIST 構造体のサイズ。

IOCTL_SPB_FULL_DUPLEX ステータス ブロック

操作が成功した場合、コントローラー ドライバーは、ステータス メンバーを STATUS_SUCCESS に設定し、情報メンバーに、全二重操作中に転送された合計バイト数 (読み取られたバイト数と書き込まれたバイト数) を設定します。

この操作は、リソース不足、無効なクライアント入力、デバイスの誤動作など、さまざまな理由で失敗する可能性があります。

IOCTL_SPB_LOCK_CONNECTION 制御コード

IOCTL_SPB_LOCK_CONNECTION コントロール コードは、別のクライアントと共有されている SPB に接続されたターゲット デバイスの接続ロックを取得するため、クライアント (周辺機器ドライバー) によって使用されます。 クライアントが接続ロックを保持している間、このクライアントはデバイスへの排他的アクセス権を持ちます。 「I/O 制御コードの定義」で説明されているシステム提供の CTL_CODE マクロは、次のように IOCTL_SPB_LOCK_CONNECTION を定義するのに使用されます。

IOCTL_SPB_LOCK_CONNECTION および IOCTL_SPB_UNLOCK_CONNECTION 要求は、単純な周辺機器バスに接続されているターゲット デバイスの接続ロックを取得して解放します。 ほとんどのクライアントは、これらの I/O 制御要求を使用しません。 これらの要求は、2 つのクライアントが同じターゲット デバイスへのアクセスを共有する場合にのみ使用されます。 詳細については、「SPB 接続ロック」を参照してください。

2 つのクライアントは、同じターゲット デバイスへの個別の論理接続を開き、いずれかのクライアントがデバイスへの排他的アクセスを必要とする場合に接続ロックを使用できます。 1 つのクライアントが接続ロックを保持すると、2 番目のクライアントからデバイスへの I/O 要求は、最初のクライアントがロックを解放するまで自動的に遅延されます。

クライアントは、ターゲット デバイスの接続ロックと SPB コントローラーのコントローラー ロックを同時に保持できます。 IOCTL_SPB_LOCK_CONTROLLER およ びIOCTL_SPB_UNLOCK_CONTROLLER 要求は、コントローラー ロックを取得して解放します。 クライアントは、コントローラー ロックを取得する前に接続ロックを取得する必要があり、接続ロックを解放する前にコントローラー ロックを解放する必要があります。 クライアントは、コントローラー ロックを使用して、1 つのアトミック バス操作として、順序付けられたバス転送 (読み取りおよび書き込み操作) のセットを実行します。 詳細については、「I/O転送シーケンス 」を参照してください。

接続がデバイスでロックされている間に IRP_MJ_CLEANUP 要求がターゲット デバイスに送信されると、接続ロックは自動的に終了します。 クライアントがデバイスへのファイル ハンドルを閉じると、クリーンアップ 要求がターゲット デバイスに送信されます。

IOCTL_SPB_LOCK_CONNECTION ステータス ブロック

操作が成功した場合、ステータス メンバーは STATUS_SUCCESS に設定されます。

操作が失敗した場合、ステータス メンバーは適切なエラー状態コードに設定されます。

クライアントがターゲット デバイスの接続ロックまたは SPB コントローラーのコントローラー ロックを既に保持している場合、この操作は Status = STATUS_INVALID_DEVICE_REQUEST で失敗します。 この操作は、リソース不足、無効なクライアント入力、デバイスの誤動作など、他の理由で失敗する可能性があります。

IOCTL_SPB_LOCK_CONTROLLER 制御コード

IOCTL_SPB_LOCK_CONTROLLER 制御コードは、SPB コントローラーをロックするためにクライアント (周辺機器ドライバー) によって使用されます。 コントローラーがロックされている間、クライアントはバスを排他的に使用して、ロック用に指定されたターゲット デバイスにアクセスします。 「I/O 制御コードの定義」で説明されているシステム提供の CTL_CODE マクロは、次のように IOCTL_SPB_LOCK_CONTROLLER を定義するのに使用されます。

ターゲット デバイスにアクセスするバスの独占的な使用を取得するには、クライアント (周辺機器ドライバー) は、ターゲットのファイル オブジェクトにこの IOCTL を送信します。 この IOCTL が完了すると、コントローラーがロックされ、バス上のすべての I/O 転送 (読み取りまたは書き込み) が指定されたターゲットにアクセスします。 転送間では、コントローラーはターゲット デバイスを選択したままですが、クロックを停止します。

クライアントがコントローラーのロックを解除する IOCTL_SPB_UNLOCK_CONTROLLER 要求を送信するまで、コントローラーはロックされたままになります。 クライアントのターゲット デバイスとの一連の転送が完了したら、コントローラーがバス上にある他のターゲットに対する I/O 要求を処理できるように、クライアントはコントローラーのロックを解除する必要があります。

コントローラーがターゲットでロックされている間に IRP_MJ_CLEANUP 要求がターゲット デバイスに送信されると、ロックは自動的に終了されます。 クライアントがターゲットへのハンドルを閉じると、クリーンアップ要求がターゲットに送信されます。

SPB コントローラーは、IOCTL_SPB_LOCK_CONTROLLER 要求と IOCTL_SPB_UNLOCK_CONTROLLER 要求をサポートする必要はありません。周辺機器ドライバーは、それらがサポートされていると想定しないでください。

SPB コントローラー ドライバーが EvtSpbControllerLock コールバック関数を登録する場合、SPB フレームワーク拡張機能 (SpbCx) はこの関数を呼び出して、処理するために IOCTL_SPB_LOCK_CONTROLLER 要求を SPB コントローラー ドライバーに渡します。

IOCTL_SPB_LOCK_CONTROLLER ステータス ブロック

操作が成功した場合、ステータス メンバーは STATUS_SUCCESS に設定されます。 この IOCTL は、排他的なアクセス モードで動作するようにコントローラーを構成できないなど、さまざまな理由でエラー ステータスを返すことができます。 このモードでは、コントローラーはターゲット デバイスが選択された状態で、バス上のすべての I/O 転送の排他ターゲットにします。 コントローラーは、ロックが解除されるまで、このモードのままです。

IOCTL_SPB_UNLOCK_CONNECTION 制御コード

IOCTL_SPB_UNLOCK_CONNECTION I/O 制御コードは、別のクライアントと共有されている SPB に接続されたターゲット デバイスの接続ロックを解除するために、クライアント (周辺機器ドライバー) によって使用されます。 クライアントは以前、デバイスへの排他的アクセスを取得するために IOCTL_SPB_LOCK_CONNECTION 要求を送信しました。

IOCTL_SPB_LOCK_CONNECTION および IOCTL_SPB_UNLOCK_CONNECTION 要求は、単純な周辺機器バスに接続されているターゲット デバイスの接続ロックを取得して解放します。 ほとんどのクライアントは、これらの I/O 制御要求を使用しません。 これらの要求は、2 つのクライアントが同じターゲット デバイスへのアクセスを共有する場合にのみ使用されます。 詳細については、「SPB 接続ロック」を参照してください。

クライアント (周辺機器ドライバー) がバス上のターゲット デバイスに IOCTL_SPB_LOCK_CONNECTION 要求を送信し、要求が正常に完了した場合、クライアントが接続のロックを解除する IOCTL_SPB_UNLOCK_CONNECTION 要求を送信するまで、接続はロックされたままです。

クライアントは、クライアントがデバイスへの排他的なアクセスを必要としない場合に、接続ロックを解除する IOCTL_SPB_UNLOCK_CONNECTION 要求をターゲット デバイスに送信します。 他のクライアントがデバイスにアクセスできるように、接続ロックを解除する必要があります。

IOCTL_SPB_UNLOCK_CONNECTION ステータス ブロック

操作が成功した場合、ステータス メンバーは STATUS_SUCCESS に設定されます。

操作が失敗した場合、ステータス メンバーは適切なエラー状態コードに設定されます。 クライアントがターゲット デバイスの接続ロックを保持していない場合、またはクライアントが SPB コントローラーの接続ロックをまだ保持している場合、この操作は Status = STATUS_INVALID_DEVICE_REQUEST で失敗します。 この操作は、リソース不足、無効なクライアント入力、デバイスの誤動作など、他の理由で失敗する可能性があります。

IOCTL_SPB_UNLOCK_CONTROLLER 制御コード

IOCTL_SPB_UNLOCK_CONTROLLER I/O 制御コードは、SPB コントローラーのロックを解除するためにクライアント (周辺機器ドライバー) によって使用されます。 クライアントは以前、バス上のターゲット デバイスにアクセスするためにバスを排他的に使用できるようコントローラーをロックしました。

クライアント (周辺機器ドライバー) が IOCTL_SPB_LOCK_CONTROLLER I/O 制御要求をバス上のターゲット デバイスに送信した後、コントローラーのロックを解除する IOCTL_SPB_UNLOCK_CONTROLLER I/O 制御要求をクライアントが送信するまで、コントローラーはロックされたままです。 クライアントは、これらの I/O 制御要求をターゲット デバイスのファイル オブジェクトに送信します。

クライアントは、バス上で一連の転送が完了し、ターゲット デバイスを解放する場合に、IOCTL_SPB_UNLOCK_CONTROLLER 要求を送信します。 バス上の他のターゲットの I/O 要求を処理できるように、コントローラーのロックを解除する必要があります。

SPB コントローラーは、IOCTL_SPB_LOCK_CONTROLLER 要求と IOCTL_SPB_UNLOCK_CONTROLLER 要求をサポートする必要はありません。周辺機器ドライバーは、それらがサポートされていると想定しないでください。

SPB フレームワーク拡張機能 (SpbCx) は、SPB コントローラー ドライバーのオプションの EvtSpbControllerUnlock コールバック関数を呼び出して、処理するための SPB コントローラー ドライバーに IOCTL_SPB_LOCK_CONTROLLER 要求を渡します。

IOCTL_SPB_UNLOCK_CONTROLLER ステータス ブロック

操作が成功した場合、ステータス メンバーは STATUS_SUCCESS に設定されます。

この IOCTL は、指定されたターゲットへの排他的なアクセス用にコントローラーがロックされていないクライアントによって送信された場合にのみ失敗します。