USB, selektives Energiesparen

Hinweis

Dieser Artikel richtet sich an Gerätetreiberentwickler. Wenn Probleme mit einem USB-Gerät auftreten, finden Sie weitere Informationen unter Behandeln häufiger USB-Probleme.

Das Feature für das selektive Anhalten von USB ermöglicht es dem Hubtreiber, einen einzelnen Port anzusetzen, ohne den Betrieb der anderen Ports auf dem Hub zu beeinträchtigen. Die selektive Aufhängung von USB-Geräten ist besonders bei tragbaren Computern nützlich, da es hilft, Akkuleistung zu sparen. Viele Geräte, z. B. Fingerabdruckleser und andere Arten von biometrischen Scannern, benötigen nur zeitweilig Strom. Das Anhalten solcher Geräte, wenn das Gerät nicht verwendet wird, reduziert den Gesamtenergieverbrauch. Noch wichtiger ist, dass jedes Gerät, das nicht selektiv angehalten wird, den USB-Hostcontroller daran hindern kann, seinen Übertragungszeitplan zu deaktivieren, der sich im Systemspeicher befindet. Übertragungen des direkten Speicherzugriffs (DMA) durch den Hostcontroller an den Scheduler können verhindern, dass die Prozessoren des Systems in tiefere Ruhezustände wie C3 gelangen.

Es gibt zwei verschiedene Mechanismen zum selektiven Anhalten eines USB-Geräts: Idle Request IRPs (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) und Festlegen von Power 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 einer Wartereaktivierungs-IRP (IRP_MN_WAIT_WAKE) aktivieren, müssen den Idle Request IRP-Mechanismus (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) verwenden, um ein Gerät selektiv anzusetzen.

Informationen zur Remoteaktivierung finden Sie unter:

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

  • 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 wdm power IRPs nicht verwenden, um ihre Geräte selektiv anzusetzen. Dadurch wird verhindert, dass andere Geräte selektiv angehalten werden.
  • Windows Vista und höhere Versionen von Windows: Treiberautoren haben mehr Auswahl zum Herunterfahren von Geräten in Windows Vista und in den späteren Versionen von Windows. Obwohl Windows Vista den IRP-Mechanismus für Die Windows-Anforderung im Leerlauf unterstützt, sind Treiber nicht erforderlich, um ihn zu verwenden.

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

Windows-Version Funktion auf zusammengesetzten Geräten, zur Aktivierung bewaffnet Funktion auf einem zusammengesetzten Gerät, nicht für aktivierungsarm USB-Gerät mit einer einzigen Schnittstelle
Windows 7 Verwenden der Idle-Anforderungs-IRP Verwenden von WDM Power IRP Verwenden von WDM Power IRP
Windows Server 2008 Verwenden der Idle-Anforderungs-IRP Verwenden von WDM Power IRP Verwenden von WDM Power IRP
Windows Vista Verwenden der Idle-Anforderungs-IRP Verwenden von WDM Power IRP Verwenden von WDM Power IRP
Windows Server 2003 Verwenden der Idle-Anforderungs-IRP Verwenden der Idle-Anforderungs-IRP Verwenden der Idle-Anforderungs-IRP
Windows XP Verwenden der Idle-Anforderungs-IRP Verwenden der Idle-Anforderungs-IRP Verwenden der Idle-Anforderungs-IRP

In diesem Abschnitt wird der Mechanismus für das selektive Anhalten von Windows erläutert.

Senden einer USB-Idle-Anforderungs-IRP

Wenn ein Gerät in den Leerlauf geht, informiert der Clienttreiber den Bustreiber, indem er eine Idle Request-IRP (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) sendet. 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 den Stapel mit der Idle Request-IRP übergeben hat.

In der Rückrufroutine muss der Clienttreiber alle ausstehenden E/A-Vorgänge abbrechen und warten, bis alle USB-E/A-IRPs abgeschlossen sind. Anschließend kann eine IRP_MN_SET_POWER Anforderung zum Ändern des WDM-Gerätestromzustands in D2 gestellt werden. Die Rückrufroutine muss warten, bis die D2-Anforderung abgeschlossen ist, bevor sie zurückgegeben wird. Weitere Informationen zur Rückrufroutine für Benachrichtigungen im Leerlauf finden Sie unter "USB-Idle-Benachrichtigungsrückrufroutine".

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

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

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

  • Treiber müssen sich im Gerätestromzustand D0 befinden, wenn sie eine Idle-Anforderungs-IRP senden.
  • Treiber müssen nur eine Idle Request-IRP pro Gerätestapel senden.

