管理 NDIS 选择性挂起的 IRP 资源
如果微型端口驱动程序支持并启用 NDIS 选择性挂起,则 NDIS 调用 MiniportIdleNotification ,以在网络适配器变为非活动状态时向驱动程序发出空闲通知。 微型端口驱动程序处理此通知时,可能需要向基础总线驱动程序发出 I/O 请求数据包 (IRP) 。 这些 IRP 通知总线驱动程序适配器的空闲状态,并请求确认适配器可以转换为低功耗状态。
微型端口驱动程序颁发的 IRP 特定于总线。 例如,当 NDIS 调用 MiniportIdleNotification 时,USB 微型端口会发出 USB 空闲请求 (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) IRP 到基础 USB 总线驱动程序。
初始化驱动程序后,NDIS 可能会多次向微型端口驱动程序发出空闲通知。 因此,建议驱动程序在调用驱动程序的 MiniportInitializeEx 函数的上下文中为 USB 空闲请求 IRP 分配资源。
以下示例演示微型端口驱动程序如何分配 IRP 资源。
//
// MiniportInitializeEx()
//
// In the miniport's initialization routine, the miniport should allocate
// an IRP. It can also set up the USB_IDLE_CALLBACK_INFO structure that
// will be used with each successive USB idle request.
//
NDIS_STATUS MiniportInitializeEx(
_In_ NDIS_HANDLE MiniportAdapterHandle,
_In_ NDIS_HANDLE MiniportDriverContext,
_In_ PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters
)
{
PIRP UsbSsIrp;
USB_IDLE_CALLBACK_INFO UsbSsCallback;
...
UsbSsIrp = IoAllocateIrp(Adapter->Fdo->StackSize, FALSE);
if (!UsbSsIrp)
{
// Handle failure
return NDIS_STATUS_RESOURCES;
}
UsbSsCallback.IdleCallback = MiniportUsbIdleRequestCallback;
UsbSsCallback.IdleContext = Adapter;
// Save these in the adapter structure for later use
Adapter->UsbSsIrp = UsbSsIrp;
Adapter->UsbSsCallback = UsbSsCallback;
...
}
如果微型端口驱动程序在调用 MiniportInitializeEx 期间分配 IRP 资源,则驱动程序必须在调用 MiniportHaltEx 期间释放这些资源。
以下示例演示微型端口驱动程序如何释放 IRP 资源。
//
// MiniportHaltEx
//
// During halt (or when the miniport performs its cleanup from
// MiniportInitializeEx) the miniport should free the IRP allocated
// earlier.
//
VOID MiniportHaltEx(
_In_ NDIS_HANDLE MiniportAdapterContext,
_In_ NDIS_HALT_ACTION HaltAction
)
{
...
if (Adapter->UsbSsIrp)
{
IoFreeIrp(Adapter->UsbSsIrp);
Adapter->UsbSsIrp = NULL;
}
...
}