本文說明 USB 驅動程式堆疊中鏈結的 MDL 功能,以及用戶端驅動程式如何將傳輸緩衝區傳送為 MDL 結構的鏈結。
大部分的USB主機控制器都需要傳輸緩衝區幾乎連續。 幾乎連續表示緩衝區可以開始和結束頁面中的任何位置,但緩衝區的其餘部分必須開始和結束於頁面界限。 許多 USB 用戶端驅動程式都能夠符合該需求。 不過,對於某些客戶端驅動程式,特別是需要新增或移除緩衝區中或從緩衝區新增或移除其他數據的驅動程式,不建議配置傳輸緩衝區的虛擬連續記憶體。
例如,請考慮三個驅動程式的網路堆疊、網路通訊協定驅動程式、中繼驅動程式和迷你埠驅動程式。 通訊協定驅動程式會起始傳輸,並將封包傳送至堆疊中的下一個驅動程式:中繼驅動程式。 中繼驅動程式想要將自定義標頭(包含在個別的記憶體區塊中)新增至封包。 中繼驅動程式會將該標頭和接收的封包傳送至堆疊中的下一個驅動程式:迷你埠驅動程式。 迷你埠驅動程式需要與 USB 驅動程式堆疊介面,因此必須準備虛擬連續的傳輸緩衝區。 若要建立這類緩衝區,迷你埠驅動程式會配置大型緩衝區、新增自定義標頭,然後複製承載。 由於承載通常很大,因此複製整個承載可能會對效能產生重大影響。
用戶端驅動程式可以藉由將傳輸緩衝區當做 記憶體描述元清單 鏈結來克服效能影響。 Windows 8 中新的 USB 驅動程式堆疊能夠接受來自用戶端驅動程式的鏈結 MDL(請參閱 MDL)。 藉由提供鏈結的 MDL,用戶端驅動程式可以參考記憶體中不和諧的頁面,而不是執行多餘的複製作業。 此功能會移除緩衝區數目、大小和對齊限制,讓傳輸緩衝區在物理記憶體中分割。
若要使用鏈結的 MDL,用戶端驅動程式必須偵測 Windows 載入的基礎 USB 驅動程式堆疊是否支援此功能,然後依適當順序建置 MDL 鏈結。
開始之前
鏈結的 MDL 功能僅支援大量、不時和中斷傳輸。 在查詢鏈結的 MDL 功能之前,請確定您的用戶端驅動程式具有 USBD 句柄,以使用 USB 驅動程式堆疊註冊驅動程式。 若要建立 USBD 句柄,請呼叫 USBD_CreateHandle。用戶端驅動程式通常會在其 AddDevice 例程中建立 USBD 句柄。
您可以在客戶端驅動程式 的 IRP_MN_START_DEVICE 處理程式或稍後查詢鏈結的 MDL 功能。 用戶端驅動程式不得在其 AddDevice 例程中查詢這項功能。
操作說明
呼叫 USBD_QueryUsbCapability 例程,以判斷 USB 驅動程式堆疊是否支援鏈結的 MDL 功能。 若要查詢該功能,請將UsbCapabilityChainedMdls指定為 GUID。 將 OutputBuffer 參數設定為 NULL,並將 OutputBufferSize 參數設定為 0。
檢查 USBD_QueryUsbCapability 所傳回的NTSTATUS值,並評估結果。 如果例程順利完成,則支援鏈結的 MDL 功能。 任何其他值都表示不支援此功能。
建立 MDL 鏈。 每個 MDL 都有指向另一個 MDL 的 Next 指標。
驅動程式可以手動設定 Next 指標來建置鏈結 MDL。
在上述範例中,通訊協定驅動程式會將封包傳送為 MDL。 中繼驅動程式可以建立另一個 MDL 來參考具有標頭資料的記憶體區塊。 若要建立鏈結,中繼驅動程式可以將標頭 MDL 的 Next 指標指向從通訊協定驅動程式收到的 MDL。 中繼驅動程式接著可以將兩個 MDL 的鏈結轉送至迷你埠驅動程式,以針對要求提供 URB 中鏈結 MDL 的參考,並將要求提交至 USB 驅動程式堆疊。 如需詳細資訊,請參閱使用 MDL 。
針對使用鏈結 MDL 的 I/O 要求建置 URB 時,請將相關聯 URB 結構的 TransferBufferMDL 成員(例如_URB_BULK_OR_INTERRUPT_TRANSFER或_URB_ISOCH_TRANSFER)設定為鏈結中的第一個 MDL,並將 TransferBufferLength 設定為要傳輸的位元組總數。 數據可能會跨越 MDL 鏈條中的多個 MDL 項目。
在 Windows 8 中,已新增兩種新類型的 URB 函式,可讓用戶端驅動程式使用鏈結的 MDL 進行數據傳輸。 如果您想要使用這項功能,請確定將URB標頭的 Function 成員設定為下列其中一個 URB 函式:
- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER_USING_CHAINED_MDL
- URB_FUNCTION_ISOCH_TRANSFER_USING_CHAINED_MDL
如需這些 URB 函式的相關信息,請參閱 _URB_HEADER。
備註
如需查詢基礎 USB 驅動程式堆疊以判斷驅動程式堆疊是否可以接受鏈結 MDL 的程式代碼範例,請參閱 USBD_QueryUsbCapability。
相關主題
- USB(I/O)作業