sysctl: pass kernel pointers to ->proc_handler
[linux-block.git] / arch / mips / lasat / sysctl.c
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 */
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 */
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
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                         c = *p;
99                         p++;
100                         if (c == 0 || c == '\n')
101                                 break;
102                         len++;
103                 }
104                 if (len >= sizeof(ipbuf)-1)
105                         len = sizeof(ipbuf) - 1;
106                 memcpy(ipbuf, buffer, len);
107                 ipbuf[len] = 0;
108                 *ppos += *lenp;
109                 /* Now see if we can convert it to a valid IP */
110                 ip = in_aton(ipbuf);
111                 *(unsigned int *)(table->data) = ip;
112                 lasat_write_eeprom_info();
113         } else {
114                 ip = *(unsigned int *)(table->data);
115                 sprintf(ipbuf, "%d.%d.%d.%d",
116                         (ip)       & 0xff,
117                         (ip >>  8) & 0xff,
118                         (ip >> 16) & 0xff,
119                         (ip >> 24) & 0xff);
120                 len = strlen(ipbuf);
121                 if (len > *lenp)
122                         len = *lenp;
123                 if (len)
124                         memcpy(buffer, ipbuf, len);
125                 if (len < *lenp) {
126                         *((char *)buffer + len) = '\n';
127                         len++;
128                 }
129                 *lenp = len;
130                 *ppos += len;
131         }
132
133         return 0;
134 }
135 #endif
136
137 int proc_lasat_prid(struct ctl_table *table, int write,
138                        void *buffer, size_t *lenp, loff_t *ppos)
139 {
140         int r;
141
142         r = proc_dointvec(table, write, buffer, lenp, ppos);
143         if (r < 0)
144                 return r;
145         if (write) {
146                 lasat_board_info.li_eeprom_info.prid =
147                         lasat_board_info.li_prid;
148                 lasat_write_eeprom_info();
149                 lasat_init_board_info();
150         }
151         return 0;
152 }
153
154 extern int lasat_boot_to_service;
155
156 static struct ctl_table lasat_table[] = {
157         {
158                 .procname       = "cpu-hz",
159                 .data           = &lasat_board_info.li_cpu_hz,
160                 .maxlen         = sizeof(int),
161                 .mode           = 0444,
162                 .proc_handler   = proc_dointvec,
163         },
164         {
165                 .procname       = "bus-hz",
166                 .data           = &lasat_board_info.li_bus_hz,
167                 .maxlen         = sizeof(int),
168                 .mode           = 0444,
169                 .proc_handler   = proc_dointvec,
170         },
171         {
172                 .procname       = "bmid",
173                 .data           = &lasat_board_info.li_bmid,
174                 .maxlen         = sizeof(int),
175                 .mode           = 0444,
176                 .proc_handler   = proc_dointvec,
177         },
178         {
179                 .procname       = "prid",
180                 .data           = &lasat_board_info.li_prid,
181                 .maxlen         = sizeof(int),
182                 .mode           = 0644,
183                 .proc_handler   = proc_lasat_prid,
184         },
185 #ifdef CONFIG_INET
186         {
187                 .procname       = "ipaddr",
188                 .data           = &lasat_board_info.li_eeprom_info.ipaddr,
189                 .maxlen         = sizeof(int),
190                 .mode           = 0644,
191                 .proc_handler   = proc_lasat_ip,
192         },
193         {
194                 .procname       = "netmask",
195                 .data           = &lasat_board_info.li_eeprom_info.netmask,
196                 .maxlen         = sizeof(int),
197                 .mode           = 0644,
198                 .proc_handler   = proc_lasat_ip,
199         },
200 #endif
201         {
202                 .procname       = "passwd_hash",
203                 .data           = &lasat_board_info.li_eeprom_info.passwd_hash,
204                 .maxlen         =
205                         sizeof(lasat_board_info.li_eeprom_info.passwd_hash),
206                 .mode           = 0600,
207                 .proc_handler   = proc_dolasatstring,
208         },
209         {
210                 .procname       = "boot-service",
211                 .data           = &lasat_boot_to_service,
212                 .maxlen         = sizeof(int),
213                 .mode           = 0644,
214                 .proc_handler   = proc_dointvec,
215         },
216 #ifdef CONFIG_DS1603
217         {
218                 .procname       = "rtc",
219                 .data           = &rtctmp,
220                 .maxlen         = sizeof(int),
221                 .mode           = 0644,
222                 .proc_handler   = proc_dolasatrtc,
223         },
224 #endif
225         {
226                 .procname       = "namestr",
227                 .data           = &lasat_board_info.li_namestr,
228                 .maxlen         = sizeof(lasat_board_info.li_namestr),
229                 .mode           = 0444,
230                 .proc_handler   = proc_dostring,
231         },
232         {
233                 .procname       = "typestr",
234                 .data           = &lasat_board_info.li_typestr,
235                 .maxlen         = sizeof(lasat_board_info.li_typestr),
236                 .mode           = 0444,
237                 .proc_handler   = proc_dostring,
238         },
239         {}
240 };
241
242 static struct ctl_table lasat_root_table[] = {
243         {
244                 .procname       = "lasat",
245                 .mode           =  0555,
246                 .child          = lasat_table
247         },
248         {}
249 };
250
251 static int __init lasat_register_sysctl(void)
252 {
253         struct ctl_table_header *lasat_table_header;
254
255         lasat_table_header =
256                 register_sysctl_table(lasat_root_table);
257         if (!lasat_table_header) {
258                 printk(KERN_ERR "Unable to register LASAT sysctl\n");
259                 return -ENOMEM;
260         }
261
262         return 0;
263 }
264
265 arch_initcall(lasat_register_sysctl);