处理 USB 主控制器驱动程序中的 I/O 请求

用于处理 UCX 发送的 I/O 请求的主机控制器驱动程序的最佳做法。

UCX 跟踪 USB 总线上设备的主机控制器驱动程序创建的所有终结点。 中心驱动程序或 USB 设备堆栈中更高版本的其他驱动程序发送的任何数据传输请求首先由 UCX 处理。 UCX 负责将框架请求对象转发到正确的终结点队列。 请求中包含的 USB 请求块(URB)可以指定终结点句柄。 如果指定了端点句柄,UCX 会检查与设备相关的终结点中是否存在相应的终结点。 如果存在指定的终结点句柄,则请求将转发到终结点的队列。 如果未找到指定的终结点句柄,则请求将失败。 如果未指定句柄,则请求为默认终结点,UCX 会将请求转发到主机控制器驱动程序的默认终结点队列。

若要确保与现有 USB 驱动程序兼容,主机控制器在完成 URB 请求时必须符合以下要求:

  • 必须在DISPATCH_LEVEL调用 WdfRequestComplete
  • 如果 URB 已被放入其框架队列,并且驱动程序开始在调用方驱动程序的线程或 DPC 上同步处理它,则不应同时同步完成请求。 请求必须在单独的 DPC 上完成,可以通过调用 WdfDpcEnqueue 来进行调度。
  • 与上述要求类似,在收到 EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUEEVT_WDF_REQUEST_CANCEL后,主机控制器驱动程序必须在与调用线程或 DPC 不同的 DPC 上完成 URB 请求。 默认情况下,WDF 以同步方式完成队列上已取消的请求。 该行为可能会导致 URB 请求出现问题。 因此,驱动程序必须为其 URB 队列提供 EvtIoCanceledOnQueue 回调。

IOCTL_INTERNAL_USB_SUBMIT_URB的框架请求对象包含位于请求的 Parameters.Others.Arg1 处的 URB。 请求完成后,必须将 URB 状态设置为 USBD_STATUS_SUCCESS,或者设置为能够指示失败性质的相应失败状态。 失败状态值在 usb.h 头文件中定义。