linux/arch/mips/lasat/sysctl.c
<<
>>
Prefs
   1/*
   2 * Thomas Horsten <thh@lasat.com>
   3 * Copyright (C) 2000 LASAT Networks A/S.
   4 *
   5 *  This program is free software; you can distribute it and/or modify it
   6 *  under the terms of the GNU General Public License (Version 2) as
   7 *  published by the Free Software Foundation.
   8 *
   9 *  This program is distributed in the hope it will be useful, but WITHOUT
  10 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12 *  for more details.
  13 *
  14 *  You should have received a copy of the GNU General Public License along
  15 *  with this program; if not, write to the Free Software Foundation, Inc.,
  16 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  17 *
  18 * Routines specific to the LASAT boards
  19 */
  20#include <linux/types.h>
  21#include <asm/lasat/lasat.h>
  22
  23#include <linux/module.h>
  24#include <linux/sysctl.h>
  25#include <linux/stddef.h>
  26#include <linux/init.h>
  27#include <linux/fs.h>
  28#include <linux/ctype.h>
  29#include <linux/string.h>
  30#include <linux/net.h>
  31#include <linux/inet.h>
  32#include <linux/uaccess.h>
  33
  34#include <asm/time.h>
  35
  36#ifdef CONFIG_DS1603
  37#include "ds1603.h"
  38#endif
  39
  40/* Strategy function to write EEPROM after changing string entry */
  41int sysctl_lasatstring(ctl_table *table, int *name, int nlen,
  42                void *oldval, size_t *oldlenp,
  43                void *newval, size_t newlen)
  44{
  45        int r;
  46
  47        r = sysctl_string(table, name,
  48                          nlen, oldval, oldlenp, newval, newlen);
  49        if (r < 0)
  50                return r;
  51
  52        if (newval && newlen)
  53                lasat_write_eeprom_info();
  54
  55        return 0;
  56}
  57
  58
  59/* And the same for proc */
  60int proc_dolasatstring(ctl_table *table, int write, struct file *filp,
  61                       void *buffer, size_t *lenp, loff_t *ppos)
  62{
  63        int r;
  64
  65        r = proc_dostring(table, write, filp, buffer, lenp, ppos);
  66        if ((!write) || r)
  67                return r;
  68
  69        lasat_write_eeprom_info();
  70
  71        return 0;
  72}
  73
  74/* proc function to write EEPROM after changing int entry */
  75int proc_dolasatint(ctl_table *table, int write, struct file *filp,
  76                       void *buffer, size_t *lenp, loff_t *ppos)
  77{
  78        int r;
  79
  80        r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
  81        if ((!write) || r)
  82                return r;
  83
  84        lasat_write_eeprom_info();
  85
  86        return 0;
  87}
  88
  89#ifdef CONFIG_DS1603
  90static int rtctmp;
  91
  92/* proc function to read/write RealTime Clock */
  93int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
  94                       void *buffer, size_t *lenp, loff_t *ppos)
  95{
  96        int r;
  97
  98        if (!write) {
  99                rtctmp = read_persistent_clock();
 100                /* check for time < 0 and set to 0 */
 101                if (rtctmp < 0)
 102                        rtctmp = 0;
 103        }
 104        r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
 105        if (r)
 106                return r;
 107
 108        if (write)
 109                rtc_mips_set_mmss(rtctmp);
 110
 111        return 0;
 112}
 113#endif
 114
 115/* Sysctl for setting the IP addresses */
 116int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen,
 117                    void *oldval, size_t *oldlenp,
 118                    void *newval, size_t newlen)
 119{
 120        int r;
 121
 122        r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
 123        if (r < 0)
 124                return r;
 125
 126        if (newval && newlen)
 127                lasat_write_eeprom_info();
 128
 129        return 0;
 130}
 131
 132#ifdef CONFIG_DS1603
 133/* Same for RTC */
 134int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen,
 135                    void *oldval, size_t *oldlenp,
 136                    void *newval, size_t newlen)
 137{
 138        int r;
 139
 140        rtctmp = read_persistent_clock();
 141        if (rtctmp < 0)
 142                rtctmp = 0;
 143        r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
 144        if (r < 0)
 145                return r;
 146        if (newval && newlen)
 147                rtc_mips_set_mmss(rtctmp);
 148
 149        return r;
 150}
 151#endif
 152
 153#ifdef CONFIG_INET
 154int proc_lasat_ip(ctl_table *table, int write, struct file *filp,
 155                       void *buffer, size_t *lenp, loff_t *ppos)
 156{
 157        unsigned int ip;
 158        char *p, c;
 159        int len;
 160        char ipbuf[32];
 161
 162        if (!table->data || !table->maxlen || !*lenp ||
 163            (*ppos && !write)) {
 164                *lenp = 0;
 165                return 0;
 166        }
 167
 168        if (write) {
 169                len = 0;
 170                p = buffer;
 171                while (len < *lenp) {
 172                        if (get_user(c, p++))
 173                                return -EFAULT;
 174                        if (c == 0 || c == '\n')
 175                                break;
 176                        len++;
 177                }
 178                if (len >= sizeof(ipbuf)-1)
 179                        len = sizeof(ipbuf) - 1;
 180                if (copy_from_user(ipbuf, buffer, len))
 181                        return -EFAULT;
 182                ipbuf[len] = 0;
 183                *ppos += *lenp;
 184                /* Now see if we can convert it to a valid IP */
 185                ip = in_aton(ipbuf);
 186                *(unsigned int *)(table->data) = ip;
 187                lasat_write_eeprom_info();
 188        } else {
 189                ip = *(unsigned int *)(table->data);
 190                sprintf(ipbuf, "%d.%d.%d.%d",
 191                        (ip)       & 0xff,
 192                        (ip >>  8) & 0xff,
 193                        (ip >> 16) & 0xff,
 194                        (ip >> 24) & 0xff);
 195                len = strlen(ipbuf);
 196                if (len > *lenp)
 197                        len = *lenp;
 198                if (len)
 199                        if (copy_to_user(buffer, ipbuf, len))
 200                                return -EFAULT;
 201                if (len < *lenp) {
 202                        if (put_user('\n', ((char *) buffer) + len))
 203                                return -EFAULT;
 204                        len++;
 205                }
 206                *lenp = len;
 207                *ppos += len;
 208        }
 209
 210        return 0;
 211}
 212#endif
 213
 214static int sysctl_lasat_prid(ctl_table *table, int *name, int nlen,
 215                                     void *oldval, size_t *oldlenp,
 216                                     void *newval, size_t newlen)
 217{
 218        int r;
 219
 220        r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
 221        if (r < 0)
 222                return r;
 223        if (newval && newlen) {
 224                lasat_board_info.li_eeprom_info.prid = *(int *)newval;
 225                lasat_write_eeprom_info();
 226                lasat_init_board_info();
 227        }
 228        return 0;
 229}
 230
 231int proc_lasat_prid(ctl_table *table, int write, struct file *filp,
 232                       void *buffer, size_t *lenp, loff_t *ppos)
 233{
 234        int r;
 235
 236        r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
 237        if (r < 0)
 238                return r;
 239        if (write) {
 240                lasat_board_info.li_eeprom_info.prid =
 241                        lasat_board_info.li_prid;
 242                lasat_write_eeprom_info();
 243                lasat_init_board_info();
 244        }
 245        return 0;
 246}
 247
 248extern int lasat_boot_to_service;
 249
 250static ctl_table lasat_table[] = {
 251        {
 252                .ctl_name       = CTL_UNNUMBERED,
 253                .procname       = "cpu-hz",
 254                .data           = &lasat_board_info.li_cpu_hz,
 255                .maxlen         = sizeof(int),
 256                .mode           = 0444,
 257                .proc_handler   = &proc_dointvec,
 258                .strategy       = &sysctl_intvec
 259        },
 260        {
 261                .ctl_name       = CTL_UNNUMBERED,
 262                .procname       = "bus-hz",
 263                .data           = &lasat_board_info.li_bus_hz,
 264                .maxlen         = sizeof(int),
 265                .mode           = 0444,
 266                .proc_handler   = &proc_dointvec,
 267                .strategy       = &sysctl_intvec
 268        },
 269        {
 270                .ctl_name       = CTL_UNNUMBERED,
 271                .procname       = "bmid",
 272                .data           = &lasat_board_info.li_bmid,
 273                .maxlen         = sizeof(int),
 274                .mode           = 0444,
 275                .proc_handler   = &proc_dointvec,
 276                .strategy       = &sysctl_intvec
 277        },
 278        {
 279                .ctl_name       = CTL_UNNUMBERED,
 280                .procname       = "prid",
 281                .data           = &lasat_board_info.li_prid,
 282                .maxlen         = sizeof(int),
 283                .mode           = 0644,
 284                .proc_handler   = &proc_lasat_prid,
 285                .strategy       = &sysctl_lasat_prid
 286        },
 287#ifdef CONFIG_INET
 288        {
 289                .ctl_name       = CTL_UNNUMBERED,
 290                .procname       = "ipaddr",
 291                .data           = &lasat_board_info.li_eeprom_info.ipaddr,
 292                .maxlen         = sizeof(int),
 293                .mode           = 0644,
 294                .proc_handler   = &proc_lasat_ip,
 295                .strategy       = &sysctl_lasat_intvec
 296        },
 297        {
 298                .ctl_name       = CTL_UNNUMBERED,
 299                .procname       = "netmask",
 300                .data           = &lasat_board_info.li_eeprom_info.netmask,
 301                .maxlen         = sizeof(int),
 302                .mode           = 0644,
 303                .proc_handler   = &proc_lasat_ip,
 304                .strategy       = &sysctl_lasat_intvec
 305        },
 306#endif
 307        {
 308                .ctl_name       = CTL_UNNUMBERED,
 309                .procname       = "passwd_hash",
 310                .data           = &lasat_board_info.li_eeprom_info.passwd_hash,
 311                .maxlen         =
 312                        sizeof(lasat_board_info.li_eeprom_info.passwd_hash),
 313                .mode           = 0600,
 314                .proc_handler   = &proc_dolasatstring,
 315                .strategy       = &sysctl_lasatstring
 316        },
 317        {
 318                .ctl_name       = CTL_UNNUMBERED,
 319                .procname       = "boot-service",
 320                .data           = &lasat_boot_to_service,
 321                .maxlen         = sizeof(int),
 322                .mode           = 0644,
 323                .proc_handler   = &proc_dointvec,
 324                .strategy       = &sysctl_intvec
 325        },
 326#ifdef CONFIG_DS1603
 327        {
 328                .ctl_name       = CTL_UNNUMBERED,
 329                .procname       = "rtc",
 330                .data           = &rtctmp,
 331                .maxlen         = sizeof(int),
 332                .mode           = 0644,
 333                .proc_handler   = &proc_dolasatrtc,
 334                .strategy       = &sysctl_lasat_rtc
 335        },
 336#endif
 337        {
 338                .ctl_name       = CTL_UNNUMBERED,
 339                .procname       = "namestr",
 340                .data           = &lasat_board_info.li_namestr,
 341                .maxlen         = sizeof(lasat_board_info.li_namestr),
 342                .mode           = 0444,
 343                .proc_handler   = &proc_dostring,
 344                .strategy       = &sysctl_string
 345        },
 346        {
 347                .ctl_name       = CTL_UNNUMBERED,
 348                .procname       = "typestr",
 349                .data           = &lasat_board_info.li_typestr,
 350                .maxlen         = sizeof(lasat_board_info.li_typestr),
 351                .mode           = 0444,
 352                .proc_handler   = &proc_dostring,
 353                .strategy       = &sysctl_string
 354        },
 355        {}
 356};
 357
 358static ctl_table lasat_root_table[] = {
 359        {
 360                .ctl_name       = CTL_UNNUMBERED,
 361                .procname       = "lasat",
 362                .mode           =  0555,
 363                .child          = lasat_table
 364        },
 365        {}
 366};
 367
 368static int __init lasat_register_sysctl(void)
 369{
 370        struct ctl_table_header *lasat_table_header;
 371
 372        lasat_table_header =
 373                register_sysctl_table(lasat_root_table);
 374        if (!lasat_table_header) {
 375                printk(KERN_ERR "Unable to register LASAT sysctl\n");
 376                return -ENOMEM;
 377        }
 378
 379        return 0;
 380}
 381
 382__initcall(lasat_register_sysctl);
 383