Windows 上 USB Device Descriptor Request Failed:用总线证据排查 Code 43

排查 Windows USB Device Descriptor Request Failed、Code 43、坏描述符、枚举超时、供电问题、固件崩溃——借助 USB 抓包证据。

USB Device Descriptor Request Failed, Code 43, Windows USB, USB 枚举, Device Descriptor, USB 诊断

"Unknown USB Device (Device Descriptor Request Failed)" 是 Windows 上最常见的 USB 错误之一。设备管理器里可能显示 Code 43。设备可能显示成 unknown、刚插就掉、或者 A 机器能用 B 机器不行。用户搜 "USB Device Descriptor Request Failed"、"Windows Code 43 USB"、"device descriptor request failed fix"、"USB 枚举失败"——因为 Windows 给你的是用户层的标签,不是总线层面的原因。

描述符请求是 USB 枚举最早的几步之一。如果它失败,主机甚至连设备是什么都搞不清楚。这意味着类驱动、应用软件、串口、HID 报告、厂商协议都还不是首要排查对象——故障发生在操作系统连装正常驱动的信息都不够的时候。

Bus Scope 在这个场景下有用,因为关键证据藏在 attach 之后的头几笔 Control Transfer 里。

Windows 在做什么

USB 设备插上之后,主机检测 attach、Reset 端口、要 Device Descriptor。Device Descriptor 包含基本的身份和能力信息:

  • USB 版本
  • Device Class / Subclass / Protocol
  • 端点 0 的 Max Packet Size
  • Vendor ID
  • Product ID
  • Device Release Number
  • Manufacturer 字符串索引
  • Product 字符串索引
  • Serial Number 字符串索引
  • Configuration 数量

如果 Windows 没法可靠地读到这份描述符,它就会报 "Device Descriptor Request Failed"。

失败可能意味着什么

这个错误可能源于:

  • 固件在端点 0 上不应答
  • USB 线材不好或不稳
  • 供电不足
  • 设备在枚举过程中被 Reset
  • 描述符内容畸形或不一致
  • 端点 0 的 Max Packet Size 有问题
  • Reset 恢复阶段的时序问题
  • Hub 或端口兼容性问题
  • USB 2.0 vs 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 个字节很关键

主机常常先读 Device Descriptor 的前 8 字节来学端点 0 的 Max Packet Size。如果这次请求失败或者回了不一致的数据,枚举可能就此停下。

固件开发者有时候只测完整的描述符响应,漏掉了最初的短请求。一台设备在 A 主机上能用、B 主机上不行,就是因为请求时序和长度不一样。

要查的:

  • 第一次描述符请求没有任何响应
  • 本该有效的响应是个短包
  • 端点 0 上 STALL
  • 超时之后 Reset
  • 描述符长度对不上预期结构
  • 多次请求之间描述符数据在变化

供电和 Reset 循环

如果设备上电慢或者拉电流过大,它可能在枚举过程中被 Reset。Windows 然后重试,结果就是一个循环:

Attach
Reset
GET_DESCRIPTOR
Timeout
Reset
GET_DESCRIPTOR
Timeout
Unknown USB Device

用户看到设备管理器的报错,可能以为是驱动问题。但描述符都没读到,正常驱动还没上场呢。

试试短直连线、换个端口、带电 Hub、另一台主机——但请保留抓包。Trace 能告诉你设备到底是在描述符响应之前挂的,还是之后。

畸形描述符

设备如果回了描述符字节但内容不合法,Windows 也会拒收。例子:

  • bLength
  • Descriptor Type 错
  • Configuration 总长度对不上
  • 端点描述符缺失
  • 接口数量不一致
  • Max Packet Size 不合法
  • String Descriptor 长度不匹配
  • 声称不支持的 USB 版本

畸形描述符在自定义固件、开发板、FPGA USB Core、手写 USB 协议栈里尤其常见。

Bus Scope 能让你直接看描述符内容,而不是依赖一个通用的设备管理器报错。

为什么 Linux 能用 Windows 不行

有些设备 Linux 上能枚举、Windows 上不行,因为主机的容忍度不一样。Windows 对描述符一致性的检查可能更严格。Linux 可能重试的方式刚好掩盖了时序问题。设备也可能依赖某个类驱动行为,而该行为在不同操作系统之间不一样。

不要直接下结论"Windows 错了"或者"设备没问题"。对比两份枚举 trace,差异通常能在请求顺序、时序、描述符长度或 Reset 行为里看出来。

排查清单

按这个流程:

  1. 插入之前开始抓
  2. 看第一次 Device Descriptor 请求有没有任何响应
  3. 看端点 0 是 STALL 还是超时
  4. 检查描述符字节长度和类型是否正确
  5. 看 Port Reset 是否反复
  6. 对比直连端口 vs Hub
  7. 对比 USB 2.0 和 USB 3.x 端口
  8. 换一条线试试
  9. 对比 Windows 和 Linux 的枚举 trace
  10. 固件如果是自定义的,显式测短描述符读

Bug 报告里要写什么

一份合格的报告包括:

  • Windows 错误文本和 Code 43(如果有)
  • 设备 VID / PID(如果读到了)
  • 第一次 8 字节描述符请求是否成功
  • 失败之前最后一笔成功的 USB 请求
  • Reset 是不是反复
  • 线材 / Hub / 端口细节
  • 抓包覆盖插入过程,不只是失败之后

固件和驱动团队就能拿到可操作的证据。

最终诊断

"USB Device Descriptor Request Failed" 意味着主机在枚举的最早阶段就失败了。根因可能在固件、描述符结构、时序、端点 0 行为、供电、线材、Hub 或主机兼容性。通常这时候甩锅给应用为时过早。

Bus Scope 支持正确的工作流:检查最初的 Control Transfer,保留枚举序列,从 USB 总线出发做诊断——而不是从 Windows 给的通用标签出发。