次の方法で共有


USB パイプの使用

フレームワークは、USB インターフェイス内の各パイプをフレームワーク USB パイプ オブジェクトとして表します。 ドライバーが USB デバイスを構成すると、フレームワークは、選択した各インターフェイスの各パイプのフレームワーク USB パイプ オブジェクトを作成します。 パイプ オブジェクト メソッドを使用すると、ドライバーは次の操作を実行できます。

パイプ情報の取得

WdfUsbInterfaceGetConfiguredPipe を呼び出してフレームワーク USB パイプ オブジェクトのハンドルを取得した後、ドライバーは USB パイプ に関する情報を取得するために USB パイプ オブジェクトが定義する次のメソッドを呼び出すことができます。

WdfUsbTargetPipeGetIoTarget
USB パイプに関連付けられている I/O ターゲット オブジェクトへのハンドルを返します。 ドライバーは、このハンドルを WdfRequestSend に渡すことができます。

WdfUsbTargetPipeGetInformation
USB パイプとそのエンドポイントに関する情報を取得します。

WdfUsbTargetPipeGetType
USB パイプの型を返します。

WdfUsbTargetPipeIsInEndpoint
USB パイプが入力エンドポイントに接続されているかどうかを判断します。

WdfUsbTargetPipeIsOutEndpoint
USB パイプが出力エンドポイントに接続されているかどうかを判断します。

WDF_USB_PIPE_DIRECTION_IN
USB エンドポイントが入力エンドポイントであるかどうかを判断します。

WDF_USB_PIPE_DIRECTION_OUT
USB エンドポイントが出力エンドポイントであるかどうかを判断します。

関連情報については、「USB パイプを列挙する方法」をご参照ください。

パイプからの読み取り

USB 入力パイプからデータを読み取るために、ドライバーは次の3つの内のいずれかの方法 (またはすべて) を使用できます。

  • データを同期的に読み取る

    USB 入力パイプからデータを同期的に読み取るために、ドライバーは WdfUsbTargetPipeReadSynchronously メソッドを呼び出すことができます。 このメソッドは、読み取り要求をビルドして送信し、I/O 操作が完了した後に返されます。

  • データを非同期的に読み取る

    USB 入力パイプから非同期的にデータを読み取るために、ドライバーは WdfUsbTargetPipeFormatRequestForRead メソッドを呼び出して読み取り要求を作成できます。 その後ドライバーは、非同期的(または同期的)に要求を送信する WdfRequestSend を呼び出すことができます。

  • データを非同期的かつ継続的に読み取る。

    連続リーダーは、USB パイプで常に読み取り要求を確実に使用できるようにするフレームワークによって提供されるメカニズムです。 このメカニズムにより、非同期の要求されていない入力ストリームを提供するデバイスからドライバーが常にデータを受信する準備が整えられることを保証します。 たとえば、ネットワーク インターフェイス カード (NIC) のドライバーは、入力データを受信するために連続リーダーを使用する場合があります。

    入力パイプの連続リーダーを構成するには、ドライバーの EvtDevicePrepareHardware コールバック関数が WdfUsbTargetPipeConfigContinuousReader メソッドを呼び出す必要があります。 このメソッドは、デバイスの I/O ターゲットに対する一連の読み取り要求をキューに入れます。

    また、ドライバーの EvtDeviceD0Entry コールバック関数は、連続リーダーを開始するために WdfIoTargetStart を呼び出す必要があり、ドライバーの EvtDeviceD0Exit コールバック関数は、連続リーダーを停止するために WdfIoTargetStop を呼び出す必要があります。

    デバイスからデータを使用できるようになるたびに、I/O ターゲットは読み取り要求を完了し、I/O ターゲットがデータを正常に読み取った場合は EvtUsbTargetPipeReadComplete、I/O ターゲットがエラーを報告する場合は EvtUsbTargetPipeReadersFailed という 2 つのコールバック関数のいずれかを呼び出します。

    省略可能な EvtUsbTargetPipeReadersFailed コールバックを指定しない場合、フレームワークは別の読み取り要求を送信することで失敗した読み取り試行に応答します。 そのため、バスが読み取りを受け入れられない状態にある場合、フレームワークは、失敗した読み取りから復旧するための新しい要求を継続的に送信します。

    ドライバーが WdfUsbTargetPipeConfigContinuousReader を呼び出した後、ドライバーは WdfUsbTargetPipeReadSynchronously または WdfRequestSend を使用して、ドライバーの EvtUsbTargetPipeReadersFailed コールバック関数が呼び出され、FALSE を返さない限り、パイプに I/O 要求を送信できません。

