STALL управляющей USB-передачи: отладка setup-пакета, endpoint 0 и сбойных запросов

Как диагностировать STALL управляющих USB-передач, поля setup-пакета, поведение endpoint 0, классовые и вендорные запросы, сбои дескрипторов и обработку запросов в прошивке.

STALL управляющей USB-передачи, setup-пакет, endpoint 0, сбой дескриптора USB, вендорный запрос, диагностика USB

Управляющие USB-передачи — фундамент перечисления и управления устройством. Они читают дескрипторы, задают адреса, выбирают конфигурации, переключают интерфейсы, отправляют классовые запросы и вендорные команды. Когда управляющая передача встаёт в stall, пользователь видит «USB device not recognized», «control transfer failed», «libusb control transfer error», «endpoint zero stalled» или прошивальщик, который останавливается на инициализации.

Запросы вроде «USB control transfer STALL», «USB setup packet debugging», «endpoint zero stall», «GET_DESCRIPTOR failed», «vendor request stalled» обычно означают, что сбой произошёл раньше, чем обычные bulk-, interrupt- или изохронные передачи успели начаться.

Bus Scope полезен тем, что setup-пакет объясняет сам запрос. Без него STALL — это просто общая ошибка.

Из чего состоит управляющая передача

Управляющая передача USB проходит стадии:

  1. Setup-стадия
  2. Необязательная data-стадия
  3. Status-стадия

Setup-пакет содержит:

  • bmRequestType
  • bRequest
  • wValue
  • wIndex
  • wLength

Эти поля задают направление, тип запроса, получателя, код запроса, тип дескриптора, интерфейс, конечную точку и ожидаемый размер данных.

Если устройство встало в stall, первым делом смотрите setup-пакет.

Endpoint 0 особенный

Endpoint 0 есть у любого USB-устройства. Он используется во время перечисления и для управляющих операций. Если endpoint 0 работает неверно, хост может вообще не привязать обычный драйвер.

Сбои endpoint 0 проявляются как:

  • Сбой запроса дескриптора устройства.
  • Сбой чтения дескриптора конфигурации.
  • Stall запроса строкового дескриптора.
  • Сбой SET_CONFIGURATION.
  • Сбой классового запроса.
  • Сбой вендорной команды.

Для нестандартных прошивок корректность endpoint 0 — это не обсуждается.

STALL бывает корректным

Не каждый STALL — ошибка. Устройство может намеренно ставить stall на неподдерживаемый запрос. Вопрос в том, ожидал ли хост поддержки и позволяет ли состояние устройства выполнить запрос.

Примеры:

  • Неподдерживаемый вендорный запрос: STALL может быть корректным.
  • Неверный индекс дескриптора: STALL может быть корректным.
  • Обязательный классовый запрос во время перечисления: STALL может сломать привязку драйвера.
  • DFU-запрос в неправильном состоянии: STALL может означать рассогласование стейт-машины.

Смысл зависит от типа запроса и момента времени.

Сбои запросов дескрипторов

STALL дескрипторов часто встречаются в нестандартных USB-стеках. Следите за:

  • Неверный тип дескриптора в wValue.
  • Неподдерживаемый индекс строкового дескриптора.
  • Расхождение полной длины конфигурации.
  • Устройство некорректно возвращает меньше данных, чем просили.
  • Устройство не обрабатывает короткие первые чтения дескриптора.
  • Прошивка рассчитывает только на один сценарий запросов хоста.

Разные ОС запрашивают дескрипторы в разном порядке. Устройство, работающее в Linux, может поставить stall на запросе Windows во время перечисления.

Классовые и вендорные запросы

Классовые запросы интерпретируются классом USB. HID, CDC, DFU, Audio, Video, Mass Storage и вендорные устройства — у всех свои требования к запросам.

Частые примеры:

  • HID GET_REPORT
  • HID SET_REPORT
  • CDC SET_LINE_CODING
  • CDC SET_CONTROL_LINE_STATE
  • DFU GETSTATUS
  • UVC-управления probe/commit
  • Вендорные команды загрузчика

Если классовый запрос встал в stall, проверьте, совпадает ли номер интерфейса в wIndex с целевым интерфейсом. В составных устройствах часто хост посылает запрос одному интерфейсу, а прошивка обрабатывает его на другом.

Чек-лист отладки

Действуйте в таком порядке:

  1. Захватите с момента подключения.
  2. Найдите первый STALL управляющей передачи.
  3. Декодируйте поля setup-пакета.
  4. Определите тип запроса: стандартный, классовый или вендорный.
  5. Определите получателя: устройство, интерфейс, конечная точка или другое.
  6. Проверьте wValue, wIndex и wLength.
  7. Сравните с дескрипторами и текущим состоянием устройства.
  8. Решите, ожидаемый STALL или фатальный.
  9. Ищите запрос восстановления — clear feature или reset.
  10. Сравните порядок запросов хоста в разных ОС, если поведение различается между платформами.

Итоговый диагноз

«USB control transfer STALL» сам по себе — недостаточная информация. Setup-пакет — это точка опоры диагноза. Он говорит, какой запрос упал, к какому получателю он обращён, сколько данных ожидалось и было ли состояние устройства совместимо с запросом.

Bus Scope помогает вытащить наружу данные endpoint 0 и setup-пакета, чтобы инженеры по прошивкам, драйверам и QA могли точно отлаживать сбои управляющего пути.