diff options
author | Thomas Horsten <thomas@horsten.com> | 2008-06-14 21:17:11 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-06-16 10:14:48 -0400 |
commit | 1f34f2e4262bae8a1aa6d8fd6306b07074d33718 (patch) | |
tree | e1162a346238af0444846ea4cded8d0a4cb04322 /arch/mips/lasat/sysctl.c | |
parent | c9c5023d83df5dc7d58830a63fd0e082120f00e3 (diff) |
[MIPS] Lasat: sysctl fixup
LASAT's sysctl interface was broken, it failed a check during boot because
a single entry had a sysctl number and the rest were unnumbered. When I
fixed it I noticed that the whole sysctl file needed a spring clean, it was
using mutexes where it wasn't needed (it's only needed to protect during
writes to the EEPROM), so I moved that stuff out and generally cleaned the
whole thing up.
So now, LASAT's sysctl/proc interface is working again.
Signed-off-by: Thomas Horsten <thomas@horsten.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/lasat/sysctl.c')
-rw-r--r-- | arch/mips/lasat/sysctl.c | 172 |
1 files changed, 49 insertions, 123 deletions
diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c index 389336c4ecc5..866881ec0cf8 100644 --- a/arch/mips/lasat/sysctl.c +++ b/arch/mips/lasat/sysctl.c | |||
@@ -29,15 +29,13 @@ | |||
29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
30 | #include <linux/net.h> | 30 | #include <linux/net.h> |
31 | #include <linux/inet.h> | 31 | #include <linux/inet.h> |
32 | #include <linux/mutex.h> | ||
33 | #include <linux/uaccess.h> | 32 | #include <linux/uaccess.h> |
34 | 33 | ||
35 | #include <asm/time.h> | 34 | #include <asm/time.h> |
36 | 35 | ||
37 | #include "sysctl.h" | 36 | #ifdef CONFIG_DS1603 |
38 | #include "ds1603.h" | 37 | #include "ds1603.h" |
39 | 38 | #endif | |
40 | static DEFINE_MUTEX(lasat_info_mutex); | ||
41 | 39 | ||
42 | /* Strategy function to write EEPROM after changing string entry */ | 40 | /* Strategy function to write EEPROM after changing string entry */ |
43 | int sysctl_lasatstring(ctl_table *table, int *name, int nlen, | 41 | int sysctl_lasatstring(ctl_table *table, int *name, int nlen, |
@@ -46,18 +44,15 @@ int sysctl_lasatstring(ctl_table *table, int *name, int nlen, | |||
46 | { | 44 | { |
47 | int r; | 45 | int r; |
48 | 46 | ||
49 | mutex_lock(&lasat_info_mutex); | ||
50 | r = sysctl_string(table, name, | 47 | r = sysctl_string(table, name, |
51 | nlen, oldval, oldlenp, newval, newlen); | 48 | nlen, oldval, oldlenp, newval, newlen); |
52 | if (r < 0) { | 49 | if (r < 0) |
53 | mutex_unlock(&lasat_info_mutex); | ||
54 | return r; | 50 | return r; |
55 | } | 51 | |
56 | if (newval && newlen) | 52 | if (newval && newlen) |
57 | lasat_write_eeprom_info(); | 53 | lasat_write_eeprom_info(); |
58 | mutex_unlock(&lasat_info_mutex); | ||
59 | 54 | ||
60 | return 1; | 55 | return 0; |
61 | } | 56 | } |
62 | 57 | ||
63 | 58 | ||
@@ -67,14 +62,11 @@ int proc_dolasatstring(ctl_table *table, int write, struct file *filp, | |||
67 | { | 62 | { |
68 | int r; | 63 | int r; |
69 | 64 | ||
70 | mutex_lock(&lasat_info_mutex); | ||
71 | r = proc_dostring(table, write, filp, buffer, lenp, ppos); | 65 | r = proc_dostring(table, write, filp, buffer, lenp, ppos); |
72 | if ((!write) || r) { | 66 | if ((!write) || r) |
73 | mutex_unlock(&lasat_info_mutex); | ||
74 | return r; | 67 | return r; |
75 | } | 68 | |
76 | lasat_write_eeprom_info(); | 69 | lasat_write_eeprom_info(); |
77 | mutex_unlock(&lasat_info_mutex); | ||
78 | 70 | ||
79 | return 0; | 71 | return 0; |
80 | } | 72 | } |
@@ -85,28 +77,24 @@ int proc_dolasatint(ctl_table *table, int write, struct file *filp, | |||
85 | { | 77 | { |
86 | int r; | 78 | int r; |
87 | 79 | ||
88 | mutex_lock(&lasat_info_mutex); | ||
89 | r = proc_dointvec(table, write, filp, buffer, lenp, ppos); | 80 | r = proc_dointvec(table, write, filp, buffer, lenp, ppos); |
90 | if ((!write) || r) { | 81 | if ((!write) || r) |
91 | mutex_unlock(&lasat_info_mutex); | ||
92 | return r; | 82 | return r; |
93 | } | 83 | |
94 | lasat_write_eeprom_info(); | 84 | lasat_write_eeprom_info(); |
95 | mutex_unlock(&lasat_info_mutex); | ||
96 | 85 | ||
97 | return 0; | 86 | return 0; |
98 | } | 87 | } |
99 | 88 | ||
89 | #ifdef CONFIG_DS1603 | ||
100 | static int rtctmp; | 90 | static int rtctmp; |
101 | 91 | ||
102 | #ifdef CONFIG_DS1603 | ||
103 | /* proc function to read/write RealTime Clock */ | 92 | /* proc function to read/write RealTime Clock */ |
104 | int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, | 93 | int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, |
105 | void *buffer, size_t *lenp, loff_t *ppos) | 94 | void *buffer, size_t *lenp, loff_t *ppos) |
106 | { | 95 | { |
107 | int r; | 96 | int r; |
108 | 97 | ||
109 | mutex_lock(&lasat_info_mutex); | ||
110 | if (!write) { | 98 | if (!write) { |
111 | rtctmp = read_persistent_clock(); | 99 | rtctmp = read_persistent_clock(); |
112 | /* check for time < 0 and set to 0 */ | 100 | /* check for time < 0 and set to 0 */ |
@@ -114,12 +102,11 @@ int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, | |||
114 | rtctmp = 0; | 102 | rtctmp = 0; |
115 | } | 103 | } |
116 | r = proc_dointvec(table, write, filp, buffer, lenp, ppos); | 104 | r = proc_dointvec(table, write, filp, buffer, lenp, ppos); |
117 | if ((!write) || r) { | 105 | if (r) |
118 | mutex_unlock(&lasat_info_mutex); | ||
119 | return r; | 106 | return r; |
120 | } | 107 | |
121 | rtc_mips_set_mmss(rtctmp); | 108 | if (write) |
122 | mutex_unlock(&lasat_info_mutex); | 109 | rtc_mips_set_mmss(rtctmp); |
123 | 110 | ||
124 | return 0; | 111 | return 0; |
125 | } | 112 | } |
@@ -132,17 +119,14 @@ int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, | |||
132 | { | 119 | { |
133 | int r; | 120 | int r; |
134 | 121 | ||
135 | mutex_lock(&lasat_info_mutex); | ||
136 | r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); | 122 | r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); |
137 | if (r < 0) { | 123 | if (r < 0) |
138 | mutex_unlock(&lasat_info_mutex); | ||
139 | return r; | 124 | return r; |
140 | } | 125 | |
141 | if (newval && newlen) | 126 | if (newval && newlen) |
142 | lasat_write_eeprom_info(); | 127 | lasat_write_eeprom_info(); |
143 | mutex_unlock(&lasat_info_mutex); | ||
144 | 128 | ||
145 | return 1; | 129 | return 0; |
146 | } | 130 | } |
147 | 131 | ||
148 | #ifdef CONFIG_DS1603 | 132 | #ifdef CONFIG_DS1603 |
@@ -153,50 +137,27 @@ int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, | |||
153 | { | 137 | { |
154 | int r; | 138 | int r; |
155 | 139 | ||
156 | mutex_lock(&lasat_info_mutex); | ||
157 | rtctmp = read_persistent_clock(); | 140 | rtctmp = read_persistent_clock(); |
158 | if (rtctmp < 0) | 141 | if (rtctmp < 0) |
159 | rtctmp = 0; | 142 | rtctmp = 0; |
160 | r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); | 143 | r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); |
161 | if (r < 0) { | 144 | if (r < 0) |
162 | mutex_unlock(&lasat_info_mutex); | ||
163 | return r; | 145 | return r; |
164 | } | ||
165 | if (newval && newlen) | 146 | if (newval && newlen) |
166 | rtc_mips_set_mmss(rtctmp); | 147 | rtc_mips_set_mmss(rtctmp); |
167 | mutex_unlock(&lasat_info_mutex); | ||
168 | 148 | ||
169 | return 1; | 149 | return r; |
170 | } | 150 | } |
171 | #endif | 151 | #endif |
172 | 152 | ||
173 | #ifdef CONFIG_INET | 153 | #ifdef CONFIG_INET |
174 | static char lasat_bcastaddr[16]; | ||
175 | |||
176 | void 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 | |||
191 | static char proc_lasat_ipbuf[32]; | ||
192 | |||
193 | /* Parsing of IP address */ | ||
194 | int proc_lasat_ip(ctl_table *table, int write, struct file *filp, | 154 | int proc_lasat_ip(ctl_table *table, int write, struct file *filp, |
195 | void *buffer, size_t *lenp, loff_t *ppos) | 155 | void *buffer, size_t *lenp, loff_t *ppos) |
196 | { | 156 | { |
197 | unsigned int ip; | 157 | unsigned int ip; |
198 | char *p, c; | 158 | char *p, c; |
199 | int len; | 159 | int len; |
160 | char ipbuf[32]; | ||
200 | 161 | ||
201 | if (!table->data || !table->maxlen || !*lenp || | 162 | if (!table->data || !table->maxlen || !*lenp || |
202 | (*ppos && !write)) { | 163 | (*ppos && !write)) { |
@@ -204,117 +165,88 @@ int proc_lasat_ip(ctl_table *table, int write, struct file *filp, | |||
204 | return 0; | 165 | return 0; |
205 | } | 166 | } |
206 | 167 | ||
207 | mutex_lock(&lasat_info_mutex); | ||
208 | if (write) { | 168 | if (write) { |
209 | len = 0; | 169 | len = 0; |
210 | p = buffer; | 170 | p = buffer; |
211 | while (len < *lenp) { | 171 | while (len < *lenp) { |
212 | if (get_user(c, p++)) { | 172 | if (get_user(c, p++)) |
213 | mutex_unlock(&lasat_info_mutex); | ||
214 | return -EFAULT; | 173 | return -EFAULT; |
215 | } | ||
216 | if (c == 0 || c == '\n') | 174 | if (c == 0 || c == '\n') |
217 | break; | 175 | break; |
218 | len++; | 176 | len++; |
219 | } | 177 | } |
220 | if (len >= sizeof(proc_lasat_ipbuf)-1) | 178 | if (len >= sizeof(ipbuf)-1) |
221 | len = sizeof(proc_lasat_ipbuf) - 1; | 179 | len = sizeof(ipbuf) - 1; |
222 | if (copy_from_user(proc_lasat_ipbuf, buffer, len)) { | 180 | if (copy_from_user(ipbuf, buffer, len)) |
223 | mutex_unlock(&lasat_info_mutex); | ||
224 | return -EFAULT; | 181 | return -EFAULT; |
225 | } | 182 | ipbuf[len] = 0; |
226 | proc_lasat_ipbuf[len] = 0; | ||
227 | *ppos += *lenp; | 183 | *ppos += *lenp; |
228 | /* Now see if we can convert it to a valid IP */ | 184 | /* Now see if we can convert it to a valid IP */ |
229 | ip = in_aton(proc_lasat_ipbuf); | 185 | ip = in_aton(ipbuf); |
230 | *(unsigned int *)(table->data) = ip; | 186 | *(unsigned int *)(table->data) = ip; |
231 | lasat_write_eeprom_info(); | 187 | lasat_write_eeprom_info(); |
232 | } else { | 188 | } else { |
233 | ip = *(unsigned int *)(table->data); | 189 | ip = *(unsigned int *)(table->data); |
234 | sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d", | 190 | sprintf(ipbuf, "%d.%d.%d.%d", |
235 | (ip) & 0xff, | 191 | (ip) & 0xff, |
236 | (ip >> 8) & 0xff, | 192 | (ip >> 8) & 0xff, |
237 | (ip >> 16) & 0xff, | 193 | (ip >> 16) & 0xff, |
238 | (ip >> 24) & 0xff); | 194 | (ip >> 24) & 0xff); |
239 | len = strlen(proc_lasat_ipbuf); | 195 | len = strlen(ipbuf); |
240 | if (len > *lenp) | 196 | if (len > *lenp) |
241 | len = *lenp; | 197 | len = *lenp; |
242 | if (len) | 198 | if (len) |
243 | if (copy_to_user(buffer, proc_lasat_ipbuf, len)) { | 199 | if (copy_to_user(buffer, ipbuf, len)) |
244 | mutex_unlock(&lasat_info_mutex); | ||
245 | return -EFAULT; | 200 | return -EFAULT; |
246 | } | ||
247 | if (len < *lenp) { | 201 | if (len < *lenp) { |
248 | if (put_user('\n', ((char *) buffer) + len)) { | 202 | if (put_user('\n', ((char *) buffer) + len)) |
249 | mutex_unlock(&lasat_info_mutex); | ||
250 | return -EFAULT; | 203 | return -EFAULT; |
251 | } | ||
252 | len++; | 204 | len++; |
253 | } | 205 | } |
254 | *lenp = len; | 206 | *lenp = len; |
255 | *ppos += len; | 207 | *ppos += len; |
256 | } | 208 | } |
257 | update_bcastaddr(); | ||
258 | mutex_unlock(&lasat_info_mutex); | ||
259 | 209 | ||
260 | return 0; | 210 | return 0; |
261 | } | 211 | } |
262 | #endif /* defined(CONFIG_INET) */ | 212 | #endif |
263 | 213 | ||
264 | static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, | 214 | static int sysctl_lasat_prid(ctl_table *table, int *name, int nlen, |
265 | void *oldval, size_t *oldlenp, | 215 | void *oldval, size_t *oldlenp, |
266 | void *newval, size_t newlen) | 216 | void *newval, size_t newlen) |
267 | { | 217 | { |
268 | int r; | 218 | int r; |
269 | 219 | ||
270 | mutex_lock(&lasat_info_mutex); | ||
271 | r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); | 220 | r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); |
272 | if (r < 0) { | 221 | if (r < 0) |
273 | mutex_unlock(&lasat_info_mutex); | ||
274 | return r; | 222 | return r; |
275 | } | ||
276 | |||
277 | if (newval && newlen) { | 223 | if (newval && newlen) { |
278 | if (name && *name == LASAT_PRID) | 224 | lasat_board_info.li_eeprom_info.prid = *(int *)newval; |
279 | lasat_board_info.li_eeprom_info.prid = *(int *)newval; | ||
280 | |||
281 | lasat_write_eeprom_info(); | 225 | lasat_write_eeprom_info(); |
282 | lasat_init_board_info(); | 226 | lasat_init_board_info(); |
283 | } | 227 | } |
284 | mutex_unlock(&lasat_info_mutex); | ||
285 | |||
286 | return 0; | 228 | return 0; |
287 | } | 229 | } |
288 | 230 | ||
289 | int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, | 231 | int proc_lasat_prid(ctl_table *table, int write, struct file *filp, |
290 | void *buffer, size_t *lenp, loff_t *ppos) | 232 | void *buffer, size_t *lenp, loff_t *ppos) |
291 | { | 233 | { |
292 | int r; | 234 | int r; |
293 | 235 | ||
294 | mutex_lock(&lasat_info_mutex); | ||
295 | r = proc_dointvec(table, write, filp, buffer, lenp, ppos); | 236 | r = proc_dointvec(table, write, filp, buffer, lenp, ppos); |
296 | if ((!write) || r) { | 237 | if (r < 0) |
297 | mutex_unlock(&lasat_info_mutex); | ||
298 | return r; | 238 | return r; |
239 | if (write) { | ||
240 | lasat_board_info.li_eeprom_info.prid = | ||
241 | lasat_board_info.li_prid; | ||
242 | lasat_write_eeprom_info(); | ||
243 | lasat_init_board_info(); | ||
299 | } | 244 | } |
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; | 245 | return 0; |
312 | } | 246 | } |
313 | 247 | ||
314 | extern int lasat_boot_to_service; | 248 | extern int lasat_boot_to_service; |
315 | 249 | ||
316 | #ifdef CONFIG_SYSCTL | ||
317 | |||
318 | static ctl_table lasat_table[] = { | 250 | static ctl_table lasat_table[] = { |
319 | { | 251 | { |
320 | .ctl_name = CTL_UNNUMBERED, | 252 | .ctl_name = CTL_UNNUMBERED, |
@@ -349,8 +281,8 @@ static ctl_table lasat_table[] = { | |||
349 | .data = &lasat_board_info.li_prid, | 281 | .data = &lasat_board_info.li_prid, |
350 | .maxlen = sizeof(int), | 282 | .maxlen = sizeof(int), |
351 | .mode = 0644, | 283 | .mode = 0644, |
352 | .proc_handler = &proc_lasat_eeprom_value, | 284 | .proc_handler = &proc_lasat_prid, |
353 | .strategy = &sysctl_lasat_eeprom_value | 285 | .strategy = &sysctl_lasat_prid |
354 | }, | 286 | }, |
355 | #ifdef CONFIG_INET | 287 | #ifdef CONFIG_INET |
356 | { | 288 | { |
@@ -363,7 +295,7 @@ static ctl_table lasat_table[] = { | |||
363 | .strategy = &sysctl_lasat_intvec | 295 | .strategy = &sysctl_lasat_intvec |
364 | }, | 296 | }, |
365 | { | 297 | { |
366 | .ctl_name = LASAT_NETMASK, | 298 | .ctl_name = CTL_UNNUMBERED, |
367 | .procname = "netmask", | 299 | .procname = "netmask", |
368 | .data = &lasat_board_info.li_eeprom_info.netmask, | 300 | .data = &lasat_board_info.li_eeprom_info.netmask, |
369 | .maxlen = sizeof(int), | 301 | .maxlen = sizeof(int), |
@@ -371,15 +303,6 @@ static ctl_table lasat_table[] = { | |||
371 | .proc_handler = &proc_lasat_ip, | 303 | .proc_handler = &proc_lasat_ip, |
372 | .strategy = &sysctl_lasat_intvec | 304 | .strategy = &sysctl_lasat_intvec |
373 | }, | 305 | }, |
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 | 306 | #endif |
384 | { | 307 | { |
385 | .ctl_name = CTL_UNNUMBERED, | 308 | .ctl_name = CTL_UNNUMBERED, |
@@ -417,7 +340,7 @@ static ctl_table lasat_table[] = { | |||
417 | .data = &lasat_board_info.li_namestr, | 340 | .data = &lasat_board_info.li_namestr, |
418 | .maxlen = sizeof(lasat_board_info.li_namestr), | 341 | .maxlen = sizeof(lasat_board_info.li_namestr), |
419 | .mode = 0444, | 342 | .mode = 0444, |
420 | .proc_handler = &proc_dostring, | 343 | .proc_handler = &proc_dostring, |
421 | .strategy = &sysctl_string | 344 | .strategy = &sysctl_string |
422 | }, | 345 | }, |
423 | { | 346 | { |
@@ -448,9 +371,12 @@ static int __init lasat_register_sysctl(void) | |||
448 | 371 | ||
449 | lasat_table_header = | 372 | lasat_table_header = |
450 | register_sysctl_table(lasat_root_table); | 373 | register_sysctl_table(lasat_root_table); |
374 | if (!lasat_table_header) { | ||
375 | printk(KERN_ERR "Unable to register LASAT sysctl\n"); | ||
376 | return -ENOMEM; | ||
377 | } | ||
451 | 378 | ||
452 | return 0; | 379 | return 0; |
453 | } | 380 | } |
454 | 381 | ||
455 | __initcall(lasat_register_sysctl); | 382 | __initcall(lasat_register_sysctl); |
456 | #endif /* CONFIG_SYSCTL */ | ||