다음을 통해 공유


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

Miniport 드라이버가 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;
        }
    ...
    }