Поделиться через


Выбор альтернативного параметра в USB-интерфейсе

В этом разделе описываются шаги по выдаче запроса на выборку интерфейса для активации альтернативного параметра в ИНТЕРФЕЙСе USB. Драйвер клиента должен выполнить этот запрос после выбора конфигурации USB. Выбор конфигурации по умолчанию также активирует первый альтернативный параметр в каждом интерфейсе в этой конфигурации.

Каждая конфигурация USB должна поддерживать один или несколько USB-интерфейсов. Каждый интерфейс предоставляет одну или несколько конечных точек, которые используются для передачи данных на устройство и с устройства. Интерфейсы USB должны иметь определяемый устройством индекс интерфейса , который используется для идентификации интерфейса. Интерфейс также должен иметь один или несколько альтернативных параметров , которые группировали конечные точки интерфейса. В рамках конфигурации устройства драйвер клиента должен выбрать один из альтернативных параметров в интерфейсе. Так как конечные точки могут быть общими для альтернативных параметров, в данный момент времени может быть активен только один параметр. После того как альтернативный параметр активен, его конечные точки становятся доступными для передачи данных.

Для устройства с несколькими интерфейсами в данный момент времени могут быть активны два интерфейса. Драйвер клиента должен активировать альтернативный параметр в каждом интерфейсе. Конечные точки не являются общими для интерфейсов, поэтому каждая одновременная передача данных может выполняться в каждом интерфейсе.

Альтернативные параметры определяются устройством и идентифицируются с помощью числа, называемого индексом параметров. Альтернативный параметр с индексом 0 называется альтернативным параметром по умолчанию в этом наборе документации. Альтернативный параметр описан в USB_INTERFACE_DESCRIPTOR структуре. Структура содержит индекс интерфейса, с которым связан параметр, и количество конечных точек, определенное параметром. Он также содержит сведения о спецификации класса, которой соответствуют функциональные возможности интерфейса. Способ группирования конечных точек зависит от функциональности устройства.

Например, интерфейс предоставляет две изохронные и две массовые конечные точки с помощью трех альтернативных параметров (индекс 0, 1, 2). Альтернативный параметр 0 не определяет ни одну конечную точку; Альтернативный параметр 1 определяет массовые конечные точки; Альтернативный параметр 2 определяет изохронные конечные точки. Так как альтернативный параметр 0 не имеет конечной точки, драйвер клиента может выбрать этот параметр, чтобы отключить передачу данных, чтобы сэкономить пропускную способность. Если любой из остальных параметров активен, устройство готово к передаче данных. Для массовой передачи данных можно использовать альтернативный параметр 1. Альтернативный параметр 2 можно выбрать, если устройство находится в режиме потоковой передачи. Таким образом, альтернативные параметры предоставляют драйверу клиента возможность изменять конфигурацию устройства по мере необходимости. В этом примере драйвер клиента может переключить функциональные возможности устройства с массовой передачи на потоковую передачу, просто выбрав альтернативный параметр.

Для задания требований к пропускной способности также можно использовать альтернативные параметры. Пример см. в разделе Макет USB-устройства.

Windows Driver Foundation (WDF) предоставляет методы на платформе драйвера в режиме ядра и среда выполнения платформы драйвера режима пользователя, которые клиентский драйвер может вызвать для выбора другого альтернативного параметра. Драйвер клиента KMDF может выбрать параметр, указав индекс параметра, дескриптор интерфейса параметра или отправив URB, содержащий запрос. Драйвер клиента UMDF может выбрать альтернативный параметр только путем указания его индекса параметров.

После успешного завершения запроса select-configuration ранее активный альтернативный параметр будет отключен.

Это важно знать

В этой статье используются следующие платформы:

Перед началом работы

Прежде чем драйвер клиента сможет выбрать альтернативный параметр, убедитесь, что выполнены следующие требования:

  • Драйвер клиента должен создать объект целевого устройства USB платформы.

  • Устройство должно иметь активную конфигурацию.

    • Драйвер клиента KMDF должен вызывать метод WdfUsbTargetDeviceSelectConfig .

    • Для драйвера клиента UMDF платформа выбирает первую конфигурацию и альтернативный параметр по умолчанию для каждого интерфейса в этой конфигурации.

      Если вы используете шаблоны USB, код выбирает первую конфигурацию и альтернативный параметр по умолчанию в каждом интерфейсе.

