取消 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 函数时,微型端口驱动程序以前将此 IRP 颁发给基础 USB 总线驱动程序。 微型端口驱动程序通过调用 IoCancelIrp 取消此 IRP。

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

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

    有关如何实现 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 网络适配器的微型端口驱动程序颁发的空闲通知时所涉及的步骤。

diagram showing the idle notification resume process.

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

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

NDIS 和微型端口驱动程序在 NDIS 因网络适配器生成的唤醒信号而取消空闲通知时,请执行以下步骤:

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

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

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

diagram showing the idle notification wake-up process.