none
Transaction Error から復帰について RRS feed

  • 質問

  • TechCenterに投稿していましたが、こちらの方に再質問 した方が良いといわれたので、

    再度質問させていただきます。

    【環境】
    Windows 7 Professional 32bit
    CPU:Core i 5
    チップセット:Intel HM55

    【事象】
    USB接続でタッチパネルを接続しているのですが、たまに動作が停止してしまう症状が発生します。

    USBトレースログなどを使用して色々調べると、動画再生などCPUに負荷がかかったときに、
    USB Host Controller上で、Interrupt 転送 (URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER) を実行中に、
    Transaction Error (USBD_STATUS_XACT_ERROR) が発生しており、その後の通信が正常に行えない状況と
    なっているようでした。

    そこで、下記のサイトなどを参考に、Transaction Errorから復帰を試みる処理をデバイスドライバに追加しようとしています。

    USB Transfer May Fail Due to Transaction Error
    http://support.microsoft.com/kb/960958

    USBパイプの操作
    http://msdn.microsoft.com/ja-jp/library/ff553109(VS.85).aspx

    この作業の中で別の問題が発生しました。

    上記サイトを参考に、Transaction Errorが発生したことを検出した際に復帰処理として下記を実行するように処理を追加いたしました。

    //Interruptのinパイプから同期データ受信
    WdfUsbTargetPipeReadSynchronously

    // エラー発生時はリセットを試みる
    else if (status == STATUS_UNSUCCESSFUL)

    //ターゲットを止める
    WdfIoTargetStop(WdfUsbTargetDeviceGetIoTarget(devContext->UsbDevice), WdfIoTargetCancelSentIo);

    //通信を止める
    WdfUsbTargetPipeAbortSynchronously

    //パイプリセットを行う
    WdfUsbTargetPipeResetSynchronously

    //ターゲットを再開する
    WdfIoTargetStart


    この処理を入れた状態で試すと、Transaction Errorが発生した後に上記の処理が実行されるのですが
    WdfUsbTargetPipeAbortSynchronouslyを実行したまま止まってしまう現象が発生しました。
    試しに、WdfUsbTargetPipeAbortSynchronously関数にタイムアウトを設けると、タイムアウト時間経過後に
    戻ってきます。
    しかし、タイムアウトを設けないと何も応答が無い状態で止まってしまいます。

    なぜ止まってしまうかわかりますでしょうか?

    上記の御社サイトには、タイムアウトに関する記述はありませんでしたが、
    WdfUsbTargetPipeAbortSynchronously関数には、タイムアウトを設けるべきなのでしょうか?
    また、適切なタイムアウト時間はあるのでしょうか?

    参考になるサイトなど教えて頂けると助かります。


    ちなみに該当部分のソースは下記になります。

    // required arg check
    status = WdfUsbTargetPipeAbortSynchronously(devContext->InterruptPipe, WDF_NO_HANDLE, NULL);
    if (!NT_SUCCESS(status)) {
        ErrLogL("WdfUsbTargetPipeAbortSynchronously error.[0x%X]", status);
        goto end;
    }
    DbgLog("WdfUsbTargetPipeAbortSynchronously OK.");

    if (!WdfRequestSend(Request, WdfUsbTargetDeviceGetIoTarget(devContext->UsbDevice), &RequestOptions)) {
        ErrLogL("WdfRequestSend error. After the WdfUsbTargetPipeAbortSynchronously.");
        goto end;
    }

    2012年10月9日 9:53

