Share via


Comment sélectionner un autre paramètre dans une interface USB

Cette rubrique décrit les étapes d’émission d’une demande de sélection d’interface pour activer un autre paramètre dans une interface USB. Le pilote client doit émettre cette requête après avoir sélectionné une configuration USB. La sélection d’une configuration, par défaut, active également le premier paramètre de remplacement dans chaque interface de cette configuration.

Chaque configuration USB doit prendre en charge une ou plusieurs interfaces USB. Chaque interface expose un ou plusieurs points de terminaison utilisés pour transférer des données vers et depuis l’appareil. Les interfaces USB doivent avoir un index d’interface défini par le périphérique qui est utilisé pour identifier l’interface. L’interface doit également avoir un ou plusieurs paramètres alternatifs qui regroupent les points de terminaison de l’interface. Dans le cadre de la configuration de l’appareil, le pilote client doit sélectionner l’un des autres paramètres dans l’interface. Étant donné que les points de terminaison peuvent être partagés entre d’autres paramètres, un seul paramètre peut être actif à un moment donné. Une fois que l’autre paramètre est actif, ses points de terminaison deviennent disponibles pour les transferts de données.

Pour un appareil à plusieurs interfaces, deux interfaces peuvent être actives à un moment donné. Le pilote client doit activer un autre paramètre dans chaque interface. Les points de terminaison ne sont pas partagés entre les interfaces et, par conséquent, chaque transfert de données simultané peut être effectué sur chaque interface.

Les autres paramètres sont définis par l’appareil et identifiés par un nombre appelé index de paramètre. L’autre paramètre à l’index 0 est appelé paramètre alternatif par défaut dans cet ensemble de documentation. Un autre paramètre est décrit dans une structure USB_INTERFACE_DESCRIPTOR . La structure contient l’index d’interface auquel le paramètre est associé et le nombre de points de terminaison définis par le paramètre. Il contient également des informations sur la spécification de classe à laquelle les fonctionnalités de l’interface sont conformes. La façon dont les points de terminaison sont regroupés dépend des fonctionnalités de l’appareil.

Par exemple, une interface expose deux points de terminaison isochrone et deux points de terminaison en bloc via trois paramètres alternatifs (index 0, 1, 2). L’autre paramètre 0 ne définit aucun point de terminaison ; Autre paramètre 1 définit les points de terminaison en bloc ; Autre paramètre 2 définit les points de terminaison isochrone. Étant donné que l’autre paramètre 0 n’a pas de point de terminaison, le pilote client peut sélectionner ce paramètre pour désactiver le transfert de données afin d’économiser la bande passante. Lorsque l’un des autres paramètres est actif, l’appareil est prêt pour les transferts de données. Un autre paramètre 1 peut être utilisé pour transférer des données en bloc. Un autre paramètre 2 peut être sélectionné lorsque l’appareil est en mode streaming. Par conséquent, d’autres paramètres permettent au pilote client de modifier la configuration de l’appareil en fonction des besoins. Dans cet exemple, le pilote client peut basculer la fonctionnalité de l’appareil d’un transfert en bloc vers la diffusion en continu, simplement en sélectionnant un autre paramètre.

D’autres paramètres peuvent également être utilisés pour définir les exigences de bande passante. Pour obtenir un exemple, consultez disposition du périphérique USB.

Windows Driver Foundation (WDF) fournit des méthodes dans l’infrastructure du pilote en mode noyau et l’infrastructure du pilote en mode utilisateur que le pilote client peut appeler pour sélectionner un autre paramètre. Le pilote client KMDF peut sélectionner un paramètre en spécifiant l’index de paramètre, le descripteur d’interface du paramètre ou en envoyant un URB qui contient la demande. Le pilote client UMDF peut uniquement sélectionner un autre paramètre en spécifiant son index de paramètre.

Une fois qu’une demande de configuration de sélection s’est terminée avec succès, l’autre paramètre précédemment actif est désactivé.

Bon à savoir

