Auswählen einer alternativen Einstellung in einer USB-Schnittstelle

In diesem Thema werden die Schritte zum Ausgeben einer Select-Interface-Anforderung zum Aktivieren einer alternativen Einstellung in einer USB-Schnittstelle beschrieben. Der Clienttreiber muss diese Anforderung ausgeben, nachdem er eine USB-Konfiguration ausgewählt hat. Wenn Sie eine Konfiguration auswählen, wird standardmäßig auch die erste alternative Einstellung in jeder Schnittstelle in dieser Konfiguration aktiviert.

Jede USB-Konfiguration muss eine oder mehrere USB-Schnittstellen unterstützen. Jede Schnittstelle macht einen oder mehrere Endpunkte verfügbar, die zum Übertragen von Daten zum und vom Gerät verwendet werden. USB-Schnittstellen müssen über einen gerätedefinierten Schnittstellenindex verfügen, der zum Identifizieren der Schnittstelle verwendet wird. Die Schnittstelle muss auch über eine oder mehrere alternative Einstellungen verfügen, die die Endpunkte der Schnittstelle gruppiert. Im Rahmen der Gerätekonfiguration muss der Clienttreiber eine der alternativen Einstellungen in der Schnittstelle auswählen. Da Endpunkte für alternative Einstellungen freigegeben werden können, kann zu einem bestimmten Zeitpunkt nur eine Einstellung aktiv sein. Nachdem die alternative Einstellung aktiv ist, werden ihre Endpunkte für Datenübertragungen verfügbar.

Bei einem Gerät mit mehreren Schnittstellen können zwei Schnittstellen zu einem bestimmten Zeitpunkt aktiv sein. Der Clienttreiber muss in jeder Schnittstelle eine alternative Einstellung aktivieren. Endpunkte werden nicht von Schnittstellen gemeinsam genutzt, sodass jede gleichzeitige Datenübertragung auf jeder Schnittstelle durchgeführt werden kann.

Alternative Einstellungen werden vom Gerät definiert und mit einer Zahl identifiziert, die als Einstellungsindex bezeichnet wird. Die alternative Einstellung bei Index 0 wird in dieser Dokumentation als alternative Standardeinstellung bezeichnet. Eine alternative Einstellung wird in einer USB_INTERFACE_DESCRIPTOR-Struktur beschrieben. Die -Struktur enthält den Schnittstellenindex, dem die Einstellung zugeordnet ist, und die Anzahl der Endpunkte, die durch die Einstellung definiert werden. Sie enthält auch Informationen über die Klassenspezifikation, der die Funktionalität der Schnittstelle entspricht. Die Art und Weise, in der Endpunkte gruppiert werden, hängt von der Funktionalität des Geräts ab.

Beispielsweise macht eine Schnittstelle zwei isochrone und zwei Massenendpunkte über drei alternative Einstellungen verfügbar (Index 0, 1, 2). Die alternative Einstellung 0 definiert keinen Endpunkt. Alternative Einstellung 1 definiert die Massenendpunkte; Alternative Einstellung 2 definiert die isochronen Endpunkte. Da die alternative Einstellung 0 keinen Endpunkt aufweist, kann der Clienttreiber diese Einstellung auswählen, um die Datenübertragung zu deaktivieren, um Bandbreite zu sparen. Wenn eine der anderen Einstellungen aktiv ist, ist das Gerät für Datenübertragungen bereit. Die alternative Einstellung 1 kann zum Übertragen von Massendaten verwendet werden. Die alternative Einstellung 2 kann ausgewählt werden, wenn sich das Gerät im Streamingmodus befindet. Daher bieten alternative Einstellungen dem Clienttreiber die Flexibilität, die Gerätekonfiguration bei Bedarf zu ändern. In diesem Beispiel kann der Clienttreiber die Gerätefunktionalität von einer Massenübertragung auf streaming umstellen, indem er einfach eine alternative Einstellung auswählt.

