USB, selektives Energiesparen

Hinweis

Dieser Artikel richtet sich an Gerätetreiberentwickler. Wenn Probleme mit einem USB-Gerät auftreten, lesen Sie bitte "Beheben von USB-C-Problemen in Windows".

Die selektive USB-Anhaltefunktion ermöglicht es dem Hubtreiber, einen einzelnen Port anzusetzen, ohne den Betrieb der anderen Ports auf dem Hub zu beeinträchtigen. Das selektive Anhalten von USB-Geräten ist besonders nützlich bei tragbaren Computern, da es hilft, Akkuleistung zu sparen. Viele Geräte, z. B. Fingerabdruckleser und andere Arten biometrischer Scanner, erfordern nur zeitweise Energie. Wenn das Gerät nicht verwendet wird, verringert das Anhalten solcher Geräte den Gesamtenergieverbrauch. Wichtiger ist, dass jedes Gerät, das nicht selektiv angehalten wird, verhindert, dass der USB-Hostcontroller seinen Übertragungszeitplan deaktiviert, der sich im Systemspeicher befindet. Direkte Speicherzugriffsübertragungen vom Hostcontroller an den Planer können verhindern, dass die Prozessoren des Systems tiefer in den Ruhezustand gelangen, z. B. C3.

Es gibt zwei unterschiedliche Mechanismen zum selektiven Anhalten eines USB-Geräts: IDle-Anforderungs-IRPs (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) und Festlegen von Netz-IRPs (IRP_MN_SET_POWER). Der zu verwendende Mechanismus hängt vom Betriebssystem und vom Typ des Geräts ab: zusammengesetzt oder nicht zusammengesetzt.

Auswählen eines selektiven Anhaltemechanismus

Clienttreiber für eine Schnittstelle auf einem zusammengesetzten Gerät, die die Schnittstelle für die Remoteaktivierung mit einem Wait Wake IRP (IRP_MN_WAIT_WAKE) aktivieren, müssen den IRP-Mechanismus (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) der Leerlaufanforderung verwenden, um ein Gerät selektiv anzuhalten.

Informationen zum Remote-Wake-up finden Sie unter:

Die Version des Windows-Betriebssystems bestimmt, wie Treiber für nicht zusammengesetzte Geräte das selektive Anhalten ermöglichen.

  • Windows XP: Unter Windows XP müssen alle Clienttreiber idle request IRPs (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) verwenden, um ihre Geräte herunterzuschalten. Clienttreiber dürfen keine WDM-Energie-IRPs verwenden, um ihre Geräte selektiv anzuhalten. Dadurch wird verhindert, dass andere Geräte selektiv angehalten werden.
  • Windows Vista und höhere Versionen von Windows: Treiberautoren haben mehr Auswahlmöglichkeiten zum Einschalten von Geräten in Windows Vista und in den späteren Versionen von Windows. Obwohl Windows Vista den IRP-Mechanismus für IRP-Anforderungen von Windows-Leerlauf unterstützt, sind Treiber nicht für die Verwendung erforderlich.

In der folgenden Tabelle sind die Szenarien aufgeführt, die die Verwendung des Idle-Anforderungs-IRP und die Szenarien erfordern, in denen ein WDM-Strom-IRP zum Anhalten eines USB-Geräts verwendet werden kann:

Windows-Version Funktion auf zusammengesetzten Geräten, zur Aktivierung bewaffnet Funktion auf zusammengesetzten Geräten, nicht für die Aktivierung bewaffnet Usb-Gerät mit einzelner Schnittstelle
Windows 7 Verwenden von Idle-Anforderungs-IRP Verwenden von WDM-Energie-IRP Verwenden von WDM-Energie-IRP
Windows Server 2008 Verwenden von Idle-Anforderungs-IRP Verwenden von WDM-Energie-IRP Verwenden von WDM-Energie-IRP
Windows Vista Verwenden von Idle-Anforderungs-IRP Verwenden von WDM-Energie-IRP Verwenden von WDM-Energie-IRP
Windows Server 2003 Verwenden von Idle-Anforderungs-IRP Verwenden von Idle-Anforderungs-IRP Verwenden von Idle-Anforderungs-IRP
Windows XP Verwenden von Idle-Anforderungs-IRP Verwenden von Idle-Anforderungs-IRP Verwenden von Idle-Anforderungs-IRP

