Поделиться через


Управление ресурсами IRP для выборочной приостановки NDIS

Если драйвер минипорта поддерживает и включает выборочную приостановку NDIS, NDIS вызывает MiniportIdleNotification , чтобы выдать драйверу уведомление о бездействии, если сетевой адаптер становится неактивным. Когда водитель мини-порта обрабатывает это уведомление, ему может потребоваться выдать пакеты запросов ввода-вывода (IRP) базовому драйверу шины. Эти irP уведомляют водителя шины о состоянии простоя адаптера и запрашивают подтверждение того, что адаптер может перейти в состояние с низким энергопотреблением.

IrP, выданные водителем минипорта, относятся к шине. Например, когда NDIS вызывает MiniportIdleNotification, минипорт USB выдает запрос на простой USB (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) для базового драйвера шины USB.

NDIS может выдавать уведомление о бездействии водителю минипорта много раз после инициализации драйвера. Поэтому рекомендуется, чтобы драйвер выделил ресурсы для IRP запроса простоя USB в контексте вызова функции MiniportInitializeEx драйвера.

В следующем примере показано, как драйвер мини-порта выделяет ресурсы 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;
    ...
    }

Если драйвер мини-порта выделяет ресурсы IRP во время вызова MiniportInitializeEx, драйвер должен освободить эти ресурсы во время вызова MiniportHaltEx.

В следующем примере показано, как драйвер мини-порта освобождает ресурсы 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;
        }
    ...
    }