Administración de recursos irP para suspensión selectiva de NDIS
Si un controlador de minipuerto admite y habilita la suspensión selectiva de NDIS, NDIS llama a MiniportIdleNotification para emitir una notificación inactiva al controlador si el adaptador de red se vuelve inactivo. Cuando el controlador de minipuerto controla esta notificación, es posible que tenga que emitir paquetes de solicitud de E/S (IRP) al controlador de bus subyacente. Estos IRP notifican al controlador de bus el estado de inactividad del adaptador y solicitan confirmación de que el adaptador puede pasar a un estado de bajo consumo.
Los IRP emitidos por el controlador de minipuerto son específicos del bus. Por ejemplo, cuando NDIS llama a MiniportIdleNotification, el miniporte USB emite una solicitud de inactividad USB (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) IRP al controlador de bus USB subyacente.
NDIS puede emitir la notificación inactiva al controlador de minipuerto muchas veces después de que se haya inicializado el controlador. Por lo tanto, se recomienda que el controlador asigne los recursos para el IRP de solicitud inactiva USB en el contexto de la llamada a la función MiniportInitializeEx del controlador.
En el ejemplo siguiente se muestra cómo el controlador de minipuerto asigna los recursos 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;
...
}
Si el controlador de minipuerto asigna los recursos IRP durante la llamada a MiniportInitializeEx, el controlador debe liberar esos recursos durante la llamada a MiniportHaltEx.
En el ejemplo siguiente se muestra cómo el controlador de minipuerto libera los recursos 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;
}
...
}