In diesem Abschnitt wird der selektive Anhaltemechanismus von Windows erläutert.

Senden eines USB-Idle-Anforderungs-IRP

Wenn ein Gerät im Leerlauf verläuft, informiert der Clienttreiber den Bustreiber durch Senden einer IdLE-Anforderungs-IRP (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION). Nachdem der Bustreiber festgestellt hat, dass es sicher ist, das Gerät in einen Energiesparzustand zu versetzen, ruft er die Rückrufroutine auf, die der Clientgerätetreiber mit dem Idle-Anforderungs-IRP übergeben hat.

In der Rückrufroutine muss der Clienttreiber alle ausstehenden E/A-Vorgänge abbrechen und auf den Abschluss aller USB-E/A-IRPs warten. Anschließend kann eine IRP_MN_SET_POWER Anforderung zum Ändern des Energiezustands des WDM-Geräts in D2 gestellt werden. Die Rückrufroutine muss warten, bis die D2-Anforderung abgeschlossen ist, bevor sie zurückgegeben wird. Weitere Informationen zur Idle-Benachrichtigungsrückrufroutine finden Sie unter "USB Idle Notification Callback Routine".

Der Bustreiber schließt das Idle-Anforderungs-IRP nicht ab, nachdem die Rückrufroutine für leerlaufbenachrichtigungen aufgerufen wurde. Stattdessen hält der Bustreiber den Leerlaufanforderungs-IRP aus, bis eine der folgenden Bedingungen zutrifft:

  • Ein IRP_MN_SUPRISE_REMOVAL oder IRP_MN_REMOVE_DEVICE IRP wird empfangen. Wenn einer dieser IRPs empfangen wird, wird der Idle-Anforderungs-IRP mit STATUS_CANCELLED abgeschlossen.
  • Der Bustreiber erhält eine Anforderung, das Gerät in einen Betriebsleistungszustand (D0) zu versetzen. Nach Erhalt dieser Anforderung schließt der Bustreiber die ausstehende Leerlaufanforderung mit STATUS_SUCCESS ab.

Die folgenden Einschränkungen gelten für die Verwendung von IRPs für Leerlaufanforderungen:

  • Treiber müssen sich im Gerätestromzustand D0 befinden, wenn ein IRP für die Leerlaufanforderung gesendet wird.
  • Treiber müssen nur eine Idle-Anforderungs-IRP pro Gerätestapel senden.

