Обработка запросов ввода-вывода в драйвере USB-контроллера узла

Рекомендации по работе с драйвером контроллера узла для обработки запросов ввода-вывода, отправляемых UCX.

UCX отслеживает все конечные точки, созданные драйвером хост-контроллера для устройств на USB-шине. Все запросы на передачу данных, отправленные драйвером концентратора или другим драйвером, который находится выше в стеке USB-устройств, сначала обрабатываются UCX. UCX отвечает за пересылку объекта запроса платформы в правильную очередь конечной точки. Блок запроса USB (URB), содержащийся в запросе, может указывать дескриптор конечной точки. Если указан дескриптор конечной точки, UCX проверяет наличие соответствующей конечной точки среди конечных точек, присутствующих на устройстве. Если указан дескриптор конечной точки, запрос перенаправляются в очередь конечной точки. Если указанный дескриптор конечной точки не найден, запрос завершается ошибкой. Если дескриптор не указан, запрос предназначен для конечной точки по умолчанию, а UCX перенаправит запрос в очередь конечной точки по умолчанию драйвера хост-контроллера для этого устройства.

Чтобы обеспечить совместимость с существующими USB-драйверами, контроллер узла должен соответствовать следующим требованиям при выполнении запроса URB:

  • WdfRequestComplete необходимо вызвать в DISPATCH_LEVEL.
  • Если URB был доставлен в очередь платформы и драйвер начал синхронно обрабатывать его в потоке вызывающего драйвера или DPC, запрос также не должен выполняться синхронно. Запрос должен быть выполнен в отдельном DPC, который можно запланировать с помощью вызова WdfDpcEnqueue.
  • Аналогично предыдущему требованию, при получении EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE или EVT_WDF_REQUEST_CANCEL драйвер хост-контроллера должен выполнить запрос URB для отдельного DPC из вызывающего потока или DPC. По умолчанию WDF выполняет отмененные запросы в очереди синхронно. Такое поведение может вызвать проблемы с запросами URB. По этой причине драйвер должен предоставить обратный вызов EvtIoCanceledOnQueue для очередей URB.

Объект запроса платформы для IOCTL_INTERNAL_USB_SUBMIT_URB содержит URB, расположенный в разделе Parameters.Others.Arg1 запроса. После завершения запроса для состояния URB должно быть задано значение USBD_STATUS_SUCCESS или состояние сбоя, которое указывает на характер сбоя. Значения состояния сбоя определяются в файле заголовка usb.h.