WindowsでUSBデバイスディスクリプタリクエスト失敗:バスレベル証拠でCode 43をデバッグ

WindowsのUSBデバイスディスクリプタリクエスト失敗、Code 43、不正ディスクリプタ、列挙タイムアウト、電源問題、ファームウェアクラッシュを、USBキャプチャ証拠で調査する方法を解説します。

USBデバイスディスクリプタリクエスト失敗, Code 43, Windows USB, USB列挙, デバイスディスクリプタ, USB診断

「Unknown USB Device (Device Descriptor Request Failed)」は最もよく見るWindows USBエラーのひとつです。デバイスマネージャにはCode 43が出ることも。デバイスは「不明デバイス」として現れたり、接続直後に失敗したり、あるマシンでは動くが別のマシンでは動かなかったりします。Windowsはユーザー向けラベルしか出さず、バスレベルの理由は教えてくれないため、USB Device Descriptor Request FailedWindows Code 43 USBdevice descriptor request failed fixUSB enumeration failed で検索されることになります。

ディスクリプタリクエストはUSB列挙の中でも最初期のステップです。これが失敗すると、ホストはデバイスが何かを判別できません。クラスドライバ/アプリ/シリアルポート/HIDレポート/ベンダープロトコルのどれよりも前の段階です。

Bus Scopeが効くのは、この種の問題で重要な証拠がアタッチ直後の最初のコントロール転送にあるからです。

Windowsがやろうとしていること

USBデバイスが挿入されると、ホストはアタッチを検出し、ポートをリセットし、デバイスディスクリプタを要求します。デバイスディスクリプタには基本的な識別情報と能力が含まれます。

  • USBバージョン
  • デバイスクラス/サブクラス/プロトコル
  • エンドポイントゼロの最大パケットサイズ
  • Vendor ID
  • Product ID
  • デバイスリリース番号
  • 製造者文字列インデックス
  • 製品文字列インデックス
  • シリアル番号文字列インデックス
  • コンフィギュレーション数

Windowsがこのディスクリプタを安定して読み出せなければ、「Device Descriptor Request Failed」と報告します。

失敗が意味しうるもの

このエラーの原因はさまざまです。

  • デバイスファームウェアがエンドポイントゼロで応答しない
  • 不良または不安定なUSBケーブル
  • 電源不足
  • 列挙中にデバイスリセット
  • ディスクリプタ内容が壊れている/矛盾
  • エンドポイントゼロの最大パケットサイズ問題
  • リセット復旧時のタイミング問題
  • ハブ/ポート互換性問題
  • USB 2.0とUSB 3.xのネゴシエーション問題
  • 電気的破損/ハードウェア欠陥
  • ホストコントローラドライバの問題

同じWindowsラベルが多くの根本原因を覆い隠しています。だからパケット証拠が大事です。

初期列挙シーケンス

正常な初期列挙はだいたい次の形です。

Port attach
Port reset
GET_DESCRIPTOR(Device, first 8 bytes)
SET_ADDRESS
GET_DESCRIPTOR(Device, full)
GET_DESCRIPTOR(Configuration)
SET_CONFIGURATION

ホストコントローラやWindowsバージョンで多少違いはありますが、パターンは似ています。最初の GET_DESCRIPTOR が失敗すると、ホストは通常のデバイスセットアップに到達しません。

最初の8バイトが重要

ホストはまずデバイスディスクリプタの最初の8バイトを読んで、エンドポイントゼロのパケットサイズを学習します。このリクエストが失敗したり、一貫性のないデータを返したりすると、列挙が止まります。

ファームウェア開発者がフルディスクリプタの応答だけテストして、この短い初期リクエストを見落とすことがあります。あるホストでは動きますが別のホストでは失敗する——タイミングとリクエスト長が違えばそれは起きます。

確認ポイント:

  • 最初のディスクリプタリクエストに何の応答もない
  • 妥当な応答が期待される場面でショートパケット
  • エンドポイントゼロのSTALL
  • タイムアウトのあとリセット
  • ディスクリプタ長が想定構造と合わない
  • 試行ごとにディスクリプタデータが変わる