Cet article utilise les frameworks suivants :

Avant de commencer

Avant que le pilote client puisse sélectionner un autre paramètre, assurez-vous que ces exigences sont remplies :

  • Le pilote client doit avoir créé l’objet de périphérique cible USB du framework.

  • L’appareil doit avoir une configuration active.

    • Un pilote client KMDF doit appeler la méthode WdfUsbTargetDeviceSelectConfig .

    • Pour un pilote client UMDF, l’infrastructure sélectionne la première configuration et l’autre paramètre par défaut pour chaque interface de cette configuration.

      Si vous utilisez des modèles USB, le code sélectionne la première configuration et l’autre paramètre par défaut dans chaque interface.

Sélectionner un autre paramètre dans un pilote client KMDF

  1. Obtenez un handle WDFUSBINTERFACE pour l’interface qui a l’autre paramètre.

    Pour obtenir handle, commencez par obtenir le nombre d’interfaces de la configuration sélectionnée en appelant WdfUsbTargetDeviceGetNumInterfaces , puis énumérez les interfaces dans une boucle. Dans chaque itération, appelez la méthode WdfUsbTargetDeviceGetInterface et incrémentez l’index (en commençant à zéro).

    Note Pendant l’énumération des périphériques, la pile de pilotes USB affecte des nombres aux autres paramètres. Les numéros d’interface sont de base zéro et séquentiels. Ces nombres peuvent être différents de l’index de paramètre défini par l’appareil. Pour obtenir l’index de paramètre défini par l’appareil, appelez la méthode WdfUsbInterfaceGetInterfaceNumber .

  2. Lancez une demande d’interface de sélection en appelant la méthode WdfUsbInterfaceSelectSetting . Dans le paramètre Params de l’appel, choisissez l’une des options suivantes :

    • Spécifiez le numéro de paramètre de remplacement attribué par la pile de pilotes USB. En règle générale, vous transmettez le même index que celui que vous avez utilisé à l’étape 1 pour énumérer les paramètres.

    • Spécifiez un pointeur du descripteur d’interface qui décrit le paramètre alternatif. Le pilote peut ensuite obtenir des descripteurs d’interface tout en énumérant d’autres paramètres dans l’interface en appelant la méthode WdfUsbInterfaceGetDescriptor . Une fois l’énumération terminée, le pilote obtient des informations sur tous les autres paramètres énumérés dans la structure USB_INTERFACE_DESCRIPTOR .

    • Spécifiez un pointeur vers un URB qui contient toutes les informations requises pour la demande select-interface.

      1. Allouez un tableau de structures USBD_INTERFACE_LIST_ENTRY . Le nombre d’éléments dans ce tableau dépend du nombre d’interfaces dans la configuration sélectionnée. Pour plus d’informations sur l’initialisation de ce tableau, consultez Comment sélectionner une configuration pour un périphérique USB.
      2. Allouez un URB pour la demande d’interface de sélection en appelant la routine USBD_SelectInterfaceUrbAllocateAndBuild . Dans cet appel, spécifiez le tableau de liste d’interfaces et le handle de configuration obtenu après la sélection d’une configuration. Vous pouvez obtenir ce handle en appelant la méthode WdfUsbTargetDeviceWdmGetConfigurationHandle .
      3. Appelez WdfUsbInterfaceSelectSetting et spécifiez l’URB.

      **Pilotes WDM :**Pour envoyer l’URB, associez l’URB à un IRP, puis envoyez l’IRP à la pile de pilotes USB. Pour plus d’informations, consultez Comment envoyer un URB.

    Les options de la liste offrent au pilote client la flexibilité nécessaire pour spécifier les critères de sélection. Si vous connaissez déjà les fonctionnalités de point de terminaison de l’autre paramètre, choisissez la première option (avec le numéro de paramètre de remplacement) dans la liste. Sinon, choisissez la deuxième option qui spécifie le descripteur d’interface. Inspectez USB_INTERFACE_DESCRIPTOR structures pour tous les autres paramètres. Pour chaque paramètre, énumérez ses points de terminaison et leurs caractéristiques, telles que le type de point de terminaison, la taille maximale des paquets, etc. Lorsque vous trouvez l’ensemble des points de terminaison dont vous avez besoin pour les transferts de données, appelez WdfUsbInterfaceSelectSetting en spécifiant un pointeur vers ce descripteur d’interface. En règle générale, vous n’avez pas besoin de la troisième option, sauf si vous êtes un pilote client WDM qui peut uniquement envoyer des requêtes à la pile de pilotes USB en envoyant des URBs.

    En fonction des informations fournies par le pilote client, la pile de pilotes USB génère ensuite une demande de contrôle standard (SET INTERFACE) et l’envoie au périphérique. Si la demande se termine correctement, la pile de pilotes USB obtient des handles de canaux vers les points de terminaison de l’autre paramètre.

    Après avoir sélectionné un autre paramètre, le pilote client doit toujours obtenir les descripteurs de canal pour les points de terminaison dans le nouveau paramètre. Si vous ne le faites pas, le pilote peut envoyer des demandes de transfert de données à l’aide de handles de canal obsolètes. Pour plus d’informations sur la récupération des poignées de canal, consultez Guide pratique pour énumérer les canaux USB.

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

