info.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,001 行 · 第 1/2 页

C
1,001
字号
{	.owner =	THIS_MODULE,	.llseek =	snd_info_entry_llseek,	.read =		snd_info_entry_read,	.write =	snd_info_entry_write,	.poll =		snd_info_entry_poll,	.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. */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	{		snd_info_entry_t *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)	{		snd_info_entry_t *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_memory_info_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_memory_info_done();	snd_info_version_done();	if (snd_proc_root) {#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)		if (snd_seq_root)			snd_info_unregister(snd_seq_root);#endif#ifdef CONFIG_SND_OSSEMUL		if (snd_oss_root)			snd_info_unregister(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(snd_card_t * card){	char str[8];	snd_info_entry_t *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(snd_card_t * 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 */int snd_info_card_free(snd_card_t * card){	snd_assert(card != NULL, return -ENXIO);	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_unregister(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(snd_info_buffer_t * buffer, char *line, int len){	int c = -1;	if (len <= 0 || buffer->stop || buffer->error)		return 1;	while (--len > 0) {		c = *buffer->curr++;		if (c == '\n') {			if ((buffer->curr - buffer->buffer) >= (long)buffer->size) {				buffer->stop = 1;			}			break;		}		*line++ = c;		if ((buffer->curr - buffer->buffer) >= (long)buffer->size) {			buffer->stop = 1;			break;		}	}	while (c != '\n' && !buffer->stop) {		c = *buffer->curr++;		if ((buffer->curr - buffer->buffer) >= (long)buffer->size) {			buffer->stop = 1;		}	}	*line = '\0';	return 0;}/** * snd_info_get_line - 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;}/** * 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 snd_info_entry_t *snd_info_create_entry(const char *name){	snd_info_entry_t *entry;	entry = kcalloc(1, sizeof(*entry), GFP_KERNEL);	if (entry == NULL)		return NULL;	entry->name = snd_kmalloc_strdup(name, GFP_KERNEL);	if (entry->name == NULL) {		kfree(entry);		return NULL;	}	entry->mode = S_IFREG | S_IRUGO;	entry->content = SNDRV_INFO_CONTENT_TEXT;	init_MUTEX(&entry->access);	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. */snd_info_entry_t *snd_info_create_module_entry(struct module * module,					       const char *name,					       snd_info_entry_t *parent){	snd_info_entry_t *entry = snd_info_create_entry(name);	if (entry) {		entry->module = module;		entry->parent = parent;	}	return 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. */snd_info_entry_t *snd_info_create_card_entry(snd_card_t * card,					     const char *name,					     snd_info_entry_t * parent){	snd_info_entry_t *entry = snd_info_create_entry(name);	if (entry) {		entry->module = card->module;		entry->card = card;		entry->parent = parent;	}	return entry;}static int snd_info_dev_free_entry(snd_device_t *device){	snd_info_entry_t *entry = device->device_data;	snd_info_free_entry(entry);	return 0;}static int snd_info_dev_register_entry(snd_device_t *device){	snd_info_entry_t *entry = device->device_data;	return snd_info_register(entry);}static int snd_info_dev_disconnect_entry(snd_device_t *device){	snd_info_entry_t *entry = device->device_data;	entry->disconnected = 1;	return 0;}static int snd_info_dev_unregister_entry(snd_device_t *device){	snd_info_entry_t *entry = device->device_data;	return snd_info_unregister(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(snd_card_t *card, const char *name,		      snd_info_entry_t **entryp){	static snd_device_ops_t ops = {		.dev_free = snd_info_dev_free_entry,		.dev_register =	snd_info_dev_register_entry,		.dev_disconnect = snd_info_dev_disconnect_entry,		.dev_unregister = snd_info_dev_unregister_entry	};	snd_info_entry_t *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;}/** * 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(snd_info_entry_t * entry){	if (entry == NULL)		return;	if (entry->name)		kfree((char *)entry->name);	if (entry->private_free)		entry->private_free(entry);	kfree(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(snd_info_entry_t * entry){	struct proc_dir_entry *root, *p = NULL;	snd_assert(entry != NULL, return -ENXIO);	root = entry->parent == NULL ? snd_proc_root : entry->parent->p;	down(&info_mutex);	p = snd_create_proc_entry(entry->name, entry->mode, root);	if (!p) {		up(&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;	up(&info_mutex);	return 0;}/** * snd_info_unregister - de-register the info entry * @entry: the info entry * * De-registers the info entry and releases the instance. * * Returns zero if successful, or a negative error code on failure. */int snd_info_unregister(snd_info_entry_t * entry){	struct proc_dir_entry *root;	snd_assert(entry != NULL && entry->p != NULL, return -ENXIO);	root = entry->parent == NULL ? snd_proc_root : entry->parent->p;	snd_assert(root, return -ENXIO);	down(&info_mutex);	snd_remove_proc_entry(root, entry->p);	up(&info_mutex);	snd_info_free_entry(entry);	return 0;}/* */static snd_info_entry_t *snd_info_version_entry = NULL;static void snd_info_version_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer){	static char *kernel_version = UTS_RELEASE;	snd_iprintf(buffer,		    "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"		    "Compiled on " __DATE__ " for kernel %s"#ifdef CONFIG_SMP		    " (SMP)"#endif#ifdef MODVERSIONS		    " with versioned symbols"#endif		    ".\n", kernel_version);}static int __init snd_info_version_init(void){	snd_info_entry_t *entry;	entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL);	if (entry == NULL)		return -ENOMEM;	entry->c.text.read_size = 256;	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){	if (snd_info_version_entry)		snd_info_unregister(snd_info_version_entry);	return 0;}#endif /* CONFIG_PROC_FS */

⌨️ 快捷键说明

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