root/arch/alpha/kernel/srm_env.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. srm_env_proc_show
  2. srm_env_proc_open
  3. srm_env_proc_write
  4. srm_env_init
  5. srm_env_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * srm_env.c - Access to SRM environment
   4  *             variables through linux' procfs
   5  *
   6  * (C) 2001,2002,2006 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
   7  *
   8  * This driver is a modified version of Erik Mouw's example proc
   9  * interface, so: thank you, Erik! He can be reached via email at
  10  * <J.A.K.Mouw@its.tudelft.nl>. It is based on an idea
  11  * provided by DEC^WCompaq^WIntel's "Jumpstart" CD. They
  12  * included a patch like this as well. Thanks for idea!
  13  */
  14 
  15 #include <linux/kernel.h>
  16 #include <linux/gfp.h>
  17 #include <linux/module.h>
  18 #include <linux/init.h>
  19 #include <linux/proc_fs.h>
  20 #include <linux/seq_file.h>
  21 #include <asm/console.h>
  22 #include <linux/uaccess.h>
  23 #include <asm/machvec.h>
  24 
  25 #define BASE_DIR        "srm_environment"       /* Subdir in /proc/             */
  26 #define NAMED_DIR       "named_variables"       /* Subdir for known variables   */
  27 #define NUMBERED_DIR    "numbered_variables"    /* Subdir for all variables     */
  28 #define VERSION         "0.0.6"                 /* Module version               */
  29 #define NAME            "srm_env"               /* Module name                  */
  30 
  31 MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
  32 MODULE_DESCRIPTION("Accessing Alpha SRM environment through procfs interface");
  33 MODULE_LICENSE("GPL");
  34 
  35 typedef struct _srm_env {
  36         char                    *name;
  37         unsigned long           id;
  38 } srm_env_t;
  39 
  40 static struct proc_dir_entry    *base_dir;
  41 static struct proc_dir_entry    *named_dir;
  42 static struct proc_dir_entry    *numbered_dir;
  43 
  44 static srm_env_t        srm_named_entries[] = {
  45         { "auto_action",        ENV_AUTO_ACTION         },
  46         { "boot_dev",           ENV_BOOT_DEV            },
  47         { "bootdef_dev",        ENV_BOOTDEF_DEV         },
  48         { "booted_dev",         ENV_BOOTED_DEV          },
  49         { "boot_file",          ENV_BOOT_FILE           },
  50         { "booted_file",        ENV_BOOTED_FILE         },
  51         { "boot_osflags",       ENV_BOOT_OSFLAGS        },
  52         { "booted_osflags",     ENV_BOOTED_OSFLAGS      },
  53         { "boot_reset",         ENV_BOOT_RESET          },
  54         { "dump_dev",           ENV_DUMP_DEV            },
  55         { "enable_audit",       ENV_ENABLE_AUDIT        },
  56         { "license",            ENV_LICENSE             },
  57         { "char_set",           ENV_CHAR_SET            },
  58         { "language",           ENV_LANGUAGE            },
  59         { "tty_dev",            ENV_TTY_DEV             },
  60         { NULL,                 0                       },
  61 };
  62 
  63 static int srm_env_proc_show(struct seq_file *m, void *v)
  64 {
  65         unsigned long   ret;
  66         unsigned long   id = (unsigned long)m->private;
  67         char            *page;
  68 
  69         page = (char *)__get_free_page(GFP_USER);
  70         if (!page)
  71                 return -ENOMEM;
  72 
  73         ret = callback_getenv(id, page, PAGE_SIZE);
  74 
  75         if ((ret >> 61) == 0) {
  76                 seq_write(m, page, ret);
  77                 ret = 0;
  78         } else
  79                 ret = -EFAULT;
  80         free_page((unsigned long)page);
  81         return ret;
  82 }
  83 
  84 static int srm_env_proc_open(struct inode *inode, struct file *file)
  85 {
  86         return single_open(file, srm_env_proc_show, PDE_DATA(inode));
  87 }
  88 
  89 static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer,
  90                                   size_t count, loff_t *pos)
  91 {
  92         int res;
  93         unsigned long   id = (unsigned long)PDE_DATA(file_inode(file));
  94         char            *buf = (char *) __get_free_page(GFP_USER);
  95         unsigned long   ret1, ret2;
  96 
  97         if (!buf)
  98                 return -ENOMEM;
  99 
 100         res = -EINVAL;
 101         if (count >= PAGE_SIZE)
 102                 goto out;
 103 
 104         res = -EFAULT;
 105         if (copy_from_user(buf, buffer, count))
 106                 goto out;
 107         buf[count] = '\0';
 108 
 109         ret1 = callback_setenv(id, buf, count);
 110         if ((ret1 >> 61) == 0) {
 111                 do
 112                         ret2 = callback_save_env();
 113                 while((ret2 >> 61) == 1);
 114                 res = (int) ret1;
 115         }
 116 
 117  out:
 118         free_page((unsigned long)buf);
 119         return res;
 120 }
 121 
 122 static const struct file_operations srm_env_proc_fops = {
 123         .owner          = THIS_MODULE,
 124         .open           = srm_env_proc_open,
 125         .read           = seq_read,
 126         .llseek         = seq_lseek,
 127         .release        = single_release,
 128         .write          = srm_env_proc_write,
 129 };
 130 
 131 static int __init
 132 srm_env_init(void)
 133 {
 134         srm_env_t       *entry;
 135         unsigned long   var_num;
 136 
 137         /*
 138          * Check system
 139          */
 140         if (!alpha_using_srm) {
 141                 printk(KERN_INFO "%s: This Alpha system doesn't "
 142                                 "know about SRM (or you've booted "
 143                                 "SRM->MILO->Linux, which gets "
 144                                 "misdetected)...\n", __func__);
 145                 return -ENODEV;
 146         }
 147 
 148         /*
 149          * Create base directory
 150          */
 151         base_dir = proc_mkdir(BASE_DIR, NULL);
 152         if (!base_dir) {
 153                 printk(KERN_ERR "Couldn't create base dir /proc/%s\n",
 154                                 BASE_DIR);
 155                 return -ENOMEM;
 156         }
 157 
 158         /*
 159          * Create per-name subdirectory
 160          */
 161         named_dir = proc_mkdir(NAMED_DIR, base_dir);
 162         if (!named_dir) {
 163                 printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n",
 164                                 BASE_DIR, NAMED_DIR);
 165                 goto cleanup;
 166         }
 167 
 168         /*
 169          * Create per-number subdirectory
 170          */
 171         numbered_dir = proc_mkdir(NUMBERED_DIR, base_dir);
 172         if (!numbered_dir) {
 173                 printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n",
 174                                 BASE_DIR, NUMBERED_DIR);
 175                 goto cleanup;
 176 
 177         }
 178 
 179         /*
 180          * Create all named nodes
 181          */
 182         entry = srm_named_entries;
 183         while (entry->name && entry->id) {
 184                 if (!proc_create_data(entry->name, 0644, named_dir,
 185                              &srm_env_proc_fops, (void *)entry->id))
 186                         goto cleanup;
 187                 entry++;
 188         }
 189 
 190         /*
 191          * Create all numbered nodes
 192          */
 193         for (var_num = 0; var_num <= 255; var_num++) {
 194                 char name[4];
 195                 sprintf(name, "%ld", var_num);
 196                 if (!proc_create_data(name, 0644, numbered_dir,
 197                              &srm_env_proc_fops, (void *)var_num))
 198                         goto cleanup;
 199         }
 200 
 201         printk(KERN_INFO "%s: version %s loaded successfully\n", NAME,
 202                         VERSION);
 203 
 204         return 0;
 205 
 206 cleanup:
 207         remove_proc_subtree(BASE_DIR, NULL);
 208         return -ENOMEM;
 209 }
 210 
 211 static void __exit
 212 srm_env_exit(void)
 213 {
 214         remove_proc_subtree(BASE_DIR, NULL);
 215         printk(KERN_INFO "%s: unloaded successfully\n", NAME);
 216 }
 217 
 218 module_init(srm_env_init);
 219 module_exit(srm_env_exit);

/* [<][>][^][v][top][bottom][index][help] */