Глава 12. Интерфейс Proc

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

ALSA предоставляет простой интерфейс для файловой системы procfs. Файлы proc очень полезны для отладки. Я рекомендую вам создавать proc файлы, если вы пишете драйвер и хотите получать статус работы или распечатку регистров. API находится в <sound/info.h>.

 

Чтобы создать proc файл, вызовите snd_card_proc_new().

 

struct snd_info_entry *entry;

int err = snd_card_proc_new(card, "my-file", &entry);

 

где второй аргумент указывает имя proc файла, который должен быть создан. В приведённом выше примере будет создан файл my-file внутри каталога карты, например, /proc/asound/card0/my-file.

 

Как и другие компоненты, запись в proc, созданная через snd_card_proc_new(), будет автоматически регистрироваться и освобождаться в функциях регистрации и освобождения карты.

 

При успешном создании функция сохраняет новый экземпляр в указателе, указанном в третьем аргументе. Он инициализируется как текстовый proc файл доступный только для чтения. Чтобы использовать данный proc файл как только читаемый текстовый файл, укажите обратный вызов read с закрытыми данными через snd_info_set_text_ops().

 

snd_info_set_text_ops(entry, chip, my_proc_read);

 

где второй аргумент (chip) является закрытыми данными, которые будут использоваться в обратных вызовах. Третий параметр указывает размер буфера чтения, а четвёртый (my_proc_read) является функцией обратного вызова, которая определяется как

 

static void my_proc_read(struct snd_info_entry *entry,

                         struct snd_info_buffer *buffer);

 

Для вывода строк в обратном вызове read используйте snd_iprintf(), которая работает так же, как обычная printf().

Например,

 

static void my_proc_read(struct snd_info_entry *entry,

                         struct snd_info_buffer *buffer)

{

    struct my_chip *chip = entry->private_data;

 

    snd_iprintf(buffer, "This is my chip!\n");

    snd_iprintf(buffer, "Port = %ld\n", chip->port);

}

 

Права доступа к файлам в последствии могут быть изменены. По умолчанию они установлены для всех пользователей как доступные только для чтения. Если вы хотите добавить для пользователя разрешение на запись (по умолчанию root-у), сделайте следующее:

 

entry->mode = S_IFREG | S_IRUGO | S_IWUSR;

 

и установите размер буфера записи и обратный вызов

 

entry->c.text.write = my_proc_write;

 

Для получения строки текста в обратном вызове write можно использовать snd_info_get_line(), а для получения из неё кусочка строки - snd_info_get_str(). Некоторые примеры можно найти в core/oss/mixer_oss.c и core/oss/pcm_oss.c.

 

Для proc файла для необработанных данных укажите атрибуты следующим образом:

 

static struct snd_info_entry_ops my_file_io_ops = {

    .read = my_file_io_read,

};

 

entry->content = SNDRV_INFO_CONTENT_DATA;

entry->private_data = chip;

entry->c.ops = &my_file_io_ops;

entry->size = 4096;

entry->mode = S_IFREG | S_IRUGO;

 

Обратный вызов является гораздо более сложным, чем версия для текстового файла. Для передачи данных необходимо использовать низкоуровневые функции ввода/вывода, такие как copy_from/to_user().

 

static long my_file_io_read(struct snd_info_entry *entry,

                            void *file_private_data,

                            struct file *file,

                            char *buf,

                            unsigned long count,

                            unsigned long pos)

{

    long size = count;

    if (pos + size > local_max_size)

        size = local_max_size - pos;

    if (copy_to_user(buf, local_data + pos, size))

        return -EFAULT;

    return size;

}

 

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