Gerenciando recursos irp para suspensão seletiva do NDIS
Se um driver de miniporta der suporte e habilitar a suspensão seletiva do NDIS, o NDIS chamará MiniportIdleNotification para emitir uma notificação ociosa para o driver se o adaptador de rede ficar inativo. Quando o driver de miniporta lida com essa notificação, pode ser necessário emitir IRPs (pacotes de solicitação de E/S) para o driver de ônibus subjacente. Esses IRPs notificam o driver de barramento sobre o estado ocioso do adaptador e solicitam a confirmação de que o adaptador pode fazer a transição para um estado de baixa potência.
Os IRPs emitidos pelo motorista do miniporto são específicos do ônibus. Por exemplo, quando o NDIS chama MiniportIdleNotification, o miniporto USB emite um IRP de solicitação ociosa usb (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) para o driver de barramento USB subjacente.
O NDIS pode emitir a notificação ociosa para o driver de miniporta muitas vezes após o driver ter sido inicializado. Portanto, recomendamos que o driver aloque os recursos para o IRP de solicitação ociosa USB no contexto da chamada para a função MiniportInitializeEx do driver.
O exemplo a seguir mostra como o driver de miniporto aloca os 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;
...
}
Se o driver de miniporto alocar os recursos IRP durante a chamada para MiniportInitializeEx, o driver deverá liberar esses recursos durante a chamada para MiniportHaltEx.
O exemplo a seguir mostra como o driver de miniporta libera os 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;
}
...
}