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