USB 批量流¶
背景¶
批量端点流是在 USB 3.0 规范中添加的。流允许设备驱动程序重载批量端点,以便可以一次排队多个传输。
流在通用串行总线 3.0 规范的 4.4.6.4 和 8.12.1.4 节中定义,网址为 https://www.usb.org/developers/docs/。使用流来排队多个 SCSI 命令的 USB 附加 SCSI 协议可以在 T10 网站上找到 (https://t10.org/)。
设备端影响¶
一旦缓冲区被排队到流环中,设备就会收到通知(通过另一个端点上的带外机制),表示该流 ID 的数据已准备就绪。然后设备告诉主机它想要启动哪个“流”。主机也可以在没有设备请求的情况下启动流上的传输,但设备可以拒绝该传输。设备可以随时在流之间切换。
驱动程序影响¶
int usb_alloc_streams(struct usb_interface *interface,
struct usb_host_endpoint **eps, unsigned int num_eps,
unsigned int num_streams, gfp_t mem_flags);
设备驱动程序将调用此 API 来请求主机控制器驱动程序分配内存,以便驱动程序可以使用最多 num_streams 个流 ID。它们必须传递一个 usb_host_endpoints 数组,该数组需要使用类似的流 ID 进行设置。这是为了确保 UASP 驱动程序能够为双向命令序列中使用的批量 IN 和 OUT 端点使用相同的流 ID。
返回值是一个错误条件(如果其中一个端点不支持流,或者 xHCI 驱动程序耗尽了内存),或者主机控制器为此端点分配的流的数量。xHCI 主机控制器硬件声明它可以支持多少个流 ID,并且 SuperSpeed 设备上的每个批量端点都会说明它可以处理多少个流 ID。因此,驱动程序应该能够处理分配给它们的流 ID 少于它们请求的流 ID 的情况。
如果您为作为参数传入的任何端点排队了 URB,请不要调用此函数。不要调用此函数来请求少于两个流。
在不调用 usb_free_streams()
的情况下,驱动程序只能对同一端点调用此 API 一次。这是对 xHCI 主机控制器驱动程序的简化,将来可能会发生变化。
选择要使用的新流 ID¶
流 ID 0 是保留的,不应用于与设备通信。如果 usb_alloc_streams()
返回值 N,则可以使用流 1 到 N。要为特定流排队 URB,请设置 urb->stream_id 值。如果端点不支持流,则会返回错误。
请注意,如果 xHCI 驱动程序支持辅助流 ID,则必须添加用于选择下一个流 ID 的新 API。
清理¶
如果驱动程序希望停止使用流与设备通信,它应该调用
void usb_free_streams(struct usb_interface *interface,
struct usb_host_endpoint **eps, unsigned int num_eps,
gfp_t mem_flags);
当驱动程序释放接口时,所有流 ID 将被取消分配,以确保不支持流的驱动程序能够使用该端点。