Der folgende WDM-Beispielcode veranschaulicht die Schritte, die ein Gerätetreiber zum Senden einer USB-Idle-Anforderungs-IRP ausführt. Fehlerüberprüfung wurde im folgenden Codebeispiel nicht angegeben.

  1. Zuordnen und Initialisieren des IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION IRP

    irp = IoAllocateIrp (DeviceContext->TopOfStackDeviceObject->StackSize, FALSE);
    nextStack = IoGetNextIrpStackLocation (irp);
    nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION;
    nextStack->Parameters.DeviceIoControl.InputBufferLength =
    sizeof(struct _USB_IDLE_CALLBACK_INFO);
    
  2. Zuordnen und Initialisieren der Informationsstruktur der Leerlaufanforderung (USB_IDLE_CALLBACK_INFO).

    idleCallbackInfo = ExAllocatePool (NonPagedPool,
    sizeof(struct _USB_IDLE_CALLBACK_INFO));
    idleCallbackInfo->IdleCallback = IdleNotificationCallback;
    // Put a pointer to the device extension in member IdleContext
    idleCallbackInfo->IdleContext = (PVOID) DeviceExtension;  
    nextStack->Parameters.DeviceIoControl.Type3InputBuffer =
    idleCallbackInfo;
    
  3. Legen Sie eine Abschlussroutine fest.

    Der Clienttreiber muss eine Abschlussroutine dem Idle-Anforderungs-IRP zuordnen. Weitere Informationen zur Benachrichtigungsabschlussroutine im Leerlauf und Beispielcode finden Sie unter "USB Idle Request IRP Completion Routine".

    IoSetCompletionRoutine (irp,
        IdleNotificationRequestComplete,
        DeviceContext,
        TRUE,
        TRUE,
        TRUE);
    
  4. Speichern Sie die Leerlaufanforderung in der Geräteerweiterung.

    deviceExtension->PendingIdleIrp = irp;
    
    
  5. Senden Sie die Idle-Anforderung an den übergeordneten Treiber.

    ntStatus = IoCallDriver (DeviceContext->TopOfStackDeviceObject, irp);
    

Abbrechen einer USB-Leerlaufanforderung

Unter bestimmten Umständen muss ein Gerätetreiber möglicherweise eine IdRP-Anforderung abbrechen, die an den Bustreiber übermittelt wurde. Dies kann auftreten, wenn das Gerät entfernt wird, nach dem Leerlauf und Senden der Leerlaufanforderung aktiv wird, oder wenn das gesamte System in einen niedrigeren Systemstromzustand wechselt.

Der Clienttreiber bricht das IRP im Leerlauf ab, indem IoCancelIrp aufgerufen wird. Die folgende Tabelle beschreibt drei Szenarien zum Abbrechen eines IRP im Leerlauf und gibt die Aktion an, die der Treiber ausführen muss:

Szenario Abbruchmechanismus für Leerlaufanforderungen
Der Clienttreiber hat den Leerlauf-IRP abgebrochen, und der USB-Treiberstapel hat die "USB Idle Notification Callback Routine" nicht aufgerufen. Der USB-Treiberstapel schließt den Leerlauf-IRP ab. Da das Gerät den D0 nie verlassen hat, ändert der Treiber den Gerätezustand nicht.
Der Clienttreiber hat den Leerlauf-IRP abgebrochen, der USB-Treiberstapel hat die RÜCKRUFroutine für die USB-Leerlaufbenachrichtigung aufgerufen und wurde noch nicht zurückgegeben. Es ist möglich, dass die Rückrufroutine für usb-Leerlaufbenachrichtigungen aufgerufen wird, obwohl der Clienttreiber den Abbruch auf dem IRP aufgerufen hat. In diesem Fall muss die Rückrufroutine des Clienttreibers das Gerät trotzdem herunterschalten, indem das Gerät synchron an einen niedrigeren Leistungszustand gesendet wird.

Wenn sich das Gerät im unteren Leistungszustand befindet, kann der Clienttreiber dann eine D0-Anforderung senden.

Alternativ kann der Treiber warten, bis der USB-Treiberstapel das IRP im Leerlauf abgeschlossen und dann den D0 IRP sendet.

Wenn die Rückrufroutine das Gerät aufgrund unzureichendem Arbeitsspeicher nicht in einen Energiesparzustand versetzen kann, um einen Strom-IRP zuzuweisen, sollte er den Leerlauf-IRP abbrechen und sofort beenden. Der Leerlauf-IRP wird erst abgeschlossen, wenn die Rückrufroutine zurückgegeben wurde. Daher sollte die Rückrufroutine nicht blockieren, bis das abgebrochene Leerlauf-IRP abgeschlossen ist.
Das Gerät befindet sich bereits im Energiesparmodus. Wenn sich das Gerät bereits im Energiesparmodus befindet, kann der Clienttreiber einen D0 IRP senden. Der USB-Treiberstapel schließt das Idle-Anforderungs-IRP mit STATUS_SUCCESS ab.

