воскресенье, 15 мая 2011 г.

13.5. USB передачи без Urb-ов


13.5. USB передачи без Urb-ов
Иногда драйвер USB не хочет проходить через все хлопоты по созданию struct urb, её инициализации и затем дожидаться работы функции завершения urb-а, а просто отправить или получить некоторые простые USB данные. Предоставить простой интерфейс готовы две функции.
usb_bulk_msg
usb_bulk_msg создаёт потоковый urb для USB и отправляет его в указанное устройство, затем ждёт его завершения, прежде чем вернуться к вызывающему. Она определяется как:

int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
                 void *data, int len, int *actual_length,
                 int timeout);

Параметры этой функции:

struct usb_device *usb_dev
Указатель на USB устройство для передачи потокового сообщения.

unsigned int pipe
Задаёт оконечную точку USB устройства, которой должно быть отправлено это потоковое сообщение. Это значение создаётся с помощью вызова либо usb_sndbulkpipe, либо usb_rcvbulkpipe.

void *data
Указатель на данные для отправки в устройство, если это ВЫХОДНАЯ оконечная точка. Если это ВХОДНАЯ оконечная точка, он указывает, где эти данные должны быть размещены после чтения из устройства.

int len
Размер буфера, на который указывает параметр data.

int *actual_length
Указывает туда, где функция размещает фактическое количество байт, которые были либо переданы в устройство или получены от устройства, в зависимости от направления оконечной точки.

int timeout
Количество времени, в тиках, которое необходимо подождать до выхода. Если это значение равно 0, функция ждёт завершения сообщения бесконечно.

Если функция завершилась успешно, возвращается значение 0; в противном случае возвращается отрицательный номер ошибки. Этот номер ошибки соответствует номерам ошибок ранее описанных для urb-ов в разделе "struct urb". При успешном выполнении параметр actual_length содержит число байт, которое было передано или получено из этого сообщения.

Ниже приведен пример использования вызова этой функции:

/* делаем блокирующее поточное чтение для получения данных из устройства */
retval = usb_bulk_msg(dev->udev,
usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
                dev->bulk_in_buffer,
                min(dev->bulk_in_size, count),
                &count, HZ*10);

/* если чтение было успешным, копируем данные в пользовательское пространство */
if (!retval) {
    if (copy_to_user(buffer, dev->bulk_in_buffer, count))
        retval = -EFAULT;
    else
        retval = count;
}

Этот пример показывает простое потоковое чтение во ВХОДНОЙ оконечной точке. Если чтение прошло успешно, данные копируются в пространство пользователя. Обычно это делается для USB драйвера в функции read.

Функция usb_bulk_msg не может быть вызвана из контекста прерывания или при удержании спин-блокировки. Кроме того, эта функция не может быть отменена любой другой функцией, так что будьте внимательны при её использовании; убедитесь, что функция disconnect вашего драйвера знает достаточно, чтобы дождаться завершения вызова, прежде чем позволить себе быть выгруженной из памяти.
usb_control_msg
Функция usb_control_msg работает подобно функции usb_bulk_msg, за исключением того, что позволяет драйверу отправлять и получать управляющие сообщения USB:

int usb_control_msg(struct usb_device *dev, unsigned int pipe,
                    __u8 request, __u8 requesttype,
                    __u16 value, __u16 index,
                    void *data, __u16 size, int timeout);

Параметры этой функции являются почти такими же, как у usb_bulk_msg, с несколькими существенными различиями:

struct usb_device *dev
Указатель на USB устройство для передачи ему управляющего сообщения.

unsigned int pipe
Определяет оконечную точку USB устройства, которой это управляющее сообщение будет отправлено. Это значение создаётся с помощью вызова либо usb_sndctrlpipe, либо usb_rcvctrlpipe.

__u8 request
Значение USB запроса для управляющего сообщения.

__u8 requesttype
Значение типа запроса USB для управляющего сообщения.

__u16 value
Значение USB сообщения для управляющего сообщения.

