Freigeben über


Implementieren einer MiniportIdleNotification-Handlerfunktion

NDIS ruft die MiniportIdleNotification-Handlerfunktion des Miniport-Treibers auf, um den Netzwerkadapter selektiv anzusetzen. Der Adapter wird angehalten, wenn NDIS den Adapter in einen Energiesparzustand übergehen.

Der Miniporttreiber kann ein Veto gegen die Leerlaufbenachrichtigung einwenden, wenn der Netzwerkadapter noch verwendet wird. Dazu gibt der Treiber NDIS_STATUS_BUSY von der MiniportIdleNotification-Handlerfunktion zurück.

Hinweis Der Miniporttreiber kann kein Veto gegen die Idle-Benachrichtigung ausführen, wenn der ForceIdle-Parameter der MiniportIdleNotification-Handlerfunktion auf TRUE festgelegt ist.

Wenn der Miniporttreiber kein Veto gegen die Leerlaufbenachrichtigung einhält, muss er möglicherweise busspezifische E/A-Anforderungspakete (IRPs) an den zugrunde liegenden Bustreiber ausstellen. Diese IRPs benachrichtigen den Bustreiber über den Leerlaufzustand des Adapters und fordern eine Bestätigung an, dass der Adapter in einen Energiesparzustand wechseln kann.

Wenn beispielsweise MiniportIdleNotification aufgerufen wird, bereitet der USB-Miniporttreiber ein E/A-Anforderungspaket (IRP) für eine USB-Leerlaufanforderung (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) vor. Wenn der Miniporttreiber den IRP vorbereitet, muss er eine Rückruffunktion angeben. Der Treiber muss auch entweder IoSetCompletionRoutine oder IoSetCompletionRoutineEx aufrufen, um eine Vervollständigungsroutine für das IRP anzugeben. Der Miniporttreiber ruft dann IoCallDriver auf, um die IRP an den USB-Bustreiber auszusetzen.

Hinweis Der USB-Bustreiber schließt die IRP nicht sofort ab. Der IRP wird durch den Übergang mit geringem Stromverbrauch in einem ausstehenden Zustand belassen. Der Bustreiber schließt die IRP nur ab, wenn er vom Miniporttreiber abgebrochen wird oder ein Hardwareereignis auftritt, z. B. die überraschende Entfernung des Netzwerkadapters aus dem USB-Hub.

Im Folgenden finden Sie ein Beispiel für eine MiniportIdleNotification-Handlerfunktion für einen USB-Miniporttreiber. Dieses Beispiel zeigt die Schritte, die beim Ausgeben einer USB-Idle-Anforderungs-IRP an den zugrunde liegenden USB-Treiber erforderlich sind. Dieses Beispiel zeigt auch, wie die IRP-Ressourcen, die zuvor in MiniportInitializeEx zugeordnet wurden, für das IRP wiederverwendet werden können.

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

Richtlinien zum Implementieren einer Rückrufroutine für eine USB-Idle-Anforderungs-IRP finden Sie unter Implementieren einer IRP-Rückrufroutine für usb-Leerlaufanforderung.