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 41/* And the same for proc */ 42int proc_dolasatstring(ctl_table *table, int write, 43 void *buffer, size_t *lenp, loff_t *ppos) 44{ 45 int r; 46 47 r = proc_dostring(table, write, buffer, lenp, ppos); 48 if ((!write) || r) 49 return r; 50 51 lasat_write_eeprom_info(); 52 53 return 0; 54} 55 56/* proc function to write EEPROM after changing int entry */ 57int proc_dolasatint(ctl_table *table, int write, 58 void *buffer, size_t *lenp, loff_t *ppos) 59{ 60 int r; 61 62 r = proc_dointvec(table, write, buffer, lenp, ppos); 63 if ((!write) || r) 64 return r; 65 66 lasat_write_eeprom_info(); 67 68 return 0; 69} 70 71#ifdef CONFIG_DS1603 72static int rtctmp; 73 74/* proc function to read/write RealTime Clock */ 75int proc_dolasatrtc(ctl_table *table, int write, 76 void *buffer, size_t *lenp, loff_t *ppos) 77{ 78 struct timespec ts; 79 int r; 80 81 if (!write) { 82 read_persistent_clock(&ts); 83 rtctmp = ts.tv_sec; 84 /* check for time < 0 and set to 0 */ 85 if (rtctmp < 0) 86 rtctmp = 0; 87 } 88 r = proc_dointvec(table, write, buffer, lenp, ppos); 89 if (r) 90 return r; 91 92 if (write) 93 rtc_mips_set_mmss(rtctmp); 94 95 return 0; 96} 97#endif 98 99#ifdef CONFIG_INET 100int proc_lasat_ip(ctl_table *table, int write, 101 void *buffer, size_t *lenp, loff_t *ppos) 102{ 103 unsigned int ip; 104 char *p, c; 105 int len; 106 char ipbuf[32]; 107 108 if (!table->data || !table->maxlen || !*lenp || 109 (*ppos && !write)) { 110 *lenp = 0; 111 return 0; 112 } 113 114 if (write) { 115 len = 0; 116 p = buffer; 117 while (len < *lenp) { 118 if (get_user(c, p++)) 119 return -EFAULT; 120 if (c == 0 || c == '\n') 121 break; 122 len++; 123 } 124 if (len >= sizeof(ipbuf)-1) 125 len = sizeof(ipbuf) - 1; 126 if (copy_from_user(ipbuf, buffer, len)) 127 return -EFAULT; 128 ipbuf[len] = 0; 129 *ppos += *lenp; 130 /* Now see if we can convert it to a valid IP */ 131 ip = in_aton(ipbuf); 132 *(unsigned int *)(table->data) = ip; 133 lasat_write_eeprom_info(); 134 } else { 135 ip = *(unsigned int *)(table->data); 136 sprintf(ipbuf, "%d.%d.%d.%d", 137 (ip) & 0xff, 138 (ip >> 8) & 0xff, 139 (ip >> 16) & 0xff, 140 (ip >> 24) & 0xff); 141 len = strlen(ipbuf); 142 if (len > *lenp) 143 len = *lenp; 144 if (len) 145 if (copy_to_user(buffer, ipbuf, len)) 146 return -EFAULT; 147 if (len < *lenp) { 148 if (put_user('\n', ((char *) buffer) + len)) 149 return -EFAULT; 150 len++; 151 } 152 *lenp = len; 153 *ppos += len; 154 } 155 156 return 0; 157} 158#endif 159 160int proc_lasat_prid(ctl_table *table, int write, 161 void *buffer, size_t *lenp, loff_t *ppos) 162{ 163 int r; 164 165 r = proc_dointvec(table, write, buffer, lenp, ppos); 166 if (r < 0) 167 return r; 168 if (write) { 169 lasat_board_info.li_eeprom_info.prid = 170 lasat_board_info.li_prid; 171 lasat_write_eeprom_info(); 172 lasat_init_board_info(); 173 } 174 return 0; 175} 176 177extern int lasat_boot_to_service; 178 179static ctl_table lasat_table[] = { 180 { 181 .procname = "cpu-hz", 182 .data = &lasat_board_info.li_cpu_hz, 183 .maxlen = sizeof(int), 184 .mode = 0444, 185 .proc_handler = proc_dointvec, 186 }, 187 { 188 .procname = "bus-hz", 189 .data = &lasat_board_info.li_bus_hz, 190 .maxlen = sizeof(int), 191 .mode = 0444, 192 .proc_handler = proc_dointvec, 193 }, 194 { 195 .procname = "bmid", 196 .data = &lasat_board_info.li_bmid, 197 .maxlen = sizeof(int), 198 .mode = 0444, 199 .proc_handler = proc_dointvec, 200 }, 201 { 202 .procname = "prid", 203 .data = &lasat_board_info.li_prid, 204 .maxlen = sizeof(int), 205 .mode = 0644, 206 .proc_handler = proc_lasat_prid, 207 }, 208#ifdef CONFIG_INET 209 { 210 .procname = "ipaddr", 211 .data = &lasat_board_info.li_eeprom_info.ipaddr, 212 .maxlen = sizeof(int), 213 .mode = 0644, 214 .proc_handler = proc_lasat_ip, 215 }, 216 { 217 .procname = "netmask", 218 .data = &lasat_board_info.li_eeprom_info.netmask, 219 .maxlen = sizeof(int), 220 .mode = 0644, 221 .proc_handler = proc_lasat_ip, 222 }, 223#endif 224 { 225 .procname = "passwd_hash", 226 .data = &lasat_board_info.li_eeprom_info.passwd_hash, 227 .maxlen = 228 sizeof(lasat_board_info.li_eeprom_info.passwd_hash), 229 .mode = 0600, 230 .proc_handler = proc_dolasatstring, 231 }, 232 { 233 .procname = "boot-service", 234 .data = &lasat_boot_to_service, 235 .maxlen = sizeof(int), 236 .mode = 0644, 237 .proc_handler = proc_dointvec, 238 }, 239#ifdef CONFIG_DS1603 240 { 241 .procname = "rtc", 242 .data = &rtctmp, 243 .maxlen = sizeof(int), 244 .mode = 0644, 245 .proc_handler = proc_dolasatrtc, 246 }, 247#endif 248 { 249 .procname = "namestr", 250 .data = &lasat_board_info.li_namestr, 251 .maxlen = sizeof(lasat_board_info.li_namestr), 252 .mode = 0444, 253 .proc_handler = proc_dostring, 254 }, 255 { 256 .procname = "typestr", 257 .data = &lasat_board_info.li_typestr, 258 .maxlen = sizeof(lasat_board_info.li_typestr), 259 .mode = 0444, 260 .proc_handler = proc_dostring, 261 }, 262 {} 263}; 264 265static ctl_table lasat_root_table[] = { 266 { 267 .procname = "lasat", 268 .mode = 0555, 269 .child = lasat_table 270 }, 271 {} 272}; 273 274static int __init lasat_register_sysctl(void) 275{ 276 struct ctl_table_header *lasat_table_header; 277 278 lasat_table_header = 279 register_sysctl_table(lasat_root_table); 280 if (!lasat_table_header) { 281 printk(KERN_ERR "Unable to register LASAT sysctl\n"); 282 return -ENOMEM; 283 } 284 285 return 0; 286} 287 288__initcall(lasat_register_sysctl); 289