Alternative Einstellungen können auch verwendet werden, um Bandbreitenanforderungen festzulegen. Ein Beispiel finden Sie unter USB-Gerätelayout.

Windows Driver Foundation (WDF) stellt Methoden in Kernel-Mode Driver Framework und User-Mode Driver Framework bereit, die der Clienttreiber aufrufen kann, um eine andere alternative Einstellung auszuwählen. Der KMDF-Clienttreiber kann eine Einstellung auswählen, indem er den Einstellungsindex, den Schnittstellendeskriptor der Einstellung oder eine URB mit der Anforderung angibt. Der UMDF-Clienttreiber kann nur eine alternative Einstellung auswählen, indem er den Einstellungsindex angibt.

Nachdem eine Select-Configuration-Anforderung erfolgreich abgeschlossen wurde, wird die zuvor aktive alternative Einstellung deaktiviert.

Wichtige Informationen

In diesem Artikel werden die folgenden Frameworks verwendet:

Vorbereitung

Bevor der Clienttreiber eine alternative Einstellung auswählen kann, stellen Sie sicher, dass diese Anforderungen erfüllt sind:

  • Der Clienttreiber muss das Framework-USB-Zielgerätobjekt erstellt haben.

  • Das Gerät muss über eine aktive Konfiguration verfügen.

    • Ein KMDF-Clienttreiber muss die WdfUsbTargetDeviceSelectConfig-Methode aufrufen.

    • Für einen UMDF-Clienttreiber wählt das Framework die erste Konfiguration und die standardmäßige alternative Einstellung für jede Schnittstelle in dieser Konfiguration aus.

      Wenn Sie USB-Vorlagen verwenden, wählt der Code die erste Konfiguration und die standardmäßige alternative Einstellung in jeder Schnittstelle aus.