Выбор альтернативного параметра в драйвере клиента KMDF

  1. Получите дескриптор WDFUSBINTERFACE для интерфейса с альтернативным параметром.

    Чтобы получить дескриптор, сначала получите количество интерфейсов выбранной конфигурации, вызвав WdfUsbTargetDeviceGetNumInterfaces , а затем перечислите интерфейсы в цикле. В каждой итерации вызовите метод WdfUsbTargetDeviceGetInterface и увеличиваете индекс (начиная с нуля).

    Примечание Во время перечисления устройств стек usb-драйвера назначает номера альтернативным параметрам. Номера интерфейсов отсчитываются от нуля и являются последовательными. Эти числа могут отличаться от индекса параметров, определяемого устройством. Чтобы получить определенный устройством индекс параметров, вызовите метод WdfUsbInterfaceGetInterfaceNumber .

  2. Запустите запрос на выборку интерфейса, вызвав метод WdfUsbInterfaceSelectSetting . В параметре Params вызова выберите один из следующих параметров:

    • Укажите альтернативный номер параметра, назначенный стеком USB-драйверов. Как правило, для перечисления параметров передается тот же индекс, который использовался на шаге 1.

    • Укажите указатель дескриптора интерфейса, описывающего альтернативный параметр. Затем драйвер может получить дескрипторы интерфейса при перечислении альтернативных параметров в интерфейсе, вызвав метод WdfUsbInterfaceGetDescriptor . После завершения перечисления драйвер получает сведения обо всех перечисленных альтернативных параметрах в структуре USB_INTERFACE_DESCRIPTOR .

    • Укажите указатель на URB, содержащий все сведения, необходимые для запроса select-interface.

      1. Выделение массива USBD_INTERFACE_LIST_ENTRY структур. Количество элементов в этом массиве зависит от количества интерфейсов в выбранной конфигурации. Сведения об инициализации этого массива см. в статье Выбор конфигурации для USB-устройства.
      2. Выделите URB для запроса интерфейса выбора, вызвав подпрограмму USBD_SelectInterfaceUrbAllocateAndBuild . В этом вызове укажите массив списков интерфейсов и дескриптор конфигурации, полученный после выбора конфигурации. Этот дескриптор можно получить, вызвав метод WdfUsbTargetDeviceWdmGetConfigurationHandle .
      3. Вызовите WdfUsbInterfaceSelectSetting и укажите URB.

      **Драйверы WDM:*Чтобы отправить URB, свяжите URB с IRP и отправьте IRP в стек драйверов USB. Дополнительные сведения см. в статье Отправка URB.

    Параметры в списке предоставляют драйверу клиента гибкость при указании критериев выбора. Если вы уже знаете о возможностях конечной точки альтернативного параметра, выберите первый вариант (с альтернативным номером параметра) в списке. В противном случае выберите второй параметр, указывающий дескриптор интерфейса. Проверьте USB_INTERFACE_DESCRIPTOR структуры на наличие всех альтернативных параметров. Для каждого параметра перечислите его конечные точки и их характеристики, такие как тип конечной точки, максимальный размер пакета и т. д. Когда вы найдете набор конечных точек, необходимых для передачи данных, вызовите WdfUsbInterfaceSelectSetting , указав указатель на этот дескриптор интерфейса. Как правило, третий вариант не требуется, если только вы не являетесь клиентским драйвером на основе WDM, который может отправлять запросы только в стек USB-драйверов, отправляя urb.

    На основе информации, предоставленной драйвером клиента, стек драйверов USB создает стандартный запрос управления (SET INTERFACE) и отправляет его на устройство. Если запрос завершается успешно, стек usb-драйвера получает дескриптора каналов к конечным точкам альтернативного параметра.

    После выбора альтернативного параметра драйвер клиента должен всегда получать дескриптора канала для конечных точек в новом параметре. Если это не сделать, драйвер будет отправлять запросы на передачу данных с помощью устаревших дескрипторов канала. Сведения о получении дескрипторов канала см. в статье Перечисление 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;
}

Выбор альтернативного параметра в драйвере клиента UMDF

  1. Получите количество USB-интерфейсов, поддерживаемых активной конфигурацией, вызвав метод IWDFUsbTargetDevice::GetNumInterfaces .

  2. Получите указатель IWDFUsbInterface для каждого интерфейса в конфигурации.

    Перечисление всех интерфейсов путем вызова метода IWDFUsbTargetDevice::RetrieveUsbInterface в цикле, пока функция не вернет значение NULL. При каждой итерации увеличивается индекс элемента (отсчитывается от нуля). Цикл извлекает указатели IWDFUsbInterface на все перечисленные интерфейсы.

  3. Для каждого интерфейса получите дескриптор WinUSB, вызвав IWDFUsbInterface::GetWinUsbHandle. Этот дескриптор потребуется на следующем шаге.

  4. Вызовите WinUsb_GetAssociatedInterface, чтобы получить дескриптор интерфейса. В параметре AssociatedInterfaceIndex укажите индекс на шаге 2.

  5. Определите количество альтернативных параметров в интерфейсе.

    Вызовите функцию WinUsb_QueryInterfaceSettings в цикле и увеличиваете индекс (отсчитываемый от нуля) в каждой итерации. При перечислении всех параметров функция возвращает ERROR_NO_MORE_ITEMS. Функция также возвращает дескрипторы интерфейса для каждого параметра.

  6. Используя значение, полученное в элементе bNumEndpoints каждого дескриптора интерфейса, и перечислите его конечные точки. Проверьте дескрипторы конечных точек и определите, какой параметр соответствует вашим требованиям.

  7. Инициируйте запрос на выборку интерфейса, вызвав функцию WinUsb_SetCurrentAlternateSetting . В вызове укажите альтернативный номер параметра, связанный с индексом на шаге 4.

  8. Освободите дескриптор интерфейса, полученный на шаге 4, вызвав функцию WinUsb_Free .

  9. Освободите дескриптор WinUSB, полученный на шаге 3, вызвав функцию WinUsb_Free .

  10. Если вы закончили использовать методы IWDFUsbInterface , опубликуйте все указатели интерфейса, полученные на шаге 2.

Комментарии

Для клиентского драйвера KMDF в вызове WdfUsbInterfaceSelectSetting драйвер может указать указатель на определенный драйвером контекст канала. Драйвер клиента может хранить сведения о каналах в контексте канала. Дополнительные сведения о каналах см. в разделе Перечисление USB-каналов.