使用 i/o 佇列的範例

針對每個連線到系統且受特定驅動程式支援的裝置,此驅動程式可以使用下列 i/o 佇列和 要求處理常式的組合:

  • 單一的預設 i/o 佇列和單一要求處理常式, EvtIoDefault。 此架構會將所有裝置的要求傳遞至預設佇列,並且會呼叫驅動程式的 EvtIoDefault 處理常式,將每個要求傳遞至驅動程式。

  • 單一的預設 i/o 佇列和多個要求處理常式,例如 EvtIoReadEvtIoWriteEvtIoDeviceControl。 架構會將所有裝置的要求傳遞至預設佇列。 它會呼叫驅動程式的 EvtIoRead 處理常式來傳遞讀取要求、傳遞寫入要求的 EvtIoWrite 處理常式,以及可傳遞裝置 I/o 控制要求的 EvtIoDeviceControl 處理常式。

  • 多個 i/o 佇列,例如一個用於讀取要求,另一個用於寫入要求。 針對每個佇列,驅動程式只會提供一個要求處理常式,因為佇列只會接收一種要求。

  • 多個 i/o 佇列,每個佇列都有多個要求處理常式。

範例案例包含:

單一連續 i/o 佇列

如果您要撰寫一次只能服務讀取和寫入要求的磁片磁碟機的函式驅動程式,則函式驅動程式只需要每個裝置有一個 i/o 佇列。

驅動程式可以使用在驅動程式呼叫WdfIoQueueCreate時,架構所建立的預設 i/o 佇列,並在佇列的WDF_IO_QUEUE_CONFIG結構中將DefaultQueue設定為TRUE 。 在 WDF_IO_QUEUE_CONFIG 結構中,驅動程式也應該指定:

  • WdfIoQueueDispatchSequential 做為分派方法,因此預設 i/o 佇列會以同步方式將 i/o 要求傳遞至驅動程式。

  • 將會接收所有 i/o 要求的單一事件回呼函數 EvtIoDefault

每次在驅動程式的預設 i/o 佇列中都可以使用 i/o 要求時,架構會呼叫驅動程式的 EvtIoDefault 要求處理常式,將要求傳遞至驅動程式。 如果佇列中的另一個要求變成可用,則在驅動程式針對先前傳遞的要求呼叫 WdfRequestComplete 之前,架構將不會提供它。

多個連續 i/o 佇列和手動佇列

請考慮具有下列特性的序列埠裝置:

  • 它可以同時執行一次讀取作業和一項寫入操作。

  • 它無法以非同步方式執行多個讀取或寫入作業。

  • 它可以接收裝置 i/o 控制項要求的狀態資訊。 裝置的驅動程式可能需要很長的時間才能完成其中某些要求 (例如等候狀態變更) 的要求。

此裝置的函式驅動程式可以針對每部裝置使用多個連續的 i/o 佇列。 驅動程式會呼叫 WdfIoQueueCreate 三次:一次是建立預設佇列,而兩次是建立兩個額外的 i/o 佇列。 在每個佇列的 WDF_IO_QUEUE_CONFIG 結構中,驅動程式應指定:

  • WdfIoQueueDispatchSequential 做為每個佇列的分派方法,讓架構能以同步方式將 i/o 要求傳遞至驅動程式。

  • 每個佇列 (EvtIoDefaultEvtIoReadEvtIoWrite) 的不同要求處理常式,會接收佇列的 i/o 要求。

在呼叫 WdfIoQueueCreate之後,驅動程式可能會呼叫 WdfDeviceConfigureRequestDispatching 兩次,以將所有讀取要求轉寄至其中一個額外的佇列,並將所有寫入要求轉寄至另一個佇列。

使用此設定時,裝置的預設 i/o 佇列 EvtIoDefault 回呼函式只會收到裝置 i/o 控制項要求的狀態資訊。

如果驅動程式必須長時間保存狀態要求,它可以建立第四個佇列,並將 WdfIoQueueDispatchManual 指定為分派方法。 當驅動程式收到必須等待的資訊要求時,它可以將要求放在此額外佇列中,直到狀態資訊變成可用為止。 然後,驅動程式可以從佇列中取出要求並完成要求。 在此同時,預設佇列可以提供對驅動程式的另一個要求。

