STALL en transferencias de control USB: depurando setup packets, endpoint cero y peticiones fallidas

Cómo diagnosticar STALLs en transferencias de control USB, campos del setup packet, comportamiento del endpoint cero, class requests, vendor requests, fallos de descriptores y manejo de peticiones en el firmware.

usb control transfer stall, setup packet, endpoint zero, fallo de descriptor USB, vendor request, diagnóstico USB

Las transferencias de control USB son la base de la enumeración y de la gestión del dispositivo. Leen descriptores, asignan direcciones, seleccionan configuraciones, cambian interfaces, lanzan class requests y mandan comandos vendor-specific. Cuando una transferencia de control hace STALL, los usuarios pueden ver "USB device not recognized", "control transfer failed", "libusb control transfer error", "endpoint zero stalled" o un actualizador de firmware que se queda en la inicialización.

Búsquedas como "USB control transfer STALL", "USB setup packet debugging", "endpoint zero stall", "GET_DESCRIPTOR failed" y "vendor request stalled" suelen significar que el fallo pasó antes de que pudiera arrancar el tráfico bulk, interrupt o isochronous normal.

Bus Scope ayuda porque el setup packet explica la petición. Sin él, un STALL es solo un error genérico.

Qué contiene una transferencia de control

Una transferencia de control USB tiene etapas:

  1. Setup stage.
  2. Data stage opcional.
  3. Status stage.

El setup packet contiene:

  • bmRequestType.
  • bRequest.
  • wValue.
  • wIndex.
  • wLength.

Esos campos definen la dirección, el request type, el recipient, el código de petición, el descriptor type, la interfaz, el endpoint y la longitud de datos esperada.

Si el dispositivo hace STALL, inspecciona primero el setup packet.

El endpoint cero es especial

El endpoint cero existe para todo dispositivo USB. Se usa durante la enumeración y en operaciones de control. Si el endpoint cero se comporta mal, puede que el host nunca llegue a enlazar el driver normal.

Fallos del endpoint cero pueden aparecer como:

  • Petición de device descriptor fallida.
  • Lectura de configuration descriptor fallida.
  • String descriptor request stalled.
  • SET_CONFIGURATION fallido.
  • Class-specific request fallida.
  • Comando vendor fallido.

Para firmware a medida, la corrección del endpoint cero es innegociable.

Un STALL puede ser válido

No todo STALL es un bug. Un dispositivo puede legítimamente hacer STALL en una petición no soportada. La pregunta es si el host esperaba soporte y si el estado del dispositivo admite la petición.

Ejemplos:

  • Vendor request no soportada: el STALL puede ser correcto.
  • Índice de descriptor inválido: el STALL puede ser correcto.
  • Class request obligatoria durante enumeración: el STALL puede romper el binding de driver.
  • Petición DFU en estado incorrecto: el STALL puede indicar un desajuste de state machine.

El significado depende del request type y del timing.

Fallos en peticiones de descriptor

Los STALLs de descriptor son habituales en stacks USB a medida. Fíjate en:

  • Descriptor type incorrecto en wValue.
  • Índice de string no soportado.
  • Desajuste de longitud total de configuración.
  • Dispositivo que devuelve menos datos de los pedidos de forma incorrecta.
  • Dispositivo que no maneja lecturas iniciales cortas del descriptor.
  • Firmware que asume un único patrón de petición del host.

Distintos sistemas operativos piden los descriptores en órdenes distintos. Un dispositivo que funciona en Linux puede hacer STALL en una petición que Windows envía durante la enumeración.

Class y vendor requests

Las class requests se interpretan por clase USB. HID, CDC, DFU, Audio, Video, Mass Storage y dispositivos vendor-specific tienen expectativas de peticiones.

Ejemplos habituales:

  • HID GET_REPORT.
  • HID SET_REPORT.
  • CDC SET_LINE_CODING.
  • CDC SET_CONTROL_LINE_STATE.
  • DFU GETSTATUS.
  • UVC probe/commit controls.
  • Comandos vendor-specific de bootloader.

Si una class request hace STALL, comprueba si el número de interfaz en wIndex coincide con la interfaz objetivo. Los dispositivos compuestos fallan a menudo porque el host envía la petición a una interfaz y el firmware la atiende en otra.

Checklist de depuración

Usa este flujo:

  1. Captura desde el momento del plug-in.
  2. Encuentra el primer STALL en una transferencia de control.
  3. Decodifica los campos del setup packet.
  4. Determina si la petición es standard, class o vendor-specific.
  5. Determina el recipient: device, interface, endpoint u other.
  6. Comprueba wValue, wIndex y wLength.
  7. Compara con los descriptores y el estado actual del dispositivo.
  8. Mira si el STALL es esperado o fatal.
  9. Busca peticiones de recuperación como clear feature o reset.
  10. Compara el orden de peticiones del SO si el comportamiento cambia entre plataformas.

Diagnóstico final

Un STALL en transferencia de control USB no basta por sí solo. El setup packet es el ancla del diagnóstico. Dice qué petición falló, qué recipient fue direccionado, cuánta data se esperaba y si el estado del dispositivo hacía la petición válida.

Bus Scope ayuda a exponer la evidencia del endpoint cero y los setup packets para que los equipos de firmware, driver y QA puedan depurar con precisión los fallos del camino de control.