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,
  42                void *oldval, size_t *oldlenp,
  43                void *newval, size_t newlen)
  44{
  45        int r;
  46
  47        r = sysctl_string(table, oldval, oldlenp, newval, newlen);
  48        if (r < 0)
  49                return r;
  50
  51        if (newval && newlen)
  52                lasat_write_eeprom_info();
  53
  54        return 0;
  55}
  56
  57
  58/* And the same for proc */
  59int proc_dolasatstring(ctl_table *table, int write,
  60                       void *buffer, size_t *lenp, loff_t *ppos)
  61{
  62        int r;
  63
  64        r = proc_dostring(table, write, buffer, lenp, ppos);
  65        if ((!write) || r)
  66                return r;
  67
  68        lasat_write_eeprom_info();
  69
  70        return 0;
  71}
  72
  73/* proc function to write EEPROM after changing int entry */
  74int proc_dolasatint(ctl_table *table, int write,
  75                       void *buffer, size_t *lenp, loff_t *ppos)
  76{
  77        int r;
  78
  79        r = proc_dointvec(table, write, buffer, lenp, ppos);
  80        if ((!write) || r)
  81                return r;
  82
  83        lasat_write_eeprom_info();
  84
  85        return 0;
  86}
  87
  88#ifdef CONFIG_DS1603
  89static int rtctmp;
  90
  91/* proc function to read/write RealTime Clock */
  92int proc_dolasatrtc(ctl_table *table, int write,
  93                       void *buffer, size_t *lenp, loff_t *ppos)
  94{
  95        struct timespec ts;
  96        int r;
  97
  98        if (!write) {
  99                read_persistent_clock(&ts);
 100                rtctmp = ts.tv_sec;
 101                /* check for time < 0 and set to 0 */
 102                if (rtctmp < 0)
 103                        rtctmp = 0;
 104        }
 105        r = proc_dointvec(table, write, buffer, lenp, ppos);
 106        if (r)
 107                return r;
 108
 109        if (write)
 110                rtc_mips_set_mmss(rtctmp);
 111
 112        return 0;
 113}
 114#endif
 115
 116/* Sysctl for setting the IP addresses */
 117int sysctl_lasat_intvec(ctl_table *table,
 118                    void *oldval, size_t *oldlenp,
 119                    void *newval, size_t newlen)
 120{
 121        int r;
 122
 123        r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
 124        if (r < 0)
 125                return r;
 126
 127        if (newval && newlen)
 128                lasat_write_eeprom_info();
 129
 130        return 0;
 131}
 132
 133#ifdef CONFIG_DS1603
 134/* Same for RTC */
 135int sysctl_lasat_rtc(ctl_table *table,
 136                    void *oldval, size_t *oldlenp,
 137                    void *newval, size_t newlen)
 138{
 139        struct timespec ts;
 140        int r;
 141
 142        read_persistent_clock(&ts);
 143        rtctmp = ts.tv_sec;
 144        if (rtctmp < 0)
 145                rtctmp = 0;
 146        r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
 147        if (r < 0)
 148                return r;
 149        if (newval && newlen)
 150                rtc_mips_set_mmss(rtctmp);
 151
 152        return r;
 153}
 154#endif
 155
 156#ifdef CONFIG_INET
 157int proc_lasat_ip(ctl_table *table, int write,
 158                       void *buffer, size_t *lenp, loff_t *ppos)
 159{
 160        unsigned int ip;
 161        char *p, c;
 162        int len;
 163        char ipbuf[32];
 164
 165        if (!table->data || !table->maxlen || !*lenp ||
 166            (*ppos && !write)) {
 167                *lenp = 0;
 168                return 0;
 169        }
 170
 171        if (write) {
 172                len = 0;
 173                p = buffer;
 174                while (len < *lenp) {
 175                        if (get_user(c, p++))
 176                                return -EFAULT;
 177                        if (c == 0 || c == '\n')
 178                                break;
 179                        len++;
 180                }
 181                if (len >= sizeof(ipbuf)-1)
 182                        len = sizeof(ipbuf) - 1;
 183                if (copy_from_user(ipbuf, buffer, len))
 184                        return -EFAULT;
 185                ipbuf[len] = 0;
 186                *ppos += *lenp;
 187                /* Now see if we can convert it to a valid IP */
 188                ip = in_aton(ipbuf);
 189                *(unsigned int *)(table->data) = ip;
 190                lasat_write_eeprom_info();
 191        } else {
 192                ip = *(unsigned int *)(table->data);
 193                sprintf(ipbuf, "%d.%d.%d.%d",
 194                        (ip)       & 0xff,
 195                        (ip >>  8) & 0xff,
 196                        (ip >> 16) & 0xff,
 197                        (ip >> 24) & 0xff);
 198                len = strlen(ipbuf);
 199                if (len > *lenp)
 200                        len = *lenp;
 201                if (len)
 202                        if (copy_to_user(buffer, ipbuf, len))
 203                                return -EFAULT;
 204                if (len < *lenp) {
 205                        if (put_user('\n', ((char *) buffer) + len))
 206                                return -EFAULT;
 207                        len++;
 208                }
 209                *lenp = len;
 210                *ppos += len;
 211        }
 212
 213        return 0;
 214}
 215#endif
 216
 217static int sysctl_lasat_prid(ctl_table *table,
 218                                     void *oldval, size_t *oldlenp,
 219                                     void *newval, size_t newlen)
 220{
 221        int r;
 222
 223        r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
 224        if (r < 0)
 225                return r;
 226        if (newval && newlen) {
 227                lasat_board_info.li_eeprom_info.prid = *(int *)newval;
 228                lasat_write_eeprom_info();
 229                lasat_init_board_info();
 230        }
 231        return 0;
 232}
 233
 234int proc_lasat_prid(ctl_table *table, int write,
 235                       void *buffer, size_t *lenp, loff_t *ppos)
 236{
 237        int r;
 238
 239        r = proc_dointvec(table, write, buffer, lenp, ppos);
 240        if (r < 0)
 241                return r;
 242        if (write) {
 243                lasat_board_info.li_eeprom_info.prid =
 244                        lasat_board_info.li_prid;
 245                lasat_write_eeprom_info();
 246                lasat_init_board_info();
 247        }
 248        return 0;
 249}
 250
 251extern int lasat_boot_to_service;
 252
 253static ctl_table lasat_table[] = {
 254        {
 255                .ctl_name       = CTL_UNNUMBERED,
 256                .procname       = "cpu-hz",
 257                .data           = &lasat_board_info.li_cpu_hz,
 258                .maxlen         = sizeof(int),
 259                .mode           = 0444,
 260                .proc_handler   = &proc_dointvec,
 261                .strategy       = &sysctl_intvec
 262        },
 263        {
 264                .ctl_name       = CTL_UNNUMBERED,
 265                .procname       = "bus-hz",
 266                .data           = &lasat_board_info.li_bus_hz,
 267                .maxlen         = sizeof(int),
 268                .mode           = 0444,
 269                .proc_handler   = &proc_dointvec,
 270                .strategy       = &sysctl_intvec
 271        },
 272        {
 273                .ctl_name       = CTL_UNNUMBERED,
 274                .procname       = "bmid",
 275                .data           = &lasat_board_info.li_bmid,
 276                .maxlen         = sizeof(int),
 277                .mode           = 0444,
 278                .proc_handler   = &proc_dointvec,
 279                .strategy       = &sysctl_intvec
 280        },
 281        {
 282                .ctl_name       = CTL_UNNUMBERED,
 283                .procname       = "prid",
 284                .data           = &lasat_board_info.li_prid,
 285                .maxlen         = sizeof(int),
 286                .mode           = 0644,
 287                .proc_handler   = &proc_lasat_prid,
 288                .strategy       = &sysctl_lasat_prid
 289        },
 290#ifdef CONFIG_INET
 291        {
 292                .ctl_name       = CTL_UNNUMBERED,
 293                .procname       = "ipaddr",
 294                .data           = &lasat_board_info.li_eeprom_info.ipaddr,
 295                .maxlen         = sizeof(int),
 296                .mode           = 0644,
 297                .proc_handler   = &proc_lasat_ip,
 298                .strategy       = &sysctl_lasat_intvec
 299        },
 300        {
 301                .ctl_name       = CTL_UNNUMBERED,
 302                .procname       = "netmask",
 303                .data           = &lasat_board_info.li_eeprom_info.netmask,
 304                .maxlen         = sizeof(int),
 305                .mode           = 0644,
 306                .proc_handler   = &proc_lasat_ip,
 307                .strategy       = &sysctl_lasat_intvec
 308        },
 309#endif
 310        {
 311                .ctl_name       = CTL_UNNUMBERED,
 312                .procname       = "passwd_hash",
 313                .data           = &lasat_board_info.li_eeprom_info.passwd_hash,
 314                .maxlen         =
 315                        sizeof(lasat_board_info.li_eeprom_info.passwd_hash),
 316                .mode           = 0600,
 317                .proc_handler   = &proc_dolasatstring,
 318                .strategy       = &sysctl_lasatstring
 319        },
 320        {
 321                .ctl_name       = CTL_UNNUMBERED,
 322                .procname       = "boot-service",
 323                .data           = &lasat_boot_to_service,
 324                .maxlen         = sizeof(int),
 325                .mode           = 0644,
 326                .proc_handler   = &proc_dointvec,
 327                .strategy       = &sysctl_intvec
 328        },
 329#ifdef CONFIG_DS1603
 330        {
 331                .ctl_name       = CTL_UNNUMBERED,
 332                .procname       = "rtc",
 333                .data           = &rtctmp,
 334                .maxlen         = sizeof(int),
 335                .mode           = 0644,
 336                .proc_handler   = &proc_dolasatrtc,
 337                .strategy       = &sysctl_lasat_rtc
 338        },
 339#endif
 340        {
 341                .ctl_name       = CTL_UNNUMBERED,
 342                .procname       = "namestr",
 343                .data           = &lasat_board_info.li_namestr,
 344                .maxlen         = sizeof(lasat_board_info.li_namestr),
 345                .mode           = 0444,
 346                .proc_handler   = &proc_dostring,
 347                .strategy       = &sysctl_string
 348        },
 349        {
 350                .ctl_name       = CTL_UNNUMBERED,
 351                .procname       = "typestr",
 352                .data           = &lasat_board_info.li_typestr,
 353                .maxlen         = sizeof(lasat_board_info.li_typestr),
 354                .mode           = 0444,
 355                .proc_handler   = &proc_dostring,
 356                .strategy       = &sysctl_string
 357        },
 358        {}
 359};
 360
 361static ctl_table lasat_root_table[] = {
 362        {
 363                .ctl_name       = CTL_UNNUMBERED,
 364                .procname       = "lasat",
 365                .mode           =  0555,
 366                .child          = lasat_table
 367        },
 368        {}
 369};
 370
 371static int __init lasat_register_sysctl(void)
 372{
 373        struct ctl_table_header *lasat_table_header;
 374
 375        lasat_table_header =
 376                register_sysctl_table(lasat_root_table);
 377        if (!lasat_table_header) {
 378                printk(KERN_ERR "Unable to register LASAT sysctl\n");
 379                return -ENOMEM;
 380        }
 381
 382        return 0;
 383}
 384
 385__initcall(lasat_register_sysctl);
 386