mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-24 09:50:04 +00:00
![Thomas Gleixner](/assets/img/avatar_default.png)
Based on 1 normalized pattern(s): 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 extracted by the scancode license scanner the SPDX license identifier GPL-2.0-only has been chosen to replace the boilerplate/reference in 136 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Alexios Zavras <alexios.zavras@intel.com> Reviewed-by: Allison Randal <allison@lohutok.net> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190530000436.384967451@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
219 lines
5 KiB
C
219 lines
5 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* 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!
|
|
*/
|
|
|
|
#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 <linux/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;
|
|
} 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 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 int srm_env_proc_show(struct seq_file *m, void *v)
|
|
{
|
|
unsigned long ret;
|
|
unsigned long id = (unsigned long)m->private;
|
|
char *page;
|
|
|
|
page = (char *)__get_free_page(GFP_USER);
|
|
if (!page)
|
|
return -ENOMEM;
|
|
|
|
ret = callback_getenv(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_DATA(inode));
|
|
}
|
|
|
|
static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer,
|
|
size_t count, loff_t *pos)
|
|
{
|
|
int res;
|
|
unsigned long id = (unsigned long)PDE_DATA(file_inode(file));
|
|
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(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 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;
|
|
}
|
|
|
|
/*
|
|
* 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);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
/*
|
|
* 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) {
|
|
if (!proc_create_data(entry->name, 0644, named_dir,
|
|
&srm_env_proc_fops, (void *)entry->id))
|
|
goto cleanup;
|
|
entry++;
|
|
}
|
|
|
|
/*
|
|
* Create all numbered nodes
|
|
*/
|
|
for (var_num = 0; var_num <= 255; var_num++) {
|
|
char name[4];
|
|
sprintf(name, "%ld", var_num);
|
|
if (!proc_create_data(name, 0644, numbered_dir,
|
|
&srm_env_proc_fops, (void *)var_num))
|
|
goto cleanup;
|
|
}
|
|
|
|
printk(KERN_INFO "%s: version %s loaded successfully\n", NAME,
|
|
VERSION);
|
|
|
|
return 0;
|
|
|
|
cleanup:
|
|
remove_proc_subtree(BASE_DIR, NULL);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
static void __exit
|
|
srm_env_exit(void)
|
|
{
|
|
remove_proc_subtree(BASE_DIR, NULL);
|
|
printk(KERN_INFO "%s: unloaded successfully\n", NAME);
|
|
}
|
|
|
|
module_init(srm_env_init);
|
|
module_exit(srm_env_exit);
|