/*
 * 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 a modified version of Erik Mouw's example proc
 * interface, 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 = 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);