Alternativ kann der Treiber das IRP im Leerlauf abbrechen, warten, bis der USB-Treiberstapel das IRP im Leerlauf abgeschlossen hat, und senden Sie dann ein D0 IRP.

IRP-Abschlussroutine für USB-Idle-Anforderungsanforderung

In vielen Fällen kann ein Bustreiber die IRP-Abschlussroutine eines Fahrers im Leerlauf aufrufen. In diesem Fall muss ein Clienttreiber erkennen, warum der Bustreiber das IRP abgeschlossen hat. Der zurückgegebene Statuscode kann diese Informationen bereitstellen. Wenn der Statuscode nicht STATUS_POWER_STATE_INVALID ist, sollte der Treiber sein Gerät in D0 platzieren, wenn das Gerät noch nicht in D0 enthalten ist. Wenn das Gerät noch im Leerlauf ist, kann der Treiber eine weitere IDRP-Anforderung senden.

Hinweis

Die Idle-Anforderungs-IRP-Abschlussroutine sollte nicht blockieren, bis eine D0-Energieanforderung abgeschlossen ist. Die Abschlussroutine kann im Kontext eines Leistungs-IRP vom Hubtreiber aufgerufen werden und das Blockieren eines anderen Strom-IRP in der Abschlussroutine kann zu einem Deadlock führen.

Die folgende Liste gibt an, wie eine Abschlussroutine für eine Leerlaufanforderung einige gängige Statuscodes interpretieren sollte:

Statuscode Beschreibung
STATUS_SUCCESS Gibt an, dass das Gerät nicht mehr angehalten werden soll. Treiber sollten jedoch überprüfen, ob ihre Geräte eingeschaltet sind, und sie in D0 platzieren, wenn sie noch nicht in D0 sind.
STATUS_CANCELLED Der Bustreiber schließt die IdRP mit STATUS_CANCELLED unter den folgenden Umständen ab:
  • Der Gerätetreiber hat das IRP abgebrochen.
  • Eine Systemleistungszustandsänderung ist erforderlich.
  • Unter Windows XP konnte der Gerätetreiber für eines der angeschlossenen USB-Geräte sein Gerät nicht in D2 platzieren, während die Rückrufroutine für die Leerlaufanforderung ausgeführt wurde. Daher hat der Bustreiber alle ausstehenden IRPs für leerstehende Anforderungen abgeschlossen.
STATUS_POWER_STATE_INVALID Gibt an, dass der Gerätetreiber einen D3-Energiezustand für sein Gerät angefordert hat. In diesem Fall schließt der Bustreiber alle ausstehenden LEERLAUF-IRPs mit STATUS_POWER_STATE_INVALID ab.
STATUS_DEVICE_BUSY Gibt an, dass der Bustreiber bereits eine Leerlaufanforderung enthält, die für das Gerät aussteht. Für ein bestimmtes Gerät kann jeweils nur ein Leerlauf-IRP ausstehen. Das Senden mehrerer IRPs für die Leerlaufanforderung ist ein Fehler im Teil des Besitzers der Energierichtlinie und sollte vom Treiberschreiber behoben werden.

Das folgende Codebeispiel zeigt eine Beispielimplementierung für die Leerlaufanforderungsabschlussroutine.

/*Routine Description:

  Completion routine for idle notification IRP

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet
    DeviceExtension - pointer to device extension

Return Value:

    NT status value

--*/

