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

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

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

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

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

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

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

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

После успешного завершения запроса на выбор конфигурации, ранее активная альтернативная настройка деактивируется.

Что нужно знать

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      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-драйверов, отправляя URI.

    На основе сведений, предоставленных драйвером клиента, стек 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-каналов.