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