Auswählen einer alternativen Einstellung in einem KMDF-Clienttreiber

  1. Rufen Sie ein WDFUSBINTERFACE-Handle für die Schnittstelle ab, die über die alternative Einstellung verfügt.

    Um das Handle zu erhalten, rufen Sie zunächst die Anzahl der Schnittstellen der ausgewählten Konfiguration ab, indem Sie WdfUsbTargetDeviceGetNumInterfaces aufrufen und dann Schnittstellen in einer Schleife auflisten. Rufen Sie in jeder Iteration die WdfUsbTargetDeviceGetInterface-Methode auf, und erhöhen Sie den Index (beginnend bei null).

    Hinweis Während der Geräteenumeration weist der USB-Treiberstapel den alternativen Einstellungen Nummern zu. Die Schnittstellennummern sind nullbasiert und sequenziell. Diese Zahlen können sich vom Index der gerätedefinierten Einstellung unterscheiden. Um den gerätedefinierte Einstellungsindex abzurufen, rufen Sie die WdfUsbInterfaceGetInterfaceNumber-Methode auf.

  2. Initiieren Sie eine select-interface-Anforderung, indem Sie die WdfUsbInterfaceSelectSetting-Methode aufrufen. Wählen Sie im Parameter Params des Aufrufs eine der folgenden Optionen aus:

    • Geben Sie die vom USB-Treiberstapel zugewiesene Nummer der alternativen Einstellung an. In der Regel übergeben Sie denselben Index, den Sie in Schritt 1 zum Aufzählen der Einstellungen verwendet haben.

    • Geben Sie einen Zeiger auf den Schnittstellendeskriptor an, der die alternative Einstellung beschreibt. Der Treiber kann dann Schnittstellendeskriptoren abrufen, während er alternative Einstellungen in der Schnittstelle aufzählt, indem er die WdfUsbInterfaceGetDescriptor-Methode aufruft. Nach Abschluss der Enumeration ruft der Treiber Informationen zu allen aufgezählten alternativen Einstellungen in der USB_INTERFACE_DESCRIPTOR-Struktur ab.

    • Geben Sie einen Zeiger auf eine URB an, die alle informationen enthält, die für die Select-Interface-Anforderung erforderlich sind.

      1. Ordnen Sie ein Array von USBD_INTERFACE_LIST_ENTRY Strukturen zu. Die Anzahl der Elemente in diesem Array hängt von der Anzahl der Schnittstellen in der ausgewählten Konfiguration ab. Informationen zum Initialisieren dieses Arrays finden Sie unter Auswählen einer Konfiguration für ein USB-Gerät.
      2. Ordnen Sie eine URB für die Anforderung zum Auswählen der Schnittstelle zu, indem Sie die USBD_SelectInterfaceUrbAllocateAndBuild-Routine aufrufen. Geben Sie in diesem Aufruf das Schnittstellenlistenarray und das Konfigurationshandle an, das nach auswahl einer Konfiguration abgerufen wurde. Sie können dieses Handle abrufen, indem Sie die WdfUsbTargetDeviceWdmGetConfigurationHandle-Methode aufrufen.
      3. Rufen Sie WdfUsbInterfaceSelectSetting auf , und geben Sie die URB an.

      **WDM-Treiber:**Um die URB zu übermitteln, ordnen Sie die URB einem IRP zu, und übermitteln Sie den IRP an den USB-Treiberstapel. Weitere Informationen finden Sie unter Übermitteln einer URB.

    Die Optionen in der Liste bieten dem Clienttreiber die Flexibilität, die Auswahlkriterien anzugeben. Wenn Sie bereits die Endpunktfunktionen der alternativen Einstellung kennen, wählen Sie die erste Option (mit der Nummer der alternativen Einstellung) in der Liste aus. Wählen Sie andernfalls die zweite Option aus, die den Schnittstellendeskriptor angibt. Überprüfen Sie USB_INTERFACE_DESCRIPTOR Strukturen für alle alternativen Einstellungen. Enumerieren Sie für jede Einstellung ihre Endpunkte und ihre Merkmale, z. B. Endpunkttyp, maximale Paketgröße usw. Wenn Sie den Satz von Endpunkten finden, den Sie für Datenübertragungen benötigen, rufen Sie WdfUsbInterfaceSelectSetting auf, indem Sie einen Zeiger auf diesen Schnittstellendeskriptor angeben. In der Regel benötigen Sie die dritte Option nicht, es sei denn, Sie sind ein WDM-basierter Clienttreiber, der Anforderungen nur durch Übermitteln von URBs an den USB-Treiberstapel senden kann.

    Basierend auf den vom Clienttreiber bereitgestellten Informationen erstellt der USB-Treiberstapel dann eine Standardsteuerungsanforderung (SET INTERFACE) und sendet sie an das Gerät. Wenn die Anforderung erfolgreich abgeschlossen wird, ruft der USB-Treiberstapel Pipes-Handles an die Endpunkte der alternativen Einstellung ab.

    Nachdem Sie eine alternative Einstellung ausgewählt haben, muss der Clienttreiber immer die Pipehandles für Endpunkte in der neuen Einstellung abrufen. Andernfalls kann der Treiber Datenübertragungsanforderungen mithilfe veralteter Pipehandles senden. Informationen zum Abrufen von Pipe-Handles finden Sie unter Auflisten von USB-Rohren.

NTSTATUS  FX3SelectInterfaceSetting(  
    _In_ WDFDEVICE Device,
    _In_ UCHAR SettingIndex)