NTSTATUS
IdleNotificationRequestComplete(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PDEVICE_EXTENSION DeviceExtension
    )
{
    NTSTATUS                ntStatus;
    POWER_STATE             powerState;
    PUSB_IDLE_CALLBACK_INFO idleCallbackInfo;

    ntStatus = Irp->IoStatus.Status;

    if(!NT_SUCCESS(ntStatus) && ntStatus != STATUS_NOT_SUPPORTED)
    {

        //Idle IRP completes with error.

        switch(ntStatus)
        {

        case STATUS_INVALID_DEVICE_REQUEST:

            //Invalid request.

            break;

        case STATUS_CANCELLED:

            //1. The device driver canceled the IRP.
            //2. A system power state change is required.

            break;

        case STATUS_POWER_STATE_INVALID:

            // Device driver requested a D3 power state for its device
            // Release the allocated resources.

            goto IdleNotificationRequestComplete_Exit;

        case STATUS_DEVICE_BUSY:

            //The bus driver already holds an idle IRP pending for the device.

            break;

        default:
            break;

        }


        // If IRP completes with error, issue a SetD0

        //Increment the I/O count because
        //a new IRP is dispatched for the driver.
        //This call is not shown.

        powerState.DeviceState = PowerDeviceD0;

        // Issue a new IRP
        PoRequestPowerIrp (
            DeviceExtension->PhysicalDeviceObject,
            IRP_MN_SET_POWER,
            powerState,
            (PREQUEST_POWER_COMPLETE) PoIrpCompletionFunc,
            DeviceExtension,
            NULL);
    }

IdleNotificationRequestComplete_Exit:

    idleCallbackInfo = DeviceExtension->IdleCallbackInfo;

    DeviceExtension->IdleCallbackInfo = NULL;

    DeviceExtension->PendingIdleIrp = NULL;

    InterlockedExchange(&DeviceExtension->IdleReqPend, 0);

    if(idleCallbackInfo)
    {
        ExFreePool(idleCallbackInfo);
    }

    DeviceExtension->IdleState = IdleComplete;

    // Because the IRP was created using IoAllocateIrp,
    // the IRP needs to be released by calling IoFreeIrp.
    // Also return STATUS_MORE_PROCESSING_REQUIRED so that
    // the kernel does not reference this.

    IoFreeIrp(Irp);

    KeSetEvent(&DeviceExtension->IdleIrpCompleteEvent, IO_NO_INCREMENT, FALSE);

    return STATUS_MORE_PROCESSING_REQUIRED;
}

Rückrufroutine für USB-Leerlaufbenachrichtigungen

Der Bustreiber (entweder eine Instanz des Hubtreibers oder der generische übergeordnete Treiber) bestimmt, wann es sicher ist, die untergeordneten Geräte anzusetzen. Wenn dies der Grund ist, ruft sie die Rückrufroutine für die Leerlaufbenachrichtigung auf, die vom Clienttreiber der einzelnen untergeordneten Elemente bereitgestellt wird.

Der Funktionsprototyp für USB_IDLE_CALLBACK lautet wie folgt:

typedef VOID (*USB_IDLE_CALLBACK)(__in PVOID Context);

Ein Gerätetreiber muss die folgenden Aktionen in der Idle-Benachrichtigungsrückrufroutine ausführen:

  • Fordern Sie eine IRP_MN_WAIT_WAKE IRP für das Gerät an, wenn das Gerät für die Remotereaktivierung bewaffnet werden muss.
  • Brechen Sie alle E/A-Vorgänge ab, und bereiten Sie das Gerät auf einen niedrigeren Leistungszustand vor.
  • Setzen Sie das Gerät in einen WDM-Energiesparzustand, indem Sie PoRequestPowerIrp aufrufen, wobei der PowerState-Parameter auf den Enumerationswert "PowerDeviceD2" festgelegt ist (definiert in wdm.h; ntddk.h). In Windows XP darf ein Treiber sein Gerät nicht in PowerDeviceD3 platzieren, auch wenn das Gerät nicht für die Remotereaktivierung bewaffnet ist.

