/* * register the card proc file * called from init.c * can be called multiple times for reinitialization
*/ int snd_info_card_register(struct snd_card *card)
{ struct proc_dir_entry *p; int err;
if (snd_BUG_ON(!card)) return -ENXIO;
err = snd_info_register(card->proc_root); if (err < 0) return err;
if (!strcmp(card->id, card->proc_root->name)) return 0;
if (card->proc_root_link) return 0;
p = proc_symlink(card->id, snd_proc_root->p, card->proc_root->name); if (!p) return -ENOMEM;
card->proc_root_link = p; return 0;
}
/* * called on card->id change
*/ void snd_info_card_id_change(struct snd_card *card)
{
guard(mutex)(&info_mutex); if (card->proc_root_link) {
proc_remove(card->proc_root_link);
card->proc_root_link = NULL;
} if (strcmp(card->id, card->proc_root->name))
card->proc_root_link = proc_symlink(card->id,
snd_proc_root->p,
card->proc_root->name);
}
/* * de-register the card proc file * called from init.c
*/ void snd_info_card_disconnect(struct snd_card *card)
{ if (!card) return;
proc_remove(card->proc_root_link); if (card->proc_root)
proc_remove(card->proc_root->p);
/* * release the card proc file resources * called from init.c
*/ int snd_info_card_free(struct snd_card *card)
{ if (!card) return 0;
snd_info_free_entry(card->proc_root);
card->proc_root = NULL; return 0;
}
/** * snd_info_get_line - read one line from the procfs buffer * @buffer: the procfs buffer * @line: the buffer to store * @len: the max. buffer size * * Reads one line from the buffer and stores the string. * * Return: Zero if successful, or 1 if error or EOF.
*/ int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len)
{ int c;
if (snd_BUG_ON(!buffer)) return 1; if (!buffer->buffer) return 1; if (len <= 0 || buffer->stop || buffer->error) return 1; while (!buffer->stop) {
c = buffer->buffer[buffer->curr++]; if (buffer->curr >= buffer->size)
buffer->stop = 1; if (c == '\n') break; if (len > 1) {
len--;
*line++ = c;
}
}
*line = '\0'; return 0;
}
EXPORT_SYMBOL(snd_info_get_line);
/** * snd_info_get_str - parse a string token * @dest: the buffer to store the string token * @src: the original string * @len: the max. length of token - 1 * * Parses the original string and copy a token to the given * string buffer. * * Return: The updated pointer of the original string so that * it can be used for the next call.
*/ constchar *snd_info_get_str(char *dest, constchar *src, int len)
{ int c;
while (*src == ' ' || *src == '\t')
src++; if (*src == '"' || *src == '\'') {
c = *src++; while (--len > 0 && *src && *src != c) {
*dest++ = *src++;
} if (*src == c)
src++;
} else { while (--len > 0 && *src && *src != ' ' && *src != '\t') {
*dest++ = *src++;
}
}
*dest = 0; while (*src == ' ' || *src == '\t')
src++; return src;
}
EXPORT_SYMBOL(snd_info_get_str);
/* * snd_info_create_entry - create an info entry * @name: the proc file name * @parent: the parent directory * * Creates an info entry with the given file name and initializes as * the default state. * * Usually called from other functions such as * snd_info_create_card_entry(). * * Return: The pointer of the new instance, or %NULL on failure.
*/ staticstruct snd_info_entry *
snd_info_create_entry(constchar *name, struct snd_info_entry *parent, struct module *module)
{ struct snd_info_entry *entry;
entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (entry == NULL) return NULL;
entry->name = kstrdup(name, GFP_KERNEL); if (entry->name == NULL) {
kfree(entry); return NULL;
}
entry->mode = S_IFREG | 0444;
entry->content = SNDRV_INFO_CONTENT_TEXT;
mutex_init(&entry->access);
INIT_LIST_HEAD(&entry->children);
INIT_LIST_HEAD(&entry->list);
entry->parent = parent;
entry->module = module; if (parent) {
guard(mutex)(&parent->access);
list_add_tail(&entry->list, &parent->children);
} return entry;
}
/** * snd_info_create_module_entry - create an info entry for the given module * @module: the module pointer * @name: the file name * @parent: the parent directory * * Creates a new info entry and assigns it to the given module. * * Return: The pointer of the new instance, or %NULL on failure.
*/ struct snd_info_entry *snd_info_create_module_entry(struct module * module, constchar *name, struct snd_info_entry *parent)
{ if (!parent)
parent = snd_proc_root; return snd_info_create_entry(name, parent, module);
}
EXPORT_SYMBOL(snd_info_create_module_entry);
/** * snd_info_create_card_entry - create an info entry for the given card * @card: the card instance * @name: the file name * @parent: the parent directory * * Creates a new info entry and assigns it to the given card. * * Return: The pointer of the new instance, or %NULL on failure.
*/ struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card, constchar *name, struct snd_info_entry * parent)
{ if (!parent)
parent = card->proc_root; return snd_info_create_entry(name, parent, card->module);
}
EXPORT_SYMBOL(snd_info_create_card_entry);
/** * snd_info_free_entry - release the info entry * @entry: the info entry * * Releases the info entry.
*/ void snd_info_free_entry(struct snd_info_entry * entry)
{ struct snd_info_entry *p, *n;
if (!entry) return; if (entry->p) {
proc_remove(entry->p);
guard(mutex)(&info_mutex);
snd_info_clear_entries(entry);
}
/* free all children at first */
list_for_each_entry_safe(p, n, &entry->children, list)
snd_info_free_entry(p);
p = entry->parent; if (p) {
guard(mutex)(&p->access);
list_del(&entry->list);
}
kfree(entry->name); if (entry->private_free)
entry->private_free(entry);
kfree(entry);
}
EXPORT_SYMBOL(snd_info_free_entry);
if (snd_BUG_ON(!entry)) return -ENXIO;
root = entry->parent == NULL ? snd_proc_root->p : entry->parent->p;
guard(mutex)(&info_mutex); if (entry->p || !root) return 0; if (S_ISDIR(entry->mode)) {
p = proc_mkdir_mode(entry->name, entry->mode, root); if (!p) return -ENOMEM;
} else { conststruct proc_ops *ops; if (entry->content == SNDRV_INFO_CONTENT_DATA)
ops = &snd_info_entry_operations; else
ops = &snd_info_text_entry_ops;
p = proc_create_data(entry->name, entry->mode, root,
ops, entry); if (!p) return -ENOMEM;
proc_set_size(p, entry->size);
}
entry->p = p; return 0;
}
/** * snd_info_register - register the info entry * @entry: the info entry * * Registers the proc info entry. * The all children entries are registered recursively. * * Return: Zero if successful, or a negative error code on failure.
*/ int snd_info_register(struct snd_info_entry *entry)
{ struct snd_info_entry *p; int err;
if (!entry->p) {
err = __snd_info_register(entry); if (err < 0) return err;
}
/** * snd_card_rw_proc_new - Create a read/write text proc file entry for the card * @card: the card instance * @name: the file name * @private_data: the arbitrary private data * @read: the read callback * @write: the write callback, NULL for read-only * * This proc file entry will be registered via snd_card_register() call, and * it will be removed automatically at the card removal, too. * * Return: zero if successful, or a negative error code
*/ int snd_card_rw_proc_new(struct snd_card *card, constchar *name, void *private_data, void (*read)(struct snd_info_entry *, struct snd_info_buffer *), void (*write)(struct snd_info_entry *entry, struct snd_info_buffer *buffer))
{ struct snd_info_entry *entry;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.