⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 info.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	return -ENXIO;}static const struct file_operations snd_info_entry_operations ={	.owner =		THIS_MODULE,	.llseek =		snd_info_entry_llseek,	.read =			snd_info_entry_read,	.write =		snd_info_entry_write,	.poll =			snd_info_entry_poll,	.unlocked_ioctl =	snd_info_entry_ioctl,	.mmap =			snd_info_entry_mmap,	.open =			snd_info_entry_open,	.release =		snd_info_entry_release,};/** * snd_create_proc_entry - create a procfs entry * @name: the name of the proc file * @mode: the file permission bits, S_Ixxx * @parent: the parent proc-directory entry * * Creates a new proc file entry with the given name and permission * on the given directory. * * Returns the pointer of new instance or NULL on failure. */static struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode,						    struct proc_dir_entry *parent){	struct proc_dir_entry *p;	p = create_proc_entry(name, mode, parent);	if (p)		snd_info_entry_prepare(p);	return p;}int __init snd_info_init(void){	struct proc_dir_entry *p;	p = snd_create_proc_entry("asound", S_IFDIR | S_IRUGO | S_IXUGO, &proc_root);	if (p == NULL)		return -ENOMEM;	snd_proc_root = p;#ifdef CONFIG_SND_OSSEMUL	{		struct snd_info_entry *entry;		if ((entry = snd_info_create_module_entry(THIS_MODULE, "oss", NULL)) == NULL)			return -ENOMEM;		entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;		if (snd_info_register(entry) < 0) {			snd_info_free_entry(entry);			return -ENOMEM;		}		snd_oss_root = entry;	}#endif#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)	{		struct snd_info_entry *entry;		if ((entry = snd_info_create_module_entry(THIS_MODULE, "seq", NULL)) == NULL)			return -ENOMEM;		entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;		if (snd_info_register(entry) < 0) {			snd_info_free_entry(entry);			return -ENOMEM;		}		snd_seq_root = entry;	}#endif	snd_info_version_init();	snd_minor_info_init();	snd_minor_info_oss_init();	snd_card_info_init();	return 0;}int __exit snd_info_done(void){	snd_card_info_done();	snd_minor_info_oss_done();	snd_minor_info_done();	snd_info_version_done();	if (snd_proc_root) {#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)		snd_info_free_entry(snd_seq_root);#endif#ifdef CONFIG_SND_OSSEMUL		snd_info_free_entry(snd_oss_root);#endif		snd_remove_proc_entry(&proc_root, snd_proc_root);	}	return 0;}/* *//* * create a card proc file * called from init.c */int snd_info_card_create(struct snd_card *card){	char str[8];	struct snd_info_entry *entry;	snd_assert(card != NULL, return -ENXIO);	sprintf(str, "card%i", card->number);	if ((entry = snd_info_create_module_entry(card->module, str, NULL)) == NULL)		return -ENOMEM;	entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;	if (snd_info_register(entry) < 0) {		snd_info_free_entry(entry);		return -ENOMEM;	}	card->proc_root = entry;	return 0;}/* * register the card proc file * called from init.c */int snd_info_card_register(struct snd_card *card){	struct proc_dir_entry *p;	snd_assert(card != NULL, return -ENXIO);	if (!strcmp(card->id, card->proc_root->name))		return 0;	p = proc_symlink(card->id, snd_proc_root, card->proc_root->name);	if (p == NULL)		return -ENOMEM;	card->proc_root_link = p;	return 0;}/* * de-register the card proc file * called from init.c */void snd_info_card_disconnect(struct snd_card *card){	snd_assert(card != NULL, return);	mutex_lock(&info_mutex);	if (card->proc_root_link) {		snd_remove_proc_entry(snd_proc_root, card->proc_root_link);		card->proc_root_link = NULL;	}	if (card->proc_root)		snd_info_disconnect(card->proc_root);	mutex_unlock(&info_mutex);}/* * release the card proc file resources * called from init.c */int snd_info_card_free(struct snd_card *card){	snd_assert(card != NULL, return -ENXIO);	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 - 1 * * Reads one line from the buffer and stores the string. * * Returns 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 = -1;	if (len <= 0 || buffer->stop || buffer->error)		return 1;	while (--len > 0) {		c = buffer->buffer[buffer->curr++];		if (c == '\n') {			if (buffer->curr >= buffer->size)				buffer->stop = 1;			break;		}		*line++ = c;		if (buffer->curr >= buffer->size) {			buffer->stop = 1;			break;		}	}	while (c != '\n' && !buffer->stop) {		c = buffer->buffer[buffer->curr++];		if (buffer->curr >= buffer->size)			buffer->stop = 1;	}	*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. * * Returns the updated pointer of the original string so that * it can be used for the next call. */char *snd_info_get_str(char *dest, char *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 * * 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(). * * Returns the pointer of the new instance, or NULL on failure. */static struct snd_info_entry *snd_info_create_entry(const char *name){	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 | S_IRUGO;	entry->content = SNDRV_INFO_CONTENT_TEXT;	mutex_init(&entry->access);	INIT_LIST_HEAD(&entry->children);	INIT_LIST_HEAD(&entry->list);	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. * * Returns the pointer of the new instance, or NULL on failure. */struct snd_info_entry *snd_info_create_module_entry(struct module * module,					       const char *name,					       struct snd_info_entry *parent){	struct snd_info_entry *entry = snd_info_create_entry(name);	if (entry) {		entry->module = module;		entry->parent = parent;	}	return entry;}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. * * Returns the pointer of the new instance, or NULL on failure. */struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card,					     const char *name,					     struct snd_info_entry * parent){	struct snd_info_entry *entry = snd_info_create_entry(name);	if (entry) {		entry->module = card->module;		entry->card = card;		entry->parent = parent;	}	return entry;}EXPORT_SYMBOL(snd_info_create_card_entry);static void snd_info_disconnect(struct snd_info_entry *entry){	struct list_head *p, *n;	struct proc_dir_entry *root;	list_for_each_safe(p, n, &entry->children) {		snd_info_disconnect(list_entry(p, struct snd_info_entry, list));	}	if (! entry->p)		return;	list_del_init(&entry->list);	root = entry->parent == NULL ? snd_proc_root : entry->parent->p;	snd_assert(root, return);	snd_remove_proc_entry(root, entry->p);	entry->p = NULL;}static int snd_info_dev_free_entry(struct snd_device *device){	struct snd_info_entry *entry = device->device_data;	snd_info_free_entry(entry);	return 0;}static int snd_info_dev_register_entry(struct snd_device *device){	struct snd_info_entry *entry = device->device_data;	return snd_info_register(entry);}/** * snd_card_proc_new - create an info entry for the given card * @card: the card instance * @name: the file name * @entryp: the pointer to store the new info entry * * Creates a new info entry and assigns it to the given card. * Unlike snd_info_create_card_entry(), this function registers the * info entry as an ALSA device component, so that it can be * unregistered/released without explicit call. * Also, you don't have to register this entry via snd_info_register(), * since this will be registered by snd_card_register() automatically. * * The parent is assumed as card->proc_root. * * For releasing this entry, use snd_device_free() instead of * snd_info_free_entry().  * * Returns zero if successful, or a negative error code on failure. */int snd_card_proc_new(struct snd_card *card, const char *name,		      struct snd_info_entry **entryp){	static struct snd_device_ops ops = {		.dev_free = snd_info_dev_free_entry,		.dev_register =	snd_info_dev_register_entry,		/* disconnect is done via snd_info_card_disconnect() */	};	struct snd_info_entry *entry;	int err;	entry = snd_info_create_card_entry(card, name, card->proc_root);	if (! entry)		return -ENOMEM;	if ((err = snd_device_new(card, SNDRV_DEV_INFO, entry, &ops)) < 0) {		snd_info_free_entry(entry);		return err;	}	if (entryp)		*entryp = entry;	return 0;}EXPORT_SYMBOL(snd_card_proc_new);/** * snd_info_free_entry - release the info entry * @entry: the info entry * * Releases the info entry.  Don't call this after registered. */void snd_info_free_entry(struct snd_info_entry * entry){	if (entry == NULL)		return;	if (entry->p) {		mutex_lock(&info_mutex);		snd_info_disconnect(entry);		mutex_unlock(&info_mutex);	}	kfree(entry->name);	if (entry->private_free)		entry->private_free(entry);	kfree(entry);}EXPORT_SYMBOL(snd_info_free_entry);/** * snd_info_register - register the info entry * @entry: the info entry * * Registers the proc info entry. * * Returns zero if successful, or a negative error code on failure. */int snd_info_register(struct snd_info_entry * entry){	struct proc_dir_entry *root, *p = NULL;	snd_assert(entry != NULL, return -ENXIO);	root = entry->parent == NULL ? snd_proc_root : entry->parent->p;	mutex_lock(&info_mutex);	p = snd_create_proc_entry(entry->name, entry->mode, root);	if (!p) {		mutex_unlock(&info_mutex);		return -ENOMEM;	}	p->owner = entry->module;	if (!S_ISDIR(entry->mode))		p->proc_fops = &snd_info_entry_operations;	p->size = entry->size;	p->data = entry;	entry->p = p;	if (entry->parent)		list_add_tail(&entry->list, &entry->parent->children);	mutex_unlock(&info_mutex);	return 0;}EXPORT_SYMBOL(snd_info_register);/* */static struct snd_info_entry *snd_info_version_entry;static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer){	snd_iprintf(buffer,		    "Advanced Linux Sound Architecture Driver Version "		    CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"		   );}static int __init snd_info_version_init(void){	struct snd_info_entry *entry;	entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL);	if (entry == NULL)		return -ENOMEM;	entry->c.text.read = snd_info_version_read;	if (snd_info_register(entry) < 0) {		snd_info_free_entry(entry);		return -ENOMEM;	}	snd_info_version_entry = entry;	return 0;}static int __exit snd_info_version_done(void){	snd_info_free_entry(snd_info_version_entry);	return 0;}#endif /* CONFIG_PROC_FS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -