---
description: 'Устройства USB в FreeBSD'
next: books/arch-handbook/newbus
params:
  path: /books/arch-handbook/usb/
prev: books/arch-handbook/scsi
showBookMenu: 'true'
tags: ["USB", "Structure", "UHCI", "OHCI"]
title: 'Глава 13. USB-устройства'
weight: 15
---

[[usb]]
= Устройства USB
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 13
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/arch-handbook/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[[usb-intro]]
== Введение

Универсальная последовательная шина (USB) — это новый способ подключения устройств к персональным компьютерам. Архитектура шины поддерживает двустороннюю связь и была разработана в ответ на усложнение устройств, требующих большего взаимодействия с хостом. Поддержка USB включена во все современные чипсеты ПК и, следовательно, доступна во всех недавно собранных компьютерах. Выпуск Apple iMac только с USB стал серьёзным стимулом для производителей оборудования выпускать USB-версии своих устройств. Согласно будущим спецификациям ПК, все устаревшие разъёмы должны быть заменены одним или несколькими USB-разъёмами, обеспечивающими универсальные возможности plug and play. Поддержка USB-оборудования появилась в NetBSD на очень раннем этапе и была разработана Леннартом Аугустссоном для проекта NetBSD. Код был портирован в FreeBSD, и в настоящее время мы поддерживаем общую кодовая базу. Для реализации подсистемы USB важны некоторые особенности USB.

_Леннарт Аугустссон выполнил большую часть работы по реализации поддержки USB для проекта NetBSD. Огромная благодарность за этот невероятный объём работы. Также большое спасибо Арди и Дирку за их комментарии и вычитку этой статьи._

* Устройства подключаются к портам компьютера напрямую или через устройства, называемые концентраторами, образуя древовидную структуру устройств.
* Устройства можно подключать и отключать во время работы.
* Устройства могут приостанавливать свою работу и инициировать возобновление работы основной системы
* Поскольку устройства могут получать питание от шины, программное обеспечение хоста должно отслеживать энергопотребление для каждого концентратора.
* Различные требования к качеству обслуживания для разных типов устройств, а также максимум в 126 устройств, которые могут быть подключены к одной шине, требуют правильного планирования передач по общей шине, чтобы полностью использовать доступную пропускную способность в 12 Мбит/с (более 400 Мбит/с для USB 2.0)
* Устройства являются интеллектуальными и содержат легко доступную информацию о себе

Разработка драйверов для подсистемы USB и подключенных к ней устройств поддерживается спецификациями, которые были разработаны и будут разрабатываться. Эти спецификации общедоступны на домашних страницах USB. Apple активно продвигает стандартизированные драйверы, предоставляя драйверы для универсальных классов в своей операционной системе MacOS и не поощряя использование отдельных драйверов для каждого нового устройства. Эта глава пытается собрать основную информацию для базового понимания реализации стека USB 2.0 в FreeBSD/NetBSD. Однако рекомендуется читать её вместе с соответствующими спецификациями 2.0 и другими ресурсами для разработчиков:

