aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorThomas Horsten <thomas@horsten.com>2008-06-14 21:17:11 -0400
committerRalf Baechle <ralf@linux-mips.org>2008-06-16 10:14:48 -0400
commit1f34f2e4262bae8a1aa6d8fd6306b07074d33718 (patch)
treee1162a346238af0444846ea4cded8d0a4cb04322 /arch/mips
parentc9c5023d83df5dc7d58830a63fd0e082120f00e3 (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')
-rw-r--r--arch/mips/lasat/lasat_board.c13
-rw-r--r--arch/mips/lasat/sysctl.c172
-rw-r--r--arch/mips/lasat/sysctl.h24
3 files changed, 56 insertions, 153 deletions
diff --git a/arch/mips/lasat/lasat_board.c b/arch/mips/lasat/lasat_board.c
index ec2f658c3709..31e328b3814d 100644
--- a/arch/mips/lasat/lasat_board.c
+++ b/arch/mips/lasat/lasat_board.c
@@ -23,18 +23,19 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/string.h> 24#include <linux/string.h>
25#include <linux/ctype.h> 25#include <linux/ctype.h>
26#include <linux/mutex.h>
26#include <asm/bootinfo.h> 27#include <asm/bootinfo.h>
27#include <asm/addrspace.h> 28#include <asm/addrspace.h>
28#include "at93c.h" 29#include "at93c.h"
29/* New model description table */ 30/* New model description table */
30#include "lasat_models.h" 31#include "lasat_models.h"
31 32
33static DEFINE_MUTEX(lasat_eeprom_mutex);
34
32#define EEPROM_CRC(data, len) (~crc32(~0, data, len)) 35#define EEPROM_CRC(data, len) (~crc32(~0, data, len))
33 36
34struct lasat_info lasat_board_info; 37struct lasat_info lasat_board_info;
35 38
36void update_bcastaddr(void);
37
38int EEPROMRead(unsigned int pos, unsigned char *data, int len) 39int EEPROMRead(unsigned int pos, unsigned char *data, int len)
39{ 40{
40 int i; 41 int i;
@@ -258,10 +259,6 @@ int lasat_init_board_info(void)
258 sprintf(lasat_board_info.li_typestr, "%d", 10 * c); 259 sprintf(lasat_board_info.li_typestr, "%d", 10 * c);
259 } 260 }
260 261
261#if defined(CONFIG_INET) && defined(CONFIG_SYSCTL)
262 update_bcastaddr();
263#endif
264
265 return 0; 262 return 0;
266} 263}
267 264
@@ -269,6 +266,8 @@ void lasat_write_eeprom_info(void)
269{ 266{
270 unsigned long crc; 267 unsigned long crc;
271 268
269 mutex_lock(&lasat_eeprom_mutex);
270
272 /* Generate the CRC */ 271 /* Generate the CRC */
273 crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), 272 crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
274 sizeof(struct lasat_eeprom_struct) - 4); 273 sizeof(struct lasat_eeprom_struct) - 4);
@@ -277,4 +276,6 @@ void lasat_write_eeprom_info(void)
277 /* Write the EEPROM info */ 276 /* Write the EEPROM info */
278 EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info, 277 EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info,
279 sizeof(struct lasat_eeprom_struct)); 278 sizeof(struct lasat_eeprom_struct));
279
280 mutex_unlock(&lasat_eeprom_mutex);
280} 281}
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
40static 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 */
43int sysctl_lasatstring(ctl_table *table, int *name, int nlen, 41int 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
100static int rtctmp; 90static int rtctmp;
101 91
102#ifdef CONFIG_DS1603
103/* proc function to read/write RealTime Clock */ 92/* proc function to read/write RealTime Clock */
104int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, 93int 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
174static char lasat_bcastaddr[16];
175
176void 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
191static char proc_lasat_ipbuf[32];
192
193/* Parsing of IP address */
194int proc_lasat_ip(ctl_table *table, int write, struct file *filp, 154int 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
264static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, 214static 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
289int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, 231int 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
314extern int lasat_boot_to_service; 248extern int lasat_boot_to_service;
315 249
316#ifdef CONFIG_SYSCTL
317
318static ctl_table lasat_table[] = { 250static 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 */
diff --git a/arch/mips/lasat/sysctl.h b/arch/mips/lasat/sysctl.h
deleted file mode 100644
index 341b97933423..000000000000
--- a/arch/mips/lasat/sysctl.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * LASAT sysctl values
3 */
4
5#ifndef _LASAT_SYSCTL_H
6#define _LASAT_SYSCTL_H
7
8/* /proc/sys/lasat */
9enum {
10 LASAT_CPU_HZ = 1,
11 LASAT_BUS_HZ,
12 LASAT_MODEL,
13 LASAT_PRID,
14 LASAT_IPADDR,
15 LASAT_NETMASK,
16 LASAT_BCAST,
17 LASAT_PASSWORD,
18 LASAT_SBOOT,
19 LASAT_RTC,
20 LASAT_NAMESTR,
21 LASAT_TYPESTR,
22};
23
24#endif /* _LASAT_SYSCTL_H */