Обработка запросов ввода-вывода в драйвере контроллера 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.