既定では、ドライバーがパイプの最大パケット サイズの倍数ではない読み取りバッファーを指定した場合、フレームワークはエラーを報告します。 ドライバーは、WdfUsbTargetPipeSetNoMaximumPacketSizeCheck を呼び出して、読み取りバッファー サイズのこのテストを無効にすることができます。

関連情報については、以下をご覧ください。

パイプへの書き込み

USB 出力パイプにデータを書き込むには、ドライバーは、次の手法のいずれか (または両方) を使用できます。

  • 同期的にデータを書き込む

    USB 出力パイプにデータを同期的に書き込むには、ドライバーは WdfUsbTargetPipeWriteSynchronously メソッドを呼び出すことができます。 このメソッドは、書き込み要求をビルドして送信し、I/O 操作が完了した後に返されます。

  • 非同期的にデータを書き込む

    USB 入力パイプに非同期的にデータを書き込むには、ドライバーは WdfUsbTargetPipeFormatRequestForWrite メソッドを呼び出して書き込み要求を作成できます。 その後ドライバーは、非同期的に要求を送信する WdfRequestSend を呼び出すことができます

関連情報については、「USB 一括転送要求を送信する方法」をご参照ください。

パイプの停止とリセット

ドライバーは、USB パイプを停止またはリセットするには、次のメソッドを呼び出すことができます。

WdfUsbTargetPipeAbortSynchronously
USB パイプを停止する要求を同期的に送信します。

WdfUsbTargetPipeFormatRequestForAbort
USB パイプを停止する要求を書式設定します。 ドライバーは、同期的または非同期的に要求を送信する WdfRequestSend を呼び出すことができます。

WdfUsbTargetPipeResetSynchronously
USB パイプをリセットする要求を同期的に送信します。

WdfUsbTargetPipeFormatRequestForReset
USB パイプをリセットする要求を書式設定します。 ドライバーは、同期的または非同期的に要求を送信する WdfRequestSend を呼び出す必要があります。

ドライバーの USB ターゲットがエラー状態の値で I/O 要求を完了 した場合、ドライバーは次の操作を行う必要があります。

  1. ターゲットが要求を完了していない場合、パイプを停止し、ドライバーが USB ターゲットに送信した追加の I/O 要求を取り消します。

    WdfIoTargetCancelSentIo フラグを設定して WdfIoTargetStop を呼び出します。

  2. パイプに中止要求を同期的に送信します。

    WdfUsbTargetPipeAbortSynchronously を呼び出すか、WDF_REQUEST_SEND_OPTION_SYNCHRONOUS フラグを設定して WdfRequestSend が後に続く WdfUsbTargetPipeFormatRequestForAbort を呼び出します。

  3. パイプにリセット要求を同期的に送信します。

    WdfUsbTargetPipeResetSynchronously を呼び出すか、WDF_REQUEST_SEND_OPTION_SYNCHRONOUS フラグを設定して WdfRequestSend が後に続く WdfUsbTargetPipeFormatRequestForReset を呼び出します。

  4. パイプを再起動します。

    WdfIoTargetStart を呼び出します。

  5. 失敗した I/O 要求と、失敗した要求に続くすべての I/O 要求を再送信します。

多数の障害が発生した後、ドライバーは次の操作を行って USB ポートのリセットを試みる必要があります。

  1. すべてのアクティブなパイプを停止し、ドライバーが各パイプの USB ターゲットに送信した追加の I/O 要求を取り消します (ターゲットが完了していない場合)。

    アクティブなパイプごとに WdfIoTargetCancelSentIo フラグを設定して WdfIoTargetStop を呼び出します。

  2. USB ポートをリセットする要求を同期的に送信します。

    WdfUsbTargetDeviceResetPortSynchronouslyを呼び出します。

  3. パイプを再起動します。

    ドライバーが停止した各パイプに対して WdfIoTargetStart を呼び出します。

  4. 最後に失敗した I/O 要求と、失敗した要求に続くすべての I/O 要求を再送信します。

関連情報については、「USB パイプ エラーから回復する方法」をご参照ください。

パイプへの URB の送信

KMDF ドライバーが、URL を含む I/O 要求を送信して USB パイプと通信する場合、ドライバーは次のメソッドを呼び出すことができます。

WdfUsbTargetPipeSendUrbSynchronously (KMDF のみ)
URB を含む I/O 要求を同期的に送信します。

WdfUsbTargetPipeFormatRequestForUrb (KMDF のみ)
URB を含む I/O 要求を書式設定します。 ドライバーは、同期的または非同期的に要求を送信する WdfRequestSend を呼び出すことができます。

WdfUsbTargetPipeWdmGetPipeHandle (KMDF のみ)
デバイスの USBD パイプ ハンドルを返します。 一部の URB には、このハンドルが必要です。