USB批量流¶
背景¶
批量端点流在USB 3.0规范中添加。流允许设备驱动程序重载批量端点,以便可以一次排队多个传输。
流在通用串行总线3.0规范的4.4.6.4和8.12.1.4节中定义,网址为https://www.usb.org/developers/docs/。USB连接的SCSI协议使用流来排队多个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,请不要调用此函数。 不要调用此函数来请求少于两个流。
驱动程序只能针对同一端点调用此API一次,而无需调用usb_free_streams()。 这是对xHCI主机控制器驱动程序的简化,将来可能会更改。
选择要使用的新流ID¶
流ID 0是保留的,不应用于与设备通信。 如果usb_alloc_streams()返回值为N,则可以使用流1到N。 要为特定流排队URB,请设置urb->stream_id值。 如果端点不支持流,将返回一个错误。
请注意,如果xHCI驱动程序支持辅助流ID,则必须添加新的API来选择下一个流ID。
清理¶
如果驱动程序希望停止使用流与设备通信,它应该调用
void usb_free_streams(struct usb_interface *interface,
struct usb_host_endpoint **eps, unsigned int num_eps,
gfp_t mem_flags);
当驱动程序释放接口时,所有流ID将被释放,以确保不支持流的驱动程序能够使用该端点。