Sélectionner un autre paramètre dans un pilote client UMDF

  1. Obtenez le nombre d’interfaces USB prises en charge par la configuration active en appelant la méthode IWDFUsbTargetDevice ::GetNumInterfaces .

  2. Obtenez un pointeur IWDFUsbInterface pour chaque interface de la configuration.

    Énumérez toutes les interfaces en appelant la méthode IWDFUsbTargetDevice ::RetrieveUsbInterface dans une boucle jusqu’à ce que la fonction retourne NULL. À chaque itération, incrémentez l’index membre (base zéro). La boucle récupère les pointeurs IWDFUsbInterface vers toutes les interfaces énumérées.

  3. Pour chaque interface, obtenez le handle WinUSB en appelant IWDFUsbInterface ::GetWinUsbHandle. Ce handle est requis à l’étape suivante.

  4. Appelez WinUsb_GetAssociatedInterface pour obtenir un handle pour l’interface. Dans le paramètre AssociatedInterfaceIndex , spécifiez l’index à l’étape 2.

  5. Déterminez le nombre de paramètres de remplacement dans l’interface.

    Appelez la fonction WinUsb_QueryInterfaceSettings dans une boucle et incrémentez l’index (base zéro) dans chaque itération. Lorsque tous les paramètres sont énumérés, la fonction retourne ERROR_NO_MORE_ITEMS. La fonction retourne également des descripteurs d’interface pour chaque paramètre.

  6. En utilisant la valeur reçue dans le membre bNumEndpoints de chaque descripteur d’interface, et énumérez ses points de terminaison. Inspectez les descripteurs de point de terminaison et déterminez quel paramètre répond à vos besoins.

  7. Lancez une demande d’interface de sélection en appelant la fonction WinUsb_SetCurrentAlternateSetting . Dans l’appel, spécifiez le numéro de paramètre de remplacement associé à l’index à l’étape 4.

  8. Relâchez le handle d’interface obtenu à l’étape 4 en appelant la fonction WinUsb_Free .

  9. Relâchez le handle WinUSB obtenu à l’étape 3 en appelant la fonction WinUsb_Free .

  10. Si vous avez terminé d’utiliser les méthodes IWDFUsbInterface , relâchez tous les pointeurs d’interface récupérés à l’étape 2.

Remarques

Pour un pilote client KMDF, dans son appel WdfUsbInterfaceSelectSetting , le pilote peut fournir un pointeur vers un contexte de canal défini par le pilote. Le pilote client peut stocker des informations sur les canaux dans le contexte du canal. Pour plus d’informations sur les canaux, consultez Guide pratique pour énumérer des canaux USB.