USB Device QualifierとOther Speed Configurationのデバッグ:High-Speed vs Full-Speedのディスクリプタ問題
USB Device Qualifierディスクリプタ、Other Speed Configurationディスクリプタ、High-Speed vs Full-Speedの列挙差、ディスクリプタ不一致による失敗をデバッグする方法を解説します。
Full-SpeedとHigh-Speedの両方をサポートするUSBデバイスは、「もう一方の速度での振る舞い」をきちんと記述する必要があります。ポート・ケーブル・ハブ・ホストコントローラ次第で同じ製品の挙動が変わるとき、USB Device Qualifier descriptor、Other Speed Configuration descriptor、high speed device enumerates as full speed、USB descriptor mismatch、device works on USB 2.0 but fails on hub で検索することになります。
Bus Scopeが効くのは、診断に「ディスクリプタリクエスト・実際の速度・エンドポイントのパケットサイズ・コンフィギュレーションディスクリプタ・列挙中のホスト判断」を比較する必要があるからです。
Device Qualifierディスクリプタとは
Device Qualifierディスクリプタは、High-Speed対応デバイスが「もう一方の速度でどう動くか」を記述します。デバイスが現在High-Speedなら、QualifierはFull-Speedでの振る舞いを伝えます。現在Full-Speedなら、High-Speed能力を記述できます。
重要なフィールド:
- USBバージョン
- デバイスクラス
- Subclass
- Protocol
- エンドポイントゼロの最大パケットサイズ
- コンフィギュレーション数
このディスクリプタが欠落・不正・矛盾していると、あるホストでは列挙できても、別のホストでは失敗することがあります。
Other Speed Configuration
Other Speed Configurationディスクリプタは、もう一方の速度でのコンフィギュレーション詳細を記述します。エンドポイントのパケットサイズ、ポーリング間隔、帯域の前提は速度ごとに変わります。
よくある失敗パターン:
- Full-Speedコンフィギュレーションが、High-Speedでしか意味のないエンドポイントサイズを提示
- High-Speedコンフィギュレーションがインターフェースを1つ忘れている
- Other-Speedディスクリプタ数が実コンフィギュレーションと一致しない
- ホストがディスクリプタを期待しているのにファームウェアがSTALLを返す
- ホストはデバイスを受け入れるが誤ったドライバをバインド
- あるハブでは動くが別のハブでは失敗
これらはアプリ側ログからは見えにくい厄介な問題です。
High-SpeedデバイスがFull-Speedで列挙される
サポート案件でよくあるのは「USB high-speed device detected as full-speed」というケース。原因はケーブル品質・ハブトポロジ・信号品質・ファームウェアのチャープ・電気設計・ディスクリプタ問題などさまざまです。
パケット証拠があればレイヤーを切り分けられます:
- High-Speedネゴシエーションは行われたか?
- ホストはDevice Qualifierを要求したか?
- デバイスは有効なディスクリプタバイトを返したか?
- エンドポイントディスクリプタは選択された速度と一致していたか?
- ホストはリセットして再試行したか?
- デバイスは後で別速度に再列挙したか?
トレースが「デバイスが一度もHigh-Speedに達していない」ことを示していれば、ディスクリプタ修正では足りないかもしれません。トレースが「High-Speedで列挙したがOther-Speedディスクリプタが不正」を示しているなら、ファームウェアが強く疑われます。
速度間でエンドポイントパケットサイズが不一致
エンドポイントディスクリプタは、Full-SpeedとHigh-Speedで異なることがあります。バルクエンドポイントがFull-Speedでは64バイト、High-Speedでは512バイト、というように。
失敗の症状:
- High-Speedポートでのみ転送が失敗
- 古いFull-Speedハブ経由でのみ失敗
- ファームウェアのバッファサイズがどちらか一方の速度としか合わない
- ホストドライバがファームウェア想定より大きい転送を送る
- 想定外のパケット境界でショートパケットが返る
これは wMaxPacketSize のデバッグと直結します。
複合デバイス
複合デバイスはOther-Speedディスクリプタをさらに脆くします。HID、CDC、ベンダー固有、マスストレージ、ファームウェア更新インターフェースを同居させる場合、Other-Speedツリー全体で一貫性を保つ必要があります。
典型バグ:
- どちらかの速度でInterface Association Descriptor(IAD)が抜けている
- 速度によってインターフェース番号が違う
- エンドポイントアドレスが想定外に変化
- あるインターフェースは有効なOther-Speedディスクリプタを持つが別のは持たない
- Windowsが再列挙後に別ドライバをバインドする
カスタムファームウェア製品では、コピペ由来の定番失敗です。
STALLが正解にも不審にもなりうる
サポートしていない機能を要求された場合、ディスクリプタリクエストのSTALLは正当なことがあります。ただしHigh-Speed対応デバイスで、Device QualifierやOther Speed Configuration周辺のリクエストが繰り返されるなら、要注意です。
レポートには次を残しましょう。
- リクエスト種別
- ディスクリプタ種別
wValuewIndexwLength- 返ってきたデータ
- STALL/タイムアウトのステータス
Bus Scopeはこれらのコントロール転送を、生バイトを手動デコードさせることなく読める形で提供します。
デバッグチェックリスト
次の流れで作業すると、原因に早くたどり着けます。
- 物理的な接続時からキャプチャを開始する
- 実際にネゴシエートされた速度を記録する
- Device Descriptorを確認する
- Device Qualifierディスクリプタを確認する
- Other Speed Configurationディスクリプタを確認する
- 速度間でエンドポイントパケットサイズを比較する
- インターフェース番号とエンドポイントアドレスを確認する
- ポート直結/ハブ/USB-Cドックの各経路を試す
- WindowsとLinuxの列挙挙動を比較する
- ディスクリプタリクエストの失敗とリトライを保全する
最終的な診断
USB Device QualifierとOther Speed Configurationのバグは、「ディスクリプタの一貫性」の問題です。ある速度で動くデバイスが、別の速度では動かなかったり、ハブやドックの後ろで挙動が変わったりする理由を説明します。
Bus Scopeは、ディスクリプタリクエスト・Other-Speedバイト・エンドポイントサイズ・STALL・リセット・ドライババインドの結果を、そのまま列挙の証拠として残します。