diff options
Diffstat (limited to 'arch/alpha/kernel/srm_env.c')
| -rw-r--r-- | arch/alpha/kernel/srm_env.c | 208 |
1 files changed, 54 insertions, 154 deletions
diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c index 5c98fc83e23..ffe996a54fa 100644 --- a/arch/alpha/kernel/srm_env.c +++ b/arch/alpha/kernel/srm_env.c @@ -2,11 +2,10 @@ * srm_env.c - Access to SRM environment * variables through linux' procfs * - * Copyright (C) 2001-2002 Jan-Benedict Glaw <jbglaw@lug-owl.de> + * (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 + * 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! @@ -21,7 +20,7 @@ * 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, @@ -29,38 +28,12 @@ * */ -/* - * Changelog - * ~~~~~~~~~ - * - * Thu, 22 Aug 2002 15:10:43 +0200 - * - Update Config.help entry. I got a number of emails asking - * me to tell their senders if they could make use of this - * piece of code... So: "SRM is something like BIOS for your - * Alpha" - * - Update code formatting a bit to better conform CodingStyle - * rules. - * - So this is v0.0.5, with no changes (except formatting) - * - * Wed, 22 May 2002 00:11:21 +0200 - * - Fix typo on comment (SRC -> SRM) - * - Call this "Version 0.0.4" - * - * Tue, 9 Apr 2002 18:44:40 +0200 - * - Implement access by variable name and additionally - * by number. This is done by creating two subdirectories - * where one holds all names (like the old directory - * did) and the other holding 256 files named like "0", - * "1" and so on. - * - Call this "Version 0.0.3" - * - */ - #include <linux/kernel.h> -#include <linux/config.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> @@ -68,7 +41,7 @@ #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.5" /* Module version */ +#define VERSION "0.0.6" /* Module version */ #define NAME "srm_env" /* Module name */ MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); @@ -78,13 +51,11 @@ 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 }, @@ -104,44 +75,41 @@ static srm_env_t srm_named_entries[] = { { "tty_dev", ENV_TTY_DEV }, { NULL, 0 }, }; -static srm_env_t srm_numbered_entries[256]; - - -static int -srm_env_read(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int srm_env_proc_show(struct seq_file *m, void *v) { - int nbytes; unsigned long ret; - srm_env_t *entry; - - if(off != 0) - return -EFAULT; + unsigned long id = (unsigned long)m->private; + char *page; - entry = (srm_env_t *) data; - ret = callback_getenv(entry->id, page, count); + page = (char *)__get_free_page(GFP_USER); + if (!page) + return -ENOMEM; - if((ret >> 61) == 0) - nbytes = (int) ret; - else - nbytes = -EFAULT; + ret = callback_getenv(id, page, PAGE_SIZE); - return nbytes; + 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 int -srm_env_write(struct file *file, const char __user *buffer, unsigned long count, - void *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; + unsigned long id = (unsigned long)PDE_DATA(file_inode(file)); char *buf = (char *) __get_free_page(GFP_USER); unsigned long ret1, ret2; - entry = (srm_env_t *) data; - if (!buf) return -ENOMEM; @@ -154,9 +122,9 @@ srm_env_write(struct file *file, const char __user *buffer, unsigned long count, goto out; buf[count] = '\0'; - ret1 = callback_setenv(entry->id, buf, count); + ret1 = callback_setenv(id, buf, count); if ((ret1 >> 61) == 0) { - do + do ret2 = callback_save_env(); while((ret2 >> 61) == 1); res = (int) ret1; @@ -167,52 +135,14 @@ srm_env_write(struct file *file, const char __user *buffer, unsigned long count, return res; } -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 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) @@ -223,89 +153,65 @@ srm_env_init(void) /* * Check system */ - if(!alpha_using_srm) { + 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", __FUNCTION__); + "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 == NULL) { + if (!base_dir) { printk(KERN_ERR "Couldn't create base dir /proc/%s\n", BASE_DIR); - goto cleanup; + return -ENOMEM; } - base_dir->owner = THIS_MODULE; /* * Create per-name subdirectory */ named_dir = proc_mkdir(NAMED_DIR, base_dir); - if(named_dir == NULL) { + if (!named_dir) { printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n", BASE_DIR, NAMED_DIR); goto cleanup; } - named_dir->owner = THIS_MODULE; /* * Create per-number subdirectory */ numbered_dir = proc_mkdir(NUMBERED_DIR, base_dir); - if(numbered_dir == NULL) { + if (!numbered_dir) { printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n", BASE_DIR, NUMBERED_DIR); goto cleanup; } - numbered_dir->owner = THIS_MODULE; /* * Create all named nodes */ entry = srm_named_entries; - while(entry->name != NULL && entry->id != 0) { - entry->proc_entry = create_proc_entry(entry->name, - 0644, named_dir); - if(entry->proc_entry == NULL) + while (entry->name && entry->id) { + if (!proc_create_data(entry->name, 0644, named_dir, + &srm_env_proc_fops, (void *)entry->id)) goto cleanup; - - entry->proc_entry->data = (void *) entry; - entry->proc_entry->owner = THIS_MODULE; - entry->proc_entry->read_proc = srm_env_read; - entry->proc_entry->write_proc = srm_env_write; - 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 = create_proc_entry(entry->name, - 0644, numbered_dir); - if(entry->proc_entry == NULL) + 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; - - entry->id = var_num; - entry->proc_entry->data = (void *) entry; - entry->proc_entry->owner = THIS_MODULE; - entry->proc_entry->read_proc = srm_env_read; - entry->proc_entry->write_proc = srm_env_write; } printk(KERN_INFO "%s: version %s loaded successfully\n", NAME, @@ -314,22 +220,16 @@ srm_env_init(void) return 0; cleanup: - srm_env_cleanup(); - + remove_proc_subtree(BASE_DIR, NULL); return -ENOMEM; } - static void __exit srm_env_exit(void) { - srm_env_cleanup(); + remove_proc_subtree(BASE_DIR, NULL); printk(KERN_INFO "%s: unloaded successfully\n", NAME); - - return; } - module_init(srm_env_init); module_exit(srm_env_exit); - |
