Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.25 456 lines 11 kB view raw
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/mutex.h> 33#include <linux/uaccess.h> 34 35#include <asm/time.h> 36 37#include "sysctl.h" 38#include "ds1603.h" 39 40static DEFINE_MUTEX(lasat_info_mutex); 41 42/* Strategy function to write EEPROM after changing string entry */ 43int sysctl_lasatstring(ctl_table *table, int *name, int nlen, 44 void *oldval, size_t *oldlenp, 45 void *newval, size_t newlen) 46{ 47 int r; 48 49 mutex_lock(&lasat_info_mutex); 50 r = sysctl_string(table, name, 51 nlen, oldval, oldlenp, newval, newlen); 52 if (r < 0) { 53 mutex_unlock(&lasat_info_mutex); 54 return r; 55 } 56 if (newval && newlen) 57 lasat_write_eeprom_info(); 58 mutex_unlock(&lasat_info_mutex); 59 60 return 1; 61} 62 63 64/* And the same for proc */ 65int proc_dolasatstring(ctl_table *table, int write, struct file *filp, 66 void *buffer, size_t *lenp, loff_t *ppos) 67{ 68 int r; 69 70 mutex_lock(&lasat_info_mutex); 71 r = proc_dostring(table, write, filp, buffer, lenp, ppos); 72 if ((!write) || r) { 73 mutex_unlock(&lasat_info_mutex); 74 return r; 75 } 76 lasat_write_eeprom_info(); 77 mutex_unlock(&lasat_info_mutex); 78 79 return 0; 80} 81 82/* proc function to write EEPROM after changing int entry */ 83int proc_dolasatint(ctl_table *table, int write, struct file *filp, 84 void *buffer, size_t *lenp, loff_t *ppos) 85{ 86 int r; 87 88 mutex_lock(&lasat_info_mutex); 89 r = proc_dointvec(table, write, filp, buffer, lenp, ppos); 90 if ((!write) || r) { 91 mutex_unlock(&lasat_info_mutex); 92 return r; 93 } 94 lasat_write_eeprom_info(); 95 mutex_unlock(&lasat_info_mutex); 96 97 return 0; 98} 99 100static int rtctmp; 101 102#ifdef CONFIG_DS1603 103/* proc function to read/write RealTime Clock */ 104int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, 105 void *buffer, size_t *lenp, loff_t *ppos) 106{ 107 int r; 108 109 mutex_lock(&lasat_info_mutex); 110 if (!write) { 111 rtctmp = read_persistent_clock(); 112 /* check for time < 0 and set to 0 */ 113 if (rtctmp < 0) 114 rtctmp = 0; 115 } 116 r = proc_dointvec(table, write, filp, buffer, lenp, ppos); 117 if ((!write) || r) { 118 mutex_unlock(&lasat_info_mutex); 119 return r; 120 } 121 rtc_mips_set_mmss(rtctmp); 122 mutex_unlock(&lasat_info_mutex); 123 124 return 0; 125} 126#endif 127 128/* Sysctl for setting the IP addresses */ 129int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, 130 void *oldval, size_t *oldlenp, 131 void *newval, size_t newlen) 132{ 133 int r; 134 135 mutex_lock(&lasat_info_mutex); 136 r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); 137 if (r < 0) { 138 mutex_unlock(&lasat_info_mutex); 139 return r; 140 } 141 if (newval && newlen) 142 lasat_write_eeprom_info(); 143 mutex_unlock(&lasat_info_mutex); 144 145 return 1; 146} 147 148#ifdef CONFIG_DS1603 149/* Same for RTC */ 150int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, 151 void *oldval, size_t *oldlenp, 152 void *newval, size_t newlen) 153{ 154 int r; 155 156 mutex_lock(&lasat_info_mutex); 157 rtctmp = read_persistent_clock(); 158 if (rtctmp < 0) 159 rtctmp = 0; 160 r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); 161 if (r < 0) { 162 mutex_unlock(&lasat_info_mutex); 163 return r; 164 } 165 if (newval && newlen) 166 rtc_mips_set_mmss(rtctmp); 167 mutex_unlock(&lasat_info_mutex); 168 169 return 1; 170} 171#endif 172 173#ifdef CONFIG_INET 174static char lasat_bcastaddr[16]; 175 176void update_bcastaddr(void) 177{ 178 unsigned int ip; 179 180 ip = (lasat_board_info.li_eeprom_info.ipaddr & 181 lasat_board_info.li_eeprom_info.netmask) | 182 ~lasat_board_info.li_eeprom_info.netmask; 183 184 sprintf(lasat_bcastaddr, "%d.%d.%d.%d", 185 (ip) & 0xff, 186 (ip >> 8) & 0xff, 187 (ip >> 16) & 0xff, 188 (ip >> 24) & 0xff); 189} 190 191static char proc_lasat_ipbuf[32]; 192 193/* Parsing of IP address */ 194int proc_lasat_ip(ctl_table *table, int write, struct file *filp, 195 void *buffer, size_t *lenp, loff_t *ppos) 196{ 197 unsigned int ip; 198 char *p, c; 199 int len; 200 201 if (!table->data || !table->maxlen || !*lenp || 202 (*ppos && !write)) { 203 *lenp = 0; 204 return 0; 205 } 206 207 mutex_lock(&lasat_info_mutex); 208 if (write) { 209 len = 0; 210 p = buffer; 211 while (len < *lenp) { 212 if (get_user(c, p++)) { 213 mutex_unlock(&lasat_info_mutex); 214 return -EFAULT; 215 } 216 if (c == 0 || c == '\n') 217 break; 218 len++; 219 } 220 if (len >= sizeof(proc_lasat_ipbuf)-1) 221 len = sizeof(proc_lasat_ipbuf) - 1; 222 if (copy_from_user(proc_lasat_ipbuf, buffer, len)) { 223 mutex_unlock(&lasat_info_mutex); 224 return -EFAULT; 225 } 226 proc_lasat_ipbuf[len] = 0; 227 *ppos += *lenp; 228 /* Now see if we can convert it to a valid IP */ 229 ip = in_aton(proc_lasat_ipbuf); 230 *(unsigned int *)(table->data) = ip; 231 lasat_write_eeprom_info(); 232 } else { 233 ip = *(unsigned int *)(table->data); 234 sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d", 235 (ip) & 0xff, 236 (ip >> 8) & 0xff, 237 (ip >> 16) & 0xff, 238 (ip >> 24) & 0xff); 239 len = strlen(proc_lasat_ipbuf); 240 if (len > *lenp) 241 len = *lenp; 242 if (len) 243 if (copy_to_user(buffer, proc_lasat_ipbuf, len)) { 244 mutex_unlock(&lasat_info_mutex); 245 return -EFAULT; 246 } 247 if (len < *lenp) { 248 if (put_user('\n', ((char *) buffer) + len)) { 249 mutex_unlock(&lasat_info_mutex); 250 return -EFAULT; 251 } 252 len++; 253 } 254 *lenp = len; 255 *ppos += len; 256 } 257 update_bcastaddr(); 258 mutex_unlock(&lasat_info_mutex); 259 260 return 0; 261} 262#endif /* defined(CONFIG_INET) */ 263 264static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, 265 void *oldval, size_t *oldlenp, 266 void *newval, size_t newlen) 267{ 268 int r; 269 270 mutex_lock(&lasat_info_mutex); 271 r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); 272 if (r < 0) { 273 mutex_unlock(&lasat_info_mutex); 274 return r; 275 } 276 277 if (newval && newlen) { 278 if (name && *name == LASAT_PRID) 279 lasat_board_info.li_eeprom_info.prid = *(int *)newval; 280 281 lasat_write_eeprom_info(); 282 lasat_init_board_info(); 283 } 284 mutex_unlock(&lasat_info_mutex); 285 286 return 0; 287} 288 289int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, 290 void *buffer, size_t *lenp, loff_t *ppos) 291{ 292 int r; 293 294 mutex_lock(&lasat_info_mutex); 295 r = proc_dointvec(table, write, filp, buffer, lenp, ppos); 296 if ((!write) || r) { 297 mutex_unlock(&lasat_info_mutex); 298 return r; 299 } 300 if (filp && filp->f_path.dentry) { 301 if (!strcmp(filp->f_path.dentry->d_name.name, "prid")) 302 lasat_board_info.li_eeprom_info.prid = 303 lasat_board_info.li_prid; 304 if (!strcmp(filp->f_path.dentry->d_name.name, "debugaccess")) 305 lasat_board_info.li_eeprom_info.debugaccess = 306 lasat_board_info.li_debugaccess; 307 } 308 lasat_write_eeprom_info(); 309 mutex_unlock(&lasat_info_mutex); 310 311 return 0; 312} 313 314extern int lasat_boot_to_service; 315 316#ifdef CONFIG_SYSCTL 317 318static ctl_table lasat_table[] = { 319 { 320 .ctl_name = CTL_UNNUMBERED, 321 .procname = "cpu-hz", 322 .data = &lasat_board_info.li_cpu_hz, 323 .maxlen = sizeof(int), 324 .mode = 0444, 325 .proc_handler = &proc_dointvec, 326 .strategy = &sysctl_intvec 327 }, 328 { 329 .ctl_name = CTL_UNNUMBERED, 330 .procname = "bus-hz", 331 .data = &lasat_board_info.li_bus_hz, 332 .maxlen = sizeof(int), 333 .mode = 0444, 334 .proc_handler = &proc_dointvec, 335 .strategy = &sysctl_intvec 336 }, 337 { 338 .ctl_name = CTL_UNNUMBERED, 339 .procname = "bmid", 340 .data = &lasat_board_info.li_bmid, 341 .maxlen = sizeof(int), 342 .mode = 0444, 343 .proc_handler = &proc_dointvec, 344 .strategy = &sysctl_intvec 345 }, 346 { 347 .ctl_name = CTL_UNNUMBERED, 348 .procname = "prid", 349 .data = &lasat_board_info.li_prid, 350 .maxlen = sizeof(int), 351 .mode = 0644, 352 .proc_handler = &proc_lasat_eeprom_value, 353 .strategy = &sysctl_lasat_eeprom_value 354 }, 355#ifdef CONFIG_INET 356 { 357 .ctl_name = CTL_UNNUMBERED, 358 .procname = "ipaddr", 359 .data = &lasat_board_info.li_eeprom_info.ipaddr, 360 .maxlen = sizeof(int), 361 .mode = 0644, 362 .proc_handler = &proc_lasat_ip, 363 .strategy = &sysctl_lasat_intvec 364 }, 365 { 366 .ctl_name = LASAT_NETMASK, 367 .procname = "netmask", 368 .data = &lasat_board_info.li_eeprom_info.netmask, 369 .maxlen = sizeof(int), 370 .mode = 0644, 371 .proc_handler = &proc_lasat_ip, 372 .strategy = &sysctl_lasat_intvec 373 }, 374 { 375 .ctl_name = CTL_UNNUMBERED, 376 .procname = "bcastaddr", 377 .data = &lasat_bcastaddr, 378 .maxlen = sizeof(lasat_bcastaddr), 379 .mode = 0600, 380 .proc_handler = &proc_dostring, 381 .strategy = &sysctl_string 382 }, 383#endif 384 { 385 .ctl_name = CTL_UNNUMBERED, 386 .procname = "passwd_hash", 387 .data = &lasat_board_info.li_eeprom_info.passwd_hash, 388 .maxlen = 389 sizeof(lasat_board_info.li_eeprom_info.passwd_hash), 390 .mode = 0600, 391 .proc_handler = &proc_dolasatstring, 392 .strategy = &sysctl_lasatstring 393 }, 394 { 395 .ctl_name = CTL_UNNUMBERED, 396 .procname = "boot-service", 397 .data = &lasat_boot_to_service, 398 .maxlen = sizeof(int), 399 .mode = 0644, 400 .proc_handler = &proc_dointvec, 401 .strategy = &sysctl_intvec 402 }, 403#ifdef CONFIG_DS1603 404 { 405 .ctl_name = CTL_UNNUMBERED, 406 .procname = "rtc", 407 .data = &rtctmp, 408 .maxlen = sizeof(int), 409 .mode = 0644, 410 .proc_handler = &proc_dolasatrtc, 411 .strategy = &sysctl_lasat_rtc 412 }, 413#endif 414 { 415 .ctl_name = CTL_UNNUMBERED, 416 .procname = "namestr", 417 .data = &lasat_board_info.li_namestr, 418 .maxlen = sizeof(lasat_board_info.li_namestr), 419 .mode = 0444, 420 .proc_handler = &proc_dostring, 421 .strategy = &sysctl_string 422 }, 423 { 424 .ctl_name = CTL_UNNUMBERED, 425 .procname = "typestr", 426 .data = &lasat_board_info.li_typestr, 427 .maxlen = sizeof(lasat_board_info.li_typestr), 428 .mode = 0444, 429 .proc_handler = &proc_dostring, 430 .strategy = &sysctl_string 431 }, 432 {} 433}; 434 435static ctl_table lasat_root_table[] = { 436 { 437 .ctl_name = CTL_UNNUMBERED, 438 .procname = "lasat", 439 .mode = 0555, 440 .child = lasat_table 441 }, 442 {} 443}; 444 445static int __init lasat_register_sysctl(void) 446{ 447 struct ctl_table_header *lasat_table_header; 448 449 lasat_table_header = 450 register_sysctl_table(lasat_root_table); 451 452 return 0; 453} 454 455__initcall(lasat_register_sysctl); 456#endif /* CONFIG_SYSCTL */