Der folgende WDM-Beispielcode veranschaulicht die Schritte, die ein Gerätetreiber ausführt, um eine USB-Idle-Anforderungs-IRP zu senden. Die Fehlerüberprüfung wurde im folgenden Codebeispiel ausgelassen.

  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. Ordnen Und initialisieren Sie die Struktur der Anforderungsinformationen im Leerlauf (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 Vervollständigungsroutine fest.

    Der Clienttreiber muss dem Idle Request-IRP eine Vervollständigungsroutine zuordnen. Weitere Informationen zur Vervollständigungsroutine für Benachrichtigungen im Leerlauf und zum Beispielcode finden Sie unter USB-Idle Request IRP Completion Routine.For more information about the idle notification completion routine and example code, see "USB Idle Request IRP Completion Routine".

    IoSetCompletionRoutine (irp,
        IdleNotificationRequestComplete,
        DeviceContext,
        TRUE,
        TRUE,
        TRUE);
    
  4. Speichern Sie die Anforderung im Leerlauf 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 Idle Request-IRP abbrechen, die an den Bustreiber übermittelt wurde. Dies kann vorkommen, wenn das Gerät entfernt wird, aktiv wird, nachdem es sich im Leerlauf befindet und die Anforderung im Leerlauf gesendet hat, oder wenn das gesamte System in einen niedrigeren Systemleistungszustand wechselt.

Der Clienttreiber bricht den IRP im Leerlauf durch Aufrufen von IoCancelIrp ab. In der folgenden Tabelle werden drei Szenarien zum Abbrechen eines IRP im Leerlauf beschrieben und die Aktion angegeben, die der Treiber ausführen muss:

Szenario Abbruchmechanismus für Leerlaufanforderungen
Der Clienttreiber hat die IRP im Leerlauf abgebrochen, und der USB-Treiberstapel hat die "USB-Idle-Benachrichtigungsrückrufroutine" nicht aufgerufen. Der USB-Treiberstapel schließt die Idle-IRP ab. Da das Gerät die D0 nie verlassen hat, ändert der Treiber den Gerätestatus nicht.
Der Clienttreiber hat die IRP im Leerlauf abgebrochen, der USB-Treiberstapel hat die USB-Idle-Benachrichtigungsrückrufroutine aufgerufen und noch nicht zurückgegeben. Es ist möglich, dass die Rückrufroutine für USB-Leerlaufbenachrichtigungen aufgerufen wird, obwohl der Clienttreiber den Abbruch für das IRP aufgerufen hat. In diesem Fall muss die Rückrufroutine des Clienttreibers das Gerät trotzdem ausschalten, indem das Gerät synchron in einen niedrigeren Leistungszustand gesendet wird.

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

Alternativ kann der Treiber warten, bis der USB-Treiberstapel den Leerlauf-IRP abgeschlossen hat, und dann den D0-IRP senden.

Wenn die Rückrufroutine das Gerät nicht in einen Energiesparzustand versetzen kann, weil nicht genügend Arbeitsspeicher zum Zuweisen eines Energie-IRP vorhanden ist, sollte die IdRP abgebrochen und sofort beendet werden. Der Idle-IRP wird erst abgeschlossen, wenn die Rückrufroutine zurückgegeben wurde. Daher sollte die Rückrufroutine das Warten auf den Abschluss des abgebrochenen Leerlauf-IRP nicht blockieren.
Das Gerät befindet sich bereits im Energiesparmodus. Wenn sich das Gerät bereits in einem energiesparenden Zustand befindet, kann der Clienttreiber eine D0-IRP senden. Der USB-Treiberstapel schließt die Idle Request-IRP mit STATUS_SUCCESS ab.

Alternativ kann der Treiber die Idle-IRP abbrechen, warten, bis der USB-Treiberstapel den Leerlauf-IRP abgeschlossen hat, und dann eine D0-IRP senden.

IRP-Vervollständigungsroutine für USB-Leerlaufanforderung

In vielen Fällen kann ein Bustreiber die IRP-Vervollständigungsroutine für die Leerlaufanforderung eines Fahrers aufrufen. In diesem Fall muss ein Clienttreiber erkennen, warum der Bustreiber die IRP abgeschlossen hat. Der zurückgegebene status Code kann diese Informationen bereitstellen. Wenn der status Code nicht STATUS_POWER_STATE_INVALID ist, sollte der Treiber sein Gerät in D0 platzieren, wenn sich das Gerät noch nicht in D0 befindet. Wenn sich das Gerät noch im Leerlauf befindet, kann der Treiber eine weitere Idle-Anforderungs-IRP senden.

Hinweis

Die IRP-Vervollständigungsroutine für Leerlaufanforderungen sollte das Warten auf den Abschluss einer D0-Energieanforderung nicht blockieren. Die Vervollständigungsroutine kann im Kontext einer Leistungs-IRP vom Hubtreiber aufgerufen werden, und das Blockieren eines anderen Energie-IRP in der Abschlussroutine kann zu einem Deadlock führen.

Die folgende Liste gibt an, wie eine Vervollständigungsroutine für eine Anforderung im Leerlauf einige gängige status-Codes interpretieren soll:

Statuscode BESCHREIBUNG
STATUS_SUCCESS Gibt an, dass das Gerät nicht mehr angehalten werden soll. Treiber sollten jedoch überprüfen, ob ihre Geräte mit Strom versorgt sind, und sie in D0 einfügen, wenn sie sich noch nicht in D0 befinden.
STATUS_CANCELLED Der Bustreiber schließt die Idle-Anforderungs-IRP mit STATUS_CANCELLED unter den folgenden Umständen ab:
  • Der Gerätetreiber hat die IRP abgebrochen.
  • Eine Änderung des Systemenergiezustands 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 er seine Anforderungsrückrufroutine im Leerlauf ausführte. Daher hat der Bustreiber alle ausstehenden Anforderungs-IRPs 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 IRPs im Leerlauf mit STATUS_POWER_STATE_INVALID ab.
STATUS_DEVICE_BUSY Gibt an, dass der Bustreiber bereits eine Idle Request-IRP für das Gerät enthält. Für ein bestimmtes Gerät kann jeweils nur ein Idle-IRP ausstehen. Das Übermitteln mehrerer IDLE-Anforderungs-IRPs ist ein Fehler des Energierichtlinienbesitzers und sollte vom Treiberwriter behoben werden.

Das folgende Codebeispiel zeigt eine Beispielimplementierung für die Routine zum Abschließen von Anforderungen im Leerlauf.

/*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 ein instance des Hubtreibers oder des generischen übergeordneten Treibers) bestimmt, wann das Anhalten der untergeordneten Geräte sicher ist. Wenn dies der Fall ist, wird die Vom Clienttreiber jedes untergeordneten Elements bereitgestellte Rückrufroutine für Benachrichtigungen im Leerlauf aufgerufen.

Der Funktionsprototyp für USB_IDLE_CALLBACK sieht wie folgt aus:

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

Ein Gerätetreiber muss die folgenden Aktionen in seiner Benachrichtigungsrückrufroutine im Leerlauf 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.
  • Versetzen Sie das Gerät in einen WDM-Ruhezustand, indem Sie PoRequestPowerIrp aufrufen, wobei der PowerState-Parameter auf den Enumeratorwert PowerDeviceD2 (definiert in wdm.h; ntddk.h) festgelegt ist. Unter Windows XP darf ein Treiber sein Gerät nicht in PowerDeviceD3 ablegen, auch wenn das Gerät nicht für die Remotereaktivierung ausgerüstet ist.

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

Sowohl der Hubtreiber als auch der USB-Usbccgp.sys (Generic Parent Driver) rufen die Rückrufroutine für Benachrichtigungen im Leerlauf unter IRQL = PASSIVE_LEVEL auf. Dadurch kann die Rückrufroutine blockiert werden, während sie auf den Abschluss der Energiezustandsänderungsanforderung wartet.

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

Die folgenden Einschränkungen gelten für Rückrufroutinen für Anforderungsbenachrichtigungen im Leerlauf:

  • Gerätetreiber können einen Übergang des Geräteenergiezustands von D0 zu D2 in der Rückrufroutine für Benachrichtigungen im Leerlauf initiieren, aber es ist kein anderer Energiezustandsübergang zulässig. Insbesondere darf ein Treiber nicht versuchen, sein Gerät in D0 zu ändern, während er seine Rückrufroutine ausführt.
  • Gerätetreiber dürfen nicht mehr als eine Energie-IRP aus der Rückrufroutine für Leerlaufbenachrichtigungen anfordern.

Armieren von Geräten für die Aktivierung in der Rückrufroutine für Benachrichtigungen im Leerlauf

Die Rückrufroutine für Benachrichtigungen im Leerlauf sollte bestimmen, ob auf dem 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 übermitteln. Weitere Informationen zum Warteaktivierungsmechanismus finden Sie unter Unterstützen von Geräten mit Aktivierungsfunktionen.

Globales Anhalten von USB

Die USB 2.0-Spezifikation definiert globales Anhalten als angehaltenen Bus hinter einem USB-Hostcontroller, indem der gesamte USB-Datenverkehr auf dem Bus eingestellt wird, einschließlich der Start-of-Frame-Pakete. Nachgeschaltete Geräte, die noch nicht angehalten sind, erkennen den Leerlaufzustand an ihrem Upstream Port und wechseln selbst in den Anhaltezustand. 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 beim selektiven Anhalten von USB-Hubs aggressiver als Windows Vista. Der Windows 7-USB-Hubtreiber hält alle Hubs, in denen sich alle angeschlossenen Geräte im D1-, D2- oder D3-Gerätestromzustand befinden, selektiv an. Der gesamte Bus wird global suspendiert, sobald alle USB-Hubs selektiv angehalten sind. 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 eine globale Unterbrechung sind in Windows Vista flexibler als in Windows XP.

Insbesondere behandelt der USB-Stapel ein Gerät in Windows Vista als Leerlauf, 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 einer globalen Unterbrechung in Windows Vista.

Dieses Diagramm veranschaulicht eine Ähnliche Situation wie im Abschnitt "Bedingungen für das globale Anhalten in Windows XP". In diesem Fall gilt Gerät 3 jedoch als Gerät im Leerlauf. Da sich alle Geräte im Leerlauf befinden, kann der Bustreiber die Rückrufroutinen für Benachrichtigungen im Leerlauf aufrufen, die den IRPs für ausstehende Anforderungen im Leerlauf zugeordnet sind. Jeder Treiber hält sein Gerät an, und der Bustreiber hält den USB-Hostcontroller an, sobald dies sicher ist.

Unter Windows Vista müssen sich alle NICHT-Hub-USB-Geräte in D1, D2 oder D3 befinden, bevor das globale Anhalten initiiert wird. Zu diesem Zeitpunkt werden alle USB-Hubs, einschließlich des Stammhubs, angehalten. Dies bedeutet, dass jeder USB-Clienttreiber, der das selektive Anhalten nicht unterstützt, verhindert, dass der Bus in die globale Suspend-Einstellung wechselt.

Bedingungen für das globale Anhalten in Windows XP

Um die Energieeinsparungen unter Windows XP zu maximieren, ist es wichtig, dass jeder Gerätetreiber IRPs für Anforderungsanforderungen im Leerlauf verwendet, um sein Gerät angehalten zu haben. Wenn ein Treiber sein Gerät mit einer IRP_MN_SET_POWER-Anforderung anstelle einer Idle Request-IRP angehalten, kann dies verhindern, dass andere Geräte angehalten werden.

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

Diagramm zur Veranschaulichung einer globalen Suspendierung in Windows XP.

In dieser Abbildung befindet sich Gerät 3 im Energiezustand D3 und hat keine Idle Request-IRP ausstehend. Gerät 3 gilt nicht als Gerät im Leerlauf für die zwecke einer globalen Unterbrechung in Windows XP, da keine Idle Request-IRP mit dem übergeordneten Gerät aussteht. Dadurch wird verhindert, dass der Bustreiber die Rückrufroutinen für die Anforderung im Leerlauf 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 sauber Installationen von Windows XP, Windows Vista und höheren Versionen von Windows aktiviert.

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

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. Der Wert 0 aktiviert das selektive Anhalten.

Für instance 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 vor dem Senden von Anforderungen im Leerlauf nicht ermitteln, ob das selektive Anhalten aktiviert ist. Sie sollten Anforderungen im Leerlauf übermitteln, wenn sich das Gerät im Leerlauf befindet. Wenn bei der Leerlaufanforderung ein Fehler auftritt, sollte der Clienttreiber den Leerlauftimer zurücksetzen und den Vorgang wiederholen.