Compartilhar via


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;
        }
    ...
    }