電源とリセットループ

デバイスの電源投入が遅かったり、電流を過剰に引いたりすると、列挙中にリセットすることがあります。Windowsはリトライし、結果としてループになります。

Attach
Reset
GET_DESCRIPTOR
Timeout
Reset
GET_DESCRIPTOR
Timeout
Unknown USB Device

エラーがデバイスマネージャに出るため、ユーザーはドライバ問題と思いがちです。しかしディスクリプタが一度も読まれていないなら、通常のドライバはまだ関与していません。

短い直結ケーブル、別ポート、給電ハブ、別ホストを試すのは有用ですが、キャプチャは必ず残してください。トレースを見れば、デバイスがディスクリプタ応答の前と後のどちらで落ちたかが分かります。

不正なディスクリプタ

ディスクリプタバイトを返しているものの無効な場合、Windowsはそのデバイスを拒否することがあります。例:

  • bLength が誤り
  • ディスクリプタ種別が誤り
  • コンフィギュレーションのトータル長不一致
  • エンドポイントディスクリプタの欠落
  • インターフェース数の不一致
  • 最大パケットサイズが無効
  • 文字列ディスクリプタ長不一致
  • サポートされないUSBバージョンの主張

不正ディスクリプタは、カスタムファームウェア/開発ボード/FPGA USBコア/手書きUSBスタックで特に多いです。

Bus Scopeは、汎用デバイスマネージャのエラーに頼らず、ディスクリプタ内容そのものを直接観察する手助けをします。

Linuxで動くのにWindowsで動かない理由

Linuxでは列挙できてもWindowsで失敗するデバイスは、ホストによって許容度が違うためです。Windowsはディスクリプタ一貫性のチェックが厳しいことがあります。Linuxはタイミング問題を覆い隠すようなリトライをします。OSごとに挙動が違うクラスドライバ機能に依存しているデバイスもあります。

「Windowsが間違っている」「デバイス側は問題ない」と結論しないでください。列挙トレースを比較しましょう。リクエスト順/タイミング/ディスクリプタ長/リセット挙動に差が見えることが多いです。

デバッグチェックリスト

次の流れで作業します。

  1. 接続前からキャプチャを開始する
  2. 最初のデバイスディスクリプタリクエストに応答があるかを確認する
  3. エンドポイントゼロがストール/タイムアウトするかを確認する
  4. ディスクリプタバイトの長さと種別を確認する
  5. ポートリセットの繰り返しを確認する
  6. ポート直結とハブ経由を比較する
  7. USB 2.0とUSB 3.xポートで比較する
  8. 別のケーブルで試す
  9. WindowsとLinuxの列挙トレースを比較する
  10. カスタムファームウェアの場合、短いディスクリプタ読み取りを明示的にテストする

バグレポートに含めるべきもの

有用なレポートには次を含めます。

  • Windowsのエラー文言とCode 43(該当する場合)
  • 読み取れた場合のデバイスVID/PID
  • 最初の8バイトディスクリプタリクエストが成功したか
  • 失敗前の最後の成功USBリクエスト
  • リセットが繰り返すか
  • ケーブル/ハブ/ポートの詳細
  • 失敗後だけでなく接続時周辺のキャプチャ

これでファームウェア/ドライバチームが動ける証拠になります。

最終的な診断

「USB Device Descriptor Request Failed」は、列挙のごく初期にホストが失敗したことを意味します。根本原因は、ファームウェア/ディスクリプタ構造/タイミング/エンドポイントゼロ挙動/電源/ケーブル/ハブ/ホスト互換性のいずれか。アプリ側のせいにするにはまだ早すぎます。

Bus Scopeは、正しいワークフローを支えます。最初のコントロール転送を観察し、列挙シーケンスを保全し、Windowsの汎用ラベルではなくUSBバスから診断する。