Обработка ошибок USB XACT_ERROR и BABBLE_DETECTED
От: Yuricsson Россия  
Дата: 15.01.16 10:14
Оценка:
Здравствуйте, гуру!

Столкнулся с такой проблемой — есть устройство (на msp430f5528) с bulk-пайпом, по которому передаю в реалтайме некие данные.
Изредка выскакивает ошибка USBD_STATUS_BABBLE_DETECTED или ещё реже USBD_STATUS_XACT_ERROR. Как я понял, в этом случае нужно сделать ABORT_PIPE, подождать завершения очереди висящих запросов, потом сделать RESET_PIPE и возобновить запросы.
Всё вроде бы понятно, но запрос ABORT_PIPE формируется с помощью IoBuildDeviceIoControlRequest, которую нужно вызывать при IRQL<=APC_LEVEL, а я в момент получения ошибки нахожусь в CompletionRoutine, то есть на уровне DISPATCH_LEVEL. Погуглил интернет, вроде бы советуют самостоятельно создавать эту IRP с помощью IoAllocateIrp. Я так сделал, но запрос возвращает STATUS_PENDING, запросы продолжают себе спокойно висеть, ничего не происходит.
Ладно, я вручную отменяю свою очередь запросов без использования ABORT_PIPE, потом когда последний запрос отменяется, мне нужно сделать RESET_PIPE, но я опять нахожусь в CompletionRoutine и не могу сформировать этот запрос через IoBuildDeviceIoControlRequest. Опять создаю IRP сам, запрос опять возвращает STATUS_PENDING и всё. Все дальнейшие запросы возвращаются с ошибкой.
Кто может подсказать механизм (лучше с кусочком работающего кода) для правильного восстановления пайпа после этих ошибок?

Я использую очередь из нескольких запросов, которая крутится сама в себе с CompetionRoutine и копит данные в буфере независимо от чтения данных из user-mode.

Спасибо большое!

Юрий
Re: Обработка ошибок USB XACT_ERROR и BABBLE_DETECTED
От: Yuricsson Россия  
Дата: 19.01.16 09:11
Оценка:
Таки никто usb-драйверы не пишет?
Пока решил эту проблему небольшим "костылём". На всякий случай оставлю здесь — может кому пригодится.
В CompletionRoutine при IRQL == DISPATCH_LEVEL я отменяю свою очередь через IoCancelIrp, а не с помощью URB_FUNCTION_ABORT_PIPE. Вызвать эту функцию на IRQL == DISPATCH_LEVEL у меня так и получилось.
После того, как в очереди не остаётся висящих запросов к bulk-пайпу, выставляю флажок ResetPipeFlag в контексте трансфера и жду, когда юзер-мод соизволит прочитать данные из моего устройства. Это будет происходить через вызов DispatchRead на IRQL == PASSIVE_LEVEL. По имеющемуся флагу вызываю URB_FUNCTION_RESET_PIPE с помощью IoBuildDeviceIoControlRequest и потом возобновляю очередь запросов.
Естественно, не забываю делать IoReuseIrp для созданных вручную IRP перед повторным вызовом IoCallDriver — в этом случае это критично, потому что флаг Cancel надо очистить.
В итоге что и требовалось — юзер-мод не догадывается о проблемах. Можно, конечно, оповещать пользователя о сбоях, но это уже другая песня.
Если есть более нормальные методы, поделитесь, не жадничайте!
Re: Обработка ошибок USB XACT_ERROR и BABBLE_DETECTED
От: _f_b_i_  
Дата: 04.04.16 12:28
Оценка:
Здравствуйте, Yuricsson, Вы писали:

Y>Всё вроде бы понятно, но запрос ABORT_PIPE формируется с помощью IoBuildDeviceIoControlRequest, которую нужно вызывать при IRQL<=APC_LEVEL, а я в момент получения ошибки нахожусь в CompletionRoutine, то есть на уровне DISPATCH_LEVEL.


А почему бы не создать запрос URB вручную с помощью IoAllocateIrp() и засабмитить из CompletionRoutine?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.