共用方式為


I/O 傳輸序列

SPB 架構延伸模組 (SpbCx) 支援 I/O 傳輸序列。 I/O 傳輸順序是一組已排序的總線傳輸(讀取和寫入作業),以單一原子性總線作業執行。 I/O 傳輸順序中的所有傳輸都會存取匯流排上的相同目的裝置。 執行序列時,即使 SPB 控制器驅動程式可能會在 I/O 傳輸序列完成之前收到其他裝置的 I/O 要求,也無法存取匯流排上的其他裝置。

I/O 傳輸序列的範例是寫入-讀取作業,其中進行匯流排寫入作業後緊接著匯流排讀取作業。 用戶端周邊裝置驅動程式可能會使用這種類型的序列,寫入 SPB 連線周邊裝置中的函式選取暫存器,然後讀取所選裝置函式的值。 這兩種傳輸可以有不同的長度。 例如,寫入作業可能會傳輸一個位元組的資料,而讀取作業可能會傳輸許多位元組的資料。

I/O 傳輸序列的類型

用戶端可以透過下列其中一種方式起始 I/O 傳輸順序:

  1. 用戶端可以在 IOCTL_SPB_EXECUTE_SEQUENCE I/O 控制要求中指定整個順序。 此要求可讓 SPB 控制器驅動程式使用任何可用的硬體特定效能優化來執行傳輸順序。 如需詳細資訊,請參閱 Single-Request 序列

  2. 用戶端可以傳送 IOCTL_SPB_LOCK_CONTROLLER I/O 控制要求,以在序列開始鎖定控制器,並在序列完成時傳送 IOCTL_SPB_UNLOCK_CONTROLLER 。 當控制器鎖定時,用戶端會針對序列中的每個讀取或寫入作業傳送個別的 I/O 要求 (IRP_MJ_READIRP_MJ_WRITE)。 如需詳細資訊,請參閱 Client-Implemented 序列

盡可能,用戶端應該使用 IOCTL_SPB_EXECUTE_SEQUENCE 要求,這更快、不易發生錯誤,並大幅減少其他用戶端鎖定匯流排的時間。 不過,如果用戶端必須先查看在序列中某次傳送期間讀取的值,才能在該序列中進行後續的傳送,那麼可以發出 IOCTL_SPB_LOCK_CONTROLLERIOCTL_SPB_UNLOCK_CONTROLLER 要求。 在此情況下,需要仔細設計,以避免將其他用戶端鎖定在匯流排之外的時間超過必要的時間,而且設計不當的周邊驅動程式可能會降低整體系統效能。

Single-Request 序列

若要改善效能,您的 SPB 控制器驅動程式應該實作 EvtSpbControllerIoSequence 回呼函式來處理 IOCTL_SPB_EXECUTE_SEQUENCE 要求。 此方法會為 SPB 控制器驅動程式增加一些複雜度,但避免要求用戶端執行 I/O 傳輸序列作為一系列個別讀取和寫入作業,而其他用戶端會鎖定在匯流排之外。

備註

強烈建議實作 EvtSpbControllerIoSequence 函式,而且可能會成為 Windows 8 的需求。

傳輸序列的實作類似於簡單的讀取或寫入作業,但另外需要更新序列中個別傳輸之間序列作業的儲存狀態。 第一次傳輸完成之後,SPB 控制器驅動程式會更新序列狀態,以選取序列中的下一個傳輸。 序列狀態儲存在裝置上下文中,並包括傳遞至 EvtSpbControllerIoSequence 回調的 SPBREQUEST 控制碼。 SPB 控制器驅動程式會使用此控制碼來取得序列中個別傳輸的緩衝區、長度、方向和位置參數。 如需取得這些參數的詳細資訊,請參閱 SpbRequestGetTransferParameters

如果 SPB 控制器驅動程式無法執行要求的 IOCTL_SPB_EXECUTE_SEQUENCE 作業,它會使用失敗碼完成要求。 如果發生這類失敗,客戶端可以選擇鎖定匯流排,明確按一系列簡單的 I/O 請求執行 I/O 傳輸順序,然後解除鎖定匯流排。 如需詳細資訊,請參閱 Client-Implemented 序列

SpbCx 會針對從周邊裝置驅動程式接收的 IOCTL_SPB_XXX 要求執行參數檢查。 針對 IOCTL_SPB_EXECUTE_SEQUENCE 要求,SpbCx 會拒絕空序列和包含 Null 緩衝區指標或零長度緩衝區的序列。

SPB 控制器驅動程式應該確認序列中每個傳輸的長度不會超過驅動程式指定的限制。 例如,Windows 驅動程式套件(WDK)中的 SkeletonI2C 範例驅動程式,若遇到指定超過4K位元組的傳輸的IOCTL_SPB_EXECUTE_SEQUENCE要求,將會失敗,並將此要求的狀態碼設定為 STATUS_INVALID_PARAMETER。 在起始 IOCTL_SPB_EXECUTE_SEQUENCE 要求的序列作業之前,驅動程式應該驗證序列中所有傳輸的參數,以確認作業可以順利完成。

SpbCx 永遠不會在 EvtSpbControllerIoSequence 回呼之前有 EvtSpbControllerLock 回呼,而且永遠不會在 EvtSpbControllerIoSequence 回呼之後接 EvtSpbControllerUnlock 回呼。

Client-Implemented 序列

SPB 控制器驅動程式的用戶端可以明確執行 I/O 傳輸序列,作為一系列簡單的讀取和寫入。 用戶端可以是核心模式驅動程式,也可以是使用者模式驅動程式,以控制連結至匯流排的周邊裝置。 在序列中的首次傳輸之前,用戶端會向目標裝置傳送 IOCTL_SPB_LOCK_CONTROLLER 要求,以防止在序列的傳輸之間發生其他與之無關的匯流排存取。 接下來,用戶端會傳送 IRP_MJ_READIRP_MJ_WRITE 要求,以依序執行傳輸。 最後,客戶端發送 IOCTL_SPB_UNLOCK_CONTROLLER 請求以釋放鎖定。

如果序列中的較晚傳輸相依於較早的傳輸,用戶端可能需要實作此類型的 I/O 傳輸順序。 例如,第一次讀取可能會指出需要讀取或寫入的額外位元組數量。 不過,如果這類相依性不存在,用戶端應該將 IOCTL_SPB_EXECUTE_SEQUENCE 要求傳送至 SPB 控制器驅動程式,以更有效率地執行序列。

在啟動用戶端實作序列的 IOCTL_SPB_LOCK_CONTROLLER 要求與結束序列的 IOCTL_SPB_UNLOCK_CONTROLLER 要求之間,用戶端可以傳送至目標裝置的唯一 I/O 要求是 IRP_MJ_READIRP_MJ_WRITE 要求。 任何違反此規則的行為都是錯誤。

SPB 鎖定僅用於保證讀取和寫入序列作為原子性匯流排操作執行,並應專用於此目的。

如需詳細資訊,請參閱 處理 Client-Implemented 序列