USB core | это... Что такое USB core? (original) (raw)

USB Core — это подсистема ядра Linux, созданная для поддержки USB-устройств и контроллеров шины USB. Цель ее создания — абстрагирование от аппаратной реализации стандарта USB (либо аппаратно-зависимых функций) путем определения набора структур данных, макросов и функций.

Содержание

История развития

Поддержка USB в ядро Linux была добавлена вскоре после появления ветки ядра 2.2 и незадолго до начала работ в линейке 2.3. Разработки из линейки 2.3 регулярно переносились в линейку 2.2, добавляя тем самым новые возможности, как например, поддержку «горячего подключения», новые драйверы, оптимизацию работы. Линейка ядра 2.5 унаследовала все эти улучшения, причем к ним добавилась поддержка работы с USB 2.0 и, как следствие, более высокая производительность, более устойчивая работа между устройствами, упрощение прикладного интерфейса (делать ошибки в коде стало труднее, а также ведение внутренней документации.

Поскольку возможность запуска Linux со временем появилась и на многих медиаустройствах, то в ходе своей эволюции поддержка USB в Linux разделилась на две части. С одной стороны, Linux может запускаться с подключаемых к устройству USB-устройств (например, флэш-накопители), с другой стороны, на основном компьютере, к которому подключают USB-устройства, также может работать Linux. Используемые при этом драйверы USB сильно различаются, поэтому чтобы их различать для драйверов устройств было введено соответствующее название англ. gadget drivers[1].

Принцип работы

Внутри ядра драйверы основной ОС обращаются к прикладным интерфейсам USB Core. Существует два типа публичных прикладных интерфейса USB Core, нацеленных на два различных уровня драйвера USB: драйверы общего назначения, доступные через фреймворки драйвера, как например блок, символ или сетевое устройство, и драйверы являющиеся частью ядра, участвующие в управлении шиной USB. Такие драйверы ядра включают в себя драйвер хаба, управляющего деревом USB-устройств, а также несколько различных типов драйверов хост-контроллера (англ. host controller driver, сокр. HCD), который контролирует отдельные шины.

Метод определения оптимального способа работы драйверов с USB-устройством довольно сложный:

Единственными драйверов хостовой ОС, которые реально обращаются к устройству (регистры чтения/записи, обработка сигналов прерываний и т. д.), это драйверы хост-контроллера. В теории все драйверы хост-контроллера поддерживают схожий функционал за счет использования единого прикладного интерфейса. На практике же это начало поддерживаться лишь в версии ядра 2.5, но при этом есть различия в обработке ошибок[2].

Список стандартных прикладных интерфейсов

Ниже перечислены стандартные прикладные интерфейсы программирования (API), входящие в состав USB Core[3].

Название Функции
usb_init_urb Инициализирует URB для их последующего использования драйвером USB
usb_alloc_urb Создает новый URB для его последующего использования драйвером USB
usb_free_urb Освобождает память, занимаемую URB, по окончании работы всех пользователей с ним
usb_get_urb Увеличивает счетчик ссылок на URB
usb_submit_urb Посылает запрос асинхронной передачи к конечному устройству
usb_unlink_urb Прерывает/отменяет запрос передачи к конечному устройству
usb_kill_urb Отменяет запрос передачи и ожидает его завершения
usb_control_msg Создает сообщение управления URB, отсылает его и ожидает выполнения
usb_bulk_msg Создает общее сообщение URB, отсылает его и ожидает выполнения
usb_sg_init Инициализирует запрос ввода-вывода общего типа или прерывания на базе распределенного списка
usb_sg_wait Синхронно выполняет запрос разделения/объединения
usb_sg_cancel Останавливает разделение/объединение ввода/вывода, начатого по команде usb_sg_wait
usb_get_descriptor Отправляет обобщенный запрос получения дескриптора (GET_DESCRIPTOR)
usb_string Возвращает строковый дескриптор в формате ISO 8859-1
usb_get_status Отправляет вызов GET_STATUS
usb_clear_halt Сообщает устройству о сбросе состояния ожидания для конечного устройства
usb_set_interface Делает активными альтернативный набор настроек
usb_reset_configuration Программная перезагрузка устройства
usb_register_dev Регистрирует USB-устройство и запрашивает младший номер
usb_deregister_dev Разрегистрирует динамический младший номер USB-устройства
usb_match_id Находит первый совпавший usb_device_id для устройства или интерфейса
usb_register_driver Регистрирует USB-драйвер
usb_deregister Разрегистрирует USB-драйвер
usb_ifnum_to_if Получает объект интерфейса для данного номера интерфейса
usb_altnum_to_altsetting Получает структуру альтернативных настроек для данного номера интерфейса
usb_driver_claim_interface Привязывает драйвер к интерфейсу
usb_driver_release_interface Отвязывает драйвер от интерфейса
usb_find_interface Находит указатель usb_interface для драйвера и устройства
usb_get_dev Увеличивает счетчик ссылок структуры USB-устройства
usb_put_dev Освобождает используемую структуру USB-устройства
usb_get_intf Увеличивает счетчик ссылок структуры интерфейса USB
usb_put_intf Освобождает используемую структуру интерфейса USB
usb_lock_device_for_reset Корректно накладывает блокировку на устройство для последующей перезагрузки
usb_find_device Находит требуемое USB-устройство в системе
usb_get_current_frame_number Возвращает номер текущего кадра шины
usb_buffer_alloc Выделяет DMA-совместимый буфер для размещения URB_NO_xxx_DMA_MAP
usb_buffer_free Освобождает память, выделенную при помощи usb_buffer_alloc
usb_buffer_map Создает DMA-привязки к URB
usb_buffer_dmasync Синхронизирует просмотр буферов DMA и центрального процессора
usb_buffer_unmap Разрушает DMA-привязки к URB
usb_buffer_map_sg Создает распределенные DMA-привязки к конечным точкам
usb_buffer_dmasync_sg Синхронизирует просмотр распределенных буферов DMA и центрального процессора
usb_buffer_unmap_sg Разрушает распределенные DMA-привязки
usb_hub_tt_clear_buffer Сбрасывает режим control/bulk в высокоскоростном хабе
usb_root_hub_lost_power Вызывается HCD в случае потери корневым хабом питания по Vbus-шине
usb_reset_device Выполняет перезагрузку порта USB для переинициализации устройства

Модели USB API

Существуют две основные модели ввод-вывода в USB API. Наиболее простейшая модель является асинхронной: драйверы отправляют запрос в виде URB, а затем обратный вызов URB на следующем шаге завершает операцию. Все типы передачи USB поддерживают данную модель, однако существуют специальные модели для управляющих URB (которые всегда имеют собственные настройки и статусы, но не всегда обладают возможностью продвижения данных (англ. data stage) и изохронных URB (которые допускают передачу больших пакетов и включают в себя генерацию отчетов по каждому некорректному пакету). Такие модели строятся на основе поддержки синхронного API, в котором драйвер вызывает подпрограмму, которая размещает в памяти один или более URB, отправляет их и ждет их завершения. Также существуют синхронные обертки для однобуферных управляющих и массовых передач (которые неудобны для применения в некоторых сценариях драйверного отключения), а также для потоковой передачи на основе распределенных списков (потоком или с прерываниями).

Драйверам USB требуется наличие буферов, которые могут быть использованы для прямого доступа к памяти (DMA), хотя им не обязательно самостоятельно выполнять привязку DMA. Существуют API, применяемые при выделении DMA-буферов, поскольку они смогут предотвратить использование некорректных буферов на некоторых системах. В некоторых случаях драйверы могут использовать 64-битный режим DMA для устранения прочих видов буферных ограничений[3].

Примечания

  1. Introduction to USB on Linux (англ.)
  2. USB Host-Side API Model (англ.)
  3. 1 2 USB Core APIs (англ.)

Ссылки