PersCom — Компьютерная Энциклопедия Компьютерная Энциклопедия

USB

Хост USB

Структуры данных и регистры контроллера OHC

Все структуры данных OHC, расположенные в системной памяти, выровнены по границе параграфа (четыре младших бита адреса — нулевые). Для работы с OHC в памяти размещают дескрипторы конечных точек (ED) выбранных интерфейсов сконфигурированных устройств, дескрипторы передач (TD) для них и коммуникационную область HCCA. Дескрипторы передач подключаются драйвером к очередям требуемых конечных точек. Дескрипторы исполненных передач (завершенных нормально или снятых аварийно) контроллером подключаются к очереди Done Queue. Буфер данных для каждого дескриптора передачи может размещаться в одной или двух физических страницах, физические адреса этих страниц определяются по физическому адресу начала (начальное значение CBP) и физическому адресу конца буфера. Дескрипторы передач делятся на два типа: общий (для передач Bulk, Control, Interrupt) и изохронный.

Дескриптор конечной точки (ED) имеет размер 4 двойных слова (16 байт), его формат приведен на рисунке ниже, назначение полей приведено ниже:

  • FA (FunctionAddress) — адрес устройства;
  • EN (EndpointNumber) — номер точки;
  • D (Direction) — направление передачи: 01 — OUT; 10 — IN; 00, 11 — брать из поля PID дескриптора передачи TD;
  • S (Speed) — скорость: 0 — FS, 1 — LS;
  • K (sKip) — пропустить (не начинать транзакций с данной точкой);
  • F (Format) — признак формата TD, связанного с данной точкой: 0 — общий (Bulk, Control, Interrupt), 1 — дескриптор изохронной передачи;
  • MPS (MaximumPacketSize) — максимальный размер пакета;
  • TailP (TD Queue Tail Pointer) — указатель на конец очереди TD, если совпадает с HeadP — очередь пуста;
  • HeadP (TD Queue Head Pointer) — указатель на очередной TD, который должен быть исполнен для данной точки;
  • H (Halted) — признак останова точки;
  • C (toggleCarry) — текущее значение переключателя Toggle Bit;
  • NextED (Next Endpoint Descriptor) — указатель на дескриптор следующей конечной точки (если ноль, то эта точка — последняя в списке).

 

Формат общего дескриптора передач приведен на рисунке 2 (см. выше). Дескриптор позволяет описывать передачу данных указанной длины в пределах 8 кбайт. Количество транзакций для передачи контроллер определяет сам из поля длины пакета в дескрипторе точки (ED) и длины буфера; количество транзакций при приеме определяется длиной пакетов, переданных устройством. Назначение полей общего дескриптора передач приведено ниже:

  • R (bufferRounding) — требование совпадения длины последнего принимаемого пакета с объявленной длиной буфера (обнаружение коротких пакетов): 0 — сообщать об ошибке, если длина последнего пакета меньше длины буфера, 1 — не реагировать на несовпадение длины;
  • DP (Direction/PID) — тип маркера (направление, должно соответствовать полю D в ED): 00 — SETUP, 01 —OUT, 10 — IN, 11 — резерв;
  • DI (DelayInterrupt) — задержка прерывания по отработке передачи: 000–110 — задержка (число пропущенных кадров), 111 — не вызывать прерывание;
  • T (DataToggle) — поле, используемое для генерации и сравнения переключателя типа пакетов данных. Вместе с битом C из ED обеспечивает корректное переключение при передачах данных, описанных серией TD. При постановке в очередь TD для передач типов Bulk и Interupt драйвер должен установить T = 00; для передач типа Control в фазе Setup драйвер должен установить T = 10; в фазе Status и в первой фазе данных — T = 11. Дальнейшие модификации поля выполняет контроллер;
  • EC (ErrorCount) — счетчик ошибок передачи для текущей транзакции. Если при EC = 2 происходит ошибка, ее код помещается в CC и вся передача аварийно завершается. При успешном завершении транзакции счетчик обнуляется;
  • CC (ConditionCode) — состояние последней попытки транзакции
  • CBP (Current Buffer Pointer) — текущий физический адрес в буфере, по которому будет записан или прочитан очередной передаваемый пакет. После успешного завершения передачи поле обнуляется, при нештатном завершении — указывает на текущее положение;
  • NextTD — указатель на следующий дескриптор передачи для данной точки;
  • BE (Buffer End) — физический адрес последнего байта в буфере для данного TD.

Формат дескриптора изохронной передачи приведен на рисунке ниже. Дескриптор позволяет описывать передачу данных длиной до 8 кбайт, состоящую из 1–8 транзакций (их количество задано в дескрипторе). Транзакции исполняются в последовательных кадрах, начиная с кадра с указанным номером. Длина пакета в каждой из этих транзакций вычисляется из значений полей OffsetN смежных транзакций (возможны и транзакции с нулевой длиной поля данных). Физический адрес буфера для каждой из этих транзакций определяется следующим образом: младшие 12 бит берутся из младших 12 бит соответствующего поля Offset, старшие биты (номер физической страницы) берутся либо из поля BPO (если в поле Offset бит 12 = 0), или из BE (если в поле Offset бит 12 = 1). Контроллер нормально отрабатывает переход буфера с одной страницы на другую даже в середине пакета. Назначение полей дескриптора изохронной передачи приведено ниже:

  • SF (StartingFrame) — младшие 16 бит номера кадра, в котором должен быть передан первый пакет;
  • DI (DelayInterrupt) — задержка прерывания по отработке передачи: 000–110 — задержка (число пропущенных кадров), 111 — не вызывать прерывание;
  • FC (FrameCount) — число пакетов данных, описанных в данном TD (0 — 1 пакет, 7 — 8 пакетов);
  • CC (ConditionCode) — код завершения на момент отправки TD в очередь выполненных заданий;
  • BP0 (BufferPage0) — физический номер страницы с первым байтом буфера данных;
  • NextTD — указатель на следующий дескриптор передачи для данной точки;
  • BE (Buffer End) — физический адрес последнего байта в буфере для данного TD;
  • Offset0… Offset7 — смещение, используемое для определения размера и стартового адреса данных каждого пакета;
  • PSW0…PSW7 — слово состояния каждого пакета: биты [15:12] — код завершения, биты [10:0] — длина принятого пакета данных (в транзакциях OUT — 0), бит 11=0.

Коды завершения для всех типов передач приведены в таблице ниже.

Код CC Условие
0000 NoError — нормальное завершение без ошибок
0001 CRC — последний принятый пакет содержит ошибку CRC
0010 BitStuffing — последний принятый пакет содержит ошибку вставки бит
0011 DataToggleMismatch — последний принятый пакет данных имеет PID, не отвечающий ожидаемому значению переключателя
0100 Stall — конечная точка остановлена (получен одноименный пакет подтверждения)
0101 DeviceNotResponding — устройство не отвечает
0110 PIDCheckFailure — ошибка контроля достоверности поля PID
0111 UnexpectedPID — прием неожиданного или недопустимого PID
1000 DataOverrun — пакет данных от устройства длиннее разрешенного в поле MPS дескриптора точки
1001 DataUnderrun — точка вернула пакет, меньший чем MPS, и недостаточный для заполнения указанного буфера
1010, 1011 Резерв
1100 BufferOverrun — во время приема данных контроллер не успел записать данные в системную память
1101 BufferUnderrun — во время вывода данных контроллер не успел считать данные из системной памяти
111x NotAccessed — не было обработки (драйвер записывает этот код в TD перед помещением его в очередь)

 

Таблица. Формат коммуникационной области HCCA контроллера OHC

Смещение Длина Назначение
0 128 HccaInterrruptTable — таблица дескрипторов точек прерываний, 32 двойных слова, указывающих на дескрипторы EP
80 2 HccaFrameNumber — текущий номер кадра, модифицируется контроллером перед обходом списка периодических передач
82h 2 HccaPad1 — это слово контроллер обнуляет, когда модифицирует значение номера кадра
84h 4 HccaDoneHead — указатель на очередь исполненных передач. Контроллер модифицирует указатель по мере исполнения передач и сигнализирует об этом установкой бита WDH в регистре HcInterruptStatus. Указатель не будет повторно модифицироваться, пока программа не сбросит бит WDH. Бит 0 указателя используется для сигнализации о наличии иных незамаскированных условий прерываний (если обработчик прерывания, считывая указатель, получает нулевое значение бита, он может не анализировать регистр HcInterruptStatus)
88h 116 Резерв для контроллера

