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將被釋放,以確保不支援流的驅動程式能夠使用該端點。