[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>

authored by Thomas Horsten and committed by Ralf Baechle 1f34f2e4 c9c5023d

+56 -153
+7 -6
arch/mips/lasat/lasat_board.c
··· 23 #include <linux/kernel.h> 24 #include <linux/string.h> 25 #include <linux/ctype.h> 26 #include <asm/bootinfo.h> 27 #include <asm/addrspace.h> 28 #include "at93c.h" 29 /* New model description table */ 30 #include "lasat_models.h" 31 32 #define EEPROM_CRC(data, len) (~crc32(~0, data, len)) 33 34 struct lasat_info lasat_board_info; 35 - 36 - void update_bcastaddr(void); 37 38 int EEPROMRead(unsigned int pos, unsigned char *data, int len) 39 { ··· 259 sprintf(lasat_board_info.li_typestr, "%d", 10 * c); 260 } 261 262 - #if defined(CONFIG_INET) && defined(CONFIG_SYSCTL) 263 - update_bcastaddr(); 264 - #endif 265 - 266 return 0; 267 } 268 269 void lasat_write_eeprom_info(void) 270 { 271 unsigned long crc; 272 273 /* Generate the CRC */ 274 crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), ··· 276 /* Write the EEPROM info */ 277 EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info, 278 sizeof(struct lasat_eeprom_struct)); 279 }
··· 23 #include <linux/kernel.h> 24 #include <linux/string.h> 25 #include <linux/ctype.h> 26 + #include <linux/mutex.h> 27 #include <asm/bootinfo.h> 28 #include <asm/addrspace.h> 29 #include "at93c.h" 30 /* New model description table */ 31 #include "lasat_models.h" 32 33 + static DEFINE_MUTEX(lasat_eeprom_mutex); 34 + 35 #define EEPROM_CRC(data, len) (~crc32(~0, data, len)) 36 37 struct lasat_info lasat_board_info; 38 39 int EEPROMRead(unsigned int pos, unsigned char *data, int len) 40 { ··· 258 sprintf(lasat_board_info.li_typestr, "%d", 10 * c); 259 } 260 261 return 0; 262 } 263 264 void lasat_write_eeprom_info(void) 265 { 266 unsigned long crc; 267 + 268 + mutex_lock(&lasat_eeprom_mutex); 269 270 /* Generate the CRC */ 271 crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), ··· 277 /* Write the EEPROM info */ 278 EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info, 279 sizeof(struct lasat_eeprom_struct)); 280 + 281 + mutex_unlock(&lasat_eeprom_mutex); 282 }
+49 -123
arch/mips/lasat/sysctl.c
··· 29 #include <linux/string.h> 30 #include <linux/net.h> 31 #include <linux/inet.h> 32 - #include <linux/mutex.h> 33 #include <linux/uaccess.h> 34 35 #include <asm/time.h> 36 37 - #include "sysctl.h" 38 #include "ds1603.h" 39 - 40 - static DEFINE_MUTEX(lasat_info_mutex); 41 42 /* Strategy function to write EEPROM after changing string entry */ 43 int sysctl_lasatstring(ctl_table *table, int *name, int nlen, ··· 44 { 45 int r; 46 47 - mutex_lock(&lasat_info_mutex); 48 r = sysctl_string(table, name, 49 nlen, oldval, oldlenp, newval, newlen); 50 - if (r < 0) { 51 - mutex_unlock(&lasat_info_mutex); 52 return r; 53 - } 54 if (newval && newlen) 55 lasat_write_eeprom_info(); 56 - mutex_unlock(&lasat_info_mutex); 57 58 - return 1; 59 } 60 61 ··· 62 { 63 int r; 64 65 - mutex_lock(&lasat_info_mutex); 66 r = proc_dostring(table, write, filp, buffer, lenp, ppos); 67 - if ((!write) || r) { 68 - mutex_unlock(&lasat_info_mutex); 69 return r; 70 - } 71 lasat_write_eeprom_info(); 72 - mutex_unlock(&lasat_info_mutex); 73 74 return 0; 75 } ··· 77 { 78 int r; 79 80 - mutex_lock(&lasat_info_mutex); 81 r = proc_dointvec(table, write, filp, buffer, lenp, ppos); 82 - if ((!write) || r) { 83 - mutex_unlock(&lasat_info_mutex); 84 return r; 85 - } 86 lasat_write_eeprom_info(); 87 - mutex_unlock(&lasat_info_mutex); 88 89 return 0; 90 } 91 92 static int rtctmp; 93 94 - #ifdef CONFIG_DS1603 95 /* proc function to read/write RealTime Clock */ 96 int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, 97 void *buffer, size_t *lenp, loff_t *ppos) 98 { 99 int r; 100 101 - mutex_lock(&lasat_info_mutex); 102 if (!write) { 103 rtctmp = read_persistent_clock(); 104 /* check for time < 0 and set to 0 */ ··· 102 rtctmp = 0; 103 } 104 r = proc_dointvec(table, write, filp, buffer, lenp, ppos); 105 - if ((!write) || r) { 106 - mutex_unlock(&lasat_info_mutex); 107 return r; 108 - } 109 - rtc_mips_set_mmss(rtctmp); 110 - mutex_unlock(&lasat_info_mutex); 111 112 return 0; 113 } ··· 119 { 120 int r; 121 122 - mutex_lock(&lasat_info_mutex); 123 r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); 124 - if (r < 0) { 125 - mutex_unlock(&lasat_info_mutex); 126 return r; 127 - } 128 if (newval && newlen) 129 lasat_write_eeprom_info(); 130 - mutex_unlock(&lasat_info_mutex); 131 132 - return 1; 133 } 134 135 #ifdef CONFIG_DS1603 ··· 137 { 138 int r; 139 140 - mutex_lock(&lasat_info_mutex); 141 rtctmp = read_persistent_clock(); 142 if (rtctmp < 0) 143 rtctmp = 0; 144 r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); 145 - if (r < 0) { 146 - mutex_unlock(&lasat_info_mutex); 147 return r; 148 - } 149 if (newval && newlen) 150 rtc_mips_set_mmss(rtctmp); 151 - mutex_unlock(&lasat_info_mutex); 152 153 - return 1; 154 } 155 #endif 156 157 #ifdef CONFIG_INET 158 - static char lasat_bcastaddr[16]; 159 - 160 - void update_bcastaddr(void) 161 - { 162 - unsigned int ip; 163 - 164 - ip = (lasat_board_info.li_eeprom_info.ipaddr & 165 - lasat_board_info.li_eeprom_info.netmask) | 166 - ~lasat_board_info.li_eeprom_info.netmask; 167 - 168 - sprintf(lasat_bcastaddr, "%d.%d.%d.%d", 169 - (ip) & 0xff, 170 - (ip >> 8) & 0xff, 171 - (ip >> 16) & 0xff, 172 - (ip >> 24) & 0xff); 173 - } 174 - 175 - static char proc_lasat_ipbuf[32]; 176 - 177 - /* Parsing of IP address */ 178 int proc_lasat_ip(ctl_table *table, int write, struct file *filp, 179 void *buffer, size_t *lenp, loff_t *ppos) 180 { 181 unsigned int ip; 182 char *p, c; 183 int len; 184 185 if (!table->data || !table->maxlen || !*lenp || 186 (*ppos && !write)) { ··· 165 return 0; 166 } 167 168 - mutex_lock(&lasat_info_mutex); 169 if (write) { 170 len = 0; 171 p = buffer; 172 while (len < *lenp) { 173 - if (get_user(c, p++)) { 174 - mutex_unlock(&lasat_info_mutex); 175 return -EFAULT; 176 - } 177 if (c == 0 || c == '\n') 178 break; 179 len++; 180 } 181 - if (len >= sizeof(proc_lasat_ipbuf)-1) 182 - len = sizeof(proc_lasat_ipbuf) - 1; 183 - if (copy_from_user(proc_lasat_ipbuf, buffer, len)) { 184 - mutex_unlock(&lasat_info_mutex); 185 return -EFAULT; 186 - } 187 - proc_lasat_ipbuf[len] = 0; 188 *ppos += *lenp; 189 /* Now see if we can convert it to a valid IP */ 190 - ip = in_aton(proc_lasat_ipbuf); 191 *(unsigned int *)(table->data) = ip; 192 lasat_write_eeprom_info(); 193 } else { 194 ip = *(unsigned int *)(table->data); 195 - sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d", 196 (ip) & 0xff, 197 (ip >> 8) & 0xff, 198 (ip >> 16) & 0xff, 199 (ip >> 24) & 0xff); 200 - len = strlen(proc_lasat_ipbuf); 201 if (len > *lenp) 202 len = *lenp; 203 if (len) 204 - if (copy_to_user(buffer, proc_lasat_ipbuf, len)) { 205 - mutex_unlock(&lasat_info_mutex); 206 return -EFAULT; 207 - } 208 if (len < *lenp) { 209 - if (put_user('\n', ((char *) buffer) + len)) { 210 - mutex_unlock(&lasat_info_mutex); 211 return -EFAULT; 212 - } 213 len++; 214 } 215 *lenp = len; 216 *ppos += len; 217 } 218 - update_bcastaddr(); 219 - mutex_unlock(&lasat_info_mutex); 220 221 return 0; 222 } 223 - #endif /* defined(CONFIG_INET) */ 224 225 - static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, 226 void *oldval, size_t *oldlenp, 227 void *newval, size_t newlen) 228 { 229 int r; 230 231 - mutex_lock(&lasat_info_mutex); 232 r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); 233 - if (r < 0) { 234 - mutex_unlock(&lasat_info_mutex); 235 return r; 236 - } 237 - 238 if (newval && newlen) { 239 - if (name && *name == LASAT_PRID) 240 - lasat_board_info.li_eeprom_info.prid = *(int *)newval; 241 - 242 lasat_write_eeprom_info(); 243 lasat_init_board_info(); 244 } 245 - mutex_unlock(&lasat_info_mutex); 246 - 247 return 0; 248 } 249 250 - int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, 251 void *buffer, size_t *lenp, loff_t *ppos) 252 { 253 int r; 254 255 - mutex_lock(&lasat_info_mutex); 256 r = proc_dointvec(table, write, filp, buffer, lenp, ppos); 257 - if ((!write) || r) { 258 - mutex_unlock(&lasat_info_mutex); 259 return r; 260 } 261 - if (filp && filp->f_path.dentry) { 262 - if (!strcmp(filp->f_path.dentry->d_name.name, "prid")) 263 - lasat_board_info.li_eeprom_info.prid = 264 - lasat_board_info.li_prid; 265 - if (!strcmp(filp->f_path.dentry->d_name.name, "debugaccess")) 266 - lasat_board_info.li_eeprom_info.debugaccess = 267 - lasat_board_info.li_debugaccess; 268 - } 269 - lasat_write_eeprom_info(); 270 - mutex_unlock(&lasat_info_mutex); 271 - 272 return 0; 273 } 274 275 extern int lasat_boot_to_service; 276 - 277 - #ifdef CONFIG_SYSCTL 278 279 static ctl_table lasat_table[] = { 280 { ··· 281 .data = &lasat_board_info.li_prid, 282 .maxlen = sizeof(int), 283 .mode = 0644, 284 - .proc_handler = &proc_lasat_eeprom_value, 285 - .strategy = &sysctl_lasat_eeprom_value 286 }, 287 #ifdef CONFIG_INET 288 { ··· 295 .strategy = &sysctl_lasat_intvec 296 }, 297 { 298 - .ctl_name = LASAT_NETMASK, 299 .procname = "netmask", 300 .data = &lasat_board_info.li_eeprom_info.netmask, 301 .maxlen = sizeof(int), 302 .mode = 0644, 303 .proc_handler = &proc_lasat_ip, 304 .strategy = &sysctl_lasat_intvec 305 - }, 306 - { 307 - .ctl_name = CTL_UNNUMBERED, 308 - .procname = "bcastaddr", 309 - .data = &lasat_bcastaddr, 310 - .maxlen = sizeof(lasat_bcastaddr), 311 - .mode = 0600, 312 - .proc_handler = &proc_dostring, 313 - .strategy = &sysctl_string 314 }, 315 #endif 316 { ··· 340 .data = &lasat_board_info.li_namestr, 341 .maxlen = sizeof(lasat_board_info.li_namestr), 342 .mode = 0444, 343 - .proc_handler = &proc_dostring, 344 .strategy = &sysctl_string 345 }, 346 { ··· 371 372 lasat_table_header = 373 register_sysctl_table(lasat_root_table); 374 375 return 0; 376 } 377 378 __initcall(lasat_register_sysctl); 379 - #endif /* CONFIG_SYSCTL */
··· 29 #include <linux/string.h> 30 #include <linux/net.h> 31 #include <linux/inet.h> 32 #include <linux/uaccess.h> 33 34 #include <asm/time.h> 35 36 + #ifdef CONFIG_DS1603 37 #include "ds1603.h" 38 + #endif 39 40 /* Strategy function to write EEPROM after changing string entry */ 41 int sysctl_lasatstring(ctl_table *table, int *name, int nlen, ··· 46 { 47 int r; 48 49 r = sysctl_string(table, name, 50 nlen, oldval, oldlenp, newval, newlen); 51 + if (r < 0) 52 return r; 53 + 54 if (newval && newlen) 55 lasat_write_eeprom_info(); 56 57 + return 0; 58 } 59 60 ··· 67 { 68 int r; 69 70 r = proc_dostring(table, write, filp, buffer, lenp, ppos); 71 + if ((!write) || r) 72 return r; 73 + 74 lasat_write_eeprom_info(); 75 76 return 0; 77 } ··· 85 { 86 int r; 87 88 r = proc_dointvec(table, write, filp, buffer, lenp, ppos); 89 + if ((!write) || r) 90 return r; 91 + 92 lasat_write_eeprom_info(); 93 94 return 0; 95 } 96 97 + #ifdef CONFIG_DS1603 98 static int rtctmp; 99 100 /* proc function to read/write RealTime Clock */ 101 int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, 102 void *buffer, size_t *lenp, loff_t *ppos) 103 { 104 int r; 105 106 if (!write) { 107 rtctmp = read_persistent_clock(); 108 /* check for time < 0 and set to 0 */ ··· 114 rtctmp = 0; 115 } 116 r = proc_dointvec(table, write, filp, buffer, lenp, ppos); 117 + if (r) 118 return r; 119 + 120 + if (write) 121 + rtc_mips_set_mmss(rtctmp); 122 123 return 0; 124 } ··· 132 { 133 int r; 134 135 r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); 136 + if (r < 0) 137 return r; 138 + 139 if (newval && newlen) 140 lasat_write_eeprom_info(); 141 142 + return 0; 143 } 144 145 #ifdef CONFIG_DS1603 ··· 153 { 154 int r; 155 156 rtctmp = read_persistent_clock(); 157 if (rtctmp < 0) 158 rtctmp = 0; 159 r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); 160 + if (r < 0) 161 return r; 162 if (newval && newlen) 163 rtc_mips_set_mmss(rtctmp); 164 165 + return r; 166 } 167 #endif 168 169 #ifdef CONFIG_INET 170 int proc_lasat_ip(ctl_table *table, int write, struct file *filp, 171 void *buffer, size_t *lenp, loff_t *ppos) 172 { 173 unsigned int ip; 174 char *p, c; 175 int len; 176 + char ipbuf[32]; 177 178 if (!table->data || !table->maxlen || !*lenp || 179 (*ppos && !write)) { ··· 204 return 0; 205 } 206 207 if (write) { 208 len = 0; 209 p = buffer; 210 while (len < *lenp) { 211 + if (get_user(c, p++)) 212 return -EFAULT; 213 if (c == 0 || c == '\n') 214 break; 215 len++; 216 } 217 + if (len >= sizeof(ipbuf)-1) 218 + len = sizeof(ipbuf) - 1; 219 + if (copy_from_user(ipbuf, buffer, len)) 220 return -EFAULT; 221 + ipbuf[len] = 0; 222 *ppos += *lenp; 223 /* Now see if we can convert it to a valid IP */ 224 + ip = in_aton(ipbuf); 225 *(unsigned int *)(table->data) = ip; 226 lasat_write_eeprom_info(); 227 } else { 228 ip = *(unsigned int *)(table->data); 229 + sprintf(ipbuf, "%d.%d.%d.%d", 230 (ip) & 0xff, 231 (ip >> 8) & 0xff, 232 (ip >> 16) & 0xff, 233 (ip >> 24) & 0xff); 234 + len = strlen(ipbuf); 235 if (len > *lenp) 236 len = *lenp; 237 if (len) 238 + if (copy_to_user(buffer, ipbuf, len)) 239 return -EFAULT; 240 if (len < *lenp) { 241 + if (put_user('\n', ((char *) buffer) + len)) 242 return -EFAULT; 243 len++; 244 } 245 *lenp = len; 246 *ppos += len; 247 } 248 249 return 0; 250 } 251 + #endif 252 253 + static int sysctl_lasat_prid(ctl_table *table, int *name, int nlen, 254 void *oldval, size_t *oldlenp, 255 void *newval, size_t newlen) 256 { 257 int r; 258 259 r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); 260 + if (r < 0) 261 return r; 262 if (newval && newlen) { 263 + lasat_board_info.li_eeprom_info.prid = *(int *)newval; 264 lasat_write_eeprom_info(); 265 lasat_init_board_info(); 266 } 267 return 0; 268 } 269 270 + int proc_lasat_prid(ctl_table *table, int write, struct file *filp, 271 void *buffer, size_t *lenp, loff_t *ppos) 272 { 273 int r; 274 275 r = proc_dointvec(table, write, filp, buffer, lenp, ppos); 276 + if (r < 0) 277 return r; 278 + if (write) { 279 + lasat_board_info.li_eeprom_info.prid = 280 + lasat_board_info.li_prid; 281 + lasat_write_eeprom_info(); 282 + lasat_init_board_info(); 283 } 284 return 0; 285 } 286 287 extern int lasat_boot_to_service; 288 289 static ctl_table lasat_table[] = { 290 { ··· 349 .data = &lasat_board_info.li_prid, 350 .maxlen = sizeof(int), 351 .mode = 0644, 352 + .proc_handler = &proc_lasat_prid, 353 + .strategy = &sysctl_lasat_prid 354 }, 355 #ifdef CONFIG_INET 356 { ··· 363 .strategy = &sysctl_lasat_intvec 364 }, 365 { 366 + .ctl_name = CTL_UNNUMBERED, 367 .procname = "netmask", 368 .data = &lasat_board_info.li_eeprom_info.netmask, 369 .maxlen = sizeof(int), 370 .mode = 0644, 371 .proc_handler = &proc_lasat_ip, 372 .strategy = &sysctl_lasat_intvec 373 }, 374 #endif 375 { ··· 417 .data = &lasat_board_info.li_namestr, 418 .maxlen = sizeof(lasat_board_info.li_namestr), 419 .mode = 0444, 420 + .proc_handler = &proc_dostring, 421 .strategy = &sysctl_string 422 }, 423 { ··· 448 449 lasat_table_header = 450 register_sysctl_table(lasat_root_table); 451 + if (!lasat_table_header) { 452 + printk(KERN_ERR "Unable to register LASAT sysctl\n"); 453 + return -ENOMEM; 454 + } 455 456 return 0; 457 } 458 459 __initcall(lasat_register_sysctl);
-24
arch/mips/lasat/sysctl.h
··· 1 - /* 2 - * LASAT sysctl values 3 - */ 4 - 5 - #ifndef _LASAT_SYSCTL_H 6 - #define _LASAT_SYSCTL_H 7 - 8 - /* /proc/sys/lasat */ 9 - enum { 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 */
···