__u16 index
Значение индекса сообщения USB для управляющего сообщения.

void *data
Указатель на данные для отправки в устройство, если это ВЫХОДНАЯ оконечная точка. Если это ВХОДНАЯ оконечная точка, он указывает, где должны быть размещены данные после чтения с устройства.

__u16 size
Размер буфера, на который указывает параметр data.

int timeout
Количество времени, в тиках, которое необходимо подождать до выхода. Если это значение равно 0, функция ждёт завершения сообщения бесконечно.

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

Все параметры, request, requesttype, value и index, напрямую привязаны со спецификацией USB в том, каким образом определяются управляющие сообщения USB. Для получения дополнительной информации о допустимых значениях этих параметров и как они используются, смотрите спецификации USB в Главе 9.

Подобно функции usb_bulk_msg, функция usb_control_msg не может быть вызвана из контекста прерывания или при удержании спин-блокировки. Также, эта функция не может быть отменена любой другой функцией, поэтому будьте осторожны при её использовании; убедитесь, что функция disconnect вашего драйвера знает достаточно, чтобы дождаться завершения вызова, прежде чем позволить себе быть выгруженной из памяти.
Другие функции для работы с данными USB
Для получения стандартной информации из всех USB устройств может быть использован ряд вспомогательных функции в ядре USB. Эти функции не могут быть названы в контексте прерывания или при удержании спин-блокировки.

Функция usb_get_descriptor возвращает указанный дескриптор USB из указанного устройства. Функция определяется как:


int usb_get_descriptor(struct usb_device *dev, unsigned char type,
                       unsigned char index, void *buf, int size);

Эта функция может быть использована USB драйвером для извлечения из структуры struct usb_device любого из дескрипторов устройства, которых уже нет в существующих структурах struct usb_device и struct usb_interface, таких как аудио дескрипторы или другой  зависящей от класса информации. Параметры функции:

struct usb_device *usb_dev
Указатель на USB устройство, из которого должно быть извлечён дескриптор.

unsigned char type
Тип дескриптора. Этот тип описан в спецификации USB и может быть одним из следующих типов:
USB_DT_DEVICE
USB_DT_CONFIG
USB_DT_STRING
USB_DT_INTERFACE
USB_DT_ENDPOINT
USB_DT_DEVICE_QUALIFIER
USB_DT_OTHER_SPEED_CONFIG
USB_DT_INTERFACE_POWER
USB_DT_OTG
USB_DT_DEBUG
USB_DT_INTERFACE_ASSOCIATION
USB_DT_CS_DEVICE
USB_DT_CS_CONFIG
USB_DT_CS_STRING
USB_DT_CS_INTERFACE
USB_DT_CS_ENDPOINT

unsigned char index
Количество дескрипторов, которые должны быть извлечены из устройства.

void *buf
Указатель на буфер, в который вы копируете дескриптор.

int size
Размер памяти, на которую указывает переменная buf.

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

Одним из наиболее часто используемых вызовов usb_get_descriptor является извлечение строки из устройства USB. Так как это происходит довольно часто, для этого есть вспомогательная функция, называемая usb_get_string:

int usb_get_string(struct usb_device *dev, unsigned short langid,
                   unsigned char index, void *buf, int size);

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

Если эта функция завершилась успешно, она возвращает строку в кодировке формата UTF-16LE (Unicode, 16 бит на символ, с порядком байтов little-endian, сначала младший) в буфере, на который указывает параметр buf. Поскольку этот формат обычно не очень удобен, есть ещё одна функция, называемая usb_string, которая возвращает строку, которая считывается из USB устройства и уже преобразована в формат строки ISO 8859-1. Этот набор символов является 8-ми разрядным подмножеством Unicode и самый распространённый формат для строк в английском и других западноевропейских языках. Так как это обычно тот формат, в котором USB устройства имеют строки, рекомендуется, чтобы вместо функции usb_get_string использовалась функция usb_string.

Комментариев нет:

Отправить комментарий

Примечание. Отправлять комментарии могут только участники этого блога.