Подробности Реабилитация наркомана в Воронеже у нас на сайте. inhomes.ru.
Все структуры данных OHC, расположенные в системной памяти, выровнены по границе параграфа (четыре младших бита адреса — нулевые). Для работы с OHC в памяти размещают дескрипторы конечных точек (ED) выбранных интерфейсов сконфигурированных устройств, дескрипторы передач (TD) для них и коммуникационную область HCCA. Дескрипторы передач подключаются драйвером к очередям требуемых конечных точек. Дескрипторы исполненных передач (завершенных нормально или снятых аварийно) контроллером подключаются к очереди Done Queue. Буфер данных для каждого дескриптора передачи может размещаться в одной или двух физических страницах, физические адреса этих страниц определяются по физическому адресу начала (начальное значение CBP) и физическому адресу конца буфера. Дескрипторы передач делятся на два типа: общий (для передач Bulk, Control, Interrupt) и изохронный.
Дескриптор конечной точки (ED) имеет размер 4 двойных слова (16 байт), его формат приведен на рисунке ниже, назначение полей приведено ниже:
Формат общего дескриптора передач приведен на рисунке 2 (см. выше). Дескриптор позволяет описывать передачу данных указанной длины в пределах 8 кбайт. Количество транзакций для передачи контроллер определяет сам из поля длины пакета в дескрипторе точки (ED) и длины буфера; количество транзакций при приеме определяется длиной пакетов, переданных устройством. Назначение полей общего дескриптора передач приведено ниже:
Формат дескриптора изохронной передачи приведен на рисунке ниже. Дескриптор позволяет описывать передачу данных длиной до 8 кбайт, состоящую из 1–8 транзакций (их количество задано в дескрипторе). Транзакции исполняются в последовательных кадрах, начиная с кадра с указанным номером. Длина пакета в каждой из этих транзакций вычисляется из значений полей OffsetN смежных транзакций (возможны и транзакции с нулевой длиной поля данных). Физический адрес буфера для каждой из этих транзакций определяется следующим образом: младшие 12 бит берутся из младших 12 бит соответствующего поля Offset, старшие биты (номер физической страницы) берутся либо из поля BPO (если в поле Offset бит 12 = 0), или из BE (если в поле Offset бит 12 = 1). Контроллер нормально отрабатывает переход буфера с одной страницы на другую даже в середине пакета. Назначение полей дескриптора изохронной передачи приведено ниже:
Коды завершения для всех типов передач приведены в таблице ниже.
Код 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 перед помещением его в очередь) |
Смещение | Длина | Назначение |
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 | |
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:
ПО эмуляции отрабатывает эти обращения, пользуясь клавиатурой и мышью, подключенными к 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 (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 вырабатывает прерывания для разных категорий событий, и категории могут быть селективно замаскированы:
Постановка запросов передач в очереди, как и включение изохронных передач в план, а также добавление/удаление очередей может выполняться драйвером динамически, во время работы хост-контроллера. Однако для сохранения целостности и связанности структур программа должна соблюдать определенные правила взаимодействия, чтобы не пытаться изменять структуры, которые в данный момент отрабатываются контроллером. Для этой синхронизации хост-контроллер использует специальные биты-признаки в своем регистре состояния и в структурах данных. Для «сбора урожая» — поиска отработанных передач — драйверу приходится просматривать во всех дескрипторах передач признаки активности. Такого сервиса, как очередь исполненных передач (как в OHC), контроллер EHC не предоставляет. Но по сравнению с UHC, конечно же, объем работ драйвера EHC сокращается, поскольку этот контроллер оперирует передачами, а не транзакциями. Однако у драйвера EHC появляется дополнительная довольно сложная задача — планирование расщепленных транзакций.
Контроллер 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 |
Смещение (длина) | Назначение |
00h (8 бит) | CAPLENGTH, длина набора регистров описания (определяет положение операционных регистров) |
01h (8 бит) | Резерв |
02h (16 бит) | HCIVERSION, номер версии интерфейса хост-контроллера (0100h) |
04h (32 бита) |
HCSPARAMS, параметры структуры: Бит 16 — P_INDICATOR, признак поддержки управления индикаторами портов |
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], формально относящиеся к нулевому порту, не используются) |
Смещение (длина) | Назначение |
00h |
USBCMD, регистр команд USB Биты 9:8 — Asynchronous Schedule Park Mode Count, число успешных транзакций из HS-очереди, которые контроллер может выполнять до продолжения прохода по асинхронному плану |
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: Бит 2 — Port Change 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] — резерв |
Формат элемента списка кадров (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-элементный список дескрипторов транзакций, выполняемых в каждом из восьми микрокадров (серым цветом выделены поля, модифицируемые хост-контроллером). В следующих семи двойных словах содержатся адреса физических страниц, в которых может располагаться буфер для транзакций, и описание конечной точки. В этом описании:
Дескриптор расщепленной изохронной транзакции 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:
Поле 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 отражает состояние текущей транзакции передачи:
Заголовок очереди 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 ориентирован на сугубо подчиненные отношения: всеми транзакциями со всеми подключенными устройствами управляет хост — как правило, это компьютер (ПК) с контроллером 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 принято следующее деление устройств:
Двухролевое устройство может поддерживать и хабы (это усложняет его задачи); однако стандартные хабы 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) используется для идентификации типа подключенного устройства:
Протокол запроса сеанса, 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):