Verwalten von IRP-Ressourcen für das selektive Anhalten von NDIS
Wenn ein Miniporttreiber das selektive Anhalten von NDIS unterstützt und aktiviert, ruft NDIS MiniportIdleNotification auf, um eine Leerlaufbenachrichtigung an den Treiber auszusetzen, wenn der Netzwerkadapter inaktiv wird. Wenn der Miniporttreiber diese Benachrichtigung verarbeitet, muss er möglicherweise E/A-Anforderungspakete (IRPs) an den zugrunde liegenden Bustreiber ausstellen. Diese IRPs benachrichtigen den Bustreiber über den Leerlaufzustand des Adapters und fordern eine Bestätigung an, dass der Adapter in einen Energiesparzustand übergehen kann.
Vom Miniporttreiber ausgegebene IRPs sind busspezifisch. Wenn NDIS beispielsweise MiniportIdleNotification aufruft, gibt der USB-Miniport eine USB-Leerlaufanforderung (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) an den zugrunde liegenden USB-Bustreiber aus.
NDIS kann die Benachrichtigung im Leerlauf mehrmals an den Miniporttreiber ausgeben, nachdem der Treiber initialisiert wurde. Daher wird empfohlen, dass der Treiber die Ressourcen für die USB-Idle-Anforderung IRP im Kontext des Aufrufs der MiniportInitializeEx-Funktion des Treibers ordnet.
Das folgende Beispiel zeigt, wie der Miniporttreiber die IRP-Ressourcen zuordnet.
//
// 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;
...
}
Wenn der Miniporttreiber die IRP-Ressourcen während des Aufrufs von MiniportInitializeEx zuweist, muss der Treiber diese Ressourcen während des Aufrufs von MiniportHaltEx freigeben.
Das folgende Beispiel zeigt, wie der Miniporttreiber die IRP-Ressourcen freigibt.
//
// 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;
}
...
}