使用 USB 管道
架構會將 USB 介面中的每個管道表示為架構 USB 管道物件。 當驅動程式 設定 USB 裝置時,架構會為每個選取介面中的每個管道建立架構 USB 管道物件。 Pipe 物件方法可讓驅動程式執行下列作業:
取得管道資訊
呼叫 WdfUsbInterfaceGetConfiguredPipe 以取得架構 USB 管道物件的控制碼之後,您的驅動程式可以呼叫 USB 管道物件所定義的下列方法來取得 USB 管道的相關資訊:
WdfUsbTargetPipeGetIoTarget
傳回與 USB 管道相關聯之 I/O 目標物件的控制碼。 驅動程式可以將此控制碼傳遞至 WdfRequestSend。
WdfUsbTargetPipeGetInformation
擷取 USB 管道及其端點的相關資訊。
WdfUsbTargetPipeGetType
傳回 USB 管道的類型。
WdfUsbTargetPipeIsInEndpoint
判斷 USB 管道是否連接到輸入端點。
WdfUsbTargetPipeIsOutEndpoint
判斷 USB 管道是否連接到輸出端點。
WDF_USB_PIPE_DIRECTION_IN
判斷 USB 端點是否為輸入端點。
WDF_USB_PIPE_DIRECTION_OUT
判斷 USB 端點是否為輸出端點。
如需相關資訊,請參閱 如何列舉 USB 管道。
從管道讀取
若要從 USB 輸入管道讀取資料,您的驅動程式可以使用下列三種技術的任何 (或所有) :
同步讀取資料
若要從 USB 輸入管道同步讀取資料,您的驅動程式可以呼叫 WdfUsbTargetPipeReadSynchronously 方法。 此方法會建置並傳送讀取要求,並在 I/O 作業完成之後傳回。
以非同步方式讀取資料
若要從 USB 輸入管道非同步讀取資料,您的驅動程式可以呼叫 WdfUsbTargetPipeFormatRequestForRead 方法來建置讀取要求。 然後,驅動程式可以呼叫 WdfRequestSend ,以非同步方式傳送要求 (或同步) 。
以非同步且持續的方式讀取資料
連續讀取器是一種架構提供的機制,可確保讀取要求一律可供 USB 管道使用。 此機制可確保驅動程式一律準備好從提供非同步、未經要求輸入資料流程的裝置接收資料。 例如,網路介面卡的驅動程式 (NIC) 可能會使用連續讀取器來接收輸入資料。
若要為輸入管道設定連續讀取器,驅動程式的 EvtDevicePrepareHardware 回呼函式必須呼叫 WdfUsbTargetPipeConfigContinuousReader 方法。 這個方法會將一組讀取要求排入裝置的 I/O 目標。
此外,驅動程式的 EvtDeviceD0Entry 回 呼函式必須呼叫 WdfIoTargetStart 來啟動連續讀取器,而驅動程式的 EvtDeviceD0Exit 回 呼函式必須呼叫 WdfIoTargetStop 來停止連續讀取器。
每次從裝置取得資料時,如果 I/O 目標回報錯誤,I/O 目標就會完成讀取要求,而且架構會呼叫下列兩個回呼函式之一: EvtUsbTargetPipeReadlete,如果 I/O 目標成功讀取資料,或 EvtUsbTargetPipeReadersFailed。
如果您未提供選用的 EvtUsbTargetPipeReadersFailed 回呼,架構會藉由傳送另一個讀取要求來回應失敗的讀取嘗試。 因此,如果匯流排處於不接受讀取的狀態,架構會持續傳送新的要求,以從失敗的讀取中復原。
驅動程式呼叫 WdfUsbTargetPipeConfigContinuousReader之後,驅動程式無法使用 WdfUsbTargetPipeReadSynchronously 或 WdfRequestSend 將 I/O 要求傳送至管道,除非呼叫驅動程式的 EvtUsbTargetPipeReadersFailed 回呼函式並傳回 FALSE。
根據預設,如果您的驅動程式指定的讀取緩衝區不是管道封包大小上限的倍數,架構就會回報錯誤。 您的驅動程式可以呼叫 WdfUsbTargetPipeSetNoMaximumPacketSizeCheck 來停用讀取緩衝區大小的此測試。
如需相關資訊,請參閱:
寫入管道
若要將資料寫入 USB 輸出管道,您的驅動程式可以使用一個 (或兩者) 下列技術:
同步寫入資料
若要以同步方式將資料寫入 USB 輸出管道,您的驅動程式可以呼叫 WdfUsbTargetPipeWriteSynchronously 方法。 這個方法會建置並傳送寫入要求,並在 I/O 作業完成之後傳回。
以非同步方式寫入資料
若要以非同步方式將資料寫入 USB 輸入管道,您的驅動程式可以呼叫 WdfUsbTargetPipeFormatRequestForWrite 方法來建置寫入要求。 然後,驅動程式可以呼叫 WdfRequestSend 以非同步方式傳送要求。
如需相關資訊,請參閱 如何傳送 USB 大量傳輸要求。
停止和重設管道
您的驅動程式可以呼叫下列方法來停止或重設 USB 管道:
WdfUsbTargetPipeAbortSynchronously
同步傳送要求以停止 USB 管道。
WdfUsbTargetPipeFormatRequestForAbort
格式化要求以停止 USB 管道。 驅動程式可以呼叫 WdfRequestSend ,以同步或非同步方式傳送要求。
WdfUsbTargetPipeResetSynchronously
同步傳送要求以重設 USB 管道。
WdfUsbTargetPipeFormatRequestForReset
格式化要求以重設 USB 管道。 驅動程式必須呼叫 WdfRequestSend ,以同步或非同步方式傳送要求。
如果您的驅動程式的 USB 目標 完成 I/O 要求並出現錯誤狀態值,驅動程式應該執行下列動作:
停止管道,如果目標尚未完成要求,則取消驅動程式傳送至 USB 目標的任何其他 I/O 要求。
同步傳送中止要求至管道。
呼叫 WdfUsbTargetPipeAbortSynchronously,或呼叫 WdfUsbTargetPipeFormatRequestForAbort ,後面接著 WdfRequestSend 並設定 WDF_REQUEST_SEND_OPTION_SYNCHRONOUS 旗標。
同步傳送重設要求至管道。
呼叫 WdfUsbTargetPipeResetSynchronously,或呼叫 WdfUsbTargetPipeFormatRequestForReset ,後面接著 WdfRequestSend 並設定 WDF_REQUEST_SEND_OPTION_SYNCHRONOUS 旗標。
重新開機管道。
呼叫 WdfIoTargetStart。
重新傳送失敗的 I/O 要求,以及遵循失敗要求的所有 I/O 要求。
在大量失敗之後,驅動程式應該執行下列動作來嘗試重設 USB 埠:
停止所有作用中的管道,如果目標尚未完成,則取消驅動程式已傳送至每個管道 USB 目標的任何其他 I/O 要求。
針對每個使用中管道,使用WdfIoTargetCancelSentIo旗標集呼叫WdfIoTargetStop。
同步傳送要求以重設 USB 埠。
重新開機管道。
針對驅動程式停止的每個管道呼叫 WdfIoTargetStart 。
重新傳送最後一個失敗的 I/O 要求,以及遵循失敗要求的所有 I/O 要求。
如需相關資訊,請參閱 如何從 USB 管道錯誤復原。
將 URB 傳送至管道
如果您的 KMDF 驅動程式透過傳送包含 URB 的 I/O 要求與 USB 管道通訊,驅動程式可以呼叫下列方法:
WdfUsbTargetPipeSendUrbSynchronously (KMDF 僅)
同步傳送包含 URB 的 I/O 要求。
WdfUsbTargetPipeFormatRequestForUrb (KMDF 僅)
格式化包含 URB 的 I/O 要求。 驅動程式可以呼叫 WdfRequestSend ,以同步或非同步方式傳送要求。
WdfUsbTargetPipeWdmGetPipeHandle (KMDF 僅)
傳回裝置的 USBD 管道控制碼。 某些 URI 需要此控制碼。