回答

  • 誰も返信しないようなので、とりあえず。。。。

    > なぜ止まってしまうかわかりますでしょうか?
    > 上記の御社サイトには、タイムアウトに関する記述はありませんでしたが、
    > WdfUsbTargetPipeAbortSynchronously関数には、タイムアウトを設けるべきなのでしょうか?
    > また、適切なタイムアウト時間はあるのでしょうか?

    下記サイトで公開されている WdfUsbTargetPipeAbortSynchronously メソッドの説明に、以下の一文があります。

    -----------------------------------------------
    WdfUsbTargetPipeAbortSynchronously Method
    http://msdn.microsoft.com/ja-jp/library/ff551129(v=vs.85).aspx

    Comments
    ....
    The WdfUsbTargetPipeAbortSynchronously method does not return until the request has completed,
    unless the driver supplies a time-out value in the RequestOptions parameter's WDF_REQUEST_SEND_OPTIONS structure,
    or unless an error is detected.
    ....
    -----------------------------------------------

    つまりタイムアウト設定無しで WdfUsbTargetPipeAbortSynchronously() コールが戻ってこないのは、このリクエストか完了しないから。。。ということでは?
    またタイムアウト値を設定して強制的に戻ってくるようにしたとしても、結局のところ WdfUsbTargetPipeAbortSynchronously() コールが成功するわけではないので、意味がないと思います。
    今回ご提示されているコードはかなり断片的なので、確証があるわけではありませんが、個人的には WdfUsbTargetPipeAbortSynchronously() の使用方法(呼び出し方)に問題があるのでは。。。と感じています。

    WDK 7.1.0 で提供されているサンプル ドライバの中で、osrusbfx2 と usbsamp の中に WdfUsbTargetPipeAbortSynchronously() の実装例があるようです。
    まずはそちらを参考にしてみてはいかがでしょうか?

    以上、参考になりましたら幸いに存じます。

    • 回答の候補に設定 佐伯玲 2012年10月15日 6:05
    • 回答としてマーク 佐伯玲 2012年10月22日 4:11
    2012年10月11日 10:55

すべての返信

  • 誰も返信しないようなので、とりあえず。。。。

    > なぜ止まってしまうかわかりますでしょうか?
    > 上記の御社サイトには、タイムアウトに関する記述はありませんでしたが、
    > WdfUsbTargetPipeAbortSynchronously関数には、タイムアウトを設けるべきなのでしょうか?
    > また、適切なタイムアウト時間はあるのでしょうか?

    下記サイトで公開されている WdfUsbTargetPipeAbortSynchronously メソッドの説明に、以下の一文があります。

    -----------------------------------------------
    WdfUsbTargetPipeAbortSynchronously Method
    http://msdn.microsoft.com/ja-jp/library/ff551129(v=vs.85).aspx

    Comments
    ....
    The WdfUsbTargetPipeAbortSynchronously method does not return until the request has completed,
    unless the driver supplies a time-out value in the RequestOptions parameter's WDF_REQUEST_SEND_OPTIONS structure,
    or unless an error is detected.
    ....
    -----------------------------------------------

    つまりタイムアウト設定無しで WdfUsbTargetPipeAbortSynchronously() コールが戻ってこないのは、このリクエストか完了しないから。。。ということでは?
    またタイムアウト値を設定して強制的に戻ってくるようにしたとしても、結局のところ WdfUsbTargetPipeAbortSynchronously() コールが成功するわけではないので、意味がないと思います。
    今回ご提示されているコードはかなり断片的なので、確証があるわけではありませんが、個人的には WdfUsbTargetPipeAbortSynchronously() の使用方法(呼び出し方)に問題があるのでは。。。と感じています。

    WDK 7.1.0 で提供されているサンプル ドライバの中で、osrusbfx2 と usbsamp の中に WdfUsbTargetPipeAbortSynchronously() の実装例があるようです。
    まずはそちらを参考にしてみてはいかがでしょうか?

    以上、参考になりましたら幸いに存じます。

    • 回答の候補に設定 佐伯玲 2012年10月15日 6:05
    • 回答としてマーク 佐伯玲 2012年10月22日 4:11
    2012年10月11日 10:55
  • こんにちは、apt-get さん
    フォーラムオペレータの佐伯 玲 です。

    その後お馬鹿 さんの情報はご確認いただけたでしょうか?
    参考になる情報だと思われたので勝手ながら私のほうで「回答としてマーク」とさせて頂きました。
    ご確認いただいてわからなかった点や追加の情報などございましたらこちらのスレッドへご返信くださいませ。

    宜しくお願いいたします。
    __________________________
    日本マイクロソフト株式会社 フォーラム オペレーター 佐伯 玲

    2012年10月22日 4:11