NDIS中斷相關
1. 注冊和取消注冊中斷: 微型端口驅動程序調用 NdisMRegisterInterruptEx 來注冊中斷。 驅動程序分配并初始化 NDIS_MINIPORT_INTERRUPT_CHARACTERISTICS 結構,以指定中斷特征和函數入口點,驅動程序將結構傳遞給 NdisMRegisterInterruptEx,驅動程序調用 NdisMDeRegisterInterruptEx 函數以釋放以前使用 NdisMRegisterInterruptEx 分配的資源。
2. 處理 NDIS 微型端口驅動程序的中斷:當 NIC 或與 NIC 共享中斷的另一臺設備生成中斷時,NDIS 調用 MiniportInterrupt 函數。如果基礎 NIC 未生成中斷,MiniportInterrupt 應立即返回 FALSE。 否則,它在處理中斷后返回 TRUE 。
微型端口驅動程序應在其 MiniportInterrupt 函數中盡可能少地執行工作。 它應將 I/O 操作延遲到 MiniportInterruptDPC 函數。 NDIS 調用 MiniportInterruptDPC 來完成中斷的延遲處理。若要在 MiniportInterrupt 返回后將其他 DPC 排隊,微型端口驅動程序將設置 MiniportInterrupt 函數的 TargetProcessors 參數的位。
若要從 MiniportInterrupt 或 MiniportInterruptDPC 請求其他 DPC,微型端口驅動程序調用 NdisMQueueDpc 函數。微型端口驅動程序可以調用 NdisMQueueDpc ,以請求其他處理器的其他 DPC 調用。
3. 與中斷同步:如果微型端口驅動程序的 MiniportInterrupt 函數將資源(如 NIC 寄存器或狀態變量)與以較低 IRQL 運行的另一個 MiniportXxx 函數共享,則 MiniportXxx 函數必須調用 NdisMSynchronizeWithInterruptEx。 此調用可確保微型端口驅動程序的 MiniportSynchronizeInterrupt 函數以同步且多處理器安全的方式訪問共享資源。
4. 中斷調解:為了減少中斷數,許多 NIC 使用中斷審查。 使用中斷審查時,NIC 硬件在收到數據包后不會立即生成中斷。 相反,硬件會等待更多數據包到達或超時過期,然后再生成中斷。 硬件供應商指定最大數據包數、超時間隔或其他中斷審查算法。數據包的測量往返時間是確定兩個終結點之間的網絡帶寬的最常用技術之一。 但是,啟用中斷審查后,接收數據包不會立即產生中斷,因此,特定數據包的感知往返時間將大于平均時間。
為了準確測量數據包的往返時間,NDIS 提供了按需禁用和啟用中斷審查的功能。所有 NDIS 6.0 及更高版本的微型端口驅動程序都必須支持 OID_GEN_INTERRUPT_MODERATION OID。 如果微型端口驅動程序不支持中斷審查,則驅動程序必須在NDIS_INTERRUPT_MODERATION_PARAMETERS結構的 InterruptModeration 成員中指定 NdisInterruptModerationNotSupported。
NDIS 6.0 及更高版本的微型端口驅動程序必須同時支持 OID_GEN_INTERRUPT_MODERATION OID 集和查詢請求。 設置請求指示微型端口驅動程序啟用或禁用中斷審查,查詢請求報告中斷審查的當前狀態。默認情況下,支持中斷審查的微型端口驅動程序應啟用此功能,除非注冊表中的 InterruptModeration 標準關鍵字 (keyword) 禁用此功能。
微型端口適配器 OID 請求
NDIS 定義對象標識符 (OID) 值來標識微型端口適配器參數,其中包括設備特征、可配置的設置和統計信息等操作參數。
對于 NDIS 6.1 及更高版本的微型端口驅動程序,NDIS 提供 直接 OID 請求接口。 直接 OID 請求路徑支持經常查詢或設置的 OID 請求。 對于 NDIS 驅動程序,直接 OID 請求接口是可選的。
對于 NDIS 6.80 及更高版本的微型端口驅動程序,NDIS 提供 同步 OID 請求接口。 同步 OID 請求路徑支持需要同步的 OID 或不應由篩選器驅動程序(如 RSSv2 OID)排隊的 OID。 同步 OID 請求接口對于 NDIS 驅動程序是可選的,但如果微型端口驅動程序播發對 RSSv2 的支持,則是必需的。
1. 微型端口適配器 OID 請求序列化
對微型端口適配器的所有 OID 請求都由 NDIS 序列化,直接 OID 請求除外,這些請求在設計上未序列化。 在完成任何掛起的請求之前,微型端口適配器不會收到新的 OID 請求。 因此,微型端口適配器必須立即完成 OID。
備注:建議在 1000 毫秒或 1 秒內完成 OID 請求,這樣用戶就不會注意到性能有任何延遲。 有關 OID 請求計時的特定信息,請參閱 NdisTimedOidComplete 驅動程序驗證程序規則。
此 OID 序列化規則的一個例外是,對于使用 WDI 的Wi-Fi微型端口適配器,如果它們花費的時間太長而無法完成以前的 OID,則可能會看到第二個 OID 請求。 以下示例說明在這種情況下會發生什么情況:
- 第一個 OID 請求傳遞到 WDI 微型端口適配器;
- NIC 不會在驅動程序指定的時間限制內響應 OID;
- WDI 調用驅動程序的 MINIPORT_WDI_ADAPTER_HANG_DIAGNOSE 回調函數來收集有關 NIC 的診斷數據;
- 第一個 OID 不再被視為阻止序列化。 這意味著 WDI 微型端口適配器現在可以接收其他 OID 請求,即使第一個 OID 已序列化。 但是,這些其他 OIDS 也會序列化,這意味著 WDI 微型端口適配器不會同時處理 (第一個仍掛起的 OID以及第二個 OID) ;
2. 處理微型端口適配器中的 OID 請求
NDIS 調用微型端口驅動程序的 MiniportOidRequest 函數以提交 OID 請求以查詢或設置驅動程序中的信息。 NDIS 代表它自己調用 MiniportOidRequest 函數,或者代表調用 NdisOidRequest 或 NdisFOidRequest 函數的過度驅動程序調用 MiniportOidRequest 函數。
NDIS 傳遞 MiniportOidRequest 指向包含請求信息的 NDIS_OID_REQUEST 結構的指針。 請求結構包含一個OID_Xxx標識符,該標識符指示請求的類型以及用于定義請求數據的其他成員。
Timeout 成員指定請求的超時時間(以秒為單位)。 如果超時在驅動程序完成請求之前過期,NDIS 可以重置驅動程序或取消請求。
RequestId 成員指定請求的可選標識符。 微型端口驅動程序可以將狀態指示的 RequestId 成員設置為從關聯 OID 請求的 RequestId 成員獲取的值。 通常,微型端口驅動程序可以忽略此成員。 如果驅動程序必須設置此成員,則特定 OID 的引用頁將提供所需的值。 有關狀態指示的詳細信息,請參閱 適配器狀態指示。
成功處理 OID 集請求的微型端口驅動程序必須在從 OID 集請求返回時在 NDIS_OID_REQUEST 結構中設置 SupportedRevision 成員。 SupportedRevision 成員通知發起方驅動程序支持的修訂請求。 例如,微型端口驅動程序可以創建Xxx_REVISION_2結構,提供適合Xxx_REVISION_1結構的值,并使用零填充結構的其余部分。 微型端口驅動程序將在 SupportedRevision 成員中報告Xxx_REVISION_1。 在這種情況下,可支持Xxx_REVISION_2的協議驅動程序將使用微型端口驅動程序支持的Xxx_REVISION_1信息。?
微型端口驅動程序可以通過返回成功或失敗狀態同步完成 OID 請求。
微型端口驅動程序可以通過返回NDIS_STATUS_PENDING異步完成 OID 請求。 在這種情況下,微型端口驅動程序必須調用 NdisMOidRequestComplete 函數才能完成操作。
如果 MiniportOidRequest 返回NDIS_STATUS_PENDING,則在掛起的請求完成之前,NDIS 不會使用針對適配器的另一個請求調用 MiniportOidRequest 。
NDIS 可以調用微型端口驅動程序的 MiniportCancelOidRequest 函數來取消 OID 請求。
3. 微型端口適配器直接 OID 請求
為了支持直接 OID 請求路徑,微型端口驅動程序在NDIS_MINIPORT_DRIVER_CHARACTERISTICS結構中提供 MiniportXxx 函數入口點,NDIS 為微型端口驅動程序提供 NdisMXxx 函數。
直接 OID 請求接口類似于標準 OID 請求接口。 例如, NdisMDirectOidRequestComplete 和 MiniportDirectOidRequest 函數類似于 NdisMOidRequestComplete 和 MiniportOidRequest 函數。
注意 NDIS 6.1 支持用于直接 OID 請求接口的特定 OID。 不支持 NDIS 6.1 和某些 NDIS 6.1 OID 之前存在的 OID。
微型端口驅動程序必須能夠處理未序列化的直接 OID 請求。 與標準 OID 請求接口不同,NDIS 不會將直接 OID 請求與通過直接 OID 接口或標準 OID 請求接口發送的其他請求序列化。 此外,微型端口驅動程序必須能夠在 IRQL <= DISPATCH_LEVEL 處理直接 OID 請求。
若要支持直接 OID 請求接口,請使用標準 OID 請求接口的文檔。下表顯示了直接 OID 請求接口中的函數與標準 OID 請求接口之間的關系。
直接 OID 函數 | 標準 OID 函數 |
---|---|
MiniportDirectOidRequest?? ? | MiniportOidRequest |
MiniportCancelDirectOidRequest?? | ?MiniportCancelOidRequest |
NdisMDirectOidRequestComplete?? ? | NdisMOidRequestComplete |
4. 微型端口適配器同步 OID 請求
為了支持同步 OID 請求路徑,微型端口驅動程序在調用 NdisMRegisterMiniportDriver 函數時,在 NDIS_MINIPORT_DRIVER_CHARACTERISTICS 結構中提供 MiniportSynchronousOidRequest 函數入口點。
對于微型端口驅動程序, 同步 OID 請求接口 不同于常規和直接 OID 請求接口,即微型端口驅動程序不必注冊異步完成回調函數。 這是因為路徑的同步性質。 口。
備注: NDIS 6.80 支持與同步 OID 請求接口配合使用的特定 OID。 不支持 NDIS 6.80 和某些 NDIS 6.80 OID 之前存在的 OID。?
若要支持同步 OID 請求接口,請使用標準 OID 請求接口的文檔。 下表顯示了同步 OID 請求接口和標準 OID 請求接口中的函數之間的關系:
同步 OID 函數 | 標準 OID 函數 |
---|---|
MiniportSynchronousOidRequest?? ? | MiniportOidRequest |
微型端口驅動其它信息?
1. 微型端口適配器狀態指示
微型端口驅動程序調用 NdisMIndicateStatusEx 函數來報告微型端口適配器的狀態更改。 微型端口驅動程序將 NdisMIndicateStatusEx 傳遞指向包含狀態信息的 NDIS_STATUS_INDICATION 結構的指針。
狀態指示包括用于標識狀態類型和狀態更改原因的信息。
微型端口驅動程序應將 SourceHandle 成員設置為 NDIS 傳遞給 MiniportInitializeEx 函數的 MiniportAdapterHandle 參數的句柄。 如果狀態指示與 OID 請求相關聯,微型端口驅動程序可以設置 DestinationHandle 和 RequestId 成員,以便 NDIS 可以提供特定協議綁定的狀態指示。
2. 微型端口適配器設備 PnP 事件通知
NDIS 調用微型端口驅動程序的 MiniportDevicePnPEventNotify 函數,以通知驅動程序即插即用 (PnP) 事件。
NDIS 提供描述 PnP 事件的事件代碼。 代碼可以指示適配器已意外從系統中刪除,或者主機系統的電源配置文件已更改。
如果事件代碼指示電源配置文件已更改,則 NDIS 還會指示更改的類型。 系統使用電池電源運行,或者系統使用交流電源運行。
微型端口驅動程序應相應地調整適配器設置。?
3. 微型端口適配器掛起檢查和重置操作
對于所有 NDIS 6.83 及更高版本的驅動程序,不建議檢查掛起 (CFH) 和重置操作。?
NDIS 調用 NDIS 微型端口驅動程序的 MiniportCheckForHangEx 函數來檢查 NDIS 適配器的操作狀態,該適配器表示網絡接口卡 (NIC) 。 MiniportCheckForHangEx 檢查適配器的內部狀態,如果檢測到適配器無法正常運行,則返回 TRUE 。
默認情況下,NDIS 大約每 2 秒調用 一次 MiniportCheckForHangEx 。 如果 MiniportCheckForHangEx 返回 TRUE,NDIS 將調用 NDIS 微型端口驅動程序的 MiniportResetEx 函數。 如果默認超時值 2 秒太小,微型端口驅動程序可以在初始化時設置不同的值,如下所示:
- 將 NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES 結構的 CheckForHangTimeInSeconds 成員設置為非零值;
- 在 NdisMSetMiniportAttributes 函數的 MiniportAttributes 參數中傳遞 NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES 結構;
CheckForHangTimeInSeconds 的值應大于微型端口驅動程序的初始化時間。 但是,如果驅動程序初始化所花費的時間超過 CheckForHangTimeInSeconds 秒 ,則此超時將過期,導致 NDIS 調用驅動程序的 MiniportCheckForHangEx 函數。 如果 MiniportCheckForHangEx 返回 TRUE,則 NDIS 將調用驅動程序的 MiniportResetEx 函數。 因此,應將驅動程序的 MiniportCheckForHangEx 函數與驅動程序初始化同步,以便在驅動程序尚未完成初始化時 ,MiniportCheckForHangEx 不會返回 TRUE 。
如果微型端口驅動程序在對 MiniportCheckForHangEx 的連續兩次調用中未完成 OID 請求,則 NDIS 可以調用驅動程序的 MiniportResetEx 函數。 對于某些 OID 請求,如果驅動程序在對 MiniportCheckForHangEx 的連續四次調用中未完成請求,則 NDIS 會調用 MiniportResetEx。
重置操作不會影響 微型端口適配器的操作狀態。 此外,重置操作正在進行時,適配器的狀態可能會更改。 例如,當正在進行重置操作時,NDIS 可能會調用驅動程序的 MiniportPause 函數。 在這種情況下,驅動程序可以按任何順序完成重置或暫停操作,同時遵循每個操作的正常要求。
對于重置操作,驅動程序可能會使傳輸請求數據包失敗,也可以讓數據包保持排隊并稍后完成。 但是,應注意,在傳輸數據包掛起時,過分的驅動程序無法完成暫停操作。
微型端口驅動程序可以通過返回成功或失敗狀態同步完成重置請求。 驅動程序可以通過返回 NDIS_STATUS_PENDING異步完成重置請求。 在這種情況下,驅動程序必須調用 NdisMResetComplete 才能完成操作。
4. NDIS 6.83 及更高版本中的檢查掛起和重置操作:
在 NDIS 6.83 之前的版本中,由于電池使用時間問題,不建議對 Always On、Always Connected (AOAC) 系統執行檢查掛起 (CFH) 和重置操作。 但是,驅動程序仍可以通過實現可選的 MiniportCheckForHangEx 和 MiniportResetEx 回調函數在其他非 AOAC Windows 系統上使用 CFH。
從 NDIS 6.83 開始,不建議 在所有 Windows 系統上使用這些回調函數,而不考慮電源功能。 盡管在 NDIS 6.83 及更高版本中使用 CFH 不是徽標測試沖突,但 NDIS 驅動程序應使用下表來獲取有關其用法的指導。
調用方 | 建議 | 說明 |
---|---|---|
面向 AOAC 系統的驅動程序?? ? | 不得實現?? ? | 由于定期檢查掛起活動而導致電池使用時間問題 |
面向 Windows Server 系統的驅動程序?? ? | 不得實現?? ? | CPU 壓力大時導致問題 |
虛擬 (僅限軟件) 微型端口驅動程序?? ? | 不得實現?? ? | 沒有硬件就無法重置 |
其他新的 NDIS 6.83 及更高版本的驅動程序 | 不應實現 | |
其他現有的 NDIS 6.82 和更早代碼 | 不需要更改,但應考慮在將來的版本中刪除“掛起檢查”和“重置” |
5. NDIS 管理信息和 OID
每個微型端口驅動程序都包含自己的 管理信息庫 (MIB) ,這是一個信息塊,驅動程序在其中存儲管理實體可以查詢或設置的動態配置信息和統計信息。 以太網多播地址列表是配置信息的示例。 接收的廣播數據包數是統計信息的一個示例。 MIB 中的每個信息元素稱為對象。 為了引用每個此類托管對象,NDIS (OID) 定義對象標識符 。 因此,如果管理實體想要查詢或設置特定的托管對象,則必須為該對象提供特定的 OID。
MIB 跟蹤三類對象:
- 所有 NDIS 微型端口驅動程序通用的對象;
- 特定于給定介質類型(如以太網)的所有 NDIS 微型端口驅動程序的對象;
- 特定于特定供應商實現的對象;
WDK 文檔的“網絡參考”部分記錄了 常規 和必需的媒體特定 OID。 特定網絡接口卡 (NIC) 驅動程序的實現特定 OID 應在給定微型端口驅動程序隨附的文檔中列出和說明。
對象被歸類為 操作特征 (例如,多播地址列表) 或 統計信息 接收的廣播數據包,它們也分類為必需或可選。 常規類或特定于媒體的類的所有操作特征對象都是強制性的,但只有一些統計信息對象是必需的。 所有特定于實現的對象都分類為必需對象。