Hantera IRP-resurser för selektiv NDIS-paus
Om en miniportdrivrutin stöder och aktiverar NDIS selektiv avstängning, anropar NDIS MiniportIdleNotification för att utfärda ett vilomeddelande till drivrutinen om nätverkskortet blir inaktivt. När miniportdrivrutinen hanterar det här meddelandet kan den behöva utfärda I/O-begärandepaket (IRP:er) till den underliggande bussdrivrutinen. Dessa IRP:er meddelar bussdrivrutinen om adapterns inaktiva tillstånd och begär bekräftelse på att adaptern kan övergå till ett lågeffektläge.
IRP:er som utfärdas av miniportdrivrutinen är specifika för bussen. När NDIS till exempel anropar MiniportIdleNotificationutfärdar USB-miniporten en USB-inaktiv begäran (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) IRP till den underliggande USB-bussdrivrutinen.
NDIS kan utfärda ett inaktivt meddelande till miniportdrivrutinen flera gånger efter att drivrutinen har initierats. Därför rekommenderar vi att drivrutinen allokerar resurserna för IRP för USB-inaktiv begäran i samband med anropet till drivrutinens MiniportInitializeEx-funktion.
I följande exempel visas hur miniportdrivrutinen allokerar IRP-resurserna.
//
// 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;
...
}
Om miniportdrivrutinen allokerar IRP-resurserna under anropet till MiniportInitializeExmåste drivrutinen frigöra dessa resurser under anropet till MiniportHaltEx.
I följande exempel visas hur miniportdrivrutinen frigör IRP-resurserna.
//
// 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;
}
...
}