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

Предыдущая  Содержание  Следующая V*D*V

Иногда драйвер 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 в Главе 13.

 

Подобно функции 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.

Предыдущая  Содержание  Следующая