/*
 * srm_env.c - Access to SRM environment
 *             variables through linux' procfs
 *
 * (C) 2001,2002,2006 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
 *
 * This driver is at all a modified version of Erik Mouw's
 * Documentation/DocBook/procfs_example.c, so: thank
 * you, Erik! He can be reached via email at
 * <J.A.K.Mouw@its.tudelft.nl>. It is based on an idea
 * provided by DEC^WCompaq^WIntel's "Jumpstart" CD. They
 * included a patch like this as well. Thanks for idea!
 *
 * This program is free software; you can redistribute
 * it and/or modify it under the terms of the GNU General
 * Public License version 2 as published by the Free Software
 * Foundation.
 *
 * 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 <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/console.h>
#include <asm/uaccess.h>
#include <asm/machvec.h>

#define BASE_DIR	"srm_environment"	/* Subdir in /proc/		*/
#define NAMED_DIR	"named_variables"	/* Subdir for known variables	*/
#define NUMBERED_DIR	"numbered_variables"	/* Subdir for all variables	*/
#define VERSION		"0.0.6"			/* Module version		*/
#define NAME		"srm_env"		/* Module name			*/

MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
MODULE_DESCRIPTION("Accessing Alpha SRM environment through procfs interface");
MODULE_LICENSE("GPL");

typedef struct _srm_env {
	char			*name;
	unsigned long		id;
	struct proc_dir_entry	*proc_entry;
} srm_env_t;

static struct proc_dir_entry	*base_dir;
static struct proc_dir_entry	*named_dir;
static struct proc_dir_entry	*numbered_dir;
static char			number[256][4];

static srm_env_t	srm_named_entries[] = {
	{ "auto_action",	ENV_AUTO_ACTION		},
	{ "boot_dev",		ENV_BOOT_DEV		},
	{ "bootdef_dev",	ENV_BOOTDEF_DEV		},
	{ "booted_dev",		ENV_BOOTED_DEV		},
	{ "boot_file",		ENV_BOOT_FILE		},
	{ "booted_file",	ENV_BOOTED_FILE		},
	{ "boot_osflags",	ENV_BOOT_OSFLAGS	},
	{ "booted_osflags",	ENV_BOOTED_OSFLAGS	},
	{ "boot_reset",		ENV_BOOT_RESET		},
	{ "dump_dev",		ENV_DUMP_DEV		},
	{ "enable_audit",	ENV_ENABLE_AUDIT	},
	{ "license",		ENV_LICENSE		},
	{ "char_set",		ENV_CHAR_SET		},
	{ "language",		ENV_LANGUAGE		},
	{ "tty_dev",		ENV_TTY_DEV		},
	{ NULL,			0			},
};
static srm_env_t	srm_numbered_entries[256];


static int srm_env_proc_show(struct seq_file *m, void *v)
{
	unsigned long	ret;
	srm_env_t	*entry;
	char		*page;

	entry = (srm_env_t *)m->private;
	page = (char *)__get_free_page(GFP_USER);
	if (!page)
		return -ENOMEM;

	ret = callback_getenv(entry->id, page, PAGE_SIZE);

	if ((ret >> 61) == 0) {
		seq_write(m, page, ret);
		ret = 0;
	} else
		ret = -EFAULT;
	free_page((unsigned long)page);
	return ret;
}

static int srm_env_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, srm_env_proc_show, PDE(inode)->data);
}

static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer,
				  size_t count, loff_t *pos)
{
	int res;
	srm_env_t	*entry = PDE(file->f_path.dentry->d_inode)->data;
	char		*buf = (char *) __get_free_page(GFP_USER);
	unsigned long	ret1, ret2;

	if (!buf)
		return -ENOMEM;

	res = -EINVAL;
	if (count >= PAGE_SIZE)
		goto out;

	res = -EFAULT;
	if (copy_from_user(buf, buffer, count))
		goto out;
	buf[count] = '\0';

	ret1 = callback_setenv(entry->id, buf, count);
	if ((ret1 >> 61) == 0) {
		do
			ret2 = callback_save_env();
		while((ret2 >> 61) == 1);
		res = (int) ret1;
	}

 out:
	free_page((unsigned long)buf);
	return res;
}