* Спецификация USB 2.0 (http://www.usb.org/developers/docs/usb20_docs/[http://www.usb.org/developers/docs/usb20_docs/])
* Универсальный интерфейс хост-контроллера (UHCI) Спецификация (link:ftp://ftp.netbsd.org/pub/NetBSD/misc/blymn/uhci11d.pdf[ftp://ftp.netbsd.org/pub/NetBSD/misc/blymn/uhci11d.pdf])
* Спецификация интерфейса Open Host Controller (OHCI)(link:ftp://ftp.compaq.com/pub/supportinformation/papers/hcir1_0a.pdf[ftp://ftp.compaq.com/pub/supportinformation/papers/hcir1_0a.pdf])
* Раздел для разработчиков на домашней странице USB (http://www.usb.org/developers/[http://www.usb.org/developers/])

=== Структура стека USB

Поддержка USB в FreeBSD может быть разделена на три уровня. Самый нижний уровень содержит драйвер контроллера хоста, предоставляющий универсальный интерфейс к оборудованию и его механизмам планирования. Он поддерживает инициализацию оборудования, планирование передач и обработку завершённых и/или неудачных передач. Каждый драйвер контроллера хоста реализует виртуальный концентратор, обеспечивающий независимый от оборудования доступ к регистрам, управляющим корневыми портами на задней панели машины.

Средний уровень обрабатывает подключение и отключение устройства, базовую инициализацию устройства, выбор драйвера, каналы связи (pipe) и управляет ресурсами. Этот сервисный уровень также контролирует стандартные каналы и запросы устройств, передаваемые через них.

Верхний уровень содержит отдельные драйверы, поддерживающие конкретные (классы) устройств. Эти драйверы реализуют протокол, используемый в каналах, отличных от стандартного. Они также реализуют дополнительную функциональность для обеспечения доступа к устройству другим частям ядра или пользовательского пространства. Они используют интерфейс драйвера USB (USBDI), предоставляемый уровнем сервисов.

[[usb-hc]]
== Контроллеры хоста

Хост-контроллер (HC) управляет передачей пакетов на шине. Используются кадры длительностью 1 миллисекунда. В начале каждого кадра хост-контроллер генерирует пакет Start of Frame (SOF).

Пакет SOF используется для синхронизации начала кадра и отслеживания номера кадра. Внутри каждого кадра передаются пакеты, либо от хоста к устройству (исходящие), либо от устройства к хосту (входящие). Передачи всегда инициируются хостом (опросные передачи). Поэтому на каждой шине USB может быть только один хост. Каждая передача пакета имеет стадию статуса, в которой получатель данных может вернуть либо ACK (подтверждение приема), NAK (повторить), STALL (ошибка) либо ничего (искаженная стадия данных, устройство недоступно или отключено). В разделе 8.5 спецификации USB 2.0 подробно объясняются детали пакетов. На шине USB могут происходить четыре различных типа передач: управляющие, массовые, прерывания и изохронные. Типы передач и их характеристики описаны ниже.

Крупные передачи между устройством на шине USB и драйвером устройства разделяются на несколько пакетов хост-контроллером или драйвером HC.

Запросы устройств (управляющие передачи) к конечным точкам по умолчанию являются особыми. Они состоят из двух или трёх фаз: SETUP, DATA (опционально) и STATUS. Пакет настройки отправляется на устройство. Если присутствует фаза данных, направление пакета(ов) данных указывается в пакете настройки. Направление в фазе статуса противоположно направлению во время фазы данных или IN, если фазы данных не было. Аппаратное обеспечение хост-контроллера также предоставляет регистры с текущим состоянием корневых портов и изменениями, произошедшими с момента последнего сброса регистра изменений статуса. Доступ к этим регистрам предоставляется через виртуализированный концентратор, как предложено в спецификации USB. Виртуальный концентратор должен соответствовать классу устройств концентратора, указанному в главе 11 этой спецификации. Он должен предоставлять канал по умолчанию, через который можно отправлять запросы устройств. Он возвращает стандартные и специфичные для класса концентратора наборы дескрипторов. Также он должен предоставлять прерывающий канал, сообщающий об изменениях, происходящих на его портах. В настоящее время доступны две спецификации для хост-контроллеров: - Universal Host Controller Interface (UHCI) от Intel и Open Host Controller Interface (OHCI) от Compaq, Microsoft и National Semiconductor. Спецификация UHCI разработана для уменьшения аппаратной сложности, требуя от драйвера хост-контроллера предоставления полного расписания передач для каждого кадра. Контроллеры типа OHCI гораздо более независимы, предоставляя более абстрактный интерфейс и выполняя большую часть работы самостоятельно.

=== UHCI

Контроллер UHCI поддерживает список кадров (framelist) с 1024 указателями на структуры данных для каждого кадра. Он распознаёт два типа данных: дескрипторы передачи (TD) и головы очередей (QH). Каждый TD представляет пакет для передачи в конечную точку устройства или из неё. QH служат для группировки TD (и других QH) вместе.

Каждая передача состоит из одного или нескольких пакетов. Драйвер UHCI разделяет большие передачи на несколько пакетов. Для каждой передачи, за исключением изохронных, выделяется QH. Для каждого типа передачи эти QH собираются в QH для соответствующего типа. Изохронные передачи должны выполняться первыми из-за требования фиксированной задержки и непосредственно указываются указателем в списке кадров. Последний изохронный TD ссылается на QH для прерывающих передач для этого кадра. Все QH для прерывающих передач указывают на QH для управляющих передач, который, в свою очередь, указывает на QH для массовых передач. Следующая диаграмма даёт графическое представление этого:

В результате выполняется следующее расписание в каждом кадре. После получения указателя на текущий кадр из списка кадров контроллер сначала выполняет TDs для всех изохронных пакетов в этом кадре. Последний из этих TDs ссылается на QH для прерывающих передач этого кадра. Хост-контроллер затем переходит от этого QH к QHs для отдельных прерывающих передач. После завершения этой очереди, QH для прерывающих передач ссылается на QH для всех управляющих передач. Он выполняет все подочереди, запланированные там, а затем все передачи, поставленные в очередь в QH для массовых передач. Для упрощения обработки завершенных или неудачных передач аппаратное обеспечение генерирует различные типы прерываний в конце каждого кадра. В последнем TD для передачи бит *Interrupt-On Completion* устанавливается драйвером HC, чтобы вызвать прерывание по завершении передачи. Прерывание ошибки возникает, если TD достигает максимального количества ошибок. Если в TD установлен бит *short packet detect* и передано меньше установленной длины пакета, это прерывание уведомляет драйвер контроллера о завершении передачи. Задача драйвера хост-контроллера — определить, какая передача завершилась или вызвала ошибку. При вызове процедура обслуживания прерывания находит все завершенные передачи и вызывает их callback-функции.

Обратитесь к спецификации UHCI для более подробного описания.

=== OHCI

Программирование OHCI-контроллера значительно проще. Контроллер предполагает, что доступен набор конечных точек, и учитывает приоритеты планирования и порядок типов передач в кадре. Основная структура данных, используемая хост-контроллером, — это дескриптор конечной точки (ED), к которому присоединена очередь дескрипторов передачи (TD). ED содержит максимальный размер пакета, разрешенный для конечной точки, а аппаратное обеспечение контроллера выполняет разделение на пакеты. Указатели на буферы данных обновляются после каждой передачи, и когда начальный и конечный указатели становятся равны, TD перемещается в очередь завершенных (done-queue). Четыре типа конечных точек (прерывание, изохронная, управление и массовая) имеют свои собственные очереди. Управляющие и массовые конечные точки помещаются каждая в свою очередь. ED прерываний организуются в дерево, где уровень в дереве определяет частоту их выполнения.

Порядок действий, выполняемых хост-контроллером в каждом кадре, выглядит следующим образом. Контроллер сначала запускает непериодические очереди управления и массовых передач, вплоть до ограничения времени, установленного драйвером HC. Затем выполняются прерывающие передачи для данного номера кадра, используя младшие пять битов номера кадра в качестве индекса уровня 0 дерева ED прерываний. В конце этого дерева подключены изохронные ED, которые затем обходятся. Изохронные TD содержат номер кадра, в котором должна быть запущена первая передача. После выполнения всех периодических передач очереди управления и массовых передач обходятся снова. Периодически вызывается процедура обслуживания прерывания для обработки очереди завершенных операций и вызова обратных вызовов для каждой передачи, а также для перепланирования прерывающих и изохронных конечных точек.

См. UHCI Specification для более подробного описания. Средний уровень обеспечивает контролируемый доступ к устройству и управляет ресурсами, используемыми различными драйверами и уровнем сервисов. Этот уровень отвечает за следующие аспекты:

* Информация о конфигурации устройства
* Каналы для взаимодействия с устройством
* Обнаружение, подключение и отключение от устройства.

[[usb-dev]]
== Информация об устройстве USB

=== Информация о конфигурации устройства

Каждое устройство предоставляет различные уровни информации о конфигурации. У каждого устройства есть одна или несколько конфигураций, из которых одна выбирается во время обнаружения/подключения. Конфигурация определяет требования к питанию и пропускной способности. В каждой конфигурации может быть несколько интерфейсов. Интерфейс устройства — это набор конечных точек. Например, USB-колонки могут иметь интерфейс для аудиоданных (Audio Class) и интерфейс для регуляторов, ручек и кнопок (HID Class). Все интерфейсы в конфигурации активны одновременно и могут быть подключены разными драйверами. Каждый интерфейс может иметь альтернативные варианты, предоставляющие различные параметры качества обслуживания. Например, в камерах это используется для поддержки разных размеров кадра и количества кадров в секунду.

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

Эта иерархическая конфигурационная информация описывается в устройстве стандартным набором дескрипторов (см. раздел 9.6 спецификации USB). Они могут быть запрошены через Get Descriptor Request. Сервисный уровень кэширует эти дескрипторы, чтобы избежать ненужных передач по шине USB. Доступ к дескрипторам предоставляется через вызовы функций.

* Дескрипторы устройств: Общая информация об устройстве, такая как Vendor (производитель), Product (продукт) и Revision Id (идентификатор ревизии), поддерживаемый класс устройства, подкласс и протокол, если применимо, максимальный размер пакета для конечной точки по умолчанию и т. д.
* Дескрипторы конфигурации: количество интерфейсов в данной конфигурации, поддержка функций приостановки и возобновления работы, а также требования к питанию.
* Дескрипторы интерфейса: класс интерфейса, подкласс и протокол (если применимо), количество альтернативных настроек интерфейса и количество конечных точек.
* Дескрипторы конечных точек: Адрес конечной точки, направление и тип, максимальный поддерживаемый размер пакета и частота опроса, если тип является конечной точкой прерывания. Для конечной точки по умолчанию (конечная точка 0) дескриптора не существует, и она никогда не учитывается в дескрипторе интерфейса.
* Дескрипторы строк: В остальных дескрипторах для некоторых полей указываются индексы строк. Эти индексы могут использоваться для получения описательных строк, возможно, на нескольких языках.

Спецификации классов могут добавлять свои собственные типы дескрипторов, которые доступны через запрос GetDescriptor.

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

Если передача через канал превышает максимальный размер пакета, указанный в соответствующем дескрипторе конечной точки, хост-контроллер (OHCI) или драйвер HC (UHCI) разделит передачу на пакеты максимального размера, при этом последний пакет может быть меньше максимального размера.

Иногда для устройства не является проблемой вернуть меньше данных, чем запрошено. Например, при передаче данных в режиме bulk-in на модем может быть запрошено 200 байт данных, но у модема в данный момент доступно только 5 байт. Драйвер может установить флаг короткого пакета (SPD). Это позволяет хост-контроллеру принять пакет, даже если объём переданных данных меньше запрошенного. Этот флаг действителен только для in-передач, так как объём данных, отправляемых на устройство, всегда известен заранее. Если во время передачи в устройстве происходит неустранимая ошибка, канал останавливается (stalled). Прежде чем принимать или отправлять дополнительные данные, драйвер должен устранить причину остановки и сбросить условие остановки конечной точки, отправив запрос `clear endpoint halt` через канал по умолчанию. Конечная точка по умолчанию никогда не должна останавливаться.

Существует четыре различных типа конечных точек и соответствующих каналов: - Управляющий канал / канал по умолчанию: На каждое устройство приходится один управляющий канал, подключенный к конечной точке по умолчанию (конечная точка 0). Этот канал передаёт запросы устройства и связанные с ними данные. Разница между передачами через канал по умолчанию и другими каналами заключается в том, что протокол для этих передач описан в спецификации USB. Эти запросы используются для сброса и настройки устройства. Базовый набор команд, который должен поддерживаться каждым устройством, приведен в главе 9 спецификации USB. Команды, поддерживаемые на этом канале, могут быть расширены спецификацией класса устройства для обеспечения дополнительной функциональности.

* Массовый канал: Это USB-эквивалент среды передачи данных в сыром виде.
* Прерывающий канал: Хост отправляет запрос данных на устройство, и если устройству нечего отправлять, оно отвечает NAK на пакет данных. Прерывающие передачи планируются с частотой, указанной при создании канала.
* Изохронный канал: Эти каналы предназначены для изохронных данных, например, видео- или аудиопотоков, с фиксированной задержкой, но без гарантированной доставки. В текущей реализации доступна некоторая поддержка каналов этого типа. Пакеты в управляющих, массовых и прерывающих передачах повторяются, если во время передачи возникает ошибка или устройство отрицательно подтверждает пакет (NAK) из-за, например, нехватки буферного пространства для хранения входящих данных. Однако изохронные пакеты не повторяются в случае неудачной доставки или NAK пакета, так как это может нарушить временные ограничения.

Доступность необходимой полосы пропускания рассчитывается во время создания канала. Передачи планируются в рамках интервалов в 1 миллисекунду. Распределение полосы пропускания внутри интервала регламентируется спецификацией USB, раздел 5.6 [2]. Изохронные и прерывающие передачи могут использовать до 90% полосы пропускания в рамках интервала. Пакеты для управляющих и массовых передач планируются после всех изохронных и прерывающих пакетов и используют всю оставшуюся полосу пропускания.

Дополнительная информация о планировании передач и освобождении пропускной способности доступна в главе 5 спецификации USB, разделе 1.3 спецификации UHCI и разделе 3.4.2 спецификации OHCI.

[[usb-devprobe]]
== Обнаружение устройства и подключение

После уведомления от концентратора о подключении нового устройства сервисный уровень включает порт, предоставляя устройству ток 100 мА. На этом этапе устройство находится в своём исходном состоянии и прослушивает адрес устройства 0. Сервисный уровень продолжит получение различных дескрипторов через стандартный канал. После этого он отправит запрос Set Address, чтобы переместить устройство с исходного адреса (адрес 0). Несколько драйверов устройств могут поддерживать данное устройство. Например, драйвер модема может поддерживать ISDN TA через интерфейс совместимости AT. Однако драйвер, предназначенный для конкретной модели ISDN-адаптера, может обеспечить гораздо лучшую поддержку этого устройства. Для обеспечения такой гибкости пробы возвращают приоритеты, указывающие уровень их поддержки. Поддержка конкретной версии продукта имеет наивысший приоритет, а универсальный драйвер — самый низкий. Также возможно, что несколько драйверов могут быть подключены к одному устройству, если в одной конфигурации присутствует несколько интерфейсов. Каждому драйверу требуется поддерживать только подмножество интерфейсов.

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

=== Отключение и извлечение устройства

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

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

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

[[usb-protocol]]
== Информация о протоколе драйверов USB

Используемый протокол для каналов, отличных от стандартного, не определен спецификацией USB. Информацию об этом можно найти из различных источников. Наиболее точный источник — раздел для разработчиков на домашних страницах USB. На этих страницах доступно растущее количество спецификаций классов устройств. Эти спецификации определяют, каким должно быть совместимое устройство с точки зрения драйвера, базовую функциональность, которую оно должно предоставлять, и протокол, используемый на каналах связи. Спецификация USB включает описание класса концентраторов (Hub Class). Спецификация класса устройств человеко-машинного интерфейса (HID) была создана для поддержки клавиатур, планшетов, сканеров штрих-кодов, кнопок, регуляторов, переключателей и т. д. Третий пример — спецификация класса устройств хранения данных (Mass Storage). Полный список классов устройств можно найти в разделе для разработчиков на домашних страницах USB.

Для многих устройств информация о протоколе ещё не опубликована. Сведения об используемом протоколе могут быть доступны у компании-производителя устройства. Некоторые компании потребуют подписания соглашения о неразглашении (NDA), прежде чем предоставить спецификации. В большинстве случаев это исключает возможность сделать драйвер открытым.

Еще один хороший источник информации — исходные коды драйверов Linux, так как ряд компаний начал предоставлять драйверы для Linux для своих устройств. Всегда полезно связаться с авторами этих драйверов для получения информации.

Пример: Устройства интерфейса пользователя (HID) — Спецификация для устройств интерфейса пользователя, таких как клавиатуры, мыши, планшеты, кнопки, регуляторы и т.д., упоминается в других спецификациях классов устройств и используется во многих устройствах.

Например, аудиоколонки предоставляют конечные точки для цифро-аналоговых преобразователей и, возможно, дополнительный канал для микрофона. Они также предоставляют конечную точку HID в отдельном интерфейсе для кнопок и регуляторов на передней панели устройства. То же самое справедливо для класса управления монитором. Реализовать поддержку этих интерфейсов достаточно просто с помощью доступных библиотек ядра и пользовательского пространства, а также драйвера класса HID или универсального драйвера. Другим примером устройства с несколькими интерфейсами в одной конфигурации, управляемыми разными драйверами, является недорогая клавиатура со встроенным устаревшим портом для мыши. Чтобы избежать затрат на включение аппаратного обеспечения USB-концентратора в устройство, производители объединили данные мыши, полученные с порта PS/2 на задней панели клавиатуры, и нажатия клавиш в два отдельных интерфейса в одной конфигурации. Драйверы мыши и клавиатуры подключаются к соответствующему интерфейсу и выделяют каналы для двух независимых конечных точек.

Пример: Загрузка микропрограммы — многие разработанные устройства основаны на процессоре общего назначения с добавленным USB-ядром. Поскольку разработка драйверов и микропрограмм для USB-устройств всё ещё очень нова, многие устройства требуют загрузки микропрограммы после подключения.

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

Примером таких устройств является плата ввода-вывода ActiveWire, основанная на чипе EZ-USB. Для этого чипа доступен универсальный загрузчик микропрограмм. Микропрограмма, загруженная в плату ActiveWire, изменяет идентификатор ревизии. Затем выполняется мягкий сброс USB-части чипа EZ-USB для отключения от USB-шины и повторного подключения.

Пример: Поддержка устройств хранения данных в основном построена на существующих протоколах. Устройство Iomega USB Zipdrive основано на SCSI-версии их накопителя. SCSI-команды и статусные сообщения упаковываются в блоки и передаются через массовые каналы к устройству и от него, эмулируя SCSI-контроллер через USB-соединение. ATAPI и UFI команды поддерживаются аналогичным образом.

Спецификация Mass Storage поддерживает 2 различных типа обёртки командного блока. Первоначальная попытка была основана на отправке команды и состояния через канал по умолчанию с использованием массовых передач для данных, перемещаемых между хостом и устройством. На основе опыта был разработан второй подход, основанный на обёртке командных и статусных блоков и их отправке через конечные точки массовой передачи (bulk out и bulk in). Спецификация точно определяет, что должно происходить и когда, а также что необходимо делать в случае возникновения ошибки. Наибольшую сложность при написании драйверов для таких устройств представляет встраивание USB-ориентированного протокола в существующую поддержку устройств хранения данных. CAM предоставляет механизмы для этого достаточно прямолинейным способом. С ATAPI всё менее просто, так как исторически интерфейс IDE никогда не имел множества различных вариантов реализации.

Поддержка USB-дисковода от Y-E Data также не прямолинейна, так как был разработан новый набор команд.
