取消 NDIS 选择性挂起空闲通知

如果网络适配器在空闲超时期间处于非活动状态,NDIS 将启动选择性挂起操作。 通过此操作,网络适配器将转换为低功耗状态。 NDIS 通过向微型端口驱动程序发出空闲通知来开始此操作。 有关此操作的详细信息,请参阅 处理 NDIS 选择性挂起空闲通知

NDIS 调用 MiniportIdleNotification 处理程序函数来通知驱动程序基础网络适配器似乎处于空闲状态。 发出空闲通知后,如果满足以下一个或多个条件,NDIS 将取消挂起的空闲通知:

  • 覆盖协议或筛选器驱动程序向微型端口驱动程序发出发送数据包请求或对象标识符 (OID) 请求。

    有关 NDIS 如何为此方案取消空闲通知的详细信息,请参阅 由于驱动程序活动过度而取消空闲通知

  • 基础适配器发出唤醒事件信号,例如接收数据包或检测其媒体连接状态的更改。

    有关 NDIS 如何为此方案取消空闲通知的详细信息,请参阅 由于唤醒事件而取消空闲通知

NDIS 通过调用基础微型端口驱动程序的 MiniportCancelIdleNotification 处理程序函数来取消空闲通知。 调用此函数时,微型端口驱动程序必须完成空闲通知,才能将适配器恢复为全功率状态。 有关此过程的指南,请参阅 完成 NDIS 选择性挂起空闲通知

有关如何实现 MiniportCancelIdleNotification 处理程序函数的详细信息,请参阅 实现 MiniportCancelIdleNotification 处理程序函数

由于驱动程序活动过度而取消空闲通知

NDIS 监视发送到其网络适配器已挂起且处于低功耗状态的微型端口驱动程序的请求和 OID 请求。 发生这种情况时,NDIS 会取消未完成的空闲通知,以便网络适配器可以恢复为全功率状态。

取消空闲通知时,NDIS 和微型端口驱动程序按照以下步骤操作:

  1. NDIS 调用 MiniportCancelIdleNotification 处理程序函数来取消未完成的空闲通知。 调用此处理程序函数时,微型端口驱动程序必须取消任何特定于总线的 I/O 请求数据包, (IRP) 之前可能已针对空闲通知发出。

    例如,调用 MiniportCancelIdleNotification 时,USB 网络适配器的微型端口执行以下步骤:

    1. 微型端口驱动程序取消挂起的 USB 空闲请求 (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) IRP。 当 NDIS 调用驱动程序的 MiniportIdleNotification 函数时,微型端口驱动程序以前向基础 USB 总线驱动程序发出了此 IRP。 微型端口驱动程序通过调用 IoCancelIrp 取消此 IRP。

    2. 当总线驱动程序取消 USB 空闲请求 IRP 时,它会为 IRP 调用微型端口驱动程序的完成例程。 此调用通知驱动程序 IRP 已完成,网络适配器可以转换为全电源状态。 在完成例程的上下文中,驱动程序调用 NdisMIdleNotificationComplete 以通知 NDIS 网络适配器可以转换为全功率状态。

    注意根据取消特定于总线的空闲请求的依赖项,微型端口驱动程序在调用 MiniportCancelIdleNotification 的上下文中同步调用 NdisMIdleNotificationComplete,或者在 MiniportCancelIdleNotification 返回后异步调用 NdisMIdleNotificationComplete。

    有关如何实现 USB 空闲请求 IRP 完成例程的详细信息,请参阅 实现 USB 空闲请求 IRP 完成例程

  2. 在微型端口驱动程序取消空闲通知的任何特定于总线的 IRP 后,它将调用 NdisMIdleNotificationComplete。 此调用通知 NDIS 空闲通知已完成。 然后,NDIS 通过将网络适配器转换为全功率状态来完成选择性挂起操作。

    调用 NdisMIdleNotificationComplete 时,NDIS 执行以下步骤:

    1. NDIS 向基础总线驱动程序 发出IRP_MN_SET_POWER 问题。 此 IRP 请求总线驱动程序将网络适配器的电源状态设置为 PowerDeviceD0。

    2. NDIS 向微型端口驱动程序发出 OID_PNP_SET_POWER 的 OID 集请求。 在此 OID 请求中,NDIS 指定网络适配器现在正在转换为 NdisDeviceStateD0 的全功率状态。

      处理此 OID 集请求时,驱动程序将准备适配器以执行全功率操作。 这包括将接收和发送引擎还原到转换到低功耗状态之前的相同状态。 然后,驱动程序使用 NDIS_STATUS_SUCCESS 完成 OID 请求。

下图显示了 NDIS 取消向 USB 网络适配器的微型端口驱动程序发出的空闲通知时所涉及的步骤。

显示 USB 网络适配器的空闲通知恢复过程的示意图。

由于唤醒事件而取消空闲通知

在网络适配器转换为低功耗状态之前,NDIS 会向网络适配器发出 OID_PM_PARAMETERS 的 OID 集请求。 此 OID 请求指定适配器可以发出信号以恢复为全功率状态的唤醒事件类型。 对于 NDIS 选择性挂起,适配器配置为发出以下任何唤醒事件的信号:

  • 与先前通过OID_PM_ADD_WOL_PATTERNOID_GEN_CURRENT_PACKET_FILTER的 OID 集请求配置的筛选器匹配的数据包的接收。

  • 适配器上的媒体连接状态更改。

当 NDIS 由于网络适配器生成的唤醒信号而取消空闲通知时,NDIS 和微型端口驱动程序遵循以下步骤:

  1. 总线驱动程序完成 NDIS 在将适配器转换为低功耗状态之前发出的 IRP_MN_WAIT_WAKE 。 完成 IRP 后,总线驱动程序会通知 NDIS 网络适配器已生成唤醒信号。

  2. NDIS 调用 MiniportCancelIdleNotification 处理程序函数来启动取消空闲通知的操作。 此操作涉及的步骤与 由于驱动程序活动过度而取消空闲通知中所述的步骤相同。

例如,下图显示了由于 USB 网络适配器发出唤醒事件而 NDIS 取消空闲通知时所涉及的步骤。

显示 USB 网络适配器的 NDIS 空闲通知唤醒过程的示意图。