單一平行 i/o 佇列

IDE 磁碟控制卡可能會重迭某些 i/o 作業,但不能與其他作業重迭。 例如,當控制器正在處理一個磁片上的讀取或寫入作業時,它就可以將搜尋命令傳送到另一個磁片。 另一方面,則不支援多個同時讀取和寫入命令。

此控制器的函數驅動程式必須檢查每個 i/o 要求。 如果驅動程式收到 seek 命令,它必須判斷是否可以處理 seek 命令。 如果有下列情況,則無法處理 seek 命令:

  • 指定的磁片磁碟機已在忙碌中。

  • 磁片磁碟機正在格式化,因此沒有其他磁片磁碟機可以處於作用中狀態。

針對連線到控制器的每個裝置,驅動程式可能會呼叫 WdfIoQueueCreate 來建立預設的 i/o 佇列。 在每個佇列的 WDF_IO_QUEUE_CONFIG 結構中,驅動程式應指定:

  • WdfIoQueueDispatchParallel 做為每個佇列的分派方法,讓架構能以非同步方式將 i/o 要求傳遞至驅動程式。

  • 每個佇列的 EvtIoDefault 事件回呼函式,將會接收佇列的 i/o 要求。

使用此設定時,會將單一的平行 i/o 佇列指派給每部裝置。 驅動程式必須檢查架構從每個 i/o 佇列傳遞的每個 i/o 要求。 如果驅動程式可以立即處理要求,就會這樣做。 否則,驅動程式會呼叫 WdfIoQueueStop,這會導致架構停止傳遞要求,直到驅動程式呼叫 WdfIoQueueStart為止。

多個平行 i/o 佇列

SCSI 主機介面卡是支援非同步、重迭 i/o 作業的裝置範例。 最多可將32裝置連接至介面卡。 請考慮具有下列設定的系統:

  • 某些連接到 SCSI 介面卡的裝置支援 "reselection",而有些則不支援。 如果 SCSI 裝置支援 reselection,則在 i/o 作業期間,裝置可以暫時釋放介面卡,讓介面卡可以服務其他裝置。 第一個裝置 reselects 本身來完成其作業。

  • SCSI 介面卡會使用硬體信箱,在驅動程式與裝置之間傳遞要求和回應。 如果裝置已準備好要求,但沒有可用的信箱,則裝置必須等待。

為了達到最佳效能,此 SCSI 主機介面卡的函式驅動程式應該會在架構提供時立即收到其 i/o 要求。 驅動程式必須檢查每個要求,並判斷它是否可以立即啟動或必須延後,直到裝置和資源 ((例如信箱記憶體) 可用)。

驅動程式可能會使用多個平行 i/o 佇列。 針對連線到介面卡的每個裝置,驅動程式會呼叫 WdfIoQueueCreate 來建立預設的 i/o 佇列。 在每個佇列的 WDF_IO_QUEUE_CONFIG 結構中,驅動程式應指定:

  • WdfIoQueueDispatchParallel 做為每個佇列的分派方法,讓架構能以非同步方式將 i/o 要求傳遞至驅動程式。

  • 每個佇列的 EvtIoDefault 事件回呼函式,將會接收佇列的 i/o 要求。

每個 i/o 佇列的 EvtIoDefault 回呼函式都必須檢查佇列的 i/o 要求(傳遞時),並判斷每一個要求是否可以立即服務。 如果有可用的裝置和系統資源,驅動程式就會啟動 i/o 操作。 如果裝置或資源無法使用,則驅動程式必須呼叫 WdfIoQueueStop 來停止傳遞額外的要求,直到可以處理目前的要求為止。

(選擇性)驅動程式可以呼叫 WdfIoQueueCreate 來為每個裝置建立額外的佇列。 然後,驅動程式可以呼叫 WdfRequestForwardToIoQueue 來 requeue 對其他佇列的某些要求類型。 當架構從其他佇列傳遞要求時,驅動程式可以視需要在該佇列(而不是預設的佇列)上呼叫 WdfIoQueueStop,進而將延遲傳遞的要求數目或類型降至最低。