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