次の方法で共有


NDIS セレクティブ サスペンドの IRP リソースの管理

ミニポート ドライバーがサポートし、NDIS 選択的中断を有効にする場合、NDIS は、ネットワーク アダプターが非アクティブになった場合にドライバーにアイドル状態の通知を発行する MiniportIdleNotification を呼び出します。 ミニポート ドライバーは、この通知を処理する場合、基盤のバス ドライバーに I/O 要求パケット (IRP) を発行する必要があります。 これらの IRP は、アダプターのアイドル状態についてバス ドライバーに通知し、アダプターが低電力状態に切り替えできることを確認するように要求します。

ミニポート ドライバーによって発行される IRP は、バス固有です。 たとえば、NDIS がMiniportIdleNotification を呼び出すと、USB ミニポートは、基盤の USB バス ドライバーに USB アイドル要求 (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) IRP を発行します。

NDIS は、ドライバーが初期化された後、ミニポート ドライバーに何度もアイドル状態の通知を発行することがあります。 そのため、ドライバーにより、その MiniportInitializeEx 関数への呼び出しのコンテキストで USB アイドル要求 IRP のリソースを割り当てることをお勧めします。

次の例は、ミニポート ドライバーが 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;
    ...
    }

ミニポート ドライバーは、MiniportInitializeEx への呼び出し中に IRP リソースを割り当てる場合、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;
        }
    ...
    }