In Windows XP muss sich ein Treiber auf eine Rückrufroutine für Leerlaufbenachrichtigungen verlassen, um ein Gerät selektiv anzuhalten. Wenn ein in Windows XP ausgeführter Treiber ein Gerät direkt in einen niedrigeren Leistungszustand versetzt, ohne eine Rückrufroutine für Leerlaufbenachrichtigungen zu verwenden, kann dies dazu führen, dass andere Geräte in der USB-Gerätestruktur angehalten werden.

Sowohl der Hubtreiber als auch der USB Generic Parent Driver (Usbccgp.sys) rufen die Idle-Benachrichtigungsrückrufroutine bei IRQL = PASSIVE_LEVEL auf. Dadurch kann die Rückrufroutine blockiert werden, während sie auf den Abschluss der Änderungsanforderung für den Energiezustand wartet.

Die Rückrufroutine wird nur aufgerufen, während sich das System in S0 befindet und sich das Gerät in D0 befindet.

Die folgenden Einschränkungen gelten für Rückrufroutinen für Idle-Anforderungsbenachrichtigungen:

  • Gerätetreiber können einen Gerätestromzustandsübergang von D0 zu D2 in der Idle-Benachrichtigungsrückrufroutine initiieren, aber es ist kein anderer Energiezustandsübergang zulässig. Insbesondere darf ein Treiber nicht versuchen, sein Gerät bei der Ausführung der Rückrufroutine in D0 zu ändern.
  • Gerätetreiber dürfen nicht mehr als ein Strom-IRP innerhalb der Rückrufroutine für Leerlaufbenachrichtigungen anfordern.

Arming devices for wakeup in the idle notification callback routine

Die Rückrufroutine für Leerlaufbenachrichtigungen sollte bestimmen, ob ihr Gerät eine IRP_MN_WAIT_WAKE Anforderung aussteht. Wenn keine IRP_MN_WAIT_WAKE Anforderung aussteht, sollte die Rückrufroutine vor dem Anhalten des Geräts eine IRP_MN_WAIT_WAKE Anforderung senden. Weitere Informationen zum Warte-Wake-Mechanismus finden Sie unter Unterstützen von Geräten mit WakeUp-Funktionen.

Globales Anhalten des USB-Speichers

Die USB 2.0-Spezifikation definiert das globale Anhalten als Anhalten des gesamten Bus hinter einem USB-Hostcontroller, indem alle USB-Datenverkehr auf dem Bus, einschließlich Start-of-Frame-Paketen, abgesenkt werden. Nachgeschaltete Geräte, die noch nicht angehalten wurden, erkennen den Leerlaufstatus auf ihrem upstream-Port und geben den Anhaltezustand selbst ein. Windows implementiert das globale Anhalten auf diese Weise nicht. Windows hält jedes USB-Gerät immer selektiv hinter einem USB-Hostcontroller an, bevor der gesamte USB-Datenverkehr auf dem Bus beendet wird.

Bedingungen für das globale Anhalten in Windows 7

Windows 7 ist aggressiver, wenn usb-Hubs selektiv angehalten werden als Windows Vista. Der Windows 7-USB-Hubtreiber hält alle Hubs selektiv an, auf denen sich alle angeschlossenen Geräte im Energiezustand D1, D2 oder D3 befinden. Der gesamte Bus wechselt in das globale Anhalten, sobald alle USB-Hubs selektiv angehalten werden. Der Windows 7-USB-Treiberstapel behandelt ein Gerät als Leerlauf, wenn sich das Gerät in einem WDM-Gerätezustand von D1, D2 oder D3 befindet.

Bedingungen für das globale Anhalten in Windows Vista

Die Anforderungen für ein globales Anhalten sind in Windows Vista flexibler als in Windows XP.

Insbesondere behandelt der USB-Stapel ein Gerät als Leerlauf in Windows Vista, wenn sich das Gerät in einem WDM-Gerätezustand von D1, D2 oder D3 befindet.

Das folgende Diagramm veranschaulicht ein Szenario, das in Windows Vista auftreten kann.

