實作 MiniportIdleNotification 處理常式函式

NDIS 會呼叫迷你埠驅動程式的 MiniportIdleNotification 處理常式函式,以選擇性地暫停網路介面卡。 當 NDIS 將介面卡轉換為低電源狀態時,介面卡會暫停。

如果網路介面卡仍在使用中,迷你埠驅動程式就可以通過閒置通知。 驅動程式會從 MiniportIdleNotification 處理常式函式傳回NDIS_STATUS_BUSY,以執行此動作。

注意如果MiniportIdleNotification處理常式函式的ForceIdle參數設定為TRUE,迷你埠驅動程式就無法傳送閒置通知。

如果迷你埠驅動程式沒有閒置通知,則可能必須發出匯流排特定的 I/O 要求封包, (IRP) 基礎匯流排驅動程式。 這些 IRP 會通知匯流排驅動程式介面卡的閒置狀態,並要求確認介面卡可以轉換為低電源狀態。

例如,呼叫 MiniportIdleNotification 時,USB 迷你埠驅動程式會針對 USB 閒置要求準備 I/O 要求封包 (IRP) , (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) 。 當迷你埠驅動程式準備 IRP 時,它必須指定回呼函式。 驅動程式也必須呼叫 IoSetCompletionRoutineIoSetCompletionRoutineEx 來指定 IRP 的完成常式。 迷你埠驅動程式接著會呼叫 IoCallDriver ,向 USB 匯流排驅動程式發出 IRP。

注意 USB 匯流排驅動程式不會立即完成 IRP。 IRP 會透過低電源轉換處於擱置狀態。 只有在迷你埠驅動程式取消 IRP 或硬體事件發生時,匯流排驅動程式才會完成 IRP,例如從 USB 中樞意外移除網路介面卡。

以下是 USB 迷你埠驅動程式的 MiniportIdleNotification 處理常式函式範例。 此範例示範向基礎 USB 驅動程式發出 USB 閒置要求 IRP 的相關步驟。 此範例也會示範先前在 MiniportInitializeEx中配置的 IRP 資源如何重複使用給 IRP。

//
// MiniportIdleNotification()
//
// This routine is invoked by NDIS when it has detected that the miniport
// is idle.  The miniport must prepare to issue its selective suspend IRP
// to the USB stack.  The driver can return NDIS_STATUS_BUSY if it is
// unwilling to become idle at this moment; NDIS will then retry later.
// Otherwise, the miniport should return NDIS_STATUS_PENDING.
//
NDIS_STATUS MiniportIdleNotification(
    _In_ NDIS_HANDLE MiniportAdapterContext,
    _In_ BOOLEAN ForceIdle
    )
{
    PIO_STACK_LOCATION IoSp;

    IoReuseIrp(Adapter->UsbSsIrp, STATUS_NOT_SUPPORTED);

    IoSp = IoGetNextIrpStackLocation(Adapter->UsbSsIrp);
    IoSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    IoSp->Parameters.DeviceIoControl.IoControlCode 
            = IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION;
    IoSp->Parameters.DeviceIoControl.InputBufferLength 
            = sizeof(Adapter->UsbSsCallback);
    IoSp->Parameters.DeviceIoControl.Type3InputBuffer 
            = Adapter->UsbSsCallback;

    IoSetCompletionRoutine(
            Adapter->UsbSsIrp,
            MiniportUsbIdleRequestCompletion,
            Adapter,
            TRUE,
            TRUE,
            TRUE);

    NtStatus = IoCallDriver(Adapter->Fdo, Adapter->UsbSsIrp);
    if (!NT_SUCCESS(NtStatus))
    {
       return NDIS_STATUS_FAILURE;
    }

    return NDIS_STATUS_PENDING;
}

如需實作 USB 閒置要求 IRP 回呼常式的指導方針,請參閱 實作 USB 閒置要求 IRP 回呼常式