Кроме дескрипторов драйвер OHCI взаимодействует с контроллером через коммуникационную область в системной памяти — HCCA. На начало этой области указывает регистр HCCA.

Для оперативного взаимодействия драйвера и хост-контроллера в OHC имеется блок операционных регистров, приписанный к пространству памяти (его положение определяется регистрами BAR в конфигурационном пространстве устройства PCI, каковым и является OHC). К этому блоку система должна обеспечивать доступ и в режиме SMM. Размер блока регистров определяется числом нисходящих портов (NDP) корневого хаба, входящего в OHC; при наличии регистров поддержки эмуляции традиционного контроллера клавиатуры и мыши размер достигает 272 байт. Все регистры, кроме специальных регистров эмуляции, требуют 32-разрядных обращений. Операционные регистры обеспечивают управление хост-контроллером в целом, планирование загрузки кадров, связь контроллера с памятью и управление корневым хабом.

Таблица. Операционные регистры OHC

Смещение Назначение
Регистры общего управления и состояния OHC
00h HcRevision — ревизия контроллера: биты [7:0] — номер версии в BCD-формате, бит 8 — признак поддержки эмуляции контроллера клавиатуры и мыши, остальные биты не используются
04h HcControl — управление операционными режимами контроллера. Назначение полей:
CBSR (ControlBulkServiceRatio) — соотношение числа обслуживаемых непустых ED для точек типов Control и Bulk: 0 — 1:1, 1 — 2:1, 2 — 3:1, 3 — 4:1, Определяет приоритет управляющих передач относительно передач массивов
PLE (PeriodicListEnable) — разрешение обслуживания списка периодических транзакций (в следующем кадре)
IE (IsochronousEnable) — разрешение обслуживания изохронных передач (в следующем кадре)
CLE (ControlListEnable) — разрешение обслуживания управляющих передач (в следующем кадре)
BLE (BulkListEnable) — разрешение обслуживания передач массивов (в следующем кадре)
HCFS (HostControllerFunctionalState) — состояние хост-контроллера в плане USB: 00 — Reset, 01 — Resume, 10 — нормальный режим, 11 — Suspend
IR (InterruptRouting) — маршрутизация прерываний (сигнализация событий, указанных в регистре HcInterruptStatus: 0 — нормальные прерывания, 1 — SMI
RWC (RemoteWakeupConnected) — признак подключенности контроллера к системе «пробуждения» хоста
RWE (RemoteWakeupEnable) — разрешение сигнализации «пробуждения» хоста по установке бита ResumeDetected в регистре HcInterruptStatus
08h HcCommandStatus — управление и состояние контроллера.Назначение полей:
HCR (HostControllerReset) — сброс контроллера (обнуляется контроллером по завершении сброса)
CLF (ControlListFilled) — признак наличия дескрипторов в очереди управляющих передач (если бит обнулен, контроллер и не начнет обход списка ED точек управления). Устанавливается драйвером по помещении дескриптора в очередь, дальше отслеживается и модифицируется контроллером.
BLF (BulkListFilled) — признак наличия дескрипторов в очереди передач массивов (аналогично CLF)
OCR (OwnershipChangeRequest) — запрос передачи права управления контроллером
SOC (SchedulingOverrunCount) — счетчик ошибок планирования (переполнений)
0Ch HcInterruptStatus — идентификация событий, вызывающих прерывание. Назначение полей:
SO (SchedulingOverrun) — признак переполнения при планирования кадра (транзакция не умещается до конца кадра)
WDH (WritebackDoneHead) — признак помещения дескриптора в очередь выполненных заданий
SF (StartofFrame) — признак начала кадра
RD (ResumeDetected) — признак получения сигнала Resume
UE (UnrecoverableError) — признак неисправимой ошибки, не связанной с USB (требуется сброс контроллера)
FNO (FrameNumberOverflow) — переполнение счетчика кадров (перенос из 15-го разряда)
RHSC (RootHubStatusChange) — признак смены состояния корневого хаба
OC (OwnershipChange) — признак передачи права управления контроллером (вызывает SMI)
10h HcInterruptEnable — разрешение прерываний по событиям. Назначение полей аналогично предыдущему, дополнительно имеется бит MIE (MasterInterruptEnable) — общее разрешение прерываний. При записи единичное значение каждого бита разрешает соответствующее условие, нулевое — игнорируется. Чтение возвращает текущее состояние (разрешенные условия)
14h HcInterruptDisable — запрет прерываний по событиям. Назначение полей аналогично предыдущему. При записи единичное значение каждого бита запрещает соответствующее условие, нулевое — игнорируется. Чтение возвращает текущее состояние (разрешенные условия)
Указатели областей памяти
18h HcHCCA — физический адрес HCCA (биты [7:0]=0)
1Ch HcPeriodCurrentED — текущий физический адрес дескриптора ED точки периодических передач (биты [3:0]=0), устанавливается контроллером, драйвер может только читать
20h HcControlHeadED — физический адрес первого дескриптора точки управления (биты [3:0]=0), устанавливается драйвером
24h HcControlCurrentED — физический адрес текущего дескриптора точки управления (биты [3:0]=0), устанавливается контроллером
28h HcBulkHeadED — физический адрес первого дескриптора точки передач массивов (биты [3:0]=0), устанавливается драйвером
2Ch HcBulkCurrentED — физический адрес текущего дескриптора точки передач массивов (биты [3:0]=0), устанавливается контроллером
30h HcDoneHead — физический адрес начала очереди завершенных передач (биты [3:0]=0), устанавливается контроллером
Регистры управления кадром
34h HcFmInterval — параметры кадра:
Биты [13:0] — FI (FrameInterval), длительность кадра (в bt), по умолчанию 2EDFh (11999)
Биты [30:16] — FSMPS (FSLargestDataPacket), значение максимального размера пакета данных, загружаемое в счетчик Data Packet Counter в начале каждого кадра (счетчик отражает длину пакета данных, допустимую в текущий момент времени без переполнения планирования)
Бит 31 — FIT (FrameIntervalToggle), переключением этого бита драйвер сигнализирует о смене длительности кадр
38h HcFmRemaining, остаток кадра:
Биты [13:0] — FR (FrameRemaining), текущее количество битовых интервалов до конца кадра. Автоматически декрементируется; по обнулению загружается значением из FI и генерируется SOF;
Бит 31 — FRT (FrameRemainingToggle), принимает значение FIT по обнулению FI
3Ch HcFmNumber — номер кадра FN (биты [15:0]), автоматически меняется на границе кадра
40h HcPeriodicStart — момент начала обхода списка периодических транзакций PS (биты [13:0]), обычно устанавливается на 10% меньше FI. Контроллер приступает к периодическим транзакциям, когда FR достигает значения PS
44h HcLSThreshold — порог LST (биты [11:0]), до которого контроллер может выполнять LS-транзакции с максимальным (8 байт) размером пакета. Эти транзакции могут начинаться только при FR≥LST, по умолчанию LST=628h (1576)
Регистры управления и состояния корневого хаба
48h HcRhDescriptorA — дескриптор-A корневого хаба. Назначение полей:
NDP (NumberDownstreamPorts) — число нисходящих портов (1–15)
PSM (PowerSwitchingMode) — режим управления питанием портов: 1 — селективное управление, 0 — общее
NPS (NoPowerSwitching) — признак отсутствия ключа подачи питания (1 — порты запитаны постоянно)
DT (DeviceType) — тип устройства: всегда 0, поскольку корневой хаб не может быть компаундным устройством
OCPM (OverCurrentProtectionMode) — режим сообщения о срабатывании токовой защиты питания портов: 0 — коллективное, 1 — индивидуальное. Действительно только при NOCP=0
NOCP (NoOverCurrentProtection) — признак невозможности сообщения о перегрузке
POTPGT (PowerOnToPowerGoodTime) — время ожидания перед обращением драйвера к контроллеру после подачи питания на порт (в 2-мс интервалах)
4Ch HcRhDescriptorB — дескриптор-B корневого хаба:
Биты [15:0] — DR (DeviceRemovable), признаки отсоединяемости устройств от портов (бит 1 — порт 1,…бит 15 — порт 15)
Биты [31:16] — PPCM (PortPowerControlMask), маски управления питанием портов: 0 — глобальное, 1 — селективное
50h HcRhStatus — регистр состояния корневого хаба. Назначение полей:
LPS (LocalPowerStatus) — чтение всегда дает 0, запись «1» выключает питание портов с глобальным управлением, запись «0» не имеет значения
OCI (OverCurrentIndicator) — индикатор перегрузки для глобальной защиты по току
DRWE (DeviceRemoteWakeupEnable) — запись «1» разрешает выход из состояния Suspend по смене состояния подключения портов, запись «0» не имеет значения
LPSC (LocalPowerStatusChange) — чтение всегда дает 0, запись «1» включает питание портов с глобальным управлением, запись «0» не имеет значения
OCIC (OverCurrentIndicatorChange) — запись «1» сбрасывает индикатор перегрузки для глобальной защиты, запись «0» не имеет значения
CRWE (ClearRemoteWakeupEnable) — запись «1» запрещает выход из состояния Suspend по смене состояния подключения портов, запись «0» не имеет значения
54h HcRhPortStatus[1], состояние первого порта корневого хаба.Назначение полей:
CCS: чтение (CurrentConnectStatus) — текущее состояние подключения к порту:
1 — подключено устройство, 0 — нет; запись «1» запрещает порт, запись «0» не имеет эффекта
PES (PortEnableStatus) — состояние разрешения порта: 0 — Disabled, 1 — Enabled; запись «1» разрешает порт, запись «0» не имеет эффекта
PSS (PortSuspendStatus) — состояние приостановки порта: 0 — не приостановлен, 1 — приостановлен или находится в процессе возобновления; запись «1» приостанавливает порт, запись «0» не имеет эффекта
POCI: чтение (PortOverCurrentIndicator) — перегрузка порта по питанию (только при селективной защите портов): 1 — защита сработала, 0 — нет; запись «1» инициирует возобновление порта (resume), запись «0» не имеет эффекта
PRS (PortResetStatus) — чтение состояния сброса порта: 1 — подается сигнал Reset, 0 — нет; запись «1» инициирует подачу сигнала Reset, запись «0» не имеет эффекта.
PPS (PortPowerStatus) — состояние питания порта: 0 — порт не запитан, 1 — порт запитан; запись «1» включает питание порта при селективном управлении, запись «0» не имеет эффекта
LSDA (LowSpeedDeviceAttached) — признак низкой скорости: 1 — обнаружено подключение LS-устройства, 0 — нет
CSC (ConnectStatusChange) — признак смены состояния подключения порта, сбрасывается записью «1»
PESC (PortEnableStatusChange) — признак смены состояния разрешения порта, сбрасывается записью «1»
PSSC (PortSuspendStatusChange) — признак завершения последовательности возобновления для порта, сбрасывается записью «1»
OCIC (PortOverCurrentIndicatorChange) — признак смены состояния индикатора селективной защиты порта, сбрасывается записью «1»
PRSC (PortResetStatusChange) — признак завершения формирования сигнала Reset, сбрасывается записью «1»
Состояние портов корневого хаба (аналогично предыдущему)
54h+4×NDP HcRhPortStatus[NDP], состояние последнего порта корневого хаба (аналогично предыдущему)
Регистры поддержки эмуляции контроллера клавиатуры и мыши (KBC)
100h HceControl — управление эмуляцией
104h HceInput — эмуляция входных буферов KBC: программный вывод байта по адресу порта 60h или 64h вызывает запись данных в биты [7:0] этого регистра, биты [31:8] — резерв
108h HceOutput — эмуляция выходного буфера KBC: программный ввод байта из порта 60h вернет данные из бит [7:0] этого регистра (и сбросит флаг BufferFull в HceStatus), биты [31:8] — резерв
10Ch HceStatus — эмуляция регистра состояния KBC

 

При разрешенной эмуляции контроллера клавиатуры и мыши контроллер OHC перехватывает (декодирует) обращения по адресам ввода/вывода 60h и 64h:

  • инструкция IN, обращенная к порту 60h, вернет байт из регистра HceOutput, а также установит в регистре HceStatus флаг OutputFull = 0;
  • инструкция OUT, обращенная к порту 60h, запишет байт в регистр HceInput, а также установит в регистре HceStatus флаги InputFull = 1 и CmdData = 0;
  • инструкция IN, обращенная к порту 64h, вернет байт текущего состояния из регистра HceStatus;
  • инструкция OUT, обращенная к порту 64h, запишет байт в регистр HceInput, а также установит в регистре HceStatus флаги InputFull = 0 и CmdData = 1.

ПО эмуляции отрабатывает эти обращения, пользуясь клавиатурой и мышью, подключенными к USB. Ряд обращений требует действий, которые эмулятор должен выполнить невидимо для ПО. Эти действия вызывают условие прерывания для эмулятора, которое может выполняться как системное прерывание SMI. При этом оказывается, что с хост-контроллером должны взаимодействовать как нормальный драйвер ОС, так и драйвер эмулятора, работающий в режиме системного управления (SMM). Чтобы корректно передавать право на управление контроллером между этими драйверами, в регистрах HcCommandStatus и HcInterruptStatus предусмотрены соответствующие биты.

 

Таблица. Назначение бит регистров управления и состояния эмуляции

Бит Назначение
Регистр HceControl
0 EmulationEnable, разрешение эмуляции
1 EmulationInterrupt, признак условия прерывания для эмуляции
2 CharacterPending, разрешение прерывания эмуляции по обнулению бита OutputFull в регистре HceStatus (требуется следующий байт от клавиатуры или мыши)
3 IRQEn, разрешение генерации IRQ1 или IRQ12 по установке бита OutputFull в регистре HceStatus
4 ExternalIRQEn, разрешение формирования сигнала прерывания эмуляции по сигналу IRQ1 и IRQ12 от KBC (независимо от состояния EmulationEnable)
5 GateA20Sequence, признак команды управления вентилем GateA20, устанавливается по записи байта D1h в порт 64h, сбрасывается по записи любого другого значения в этот порт
6 IRQ1Active, признак сигнала IRQ1 от KBC (сбрасывается записью «1»)
7 IRQ12Active, признак сигнала IRQ12 от KBC (сбрасывается записью «1»)
8 A20State, индикатор состояния сигнала GateA20 от KBC
9-31 Резерв (0)
Регистр HceStatus
0 OutputFull, выходной буфер контроллера полон. Сбрасывается при чтении порта 60h. При установке этого бита и при IRQEn = 1 вырабатывается IRQ1 (при AuxOutputFull = 0) или IRQ12 (при AuxOutputFull = 1)
1 InputFull, входной буфер полон. Устанавливается при записи в порт 60h или 64h (кроме команд управления вентилем GateA20)
2 Flag, системный флаг для определения «холодной» или «теплой» загрузки
3 CmdData, признак команды или данных для контроллера: запись в порт 60h сбрасывает бит, запись в порт 64h — устанавливает
4 Inhibit Switch, состояние ключа запрета клавиатуры (1 — клавиатура не запрещена)
5 AuxOutputFull, признак прихода данных от мыши
6 Time-out, признак тайм-аута при обмене с клавиатурой
7 Parity, признак ошибки четности при обмене с клавиатурой


«Расширенный» хост-контроллер — EHC

«Расширенный» хост-контроллер EHC (Enhanced Host Controller) был введен фирмой Intel для поддержки высокой скорости в USB 2.0. Его интерфейс — EHCI — описан в документе «Enhanced Host Controller Interface Specification for Universal Serial Bus», версия 1.0 опубликована в марте 2002 года. Контроллер EHC предназначен для работы с устройствами только на высокой скорости подключения к корневому хабу, при этом для устройств FS/LS, которые подключены через промежуточный хаб USB 2.0, контроллер EHC выполняет расщепленные транзакции. С теми портами корневого хаба, к которым непосредственно подключены хабы и устройства USB 1.x, работает контроллер-компаньон (UHC или OHC). Коммутацию портов и контроллеров осуществляет маршрутизирующая логика, входящая в состав корневого хаба USB 2.0. Обнаружением подключения устройств к корневому хабу занимается драйвер EHC через регистры EHC. Обнаружив подключение FS/LS-устройства, драйвер перекоммутирует данный порт на контроллер-компаньон, и с этого момента порт отдается в ведение компаньону и его драйверу. Компаньон и его драйвер могут и не «знать» о том, что они работают в составе контроллера USB 2.0. Для портов, остающихся в ведении EHC, эмулируется внешний хаб — ПО манипулирует портами, используя стандартные запросы к хабам USB.

Контроллер EHC имеет конфигурационные регистры PCI, операционные регистры ввода/вывода, отображенные на пространство памяти (memory mapped I/O) и использует область системной памяти для взаимодействия с драйвером. С точки зрения взаимодействия с драйвером EHC отчасти напоминает UHC, но высокая скорость передачи (480 Мбит/с) потребовала усиления интеллекта контроллера с целью уменьшения числа операций обмена между драйвером, памятью и контроллером. В EHC просматриваются многие идеи, заложенные в OHC. Структуры данных разработаны с учетом минимизации обращений к памяти. Все структуры должны размещаться в памяти так, чтобы они не пересекали границы четырехкилобайтных страниц памяти — это позволяет оптимизировать сосуществование OHC с виртуальной памятью, основанной на страничной переадресации, применяемой в процессорах x86.

В EHCI с точки зрения планирования транзакций передачи делятся на периодические (изохронные и прерывания) и асинхронные (управляющие передачи и массивы). Каждый из этих двух планов реализуется по-своему и может быть включен в работу и выключен. Контроллер начинает каждый микрокадр с выполнения периодических передач (если они разрешены), оставшееся от них время выделяется для выполнения асинхронных передач (аналогично UHC). За то, чтобы в микрокадре оставалось время для асинхронных передач, отвечает драйвер. Хост-контроллер аппаратно следит лишь за тем, чтобы транзакции не пересекали границу микрокадра: если контроллер «видит», что транзакция может не успеть завершиться к моменту EOF1, он ее не начнет. При этом возможна перестраховка, поскольку точное время исполнения транзакции заранее не известно (неизвестно, сколько придется вставить бит и каковы задержки в кабелях, хабах и устройстве).

Для всех передач с гарантированной доставкой (прерывания, управление и массивы) используются структуры данных qTD (Queue Element Transfer Descriptor), описывающие очереди буферов, обеспечивающие автоматическое упорядоченное исполнение потоков передач. В EHC под передачей понимается последовательность однотипных транзакций; ограничен лишь суммарный размер передаваемых блоков (20 Кбайт). Транзакции управления хост планирует как последовательность двух-трех «передач» (в терминах EHC). Драйвер может динамически (во время исполнения плана) добавлять новые передачи в очереди. Контроллер аппаратно поддерживает сигнализацию окончания блоков короткими пакетами: приняв короткий пакет, контроллер может пойти по альтернативной последовательности передач для данной очереди (то есть организуется условный переход). Для изохронных передач используются специальные структуры данных (iTD — Isochronous Transaction Descriptors для HS и siTD — Split-transaction IsochronousTransfer Descriptors для расщепления транзакций с FS-устройствами). Для изохронных передач на HS дескриптор может описывать передачу до 24 Кбайт данных, на FS — до 1023 байт.

Основой планирования периодических транзакций является список кадров (Frame List) на 1024, 512 или 256 вхождений. Базовый адрес и длина списка устанавливается программно, текущий элемент списка выбирается по счетчику кадров. Исполнение плана начинается в каждом микрокадре, таким образом, каждый текущий элемент списка выбирается 8 раз подряд, после чего контроллер переходит к следующему элементу. Элемент списка может указывать на iTD, siTD или заголовок очереди (QH), относящейся к прерываниям. Кроме того, он может указывать на специальные структуры (FSTN), используемые для обеспечения корректности отработки расщепленных транзакций около границы кадра. В элементе списка кроме собственно указателя имеется идентификатор типа структуры (Typ), на которую ссылается указатель (iTD, siTD, QH или FSTN), а также признак заглушкитерминатора (T). Все дескрипторы изохронных передач и заголовки очередей имеют «горизонтальный» указатель на следующую структуру, в котором также задается и тип (Typ) этой структуры, и признак заглушки-терминатора (T). Цепочка дескрипторов и заголовков очередей, начинающаяся от списка кадров, должна завершаться дескриптором (или заголовком), у которого установлен признак заглушки-терминатора (T). Только отработав такой дескриптор (или заголовок), контроллер приступает к исполнению плана асинхронных передач.

Для упрощения планирования расщепленных транзакций (они не должны пересекать границу кадра) контроллер организует фазовый сдвиг между кадрами шины (BFrame), которые видны хабам и устройствам по факту смены номера кадра в маркере SOF, и кадрами хоста (HFrame), которыми оперирует драйвер при построении планов и по которым выбираются периодические транзакции из списка кадров. Кадры шины отстают от кадров хоста на один микрокадр, более подробные пояснения (но не мотивы) приведены в спецификации EHCI. Для обслуживания расщепленных периодических транзакций имеется специальная структура (узел) FSTN, содержащая пару указателей: нормальный, обеспечивающий переход к следующей структуре (iTD, siTD, QH или FSTN), и обратный, который может указывать только на заголовок очереди. Нюансы планирования расщепленных транзакций здесь приводить не будем, с ними можно ознакомиться в спецификации EHCI.

Основой планирования непериодических транзакций является асинхронный список (asynchronous list), представляющий собой кольцо из заголовков очередей. В OHC регистр AsyncListAddr указывает на текущий элемент списка; к отработке этого элемента контроллер приступает, завершив отработку периодических передач в данном микрокадре (или сразу, если периодические передачи запрещены или отсутствуют). Далее, по мере отработки очередей, контроллер заносит в этот регистр адреса последующих указателей. Таким образом, обслуживание всех асинхронных очередей выполняется по кругу, без привязки к конкретным кадрам. Контроллер останавливает обход асинхронного списка, когда обнаруживает опустошение всех его очередей, для возобновления обхода требуется вмешательство драйвера. Нормальной дисциплиной обслуживания очередей является отработка одной шинной транзакции из очереди, после чего контроллер переходит к следующей очереди. Возможен и специальный режим парковки (Asynchronous Schedule Park Mode), в котором контроллеру разрешается выполнять подряд по несколько транзакций из одной очереди. Режим парковки распространяется на все очереди высокоскоростных асинхронных передач.

Дескриптор iTD описывает изохронную передачу, которая может выполняться за1–8 этапов (микрокадров, в которых происходит обращение к данному дескриптору). Каждому этапу в дескрипторе соответствует своя запись (transaction record), управляющая выполнением и отражающая состояние транзакции (активность, ошибки выполнения, необходимость прерывания по выполнению, реальная длина) и содержащая указатель на буфер данных. Каждый этап может выполняться за 1–3 транзакции в микрокадре (точка может быть широкополосной). Дескриптор содержит и описание конечной точки: адрес устройства и точки, направление, размер пакета. Контроллер формирует транзакции исходя из указанного размера пакета. Буферы для данных могут располагаться в разных физических страницах памяти, но логически они должны представлять собой непрерывную область в виртуальной памяти. Для хранения данных (максимум 8 этапов по три транзакции по 1024 байт — 24 576 байт) может потребоваться до 7 страниц по 4 кбайт; для всех этих страниц в дескрипторе имеются соответствующие указатели.

Дескриптор siTD описывает одну расщепленную транзакцию. Адресная часть содержит номер и направление конечной точки, адрес устройства, а также адрес и номер порта хаба, выполняющего трансляцию данной транзакции. В дескрипторе имеются поля битовых масок μFrame_S-mask и μFrame_C-mask, определяющих, в каких микрокадрах данного кадра должны выполняться транзакции SS и CS соответственно. Контроллер в дескрипторе отмечает микрокадры, в которых в действительности происходили транзакции CS. Дескриптор имеет обычный набор полей, управляющих выполнением и отражающих состояние транзакции (активность, ошибки выполнения, необходимость прерывания по выполнению, реальная длина). Кроме того, в siTD имеются специфические поля, управляющие текущей фазой (SS или CS), а также признак специфической ошибки расщепленной транзакции — пропуска микрокадра, в котором должна выполняться очередная транзакция CS. Этот пропуск может случиться, если контроллер не выпустит текущую транзакцию из-за нехватки времени в микрокадре. Блок передаваемых данных (до 1023 байт) может располагаться в одной или двух физических страницах памяти, и в дескрипторе для них имеются необходимые указатели. В siTD имеется специфический элемент — обратный указатель (Back Pointer) на siTD предыдущего кадра, который используется при планировании транзакций IN, завершающихся близко к границе кадра.

Элемент очереди-дескриптор передачи qTD, описывает одну передачу размером до 20 480 байт. Дескриптор привязан к своему заголовку очереди (QH); он содержит пару указателей на следующие элементы данной очереди:

  • основной, указывающий на дескриптор следующей передачи, которую требуется выполнить после нормального завершения текущей;
  • альтернативный, указывающий на дескриптор передачи, которую требуется выполнить в случае завершения текущей передачи по приему короткого пакета

Дескриптор имеет обычный набор полей, управляющих выполнением и отражающих состояние транзакции: активность, ошибки выполнения, необходимость прерывания по выполнению, используемый маркер (IN, OUT или SETUP). В дескрипторе указывается общая длина передачи. Буфер данных для передачи должен располагаться в непрерывной области виртуальной памяти; для описания буфера передачи максимальной длины имеется массив из пяти указателей физических страниц.

Заголовок очереди QH создается для каждой сконфигурированной неизохронной конечной точки каждого устройства USB. Заголовки очередей непериодических конечных точек связаны между собой по горизонтали в кольцо, для чего в каждом заголовке имеется соответствующий указатель. Заголовок очереди несет исчерпывающее описание конечной точки: номер и направление точки, максимальный размер пакета, число пакетов в микрокадре (для широкополосных точек), адрес устройства, его скорость. Для FS/LS устройств имеется и информация для выполнения расщепленных транзакций: номер хаба и порта, выполняющего расщепление транзакций, маски микрокадров для транзакций SS и CS. В заголовке очереди имеется оверлейная область, в которую контроллер помещает необходимые ему поля qTD текущей транзакции. Продвижение по очереди осуществляет контроллер, помещая в оверлей следующий qTD после завершения отработки предыдущего.

Контроллер EHC вырабатывает прерывания для разных категорий событий, и категории могут быть селективно замаскированы:

  • по завершении передачи, в дескрипторе которой имеется соответствующий признак, а также по приему короткого пакета. Эти прерывания могут быть задержаны по времени до определенного задаваемого программно порога, что позволяет снизить частоту запросов прерывания от EHC. Без задержки частота запросов может достигать частоты микрокадров (для IBM PC это слишком часто); с задержкой они не смогут появляться быстрее, чем определяет значение порога;
  • по событию хост-контроллера: оборот по списку кадров, изменению состояния или перегрузке портов хаба, специальному разрешению программного изменения последовательности заголовков очередей, по ошибке системного подключения (переполнение или переопустошение буфера FIFO из-за занятости шины PCI).

Постановка запросов передач в очереди, как и включение изохронных передач в план, а также добавление/удаление очередей может выполняться драйвером динамически, во время работы хост-контроллера. Однако для сохранения целостности и связанности структур программа должна соблюдать определенные правила взаимодействия, чтобы не пытаться изменять структуры, которые в данный момент отрабатываются контроллером. Для этой синхронизации хост-контроллер использует специальные биты-признаки в своем регистре состояния и в структурах данных. Для «сбора урожая» — поиска отработанных передач — драйверу приходится просматривать во всех дескрипторах передач признаки активности. Такого сервиса, как очередь исполненных передач (как в OHC), контроллер EHC не предоставляет. Но по сравнению с UHC, конечно же, объем работ драйвера EHC сокращается, поскольку этот контроллер оперирует передачами, а не транзакциями. Однако у драйвера EHC появляется дополнительная довольно сложная задача — планирование расщепленных транзакций.



Структуры данных и регистры EHC

Контроллер EHC имеет несколько наборов регистров:

  • конфигурационные регистры PCI — стандартный заголовок и специфические регистры. В заголовке для EHC указывается код класса 0Ch, подкласс 03h, интерфейс 20h;
  • регистры описания структуры контроллера, отображенные на память; на их положение указывает BAR в заголовке конфигурационного пространства;
  • операционные регистры EHC (32-битные), отображенные на память; они расположены вслед за предыдущим набором.

Таблица. Специфические регистры конфигурационного пространства EHC

Смещение (длина) Назначение
60h (8 бит) SBRN (Serial Bus Release Number) — версия шины USB (20h)
61h (8 бит) FLADJ (Frame Length Adjustment Register) — регистр подстройки длительности кадра, используются биты [5:0]. Длительность кадра в битовых интервалах HS определяется по формуле 59488+16× FLADJ, по умолчанию FLADJ=20h (60 000 bt)
62-63h (16 бит) PORTWAKECAP, регистр возможности генерации событий пробуждения для портов корневого хаба. Бит 0 — признак наличия данного регистра (0 — нет регистра), биты [15:1] — маски для портов с теми же номерами. На работу EHC регистр не влияет (это только информация для драйвера)
EECP+0h (32 бита) USBLEGSUP (USB Legacy Support), регистр возможностей поддержки эмуляции старых устройств, адрес определяется в поле EECP регистра HCCPARAMS, отображенного на память. Назначение бит: Биты 31:25 — резерв
Бит 24 — HC OS Owned Semaphore, семафор запроса управления контроллером. ОС устанавливает в «1» как запрос, право считается предоставленным, когда BIOS установит в «0» бит 16;
Биты [23:17] — резерв;
Бит 16 — HC BIOS Owned Semaphore, семафор права управления контроллером. BIOS устанавливает в «1» как признак владения контроллером;
Бит [15:8] — Next EHCI Extended Capability Pointer, указатель на следующий идентификатор расширенных возможностей; [7:0] Capability ID, идентификатор поддержки старых устройств (01h)
EECP+4h (32 бита)

USBLEGCTLSTS (USB Legacy Support Control and Status), регистр управления и состояния эмуляции. BIOS использует этот регистр для разрешения SMI по различным событиям и идентификации событий. Назначение бит: Бит 31 — SMI on BAR, прерывание SMI по смене базового адреса регистров EHC

Бит 30 — SMI on PCI Command, прерывание SMI по записи в регистр команд конфигурационного пространства устройства PCI
Бит 29 — SMI on OS Ownership Change, прерывание SMI по смене состояния права управления для ОС
Биты [28:22] — резерв
Бит 21 — SMI on Async Advance, прерывание SMI по установке бита Async_Advance в регистре USBSTS
Бит 20 — SMI on Host System Error, прерывание SMI по системной ошибке EHC
Бит 19 — SMI on Frame List Rollover, прерывание SMI по полному обороту списка кадров
Бит 18 — SMI on Port Change Detect, прерывание SMI по смене состояния порта
Бит 17 — SMI on USB Error, прерывание SMI по ошибке USB
Бит 16 — SMI on USB Complete, прерывание SMI по завершению передачи
Бит 15 — SMI on BAR Enable, разрешение прерывания SMI по смене базового адреса регистров EHC
Бит 14 — SMI on PCI Command Enable, разрешение прерывания SMI по записи в регистр команд конфигурационного пространства устройства PCI
Бит 13 — SMI on OS Ownership Change Enable, разрешение прерывания SMI по смене состояния права управления для ОС
Биты [12:6] — резерв
Бит 5 — SMI on Async Advance Enable, разрешение прерывания SMI по установке бита Async_Advance в регистре USBSTS
Бит 4 — SMI on Host System Error Enable, разрешение прерывания SMI по системной ошибке EHC
Бит 3 — SMI on Frame List Rollover Enable, разрешение прерывания SMI по полному обороту списка кадров
Бит 2 — SMI on Port Change Enable, разрешение прерывания SMI по смене состояния порта
Бит 1 — SMI on USB Error Enable, разрешение прерывания SMI по ошибке USB
Бит 0 — USB SMI Enable, разрешение прерывания SMI по завершению передачи

Таблица. Регистры описания структуры контроллера EHC

Смещение (длина) Назначение
00h (8 бит)  CAPLENGTH, длина набора регистров описания (определяет положение операционных регистров)
01h (8 бит)  Резерв
02h (16 бит)  HCIVERSION, номер версии интерфейса хост-контроллера (0100h)
04h (32 бита)

HCSPARAMS, параметры структуры:
Биты [31:24] — резерв
Биты [23:20] — Debug Port Number, номер порта, являющегося отладочным (0 — нет такого)
Биты 19:17 — резерв

Бит 16 — P_INDICATOR, признак поддержки управления индикаторами портов
Биты [15:12] — N_CC, число контроллеров-компаньонов (если 0, то к контроллеру можно подключать только HS-устройства)
Биты [11:8] — N_PCC, число портов у каждого контроллера-компаньона
Бит 7 — Port Routing Rules, правило сопоставления портов контроллерамкомпаньоном: 0 — порты распределяются группами по N_PCC по контроллерам с нарастающими номерами, 1 — распределение в соответствии с таблицей HCSP-PORTROUTE
Биты 6:5 — резерв
Бит 4 — PPC (Port Power Control), признак наличия управления питанием портов
Биты [3:0] — N_PORTS, число нисходящих портов (1–Fh)

08h (32 бита) HCCPARAMS, параметры свойств:
Биты [31:16] — резерв.
Биты [15:8] — EECP (EHCI Extended Capabilities Pointer), указатель на положение регистра USBLEGSUP в конфигурационном пространстве
Биты [7:4] — Isochronous Scheduling Threshold, порог планирования изохронных передач. Если бит 7=0, то биты [6:4] определяют минимальную дистанцию (число микрокадров) от текущей позиции, на которой драйвер может менять дескрипторы изохронных передач. Единичное значение бита 7 означает, что контроллер способен удержать в своем кэше дескрипторы для целого кадра
Бит 3 — резерв
Бит 2 — Asynchronous Schedule Park Capability, поддержка режима парковки для заголовков HS-очередей асинхронного плана
Бит 1 — Programmable Frame List Flag, признак поддержки программируемого размера списка кадров (0 — размер только 1024 элемента)
Бит 0 — 64-bit Addressing Capability, способность использования 64-битной адресации памяти
0Ch (64 бита)  HCSP-PORTROUTE, описание распределения портов по контроллерам-компаньонам, массив 4-байтных номеров контроллера-компаньона для каждого нисходящего порта корневого хаба. Вмещает описания для 15 портов (биты [3:0], формально относящиеся к нулевому порту, не используются)

 Таблица. Операционные регистры контроллера EHC

Смещение (длина) Назначение
00h

USBCMD, регистр команд USB
Биты [31:24] — резерв
Биты [23:16] — Interrupt Threshold Control, минимальный интервал (в микрокадрах) генерации прерываний (125 мкс–64 мс). Допустимы значения 2^N, по умолчанию 08h (1 мс)
Биты [15:12] — резерв
Бит 11 — Asynchronous Schedule Park Mode Enable, разрешение режима парковки для заголовков HS-очередей асинхронного плана (необязательно)
Бит 10 — резерв

Биты 9:8 — Asynchronous Schedule Park Mode Count, число успешных транзакций из HS-очереди, которые контроллер может выполнять до продолжения прохода по асинхронному плану
Бит 7 — Light Host Controller Reset, сброс хост-контроллера без затрагивания портов, относящихся к компаньонам (необязательно)
Бит 6 — Interrupt on Async Advance Doorbell, программный запрос контроллеру на выработку прерывания по очередному продвижению по асинхронному плану
Бит 5 — Asynchronous Schedule Enable, разрешение исполнения асинхронного плана
Бит 4 — Periodic Schedule Enable, разрешение исполнения периодического плана
Биты 3:2 — Frame List Size, размер списка кадров: 00 — 1024 элемента, 01 — 512, 10 — 256, 11 — резерв
Бит 1 — HCRESET (Host Controller Reset), программный сброс контроллера (аналогично аппаратному), бит обнуляется контроллером по завершении сброса
Бит 0 — RS (Run/Stop), пуск/останов исполнения транзакций. После обнуления контроллер должен через 16 микрокадров остановить все транзакции

04h USBSTS, регистр состояния USB
Биты [31:16] — резерв
Бит 15 — Asynchronous Schedule Status, реальное текущее состояние разрешения асинхронного плана (может отставать от команды смены)
Бит 14 — Periodic Schedule Status, реальное текущее состояние разрешения периодического плана (может отставать от команды смены)
Бит 13 — Reclamation, признак не пустого асинхронного плана. Обнуляется, когда контроллер встречает заголовок очереди с установленным флагом H, устанавливается в «1» при исполнении любой транзакции асинхронного плана. Если при обнуленном бите Reclamation контроллер встречает заголовок очереди с флагом H, он останавливает обход асинхронного плана
Бит 12 — HCHalted, состояния останова контроллера
Биты [11:6] — резерв
Бит 5 — Interrupt on Async Advance, признак прерывания по продвижению асинхронного плана
Бит 4 — Host System Error, признак системной ошибки контроллера (как устройства PCI)
Бит 3 — Frame List Rollover, признак оборота по списку кадров
Бит 2 — Port Change Detect, обнаружена смена состояния порта
Бит 1 — USBERRINT (USB Error Interrupt), признак завершения транзакции по ошибке USB
Бит 0 —USBINT (USB Interrupt), признак завершения транзакции, для которой предписана генерация прерывания
08h

USBINTR, регистр разрешения прерываний USB:
Биты [31:6] — резерв
Бит 5 — Interrupt on Async Advance Enable, разрешение прерывания по продвижению асинхронного плана
Бит 4 — Host System Error Enable, разрешение прерывания по системной ошибке контроллера
Бит 3 — Frame List Rollover Enable, разрешение прерывания по обороту списка кадров

Бит 2 — Port Change Interrupt Enable, разрешение прерывания по смене состояния порта
Бит 1 — USB Error Interrupt Enable, разрешение прерывания по ошибке USB
Бит 0 — USB Interrupt Enable, разрешение прерывания по выполнению транзакций

0Ch FRINDEX, индекс кадра. Инкрементируется с каждым микрокадром, биты [N:3] используются как текущий индекс в списке кадров
10h CTRLDSSEGMENT, старшие биты 64-битного адреса (адрес 4G-сегмента, содержащего все структуры данных и регистры EHC)
14h PERIODICLISTBASE, базовый адрес списка кадров (биты [11:0] нулевые — список должен быть выровнен по границе станицы 4 Кб)
18h ASYNCLISTADDR, очередной адрес асинхронного списка, указывает на следующий заголовок очереди в асинхронном плане (биты [4:0] — резерв)
1C-3Fh Резерв
40h CONFIGFLAG, флаг конфигурирования: бит 0 устанавливается в 1, когда ПО завершает конфигурирование EHC (по этому флагу включается управление маршрутизацией портов от EHC, при нулевом значении порты безусловно подключены к своим контроллерам-компаньонам). Биты [31:1] не используются
44h…
…40h+4×n

PORTSC(n), управление и состояние n-го порта корневого хаба:

Биты [31:23] — резерв
Бит 22 — WKOC_E (Wake on Over-current Enable) — разрешение реакции на перегрузку по току как на пробуждающее событие
Бит 21 — WKDSCNNT_E (Wake on Disconnect Enable) — разрешение пробуждения по отключению
Бит 20 —WKCNNT_E (Wake on Connect Enable) — разрешение пробуждения по подключению устройства
Биты [19:16] — Port Test Control, управление режимом тестирования: 0000 — рабочий режим, 0001 — Test J_STATE, 0010 — Test K_STATE, 0011 — Test SE0_NAK, 0100 — Test Packet, 0101 — Test FORCE_ENABLE
Биты 15:14 — Port Indicator Control, управление индикатором порта: 00 — отключен, 01 — янтарный, 10 — зеленый, 11 — неопределено
Бит 13 — Port Owner, признак владельца порта: 1 — порт подключен к контроллеру-компаньону (определено подключение устройства не HS или EHC не сконфигурирован)
Бит 12 — PP (Port Power), питание порта (если PPC=1): 0 — выключено, 1 — включено
Биты [11:10] — Line Status, текущее состояние логических уровней на линиях D+ (бит 11) и D- (бит 10)
Бит 9 — резерв
Бит 8 — Port Reset, сбос порта, устанавливается программно, сбрасывается контроллером
Бит 7 — Suspend, приостановка порта
Бит 6 — Force Port Resume, возобновление порта
Бит 5 — Over-current Change, признак срабатывания токовой защиты (сбрасывается записью «1»)
Бит 4 — Over-current Active, состояние защиты (1 — питание отключено по перегрузке)
Бит 3 — Port Enable/Disable Change, признак отключения порта по ошибке, зафиксированной хабом (сбрасывается записью «1»)
Бит 2 — Port Enabled/Disabled, разрешение-запрет порта (программно можно только запретить, разрешается по сбросу)
Бит 1 — Connect Status Change, признак смены состояния подключения
Бит 0 — Current Connect Status, текущее состояние подключения

Формат элемента списка кадров (Frame List Element Pointer) приведен на рисунке ниже.Здесь Frame List Link Pointer — указатель на дескриптор изохронной передачи или заголовок очереди (для прерываний); если бит T = 1 (Terminate), то указатель не используется. Поле Typ описывает тип структуры, на которую ссылается указатель: 00 — iTD, 01 — QH, 10 — siTD, 11 — FSTN.

Дескриптор изохронной передачи iTD (Isochronous Transfer Descriptor) относится к точкам HS-устройств, его формат приведен на рисунке ниже. Первое двойное слово по формату совпадает с элементом списка кадров. Далее следует 8-элементный список дескрипторов транзакций, выполняемых в каждом из восьми микрокадров (серым цветом выделены поля, модифицируемые хост-контроллером). В следующих семи двойных словах содержатся адреса физических страниц, в которых может располагаться буфер для транзакций, и описание конечной точки. В этом описании:

  • поле Status отражает состояние выполнения транзакции:
  • бит 31 — Active, активность, устанавливается драйвером как признак необходимости исполнения, сбрасывается контроллером по исполнении транзакции;
  • бит 30 — Data Buffer Error, ошибка буфера данных (несвоевременность доставки данных в/из памяти);
  • бит 29 — Babble Detected, «болтливость», обнаруженная при исполнении транзакции;
  • бит 28 — Transaction Error (XactErr), ошибка USB при выполнении транзакции (только для транзакций IN).
  • поле Transaction X Length задает число переданных байтов (0–3072). Для транзакций IN драйвер устанавливает ожидаемое число, контроллер его меняет на реальное число принятых байтов;
  • бит IOC (Interrupt On Complete) заказывает прерывание по исполнению;
  • поле PG (Page Select) задает номер страницы буфера (0–6), из которого берутся старшие (31:12) биты адреса для формирования стартового адреса буфера данной транзакции;
  • поле Transaction X Offset задает смещение начала буфера X-транзакции относительно выбранной страницы;
  • поля Buffer Pointer (Page n) задают физические адреса страниц 0–7;
  • поле EndPt задает номер конечной точки;
  • поле I/O задает направление: 0 — OUT, 1 — IN;
  • поле Device Address задает адрес устройства;
  • поле Maximum Packet Size — максимальный размер пакета для точки (1–1024), в транзакции IN используется как порог для определения «болтливости» устройства;
  • поле Mult задает число транзакций за один микрокадр (00 — резерв).

Дескриптор расщепленной изохронной транзакции siTD (Split-transaction Isochronous Transfer Descriptor) относится к точкам FS-устройств, его формат приведен на следующем рисунке. Первое двойное слово по формату совпадает с элементом списка кадров. Поля I/O, EndPt, Device Address описывают координаты и направление конечной точки.

Поля Hub Addr и Port Number задают адрес расщепляющего транзакцию хаба и номер порта.

Битовые поля μFrame S-mask и μFrame C-mask задают маски для микрокадров, в которых планируются транзакции SS и CS (транзакция в микрокадре выполняется при единичном значении маски). В поле μFrame C-prog-mask контроллер отмечает кадры, в которых произошли транзакции завершения.

Адрес буфера для начала транзакции задается полями Buffer Pointer (Page 0) и Current offset, при переходе на другую физическую станицу в качестве ее адреса используется поле Buffer Pointer (Page 1). Бит P определяет номер используемой страницы. Ожидаемый размер пакета задается в поле Total Bytes to Transfer, контроллер этот размер заменит реальным. Бит IOC (Interrupt On Complete) заказывает прерывание по исполнении.

Поле TP (Transaction Position) — позиция текущей HS-транзакции: 00 — All, HSтранзакция содержит все данные FS-транзакции (не более 188 байт), 01 — Begin, первый пакет для FS-транзакции, 10 —Mid, промежуточный, 11 — End, последний HS-пакет для FS-транзакции.

Поле T-Count (Transaction Count), число HS-транзакций, необходимых для выполнения FS-транзакции (1–6).

Состояние выполнения транзакции определяется полем Status:

  • бит 7 — Active, активность, устанавливается драйвером как признак необходимости исполнения, сбрасывается контроллером по исполнении или по ошибке;
  • бит 6 — ERR, признак получения одноименного ответа от транслятора транзакций;
  • бит 5 — Data Buffer Error, ошибка буфера данных (несвоевременность доставки данных в/из памяти);
  • бит 4 — Babble Detected, «болтливость», обнаруженная при исполнении транзакции;
  • бит 3 — Transaction Error (XactErr), ошибка USB при выполнении транзакции (только для транзакций IN);
  • бит 2 — Missed Micro-Frame, пропуск микрокадра (по вине контроллера), в котором должно было быть завершение;
  • бит 1 — SplitXstate (Split Transaction State), состояние (фаза) расщепленной транзакции: 0 — SS, 1 — CS;
  • бит 0 — резерв.

Поле si-TD Back Pointer является обратным указателем на декриптор si-TD (если в том же двойном слове бит T = 1, указатель не используется).

Дескриптор передачи — элемент очереди qTD (Queue Element Transfer Descriptor) имеет формат, приведенный на следующем рисунке. Поле Next qTD Pointer указывает на следующий qTD (если T = 0), к которому следует перейти после нормальной отработки передачи. Поле Alternate Next qTD Pointer позволяет указать на qTD, к которому следует перейти в случае приема короткого пакета. Ожидаемая длина передачи задается полем Total Bytes to Transfer, по окончании в этом поле окажется реальная длина. Адрес буфера для начала транзакции задается полями Buffer Pointer (Page 0) и Current offset, по мере продвижения контроллер меняет значение поля C_Page, определяющего номер физической страницы. Бит IOC задает прерывание по выполнению. Поле PID задает тип маркера в транзакциях: 00 — OUT, 01 — IN, 10 — SETUP, 11 — резерв. Бит DT — текущее значение Data Toggle для данной передачи, В поле CErr драйвер заносит допустимое число повторов (из-за ошибок) в каждой транзакции данной передачи (0 — число повторов неограниченно). Поле Status отражает состояние текущей транзакции передачи:

  • бит 7 — Active, активность, устанавливается драйвером как признак необходимости исполнения, сбрасывается контроллером по исполнении или по достижении лимита повторов;
  • бит 6 — Halted — признак получения ответа STALLl;
  • бит 5 — Data Buffer Error, ошибка буфера данных (несвоевременность доставки данных в/из памяти);
  • бит 4 — Babble Detected, «болтливость», обнаруженная при исполнении транзакции;
  • бит 3 — Transaction Error (XactErr), ошибка USB при выполнении транзакции (только для транзакций IN);
  • бит 2 — Missed Micro-Frame, пропуск микрокадра (по вине контроллера), в котором должно было быть завершение (только для FS- и LS-точек);
  • бит 1 — SplitXstate (Split Transaction State), состояние (фаза) расщепленной транзакции (только для FS- и LS-точек): 0 — SS, 1 — CS;
  • бит 0 — P/ERR, для HS-точек при PID Code = 00 (OUT) — состояние протокола Ping (Ping State): 0 — выполнять транзакцию OUT, 1 — PING. Для не-HS точек — ERR, признак получения подтверждения ERR на расщепленную периодическую транзакцию.

Заголовок очереди QH имеет формат, приведенный на рисунке ниже. Здесь Queue Head Horizontal Link Pointer указывает на следующую структуру по горизонтали, которая может быть заголовком очереди или любым дескриптором изохронной передачи. В последующих двух двойных словах описывается конечная точка, а для точек LS/FS еще и дополнительные параметры, требуемые для расщепления транзакций. Поля Device Address, EndPt и Maximum Packet Length задают адрес устройства, номер точки и максимальный размер пакета. Поле EPS задает скорость: 00 — LS, 01 — FS, 10 — HS, 11 — резерв. Бит H (Head of Reclamation List Flag) — флаг, которым драйвер помечает один из заголовков очередей из асинхронного плана для определения опустошения всех очередей этого плана (этот флаг вызывает обнуление бита Reclamation в регистре состояния контроллера). Бит DTC управляет переключателем Toggle Bit: 0 — использовать бит DT из данного заголовка очереди QH, 1 — из qTD. Флаг C — признак управляющей точки HS-устройства. Флаг I (Inactivate on Next Transaction) — программный запрос контроллеру обнулить бит активности при следующей транзакции. Используется только в заголовке очереди периодических транзакций FS/LS-устройств для обеспечения возможности программной коррекции значений полей S-mask и C-mask в данном заголовке. Поле RL (Nak Count Reload) задает значение счетчика ответов NAK, загружаемое в поле Nak Cnt. Поле Mult задает число транзакций в микрокадре для широкополосных точек (0 — резерв). Поля Port Number, Hub Addr, μFrame S-mask и μFrame C-mask требуются для точек FS/LS-устройств, по назначению они совпадает с одноименными полями siTD.

Поле Current qTD Pointer содержит адрес текущего обрабатываемого qTD, последующие 8 двойных слов являются оверлейной областью передачи (Transfer Overlay), в которую контроллер загружает требуемые параметры для обрабатываемого элемента. Большинство полей по назначению (и положению) совпадает с одноименными полями qTD, здесь перечислим только особые. Поле NakCnt (Nak Counter) — счетчик ответов NAK или NYET. В поле C-prog-mask контроллер отмечает микрокадры, в которых происходили транзакции завершения расщепленных транзакций. В поле FrameTag контроллер записывает тег кадра, в котором производится расщепленная транзакция прерывания. В поле S-bytes контроллер указывает число байтов, переданных в расщепленных транзакциях IN и OUT.

Формат узла FSTN (Periodic Frame Span Traversal Node) приведен на последнем рисунке. Здесь Normal Path Link Pointer может указывать на любую структуру данных, а обратный указатель Back Path Link Pointer может указывать только на заголовок очереди.



USB без ПК — расширение On-The-Go

Протокол шины USB ориентирован на сугубо подчиненные отношения: всеми транзакциями со всеми подключенными устройствами управляет хост — как правило, это компьютер (ПК) с контроллером USB. Никакого равноправия в отношениях на шине USB быть не может, однако в ряде случаев хотелось бы обойтись и без компьютера. Так, например, напрашивается непосредственное соединение цифровой фотокамеры и фотопринтера, обеспечивающее печать снимков без участия ПК. Практически все периферийные устройства USB имеют встроенные микроконтроллеры, и функциональные возможности этих микроконтроллеров неуклонно растут. Периферийное устройство, имеющее хотя бы простейшие средства диалога с пользователем (дисплей, отображающий пару строк текста, и несколько кнопок управления), вполне может взять на себя управляющие функции в плане организации транзакций USB. Функции такого мини-хоста можно упростить, если ориентироваться на двухточечное соединение пары устройств без промежуточных хабов. В этом случае мини-хосту остается лишь идентифицировать одно подключенное устройство, и, если ему известно, как это устройство можно использовать, сконфигурировать его. Задача планирования транзакций лишь с одним устройством гораздо проще общей задачи «большого» хоста и хост-контроллера. Именно на создание таких упрощенных связей пары устройств нацелено расширение OTG (On-The-Go).

Документ On-The-Go Supplement to USB 2.0 Specification (версия 1.0 вышла в июне 2003 года) определяет дополнения к USB 2.0, необходимые для организации упрощенных соединений пары устройств. Большая часть документа посвящена описанию разъемов, и терминология OTG тоже привязана к типам разъемов (собственно, пользователь видит разъемы на устройствах и просто пытается соединить их доступными кабелями). В OTG принято следующее деление устройств:

  • устройство-A (A-Device) — устройство, в гнездо которого вставлена вилка типа A (или mini-A). Это устройство подает питание (Vbus) на шину и играет роль хоста, по крайней мере, в первое время после подключения к другому устройству. По ходу сеанса связи устройство-A может передать функции хоста своему партнеру, а само стать периферийным (в терминах USB);
  • устройство-B (B-Device) — устройство, в гнездо которого вставлена вилка типа B (или mini-B). Это устройство при подключении к другому устройству играет роль периферийного (ведомого) устройства USB. Если это устройство является двухролевым, то по ходу сеанса связи ему могут быть переданы функции хоста;
  • двухролевое устройство (Dual-role device) — устройство с единственным гнездом типа mini-AB, обеспечивающее питание шины с током не менее 8 мА, поддерживающее FS (дополнительно может поддерживать и HS, а в роли периферийного устройства — и LS). Это устройство имеет усеченные возможности хоста, список поддерживаемых периферийных устройств, средства диалога с пользователем. Для управления связью устройство должно поддерживать протоколы запроса сессий (SRP) и согласования роли хоста (HNP).

Двухролевое устройство может поддерживать и хабы (это усложняет его задачи); однако стандартные хабы USB не позволяют работать протоколам SRP и HNP.

В основной спецификации USB фигурируют три типа разъемов (гнезд и вилок): стандартные 4-контактные A и B, а также 5-контактный mini-B. Здесь допустимы кабели с вилкой A на одном конце и вилкой (mini)B на другом, а также неотсоединяемые от устройства кабели с вилкой A. В OTG введены 5-контактные вилки mini-A и универсальное 5-контактное гнездо mini-AB. Внутри вилки mini-A контакты 4 и 5 электрически соединены, в вилке mini-B контакт 4 свободен. Для облегчения различения разъемов принята цветовая маркировка: разъемы mini-A должны быть белого цвета, mini-B — черного, а гнезда mini-AB — серого.

В гнездо mini-AB двухролевого устройства может вставляться как вилка mini-A, так и вилка mini-B. При этом контакт 4 (ID) используется для идентификации типа подключенного устройства:

  • если контакт 4 (ID) соединен с линией GND (сопротивление <10 Ом), то вставлена вилка mini-A — значит, подключено устройство-B; следовательно, двухролевое устройство должно стать хостом;
  • если контакт 4 (ID) не соединен с линией GND (сопротивление >10 Ом), то вставлена вилка mini-B — значит, подключено устройство-A; следовательно, двухролевое устройство должно стать периферийным.

Протокол запроса сеанса, SRP (Session Request Protocol), предназначен для дополнительного энергосбережения: когда устройство-A не нуждается в обмене по шине, оно может снять питание Vbus. При этом устройство-B все-таки может «попросить внимания» — запросить сеанс связи. Здесь сеансом называется интервал времени, в течение которого двухролевое устройство подает достаточное (для работы) напряжение питания. Запрос может выполняться подачей положительных импульсов либо по линии Vbus, либо по сигнальным линиям (D+ или D-). Устройство-B должно использовать оба метода подачи запроса, устройство-A может распознавать любой из них (как удобнее его разработчику).

Протокол согласования роли хоста, HNP (Host Negotiation Protocol), позволяет устройству-A и устройству-B поменяться ролями во время сеанса связи (если они оба двухролевые). Протокол может быть инициирован, только если устройство-A пошлет устройству-B специальный разрешающий запрос, предварительно убедившись, что устройство-B протокол HNP поддерживает. Возможность поддержки протоколов HNP и SRP сообщается устройством-B в специальном дескрипторе OTG-устройства.

Устройство-B может запросить управление шиной (стать хостом на время), когда устройство-A прекращает активность (переводит шину в состояние покоя). Для этого устройство-B отключается от шины (отключает свой «подтягивающий» резистор от линии D+). Устройство-A расценивает это как запрос смены роли и подключает свой «подтягивающий» резистор к линии D+. Теперь устройство-B может начинать транзакции, управляя шиной. Когда оно захочет отдать управление шиной, оно прекращает активность и подключает свой «подтягивающий» резистор к линии D+. Устройство-A это расценивает как возврат управления и отключает свой «подтягивающий» резистор от линии D+ — исходные роли, определенные по типу разъема, восстановлены.

Дескриптор OTG (длина 3, тип 9) должен присутствовать во всех конфигурациях OTG-устройства, он считывается обычным запросом Get_Descriptor. Дескриптор OTG содержит лишь один байт атрибутов, в котором бит 0 указывает на поддержку SRP, бит 1 — на поддержку HNP (остальные биты — нулевые).

Убедившись в поддержке протокола HNP, устройство-A, еще до выбора конфигурации устройства-B, должно сообщить ему свое отношение к HNP. Для этого служат запросы к устройству Set_Feature (bmRequestType = 00000000b, bRequest = 3):

  • запросом Set b_hnp_enable (wValue = 3) устройство-A разрешает устройствуB запрашивать роль хоста;
  • запросом Set a_hnp_support (wValue = 4) устройство-A только информирует устройство-B о том, что оно подключено к порту, поддерживающему HNP, и запрос роли хоста может быть разрешен позже;
  • запросом Set a_alt_hnp_support (wValue = 5) устройство-A информирует устройство-B о том, что оно (устройство-B) подключено к порту, не поддерживающему HNP, но у устройства-A имеется другой порт, на котором HNP поддерживается.