/*
 *  Information interface for ALSA driver
 *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
 *
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

#include <sound/driver.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/time.h>
#include <linux/smp_lock.h>
#include <linux/string.h>
#include <sound/core.h>
#include <sound/minors.h>
#include <sound/info.h>
#include <sound/version.h>
#include <linux/proc_fs.h>
#include <linux/devfs_fs_kernel.h>
#include <stdarg.h>

/*
 *
 */

int snd_info_check_reserved_words(const char *str)
{
	static char *reserved[] =
	{
		"version",
		"meminfo",
		"memdebug",
		"detect",
		"devices",
		"oss",
		"cards",
		"timers",
		"synth",
		"pcm",
		"seq",
		NULL
	};
	char **xstr = reserved;

	while (*xstr) {
		if (!strcmp(*xstr, str))
			return 0;
		xstr++;
	}
	if (!strncmp(str, "card", 4))
		return 0;
	return 1;
}

#ifdef CONFIG_PROC_FS

static DECLARE_MUTEX(info_mutex);

typedef struct _snd_info_private_data {
	snd_info_buffer_t *rbuffer;
	snd_info_buffer_t *wbuffer;
	snd_info_entry_t *entry;
	void *file_private_data;
} snd_info_private_data_t;

static int snd_info_version_init(void);
static int snd_info_version_done(void);


/**
 * snd_iprintf - printf on the procfs buffer
 * @buffer: the procfs buffer
 * @fmt: the printf format
 *
 * Outputs the string on the procfs buffer just like printf().
 *
 * Returns the size of output string.
 */
int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...)
{
	va_list args;
	int len, res;

	if (buffer->stop || buffer->error)
		return 0;
	len = buffer->len - buffer->size;
	va_start(args, fmt);
	res = vsnprintf(buffer->curr, len, fmt, args);
	va_end(args);
	if (res >= len) {
		buffer->stop = 1;
		return 0;
	}
	buffer->curr += res;
	buffer->size += res;
	return res;
}

/*

 */

static struct proc_dir_entry *snd_proc_root = NULL;
snd_info_entry_t *snd_seq_root = NULL;
#ifdef CONFIG_SND_OSSEMUL
snd_info_entry_t *snd_oss_root = NULL;
#endif

static inline void snd_info_entry_prepare(struct proc_dir_entry *de)
{
	de->owner = THIS_MODULE;
}

static void snd_remove_proc_entry(struct proc_dir_entry *parent,
				  struct proc_dir_entry *de)
{
	if (de)
		remove_proc_entry(de->name, parent);
}

static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
{
	snd_info_private_data_t *data;
	struct snd_info_entry *entry;
	loff_t ret;

	data = file->private_data;
	entry = data->entry;
	lock_kernel();
	switch (entry->content) {
	case SNDRV_INFO_CONTENT_TEXT:
		switch (orig) {
		case 0:	/* SEEK_SET */
			file->f_pos = offset;
			ret = file->f_pos;
			goto out;
		case 1:	/* SEEK_CUR */
			file->f_pos += offset;
			ret = file->f_pos;
			goto out;
		case 2:	/* SEEK_END */
		default:
			ret = -EINVAL;
			goto out;
		}
		break;
	case SNDRV_INFO_CONTENT_DATA:
		if (entry->c.ops->llseek) {
			ret = entry->c.ops->llseek(entry,
						    data->file_private_data,
						    file, offset, orig);
			goto out;
		}
		break;
	}
	ret = -ENXIO;
out:
	unlock_kernel();
	return ret;
}

static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
				   size_t count, loff_t * offset)
{
	snd_info_private_data_t *data;
	struct snd_info_entry *entry;
	snd_info_buffer_t *buf;
	size_t size = 0;
	loff_t pos;

	data = file->private_data;
	snd_assert(data != NULL, return -ENXIO);
	pos = *offset;
	if (pos < 0 || (long) pos != pos || (ssize_t) count < 0)
		return -EIO;
	if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos)
		return -EIO;
	entry = data->entry;
	switch (entry->content) {
	case SNDRV_INFO_CONTENT_TEXT:
		buf = data->rbuffer;
		if (buf == NULL)
			return -EIO;
		if (pos >= buf->size)
			return 0;
		size = buf->size - pos;
		size = min(count, size);
		if (copy_to_user(buffer, buf->buffer + pos, size))
			return -EFAULT;
		break;
	case SNDRV_INFO_CONTENT_DATA:
		if (entry->c.ops->read)
			size = entry->c.ops->read(entry,
						  data->file_private_data,
						  file, buffer, count, pos);
		break;
	}
	if ((ssize_t) size > 0)
		*offset = pos + size;
	return size;
}

