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