共用方式為


如何傳送鏈結的 MDL 結構

本文說明 USB 驅動程式堆疊中的鏈結 MDL 功能,以及用戶端驅動程式如何將傳輸緩衝區當做 MDL 結構的鏈結傳送。

大部分的USB主機控制器都需要傳輸緩衝區幾乎連續。 幾乎連續表示緩衝區可以在頁面的任何位置啟動和結束,但緩衝區的其餘部分必須在頁面界限上開始和結束。 許多 USB 用戶端驅動程式都能夠符合該需求。 不過,對於某些客戶端驅動程式,特別是需要新增或移除緩衝區內或從緩衝區中移除其他數據的驅動程式,不偏好配置傳輸緩衝區的虛擬連續記憶體。

例如,請考慮三個驅動程式的網路堆疊、網路通訊協定驅動程式、中繼驅動程式和迷你埠驅動程式。 通訊協定驅動程式會起始傳輸,並將封包傳送至堆疊中的下一個驅動程式:中繼驅動程式。 中繼驅動程式想要將自定義標頭 (包含在個別記憶體區塊) 封包中。 中繼驅動程式會將該標頭和接收的封包傳送至堆疊中的下一個驅動程式:迷你埠驅動程式。 迷你埠驅動程式介面與 USB 驅動程式堆疊,因此必須準備幾乎連續的傳輸緩衝區。 若要建立這類緩衝區,迷你埠驅動程式會配置大型緩衝區、新增自定義標頭,然後複製承載。 因為承載通常很大,所以複製整個承載可能會對效能產生重大影響。

用戶端驅動程式可以藉由將傳輸緩衝區傳送為 記憶體描述元清單 鏈結, (MDL) 來克服該效能影響。 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 例程中查詢此功能。

指示

  1. 呼叫 USBD_QueryUsbCapability 例程,以判斷 USB 驅動程式堆疊是否支援鏈結的 MDLs 功能。 若要查詢該功能,請將UsbCapabilityChainedMdls指定為 GUID。 將 OutputBuffer 參數設定為 NULL, 並將 OutputBufferSize 參數設定為 0。

  2. 檢查 USBD_QueryUsbCapability 傳回的NTSTATUS值,並評估結果。 如果例程成功完成,則會支援鏈結的 MDLs 功能。 任何其他值都表示不支援此功能。

  3. 建立 MDL 鏈結。 每個 MDL 都有指向另一個 MDLNext 指標。

    驅動程式可以手動設定 Next 指標來建置鏈結 MDL。

    在上述範例中,通訊協定驅動程式會將封包傳送為 MDL。 中繼驅動程式可以建立另一個 MDL ,以參考具有標頭數據的記憶體區塊。 若要建立鏈結,中繼驅動程式可以將標頭 MDL 的 Next 指標指向從通訊協定驅動程式接收的 MDL。 接著,中繼驅動程式可以將兩個 MDL 的鏈結轉送至迷你埠驅動程式,此驅動程式會針對要求的 URB 中提供鏈結 MDL 的參考,並將要求提交至 USB 驅動程式堆疊。 如需詳細資訊,請參閱 使用 MDL

  4. 針對使用鏈結 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