static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer,
				    size_t count, loff_t * offset)
{
	snd_info_private_data_t *data;
	struct snd_info_entry *entry;
	snd_info_buffer_t *buf;
	size_t size = 0;
	loff_t pos;

	data = file->private_data;
	snd_assert(data != NULL, return -ENXIO);
	entry = data->entry;
	pos = *offset;
	if (pos < 0 || (long) pos != pos || (ssize_t) count < 0)
		return -EIO;
	if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos)
		return -EIO;
	switch (entry->content) {
	case SNDRV_INFO_CONTENT_TEXT:
		buf = data->wbuffer;
		if (buf == NULL)
			return -EIO;
		if (pos >= buf->len)
			return -ENOMEM;
		size = buf->len - pos;
		size = min(count, size);
		if (copy_from_user(buf->buffer + pos, buffer, size))
			return -EFAULT;
		if ((long)buf->size < pos + size)
			buf->size = pos + size;
		break;
	case SNDRV_INFO_CONTENT_DATA:
		if (entry->c.ops->write)
			size = entry->c.ops->write(entry,
						   data->file_private_data,
						   file, buffer, count, pos);
		break;
	}
	if ((ssize_t) size > 0)
		*offset = pos + size;
	return size;
}

static int snd_info_entry_open(struct inode *inode, struct file *file)
{
	snd_info_entry_t *entry;
	snd_info_private_data_t *data;
	snd_info_buffer_t *buffer;
	struct proc_dir_entry *p;
	int mode, err;

	down(&info_mutex);
	p = PDE(inode);
	entry = p == NULL ? NULL : (snd_info_entry_t *)p->data;
	if (entry == NULL || entry->disconnected) {
		up(&info_mutex);
		return -ENODEV;
	}
	if (!try_module_get(entry->module)) {
		err = -EFAULT;
		goto __error1;
	}
	mode = file->f_flags & O_ACCMODE;
	if (mode == O_RDONLY || mode == O_RDWR) {
		if ((entry->content == SNDRV_INFO_CONTENT_TEXT &&
		     !entry->c.text.read_size) ||
		    (entry->content == SNDRV_INFO_CONTENT_DATA &&
		     entry->c.ops->read == NULL)) {
		    	err = -ENODEV;
		    	goto __error;
		}
	}
	if (mode == O_WRONLY || mode == O_RDWR) {
		if ((entry->content == SNDRV_INFO_CONTENT_TEXT &&
		     !entry->c.text.write_size) ||
		    (entry->content == SNDRV_INFO_CONTENT_DATA &&
		     entry->c.ops->write == NULL)) {
		    	err = -ENODEV;
		    	goto __error;
		}
	}
	data = kcalloc(1, sizeof(*data), GFP_KERNEL);
	if (data == NULL) {
		err = -ENOMEM;
		goto __error;
	}
	data->entry = entry;
	switch (entry->content) {
	case SNDRV_INFO_CONTENT_TEXT:
		if (mode == O_RDONLY || mode == O_RDWR) {
			buffer = kcalloc(1, sizeof(*buffer), GFP_KERNEL);
			if (buffer == NULL) {
				kfree(data);
				err = -ENOMEM;
				goto __error;
			}
			buffer->len = (entry->c.text.read_size +
				      (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
			buffer->buffer = vmalloc(buffer->len);
			if (buffer->buffer == NULL) {
				kfree(buffer);
				kfree(data);
				err = -ENOMEM;
				goto __error;
			}
			buffer->curr = buffer->buffer;
			data->rbuffer = buffer;
		}
		if (mode == O_WRONLY || mode == O_RDWR) {
			buffer = kcalloc(1, sizeof(*buffer), GFP_KERNEL);
			if (buffer == NULL) {
				if (mode == O_RDWR) {
					vfree(data->rbuffer->buffer);
					kfree(data->rbuffer);
				}
				kfree(data);
				err = -ENOMEM;
				goto __error;
			}
			buffer->len = (entry->c.text.write_size +
				      (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
			buffer->buffer = vmalloc(buffer->len);
			if (buffer->buffer == NULL) {
				if (mode == O_RDWR) {
					vfree(data->rbuffer->buffer);
					kfree(data->rbuffer);
				}
				kfree(buffer);
				kfree(data);
				err = -ENOMEM;
				goto __error;
			}
			buffer->curr = buffer->buffer;
			data->wbuffer = buffer;
		}
		break;
	case SNDRV_INFO_CONTENT_DATA:	/* data */
		if (entry->c.ops->open) {
			if ((err = entry->c.ops->open(entry, mode,
						      &data->file_private_data)) < 0) {
				kfree(data);
				goto __error;
			}
		}
		break;
	}
	file->private_data = data;
	up(&info_mutex);
	if (entry->content == SNDRV_INFO_CONTENT_TEXT &&
	    (mode == O_RDONLY || mode == O_RDWR)) {
		if (entry->c.text.read) {
			down(&entry->access);
			entry->c.text.read(entry, data->rbuffer);
			up(&entry->access);
		}
	}
	return 0;

      __error:
	module_put(entry->module);
      __error1:
	up(&info_mutex);
	return err;
}

static int snd_info_entry_release(struct inode *inode, struct file *file)
{
	snd_info_entry_t *entry;
	snd_info_private_data_t *data;
	int mode;

	mode = file->f_flags & O_ACCMODE;
	data = file->private_data;
	entry = data->entry;
	switch (entry->content) {
	case SNDRV_INFO_CONTENT_TEXT:
		if (mode == O_RDONLY || mode == O_RDWR) {
			vfree(data->rbuffer->buffer);
			kfree(data->rbuffer);
		}
		if (mode == O_WRONLY || mode == O_RDWR) {
			if (entry->c.text.write) {
				entry->c.text.write(entry, data->wbuffer);
				if (data->wbuffer->error) {
					snd_printk(KERN_WARNING "data write error to %s (%i)\n",
						entry->name,
						data->wbuffer->error);
				}
			}
			vfree(data->wbuffer->buffer);
			kfree(data->wbuffer);
		}
		break;
	case SNDRV_INFO_CONTENT_DATA:
		if (entry->c.ops->release)
			entry->c.ops->release(entry, mode,
					      data->file_private_data);
		break;
	}
	module_put(entry->module);
	kfree(data);
	return 0;
}

static unsigned int snd_info_entry_poll(struct file *file, poll_table * wait)
{
	snd_info_private_data_t *data;
	struct snd_info_entry *entry;
	unsigned int mask;

	data = file->private_data;
	if (data == NULL)
		return 0;
	entry = data->entry;
	mask = 0;
	switch (entry->content) {
	case SNDRV_INFO_CONTENT_DATA:
		if (entry->c.ops->poll)
			return entry->c.ops->poll(entry,
						  data->file_private_data,
						  file, wait);
		if (entry->c.ops->read)
			mask |= POLLIN | POLLRDNORM;
		if (entry->c.ops->write)
			mask |= POLLOUT | POLLWRNORM;
		break;
	}
	return mask;
}

static inline int _snd_info_entry_ioctl(struct inode *inode, struct file *file,
					unsigned int cmd, unsigned long arg)
{
	snd_info_private_data_t *data;
	struct snd_info_entry *entry;

	data = file->private_data;
	if (data == NULL)
		return 0;
	entry = data->entry;
	switch (entry->content) {
	case SNDRV_INFO_CONTENT_DATA:
		if (entry->c.ops->ioctl)
			return entry->c.ops->ioctl(entry,
						   data->file_private_data,
						   file, cmd, arg);
		break;
	}
	return -ENOTTY;
}

/* FIXME: need to unlock BKL to allow preemption */
static int snd_info_entry_ioctl(struct inode *inode, struct file *file,
				unsigned int cmd, unsigned long arg)
{
	int err;
	unlock_kernel();
	err = _snd_info_entry_ioctl(inode, file, cmd, arg);
	lock_kernel();
	return err;
}

static int snd_info_entry_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct inode *inode = file->f_dentry->d_inode;
	snd_info_private_data_t *data;
	struct snd_info_entry *entry;

	data = file->private_data;
	if (data == NULL)
		return 0;
	entry = data->entry;
	switch (entry->content) {
	case SNDRV_INFO_CONTENT_DATA:
		if (entry->c.ops->mmap)
			return entry->c.ops->mmap(entry,
						  data->file_private_data,
						  inode, file, vma);
		break;
	}
	return -ENXIO;
}

static 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,
	.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
	{
		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_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;
}

/**
 * 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 = kstrdup(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;
	kfree(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, return -ENXIO);
	snd_assert(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)
{
	snd_iprintf(buffer,
		    "Advanced Linux Sound Architecture Driver Version "
		    CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"
		   );
}

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 */
