uchan-nos/os-from-zero

【USBドライバー実装】ArrayMapを使わずにSetupStageTRBを取得する方法はありますか?

paulsohn opened this issue · 1 comments

先日はどうもありがとうございました。ドライバーは問題なく動作しています。

どちらかというと興味本位の質問ですが、
私の理解が正しければ、ControlIn / ControlOut メソッドではTransfer Ringに複数のTRBを積み、コントロラーのOn(Transfer)Eventでは発行元のTRBの中でSetup Stageのものを取得しています。
その取得においては、ArrayMapを使っていますが、ArrayMapってぶっちゃけ作為的すぎるのでは?
と思いArrayMapを使わない実装ができるか気になってきました。

(mikanosのUSBドライバーでArrayMapを使うもう一箇所はクラスドライバーですが、
すべてのクラスドライバーに対してOnControlCompletedを呼び出し、各クラスドライバーは引数のセットアップリクエストが自分の発行したものでなければ無視するようにすればArrayMap無しに実装できます。)

最初はChain BitをセットするとTransferEventの発行元がTDの中の先頭となるSetup Stageになるのかな、と思いましたが、実行してみたところ上手くいかないようです。

Device::OnTransferEventReceived で ArrayMap を使っている場所はここですね。
https://github.com/uchan-nos/mikanos/blob/b5f7740c04002e67a95af16a5c6e073b664bf3f5/kernel/usb/xhci/device.cpp#L233

ArrayMapってぶっちゃけ作為的すぎるのでは?

の意図がちょっと分かりませんでした。プログラミングって全部作為的だと思ってます。

USB ドライバの実装については大分忘れているので、コードを見ながらの回答です。
最終的に呼び出される USB クラスドライバの中で、setup_data を使って処理をしています。 https://github.com/uchan-nos/mikanos/blob/b5f7740c04002e67a95af16a5c6e073b664bf3f5/kernel/usb/device.cpp#L205-L222
そのためには Event 受信時に setup_data を取得する必要があります。
その方法として ArrayMap を使っていますね。

Event TRB と、それを引き起こす原因となった setup_data を紐付ける仕組みがあれば、ArrayMap でなくてもいいはずです。

すべてのクラスドライバーに対してOnControlCompletedを呼び出し、各クラスドライバーは引数のセットアップリクエストが自分の発行したものでなければ無視するようにすればArrayMap無しに実装できます。
まさにこの方法は一つの代替案かと思います。