{
    NTSTATUS                 status;  
    PDEVICE_CONTEXT          pDeviceContext;  
    WDF_OBJECT_ATTRIBUTES               pipeAttributes;

    WDF_USB_INTERFACE_SELECT_SETTING_PARAMS settingParams;

    PAGED_CODE();  

    pDeviceContext = GetDeviceContext(Device);

    if (pDeviceContext->UsbInterface == NULL)
    {
        status = USBD_STATUS_BAD_NUMBER_OF_INTERFACES;
        goto Exit;
    }

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&pipeAttributes, PIPE_CONTEXT);  

    pipeAttributes.EvtCleanupCallback = FX3EvtPipeContextCleanup;

    WDF_USB_INTERFACE_SELECT_SETTING_PARAMS_INIT_SETTING (&settingParams, SettingIndex);

    status = WdfUsbInterfaceSelectSetting (
        pDeviceContext->UsbInterface,
        &pipeAttributes,
        &settingParams);

    if (status != STATUS_SUCCESS)
    {
        goto Exit;
    }

    if (WdfUsbInterfaceGetNumConfiguredPipes (pDeviceContext->UsbInterface) > 0)
    {
        status = FX3EnumeratePipes (Device);

        if (status != STATUS_SUCCESS)
        {
            goto Exit;
        }
    }

Exit:
    return status;
}

Auswählen einer alternativen Einstellung in einem UMDF-Clienttreiber

  1. Rufen Sie die Anzahl der USB-Schnittstellen ab, die die aktive Konfiguration unterstützt, indem Sie die IWDFUsbTargetDevice::GetNumInterfaces-Methode aufrufen.

  2. Rufen Sie einen IWDFUsbInterface-Zeiger für jede Schnittstelle in der Konfiguration ab.

    Auflisten aller Schnittstellen durch Aufrufen der IWDFUsbTargetDevice::RetrieveUsbInterface-Methode in einer Schleife, bis die Funktion NULL zurückgibt. Erhöhen Sie bei jeder Iteration den Memberindex (nullbasiert). Die Schleife ruft IWDFUsbInterface-Zeiger auf alle aufgelisteten Schnittstellen ab.

  3. Rufen Sie für jede Schnittstelle das WinUSB-Handle ab, indem Sie IWDFUsbInterface::GetWinUsbHandle aufrufen. Dieses Handle ist im nächsten Schritt erforderlich.

  4. Rufen Sie WinUsb_GetAssociatedInterface auf, um ein Handle für die Schnittstelle abzurufen. Geben Sie im AssociatedInterfaceIndex-Parameter den Index in Schritt 2 an.

  5. Bestimmen Sie die Anzahl der alternativen Einstellungen in der Schnittstelle.

    Rufen Sie die WinUsb_QueryInterfaceSettings-Funktion in einer Schleife auf, und erhöhen Sie den Index (nullbasiert) in jeder Iteration. Wenn alle Einstellungen aufgelistet sind, gibt die Funktion ERROR_NO_MORE_ITEMS zurück. Die Funktion gibt auch Schnittstellendeskriptoren für jede Einstellung zurück.

  6. Indem Sie den Wert verwenden, der im bNumEndpoints-Member der einzelnen Schnittstellendeskriptor empfangen wird, und seine Endpunkte auflisten. Überprüfen Sie die Endpunktdeskriptoren, und ermitteln Sie, welche Einstellung Ihren Anforderungen entspricht.

  7. Initiieren Sie eine Select-Interface-Anforderung, indem Sie die WinUsb_SetCurrentAlternateSetting-Funktion aufrufen. Geben Sie im Aufruf die alternative Einstellungsnummer an, die dem Index in Schritt 4 zugeordnet ist.

  8. Lassen Sie das in Schritt 4 abgerufene Schnittstellenhandle los, indem Sie die funktion WinUsb_Free aufrufen.

  9. Lassen Sie das in Schritt 3 abgerufene WinUSB-Handle los, indem Sie die WinUsb_Free-Funktion aufrufen.

  10. Wenn Sie die Verwendung von IWDFUsbInterface-Methoden abgeschlossen haben, geben Sie alle in Schritt 2 abgerufenen Schnittstellenzeiger frei.

Hinweise

Für einen KMDF-Clienttreiber kann der Treiber in seinem WdfUsbInterfaceSelectSetting-Aufruf einen Zeiger auf einen vom Treiber definierten Pipekontext bereitstellen. Der Clienttreiber kann Informationen zu Pipes im Pipekontext speichern. Weitere Informationen zu Pipeinformationen finden Sie unter Auflisten von USB-Rohren.