static const struct file_operations srm_env_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= srm_env_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
	.write		= srm_env_proc_write,
};

static void
srm_env_cleanup(void)
{
	srm_env_t	*entry;
	unsigned long	var_num;

	if (base_dir) {
		/*
		 * Remove named entries
		 */
		if (named_dir) {
			entry = srm_named_entries;
			while (entry->name != NULL && entry->id != 0) {
				if (entry->proc_entry) {
					remove_proc_entry(entry->name,
							named_dir);
					entry->proc_entry = NULL;
				}
				entry++;
			}
			remove_proc_entry(NAMED_DIR, base_dir);
		}

		/*
		 * Remove numbered entries
		 */
		if (numbered_dir) {
			for (var_num = 0; var_num <= 255; var_num++) {
				entry =	&srm_numbered_entries[var_num];

				if (entry->proc_entry) {
					remove_proc_entry(entry->name,
							numbered_dir);
					entry->proc_entry	= NULL;
					entry->name		= NULL;
				}
			}
			remove_proc_entry(NUMBERED_DIR, base_dir);
		}

		remove_proc_entry(BASE_DIR, NULL);
	}

	return;
}

static int __init
srm_env_init(void)
{
	srm_env_t	*entry;
	unsigned long	var_num;

	/*
	 * Check system
	 */
	if (!alpha_using_srm) {
		printk(KERN_INFO "%s: This Alpha system doesn't "
				"know about SRM (or you've booted "
				"SRM->MILO->Linux, which gets "
				"misdetected)...\n", __func__);
		return -ENODEV;
	}

	/*
	 * Init numbers
	 */
	for (var_num = 0; var_num <= 255; var_num++)
		sprintf(number[var_num], "%ld", var_num);

	/*
	 * Create base directory
	 */
	base_dir = proc_mkdir(BASE_DIR, NULL);
	if (!base_dir) {
		printk(KERN_ERR "Couldn't create base dir /proc/%s\n",
				BASE_DIR);
		goto cleanup;
	}

	/*
	 * Create per-name subdirectory
	 */
	named_dir = proc_mkdir(NAMED_DIR, base_dir);
	if (!named_dir) {
		printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n",
				BASE_DIR, NAMED_DIR);
		goto cleanup;
	}

	/*
	 * Create per-number subdirectory
	 */
	numbered_dir = proc_mkdir(NUMBERED_DIR, base_dir);
	if (!numbered_dir) {
		printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n",
				BASE_DIR, NUMBERED_DIR);
		goto cleanup;

	}

	/*
	 * Create all named nodes
	 */
	entry = srm_named_entries;
	while (entry->name && entry->id) {
		entry->proc_entry = proc_create_data(entry->name, 0644, named_dir,
						     &srm_env_proc_fops, entry);
		if (!entry->proc_entry)
			goto cleanup;
		entry++;
	}

	/*
	 * Create all numbered nodes
	 */
	for (var_num = 0; var_num <= 255; var_num++) {
		entry = &srm_numbered_entries[var_num];
		entry->name = number[var_num];

		entry->proc_entry = proc_create_data(entry->name, 0644, numbered_dir,
						     &srm_env_proc_fops, entry);
		if (!entry->proc_entry)
			goto cleanup;

		entry->id			= var_num;
	}

	printk(KERN_INFO "%s: version %s loaded successfully\n", NAME,
			VERSION);

	return 0;

cleanup:
	srm_env_cleanup();

	return -ENOMEM;
}

static void __exit
srm_env_exit(void)
{
	srm_env_cleanup();
	printk(KERN_INFO "%s: unloaded successfully\n", NAME);

	return;
}

module_init(srm_env_init);
module_exit(srm_env_exit);