Diagramm zur Veranschaulichung eines globalen Anhaltens in Windows Vista.

Dieses Diagramm veranschaulicht eine Situation, die dem im Abschnitt "Bedingungen für das globale Anhalten in Windows XP" dargestellt ist. In diesem Fall ist Device 3 jedoch als Idle-Gerät qualifiziert. Da alle Geräte im Leerlauf sind, kann der Bustreiber die Idle-Benachrichtigungsrückrufroutinen aufrufen, die den ausstehenden IRPs der leerstehenden Anforderung zugeordnet sind. Jeder Treiber hält sein Gerät an, und der Bustreiber hält den USB-Hostcontroller an, sobald er sicher ist.

Unter Windows Vista müssen alle Nicht-Hub-USB-Geräte in D1, D2 oder D3 vorhanden sein, bevor das globale Anhalten initiiert wird, wobei alle USB-Hubs, einschließlich des Stammhubs, angehalten werden. Dies bedeutet, dass jeder USB-Clienttreiber, der keine selektive Anhalte unterstützt, verhindert, dass der Bus global angehalten wird.

Bedingungen für das globale Anhalten in Windows XP

Um Energieeinsparungen unter Windows XP zu maximieren, ist es wichtig, dass jeder Gerätetreiber IRPs im Leerlauf verwendet, um sein Gerät anzusetzen. Wenn ein Treiber sein Gerät mit einer IRP_MN_SET_POWER Anforderung anstelle eines Idle-Anforderungs-IRP angehalten hat, kann es verhindern, dass andere Geräte angehalten werden.

Das folgende Diagramm veranschaulicht ein Szenario, das in Windows XP auftreten kann.

Diagramm zur Veranschaulichung eines globalen Anhaltens in Windows XP.

In dieser Abbildung befindet sich Das Gerät 3 im Energiezustand D3 und hat keine Leerlaufanforderung ausstehend. Gerät 3 gilt nicht als Leerlaufgerät für zwecke eines globalen Anhaltevorgangs in Windows XP, da keine idle-Anforderung mit dem übergeordneten Element aussteht. Dadurch wird verhindert, dass der Bustreiber die Idle-Anforderungsrückrufroutinen aufruft, die den Treibern anderer Geräte in der Struktur zugeordnet sind.

Aktivieren des selektiven Anhaltens

Das selektive Anhalten ist für Upgradeversionen von Microsoft Windows XP deaktiviert. Es ist für Neuinstallationen von Windows XP, Windows Vista und höheren Versionen von Windows aktiviert.

Um die selektive Anhalteunterstützung für einen bestimmten Stammhub und seine untergeordneten Geräte zu aktivieren, aktivieren Sie das Kontrollkästchen auf der Registerkarte "Energieverwaltung" für den USB-Stammhub in Geräte-Manager.

Alternativ können Sie das selektive Anhalten aktivieren oder deaktivieren, indem Sie den Wert von HcDisableSelectiveSuspend unter dem Softwareschlüssel des USB-Porttreibers festlegen. Der Wert 1 deaktiviert das selektive Anhalten. Ein Wert von 0 ermöglicht das selektive Anhalten.

Beispielsweise deaktivieren die folgenden Zeilen in Usbport.inf das selektive Anhalten für einen Hydra OHCI-Controller:

[OHCI_NOSS.AddReg.NT]
HKR,,"HcDisableSelectiveSuspend",0x00010001,1

Clienttreiber sollten nicht versuchen, festzustellen, ob das selektive Anhalten aktiviert ist, bevor Leerlaufanforderungen gesendet werden. Sie sollten Leerlaufanforderungen senden, wenn das Gerät im Leerlauf ist. Wenn die Leerlaufanforderung fehlschlägt, sollte der Clienttreiber den Leerlaufzeitgeber zurücksetzen und den Vorgang wiederholen.