Udostępnij za pośrednictwem


Zarządzanie zasobami IRP w kontekście selektywnego zawieszenia NDIS

Jeśli sterownik miniportu obsługuje i włącza selektywne wstrzymanie NDIS, to NDIS wywołuje MiniportIdleNotification, aby wysłać powiadomienie o bezczynności do sterownika, jeśli adapter sieciowy stanie się nieaktywny. Gdy sterownik miniportu obsługuje to powiadomienie, może być konieczne wysłanie pakietów żądań we/wy (IRPs) do bazowego sterownika magistrali. IRPs powiadamiają sterownik magistrali o stanie bezczynności adaptera i żądają potwierdzenia, że adapter może przejść do stanu niskiego poboru mocy.

IRP wydawane przez sterownik miniportu są specyficzne dla szyny. Na przykład, gdy NDIS dokonuje wywołania MiniportIdleNotification, miniport USB przesyła żądanie bezczynności USB (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) IRP do bazowego sterownika magistrali USB.

NDIS może kilkakrotnie wydawać powiadomienie o bezczynności do sterownika miniportu po zainicjowaniu sterownika. W związku z tym zaleca się, aby sterownik przydzielił zasoby dla bezczynnego żądania USB IRP w kontekście wywołania funkcji MiniportInitializeEx sterownika.

W poniższym przykładzie pokazano, jak sterownik miniportu przydziela zasoby 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;
    ...
    }

Jeśli sterownik miniportu przydziela zasoby IRP podczas wywołania do MiniportInitializeEx, sterownik musi zwolnić te zasoby podczas wywołania do MiniportHaltEx.

W poniższym przykładzie pokazano, jak sterownik miniportu zwalnia zasoby 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;
        }
    ...
    }