windows网络适配器驱动开发-使用 NetAdapterCx PLDR 恢复无响应的 NIC(下)
实现 EVT_NET_DEVICE_COLLECT_RESET_DIAGNOSTICS重置和恢复顺序可以随时发生。 因此客户端驱动程序的 EVT_NET_DEVICE_COLLECT_RESET_DIAGNOSTICS 回调实现必须考虑以下事项NetAdapterCx 将 EVT_NET_DEVICE_COLLECT_RESET_DIAGNOSTICS 回调与 关机序列期间可能发生的其他回调同步。 客户端驱动程序可以假定 NetAdapterCx 不会调用数据包队列取消/停止、硬件释放和设备对象删除等回调直到 EVT_NET_DEVICE_COLLECT_RESET_DIAGNOSTICS 返回。客户端驱动程序在处理诊断集合时必须格外小心以避免死锁。 必须考虑到硬件可能已处于故障状态。EVT_NET_DEVICE_COLLECT_RESET_DIAGNOSTICS尽快完成这一点至关重要以便 PLDR 过程的其余部分可以继续进行。 EVT_NET_DEVICE_COLLECT_RESET_DIAGNOSTICS 必须可靠并且必须在 3 秒内返回。NetAdapterCx 始终在 PASSIVE_LEVEL 调用EVT_NET_DEVICE_COLLECT_RESET_DIAGNOSTICS。若要将诊断提交到 NetAdapterCx客户端驱动程序执行以下步骤从分页池或非分页池中预分配平面缓冲区以收集重置诊断。 驱动程序应预先分配此缓冲区以避免在设备重置期间出现内存不足错误。在EVT_NET_DEVICE_COLLECT_RESET_DIAGNOSTICS回调中通过调用 NetDeviceStoreResetDiagnostics API 将诊断作为平面数据缓冲区提交。 客户端驱动程序必须在 PASSIVE_LEVEL 调用 NetDeviceStoreResetDiagnostics API。在 NetDeviceStoreResetDiagnostics 返回后释放数据缓冲区。NetDeviceStoreResetDiagnostics API 只能在EVT_NET_DEVICE_COLLECT_RESET_DIAGNOSTICS回调中调用。 在以前的 NetDeviceStoreResetDiagnostics 返回后它也不能用于重新提交诊断数据。 违反上述任一情况都将导致 bug 检查。并且重置诊断的大小限制为 1 MB。客户端驱动程序如何请求 PLDR客户端驱动程序在检测到设备故障时使用 NetAdapterCx NetDeviceRequestReset API 触发 PLDR。 NetDeviceRequestReset 立即返回到客户端驱动程序。 NetAdapterCx 重置和恢复序列中所述的重置和恢复序列将触发并且与 NetDeviceRequestReset 调用异步。任何给定时间只能发生一个 PLDR 操作。 因此当 PLDR 操作已启动时 对 NetDeviceRequestReset 的后续调用不起作用。如果已启动关机序列则调用 NetDeviceRequestReset 也不起作用。NetAdapterCx 重置和恢复序列当 OS 或客户端驱动程序触发 PLDR 时将发生以下顺序收集重置诊断NetAdapterCx 调用客户端驱动程序的EVT_NET_DEVICE_COLLECT_RESET_DIAGNOSTICS回调以从故障设备收集诊断。 例如驱动程序可能会收集设备固件的快照。 此步骤是可选的仅当客户端驱动程序已注册 NET_DEVICE_RESET_CAPABILITIES 结构时才会发生。 否则NetAdapterCx 将跳过此步骤。执行 PLDRNetAdapterCx 执行平台级设备重置操作。 NetAdapterCx 电源回收硬件并拆除软件设备堆栈。下图演示了 NetAdapterCx 重置和恢复顺序注意: 重置顺序也受到系统其他电源事件变化影响