SPB I/O 要求
系統提供的CTL_CODE宏,如 定義 I/O 控制項代碼中所述,可用來在 Spb.h 中定義IOCTL_SPB_* 控制項程式代碼。
IOCTL_SPB_EXECUTE_SEQUENCE控件程式代碼
IOCTL_SPB_EXECUTE_SEQUENCE I/O 控制程式代碼可讓 SPB 控制器驅動程式的用戶端 (周邊驅動程式) ,以單一、不可部分完成的 I/O 要求執行一連串傳輸 (讀取和) 寫入。 總線上指定的裝置是序列中所有傳輸的目標。
藉由將固定長度傳輸序列指定為單一不可部分完成的作業,IOCTL_SPB_EXECUTE_SEQUENCE I/O 控制要求可讓控制器驅動程式優化 I/O 傳輸並改善效能。
用戶端會將這個 I/O 控制要求傳送至目標裝置的檔案物件。
SPB 控制器驅動程式會註冊 EvtSpbControllerIoSequence 回呼函式,以執行 I/O 傳輸序列的總線傳輸。 SPB 架構延伸模組 (SpbCx) 會呼叫此函式,以將IOCTL_SPB_EXECUTE_SEQUENCE要求傳遞至 SPB 控制器驅動程式進行處理。
IOCTL_SPB_EXECUTE_SEQUENCE輸入緩衝區
輸入緩衝區是SPB_TRANSFER_LIST結構,其中包含客戶端數據緩衝區的指標清單。 此清單包含 I/O 傳輸順序中每個傳輸 (讀取或寫入) 的數據緩衝區。
IOCTL_SPB_EXECUTE_SEQUENCE輸入緩衝區長度
SPB_TRANSFER_LIST 結構的大小。
IOCTL_SPB_EXECUTE_SEQUENCE狀態區塊
如果作業成功,控制器驅動程式會將 Status 成員設定為 STATUS_SUCCESS,並將 Information 成員設定為序列期間傳輸的位元組總數。
這項作業可能會因為各種原因而失敗,其中包括低資源、無效的用戶端輸入和裝置故障。
例如,如果控制器驅動程式開始處理 I/O 要求,但在序列中的其中一個傳輸期間發生錯誤 (,例如,目標裝置會發出 NACK 來拒絕傳輸) ,控制器驅動程式會中止序列中的其餘傳輸。 驅動程式接著會將完成狀態設定為 STATUS_SUCCESS、將 Information 成員設定為錯誤發生前成功傳輸的位元組數目,並完成要求。
IOCTL_SPB_FULL_DUPLEX控件程式代碼
用戶端 (周邊驅動程式) 會使用IOCTL_SPB_FULL_DUPLEX控件程式代碼來要求全雙工 I/O 作業。 控制器支援全雙工 I/O 作業,例如可以同時讀取和寫入數據的 SPI。 系統提供的CTL_CODE宏,如 定義 I/O 控制件代碼中所述,可用來定義IOCTL_SPB_FULL_DUPLEX,如下所示。
總線上裝置的使用者模式驅動程式或內核模式驅動程式會將此 I/O 控制項要求傳送至目標裝置的檔案物件。
只有SPB控制器驅動程式支援這個IOCTL,例如SPI,可以同時讀取和寫入數據。
完整雙工傳輸的寫入和讀取緩衝區是由SPB_TRANSFER_LIST結構所描述。 此結構必須使用下列格式:
SPB_TRANSFER_LIST_ENTRY 結構的陣列只包含兩個元素。 第一個元素描述方向 = SpbTransferDirectionToDevice) 寫入 (緩衝區。 第二個元素描述方向 = SpbTransferDirectionFromDevice) 的讀取 (緩衝區。
兩個SPB_TRANSFER_LIST_ENTRY結構的DelayInUs成員必須是零。 寫入緩衝區和讀取緩衝區的緩衝區格式可以是下列任一項:
- SpbTransferBufferFormatSimple
- SpbTransferBufferFormatList
- SpbTransferBufferFormatSimpleNonPaged
- SpbTransferBufferFormatMdl
上述清單中的最後兩種格式只能由內核模式用戶端使用。 寫入和讀取緩衝區的格式不需要相同。 如需這些緩衝區格式的詳細資訊,請參閱SPB_TRANSFER_BUFFER_FORMAT。
成功的作業可能會將 Information 成員設定為小於寫入緩衝區大小和讀取緩衝區總和的值,如果取消要求,或作業無法將寫入緩衝區的完整內容寫入至裝置,或將讀取緩衝區的完整內容完全填入從裝置讀取的數據。
寫入和讀取緩衝區大小不需要相同。 如果寫入緩衝區大於讀取緩衝區,作業會在讀取緩衝區滿後繼續從寫入緩衝區寫入數據。 如果讀取緩衝區大於寫入緩衝區,作業就會在寫入緩衝區清空之後繼續填滿讀取緩衝區。
如果SPB控制器驅動程式註冊 EvtSpbControllerIoOther 回呼函式,SPB 架構擴充功能 (SpbCx) 會呼叫此函式,以將IOCTL_SPB_FULL_DUPLEX要求傳遞給SPB控制器驅動程序進行處理。 SpbCx 不會針對IOCTL_SPB_FULL_DUPLEX要求執行任何參數檢查、傳輸清單驗證或其他處理。
如需SPB控制器驅動程式如何實作此IOCTL支援的詳細資訊,請參閱處理IOCTL_SPB_FULL_DUPLEX要求。
IOCTL_SPB_FULL_DUPLEX輸入緩衝區
SPB_TRANSFER_LIST 結構的指標,其中包含用戶端輸入和輸出數據緩衝區的指標。 這個結構包含剛好兩個專案的 Transfers 陣列。 第一個專案描述緩衝區,其中包含要寫入裝置的數據。 第二個元素描述用來保存從裝置讀取數據的緩衝區。 如需SPB控制器驅動程式如何實作自定義I/O控件的詳細資訊, (IOCTL) 使用SPB_TRANSFER_LIST結構來描述緩衝區的要求,請參閱使用自定義IOCTLs的 SPB_TRANSFER_LIST結構。
IOCTL_SPB_FULL_DUPLEX輸入緩衝區長度
SPB_TRANSFER_LIST 結構的大小。
IOCTL_SPB_FULL_DUPLEX狀態區塊
如果作業成功,控制器驅動程式會將 Status 成員設定為 STATUS_SUCCESS,並將 Information 成員設定為在全雙工作業期間 (讀取的位元組總數,以及寫入) 位元組的位元組總數。
這項作業可能會因為各種原因而失敗,其中包括低資源、無效的用戶端輸入和裝置故障。
IOCTL_SPB_LOCK_CONNECTION控件程式代碼
用戶端 (周邊驅動程式) 使用IOCTL_SPB_LOCK_CONNECTION控制程式代碼,以取得與另一個客戶端共用之SPB連線目標裝置上的連線鎖定。 當用戶端保有連線鎖定時,此用戶端具有裝置的獨佔存取權。 系統提供的CTL_CODE宏,如 定義 I/O 控制代碼中所述,可用來定義IOCTL_SPB_LOCK_CONNECTION,如下所示。
IOCTL_SPB_LOCK_CONNECTION和IOCTL_SPB_UNLOCK_CONNECTION要求會取得並釋放附加至簡單周邊總線之目標裝置上的連線鎖定。 大部分的用戶端不會使用這些 I/O 控制要求。 只有在兩個用戶端共用相同目標裝置的存取權時,才會使用這些要求。 如需詳細資訊,請參閱SPB連線鎖定。
兩個用戶端可以開啟相同目標裝置的個別邏輯連線,並在任一用戶端需要裝置的獨佔存取權時使用聯機鎖定。 當其中一個用戶端持有鎖定時,第二個用戶端對裝置的 I/O 要求會自動延後,直到第一個用戶端釋放鎖定為止。
用戶端可以在目標裝置上同時保存連線鎖定,以及SPB控制器上的控制器鎖定。 IOCTL_SPB_LOCK_CONTROLLER和IOCTL_SPB_UNLOCK_CONTROLLER要求會取得並釋放控制器鎖定。 客戶端必須先取得連線鎖定,才能取得控制器鎖定,而且必須在釋放連線鎖定之前釋放控制器鎖定。 用戶端會使用控制器鎖定來執行一組已排序的總線傳輸, (讀取和寫入作業) 為單一不可部分完成的總線作業。 如需詳細資訊,請參閱 I/O 傳輸序列。
如果在裝置上鎖定連線時,IRP_MJ_CLEANUP要求傳送至目標裝置,則會自動終止連線鎖定。 當用戶端將其檔案句柄關閉至裝置時,清除要求會傳送至目標裝置。
IOCTL_SPB_LOCK_CONNECTION狀態區塊
如果作業成功,狀態成員會設定為 STATUS_SUCCESS。
如果作業失敗,狀態成員會設定為適當的錯誤狀態代碼。
如果客戶端已經保留目標裝置上的連線鎖定或SPB控制器上的控制器鎖定,則此作業會失敗,且 Status = STATUS_INVALID_DEVICE_REQUEST。 這項作業可能會因為其他原因而失敗,其中包括低資源、無效的用戶端輸入和裝置故障。
IOCTL_SPB_LOCK_CONTROLLER控件程序代碼
用戶端 (周邊驅動程式) 會使用IOCTL_SPB_LOCK_CONTROLLER控件程式代碼來鎖定SPB控制器。 當控制器鎖定時,用戶端會獨佔使用總線來存取鎖定的指定目標裝置。 系統提供的CTL_CODE宏,如 定義 I/O 控制項代碼中所述,可用來定義IOCTL_SPB_LOCK_CONTROLLER,如下所示。
若要取得專用的總線來存取目標裝置,用戶端 (周邊驅動程式) 將此 IOCTL 傳送至目標的檔案物件。 完成此 IOCTL 之後,控制器會鎖定,而所有 I/O 傳輸 (總線上的讀取或寫入) 都會存取指定的目標。 在傳輸之間,控制器會讓目標裝置保持選取狀態,但會停止時鐘。
控制器會保持鎖定狀態,直到用戶端傳送IOCTL_SPB_UNLOCK_CONTROLLER要求來解除鎖定控制器為止。 當客戶端在目標裝置的傳輸序列完成時,客戶端必須解除鎖定控制器,讓控制器可以處理總線上其他目標的 I/O 要求。
當控制器鎖定目標時,如果IRP_MJ_CLEANUP要求傳送至目標裝置,就會自動終止鎖定。 當用戶端關閉目標句柄時,清除要求會傳送至目標。
SPB 控制器不需要支援IOCTL_SPB_LOCK_CONTROLLER和IOCTL_SPB_UNLOCK_CONTROLLER要求,而且周邊設備驅動器不應該假設它們受到支援。
如果SPB控制器驅動程式註冊 EvtSpbControllerLock 回呼函式,SPB 架構擴充功能 (SpbCx) 呼叫此函式,以將IOCTL_SPB_LOCK_CONTROLLER要求傳遞給SPB控制器驅動程式進行處理。
IOCTL_SPB_LOCK_CONTROLLER狀態區塊
如果作業成功,狀態成員會設定為 STATUS_SUCCESS。 此 IOCTL 可能會因為許多原因而傳回錯誤狀態,包括無法設定控制器以獨佔存取模式運作。 在此模式中,控制器會讓目標裝置保持選取狀態,使其是總線上所有 I/O 傳輸的獨佔目標。 控制器會維持在此模式中,直到解除鎖定為止。
IOCTL_SPB_UNLOCK_CONNECTION控件程式代碼
用戶端 (周邊驅動程式會使用IOCTL_SPB_UNLOCK_CONNECTION I/O 控制程式碼) ,以釋放與另一個用戶端共用之 SPB 連線目標裝置上的連線鎖定。 用戶端先前已傳送IOCTL_SPB_LOCK_CONNECTION要求,以取得裝置的獨佔存取權。
IOCTL_SPB_LOCK_CONNECTION和IOCTL_SPB_UNLOCK_CONNECTION要求會在連結至簡單周邊總線的目標裝置上取得並釋放連線鎖定。 大部分用戶端都不會使用這些 I/O 控制要求。 只有在兩個用戶端共用相同目標裝置的存取權時,才會使用這些要求。 如需詳細資訊,請參閱SPB連線鎖定。
在用戶端 (周邊驅動程式) 將IOCTL_SPB_LOCK_CONNECTION要求傳送至總線上的目標裝置,且要求成功完成之後,聯機會維持鎖定狀態,直到用戶端傳送IOCTL_SPB_UNLOCK_CONNECTION要求來解除鎖定連線為止。
當用戶端不再需要裝置的獨佔存取權時,用戶端會傳送IOCTL_SPB_UNLOCK_CONNECTION要求,以釋放目標裝置的連線鎖定。 聯機必須解除鎖定,讓其他用戶端可以存取裝置。
IOCTL_SPB_UNLOCK_CONNECTION狀態區塊
如果作業成功,狀態成員會設定為 STATUS_SUCCESS。
如果作業失敗,狀態成員會設定為適當的錯誤狀態代碼。 如果用戶端未在目標裝置上保留連線鎖定,或用戶端仍然在SPB控制器上保留連線鎖定,則此作業會失敗,且 Status = STATUS_INVALID_DEVICE_REQUEST。 這項作業可能會因為其他原因而失敗,包括低資源、無效的用戶端輸入和裝置故障。
IOCTL_SPB_UNLOCK_CONTROLLER控件程式代碼
用戶端 (周邊驅動程式會使用IOCTL_SPB_UNLOCK_CONTROLLER I/O 控制程式碼) 來解除鎖定 SPB 控制器。 用戶端先前已鎖定控制器,以獨佔使用總線來存取總線上的目標裝置。
用戶端 (周邊驅動程式) 將IOCTL_SPB_LOCK_CONTROLLER I/O 控制要求傳送至總線上的目標裝置之後,控制器會保持鎖定狀態,直到用戶端傳送IOCTL_SPB_UNLOCK_CONTROLLER I/O 控制要求來解除鎖定控制器為止。 用戶端會將這些 I/O 控制要求傳送至目標裝置的檔案物件。
用戶端在總線上完成一連串傳輸,並想要釋放目標裝置時,傳送IOCTL_SPB_UNLOCK_CONTROLLER要求。 控制器必須解除鎖定,才能處理總線上其他目標的 I/O 要求。
不需要SPB控制器才能支援IOCTL_SPB_LOCK_CONTROLLER和IOCTL_SPB_UNLOCK_CONTROLLER要求,而且周邊設備驅動器不應假設它們受到支援。
SPB 架構延伸模組 (SpbCx) 呼叫 SPB 控制器驅動程式的選擇性 EvtSpbControllerUnlock 回呼函式,以將IOCTL_SPB_LOCK_CONTROLLER要求傳遞至 SPB 控制器驅動程式進行處理。
IOCTL_SPB_UNLOCK_CONTROLLER狀態區塊
如果作業成功,狀態成員會設定為 STATUS_SUCCESS。
只有當用戶端未鎖定控制器以獨佔存取指定目標時,此 IOCTL 才會失敗。