Commit 1f34f2e4 authored by Thomas Horsten's avatar Thomas Horsten Committed by Ralf Baechle

[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: default avatarThomas Horsten <thomas@horsten.com>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent c9c5023d
...@@ -23,18 +23,19 @@ ...@@ -23,18 +23,19 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/mutex.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include "at93c.h" #include "at93c.h"
/* New model description table */ /* New model description table */
#include "lasat_models.h" #include "lasat_models.h"
static DEFINE_MUTEX(lasat_eeprom_mutex);
#define EEPROM_CRC(data, len) (~crc32(~0, data, len)) #define EEPROM_CRC(data, len) (~crc32(~0, data, len))
struct lasat_info lasat_board_info; struct lasat_info lasat_board_info;
void update_bcastaddr(void);
int EEPROMRead(unsigned int pos, unsigned char *data, int len) int EEPROMRead(unsigned int pos, unsigned char *data, int len)
{ {
int i; int i;
...@@ -258,10 +259,6 @@ int lasat_init_board_info(void) ...@@ -258,10 +259,6 @@ int lasat_init_board_info(void)
sprintf(lasat_board_info.li_typestr, "%d", 10 * c); sprintf(lasat_board_info.li_typestr, "%d", 10 * c);
} }
#if defined(CONFIG_INET) && defined(CONFIG_SYSCTL)
update_bcastaddr();
#endif
return 0; return 0;
} }
...@@ -269,6 +266,8 @@ void lasat_write_eeprom_info(void) ...@@ -269,6 +266,8 @@ void lasat_write_eeprom_info(void)
{ {
unsigned long crc; unsigned long crc;
mutex_lock(&lasat_eeprom_mutex);
/* Generate the CRC */ /* Generate the CRC */
crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
sizeof(struct lasat_eeprom_struct) - 4); sizeof(struct lasat_eeprom_struct) - 4);
...@@ -277,4 +276,6 @@ void lasat_write_eeprom_info(void) ...@@ -277,4 +276,6 @@ void lasat_write_eeprom_info(void)
/* Write the EEPROM info */ /* Write the EEPROM info */
EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info, EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info,
sizeof(struct lasat_eeprom_struct)); sizeof(struct lasat_eeprom_struct));
mutex_unlock(&lasat_eeprom_mutex);
} }
...@@ -29,15 +29,13 @@ ...@@ -29,15 +29,13 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/net.h> #include <linux/net.h>
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/mutex.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/time.h> #include <asm/time.h>
#include "sysctl.h" #ifdef CONFIG_DS1603
#include "ds1603.h" #include "ds1603.h"
#endif
static DEFINE_MUTEX(lasat_info_mutex);
/* Strategy function to write EEPROM after changing string entry */ /* Strategy function to write EEPROM after changing string entry */
int sysctl_lasatstring(ctl_table *table, int *name, int nlen, 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,18 +44,15 @@ int sysctl_lasatstring(ctl_table *table, int *name, int nlen,
{ {
int r; int r;
mutex_lock(&lasat_info_mutex);
r = sysctl_string(table, name, r = sysctl_string(table, name,
nlen, oldval, oldlenp, newval, newlen); nlen, oldval, oldlenp, newval, newlen);
if (r < 0) { if (r < 0)
mutex_unlock(&lasat_info_mutex);
return r; return r;
}
if (newval && newlen) if (newval && newlen)
lasat_write_eeprom_info(); lasat_write_eeprom_info();
mutex_unlock(&lasat_info_mutex);
return 1; return 0;
} }
...@@ -67,14 +62,11 @@ int proc_dolasatstring(ctl_table *table, int write, struct file *filp, ...@@ -67,14 +62,11 @@ int proc_dolasatstring(ctl_table *table, int write, struct file *filp,
{ {
int r; int r;
mutex_lock(&lasat_info_mutex);
r = proc_dostring(table, write, filp, buffer, lenp, ppos); r = proc_dostring(table, write, filp, buffer, lenp, ppos);
if ((!write) || r) { if ((!write) || r)
mutex_unlock(&lasat_info_mutex);
return r; return r;
}
lasat_write_eeprom_info(); lasat_write_eeprom_info();
mutex_unlock(&lasat_info_mutex);
return 0; return 0;
} }
...@@ -85,28 +77,24 @@ int proc_dolasatint(ctl_table *table, int write, struct file *filp, ...@@ -85,28 +77,24 @@ int proc_dolasatint(ctl_table *table, int write, struct file *filp,
{ {
int r; int r;
mutex_lock(&lasat_info_mutex);
r = proc_dointvec(table, write, filp, buffer, lenp, ppos); r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
if ((!write) || r) { if ((!write) || r)
mutex_unlock(&lasat_info_mutex);
return r; return r;
}
lasat_write_eeprom_info(); lasat_write_eeprom_info();
mutex_unlock(&lasat_info_mutex);
return 0; return 0;
} }
#ifdef CONFIG_DS1603
static int rtctmp; static int rtctmp;
#ifdef CONFIG_DS1603
/* proc function to read/write RealTime Clock */ /* proc function to read/write RealTime Clock */
int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int r; int r;
mutex_lock(&lasat_info_mutex);
if (!write) { if (!write) {
rtctmp = read_persistent_clock(); rtctmp = read_persistent_clock();
/* check for time < 0 and set to 0 */ /* check for time < 0 and set to 0 */
...@@ -114,12 +102,11 @@ int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, ...@@ -114,12 +102,11 @@ int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
rtctmp = 0; rtctmp = 0;
} }
r = proc_dointvec(table, write, filp, buffer, lenp, ppos); r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
if ((!write) || r) { if (r)
mutex_unlock(&lasat_info_mutex);
return r; return r;
}
if (write)
rtc_mips_set_mmss(rtctmp); rtc_mips_set_mmss(rtctmp);
mutex_unlock(&lasat_info_mutex);
return 0; return 0;
} }
...@@ -132,17 +119,14 @@ int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, ...@@ -132,17 +119,14 @@ int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen,
{ {
int r; int r;
mutex_lock(&lasat_info_mutex);
r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
if (r < 0) { if (r < 0)
mutex_unlock(&lasat_info_mutex);
return r; return r;
}
if (newval && newlen) if (newval && newlen)
lasat_write_eeprom_info(); lasat_write_eeprom_info();
mutex_unlock(&lasat_info_mutex);
return 1; return 0;
} }
#ifdef CONFIG_DS1603 #ifdef CONFIG_DS1603
...@@ -153,50 +137,27 @@ int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, ...@@ -153,50 +137,27 @@ int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen,
{ {
int r; int r;
mutex_lock(&lasat_info_mutex);
rtctmp = read_persistent_clock(); rtctmp = read_persistent_clock();
if (rtctmp < 0) if (rtctmp < 0)
rtctmp = 0; rtctmp = 0;
r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
if (r < 0) { if (r < 0)
mutex_unlock(&lasat_info_mutex);
return r; return r;
}
if (newval && newlen) if (newval && newlen)
rtc_mips_set_mmss(rtctmp); rtc_mips_set_mmss(rtctmp);
mutex_unlock(&lasat_info_mutex);
return 1; return r;
} }
#endif #endif
#ifdef CONFIG_INET #ifdef CONFIG_INET
static char lasat_bcastaddr[16];
void update_bcastaddr(void)
{
unsigned int ip;
ip = (lasat_board_info.li_eeprom_info.ipaddr &
lasat_board_info.li_eeprom_info.netmask) |
~lasat_board_info.li_eeprom_info.netmask;
sprintf(lasat_bcastaddr, "%d.%d.%d.%d",
(ip) & 0xff,
(ip >> 8) & 0xff,
(ip >> 16) & 0xff,
(ip >> 24) & 0xff);
}
static char proc_lasat_ipbuf[32];
/* Parsing of IP address */
int proc_lasat_ip(ctl_table *table, int write, struct file *filp, int proc_lasat_ip(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
unsigned int ip; unsigned int ip;
char *p, c; char *p, c;
int len; int len;
char ipbuf[32];
if (!table->data || !table->maxlen || !*lenp || if (!table->data || !table->maxlen || !*lenp ||
(*ppos && !write)) { (*ppos && !write)) {
...@@ -204,117 +165,88 @@ int proc_lasat_ip(ctl_table *table, int write, struct file *filp, ...@@ -204,117 +165,88 @@ int proc_lasat_ip(ctl_table *table, int write, struct file *filp,
return 0; return 0;
} }
mutex_lock(&lasat_info_mutex);
if (write) { if (write) {
len = 0; len = 0;
p = buffer; p = buffer;
while (len < *lenp) { while (len < *lenp) {
if (get_user(c, p++)) { if (get_user(c, p++))
mutex_unlock(&lasat_info_mutex);
return -EFAULT; return -EFAULT;
}
if (c == 0 || c == '\n') if (c == 0 || c == '\n')
break; break;
len++; len++;
} }
if (len >= sizeof(proc_lasat_ipbuf)-1) if (len >= sizeof(ipbuf)-1)
len = sizeof(proc_lasat_ipbuf) - 1; len = sizeof(ipbuf) - 1;
if (copy_from_user(proc_lasat_ipbuf, buffer, len)) { if (copy_from_user(ipbuf, buffer, len))
mutex_unlock(&lasat_info_mutex);
return -EFAULT; return -EFAULT;
} ipbuf[len] = 0;
proc_lasat_ipbuf[len] = 0;
*ppos += *lenp; *ppos += *lenp;
/* Now see if we can convert it to a valid IP */ /* Now see if we can convert it to a valid IP */
ip = in_aton(proc_lasat_ipbuf); ip = in_aton(ipbuf);
*(unsigned int *)(table->data) = ip; *(unsigned int *)(table->data) = ip;
lasat_write_eeprom_info(); lasat_write_eeprom_info();
} else { } else {
ip = *(unsigned int *)(table->data); ip = *(unsigned int *)(table->data);
sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d", sprintf(ipbuf, "%d.%d.%d.%d",
(ip) & 0xff, (ip) & 0xff,
(ip >> 8) & 0xff, (ip >> 8) & 0xff,
(ip >> 16) & 0xff, (ip >> 16) & 0xff,
(ip >> 24) & 0xff); (ip >> 24) & 0xff);
len = strlen(proc_lasat_ipbuf); len = strlen(ipbuf);
if (len > *lenp) if (len > *lenp)
len = *lenp; len = *lenp;
if (len) if (len)
if (copy_to_user(buffer, proc_lasat_ipbuf, len)) { if (copy_to_user(buffer, ipbuf, len))
mutex_unlock(&lasat_info_mutex);
return -EFAULT; return -EFAULT;
}
if (len < *lenp) { if (len < *lenp) {
if (put_user('\n', ((char *) buffer) + len)) { if (put_user('\n', ((char *) buffer) + len))
mutex_unlock(&lasat_info_mutex);
return -EFAULT; return -EFAULT;
}
len++; len++;
} }
*lenp = len; *lenp = len;
*ppos += len; *ppos += len;
} }
update_bcastaddr();
mutex_unlock(&lasat_info_mutex);
return 0; return 0;
} }
#endif /* defined(CONFIG_INET) */ #endif
static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, static int sysctl_lasat_prid(ctl_table *table, int *name, int nlen,
void *oldval, size_t *oldlenp, void *oldval, size_t *oldlenp,
void *newval, size_t newlen) void *newval, size_t newlen)
{ {
int r; int r;
mutex_lock(&lasat_info_mutex);
r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
if (r < 0) { if (r < 0)
mutex_unlock(&lasat_info_mutex);
return r; return r;
}
if (newval && newlen) { if (newval && newlen) {
if (name && *name == LASAT_PRID)
lasat_board_info.li_eeprom_info.prid = *(int *)newval; lasat_board_info.li_eeprom_info.prid = *(int *)newval;
lasat_write_eeprom_info(); lasat_write_eeprom_info();
lasat_init_board_info(); lasat_init_board_info();
} }
mutex_unlock(&lasat_info_mutex);
return 0; return 0;
} }
int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, int proc_lasat_prid(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int r; int r;
mutex_lock(&lasat_info_mutex);
r = proc_dointvec(table, write, filp, buffer, lenp, ppos); r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
if ((!write) || r) { if (r < 0)
mutex_unlock(&lasat_info_mutex);
return r; return r;
} if (write) {
if (filp && filp->f_path.dentry) {
if (!strcmp(filp->f_path.dentry->d_name.name, "prid"))
lasat_board_info.li_eeprom_info.prid = lasat_board_info.li_eeprom_info.prid =
lasat_board_info.li_prid; lasat_board_info.li_prid;
if (!strcmp(filp->f_path.dentry->d_name.name, "debugaccess"))
lasat_board_info.li_eeprom_info.debugaccess =
lasat_board_info.li_debugaccess;
}
lasat_write_eeprom_info(); lasat_write_eeprom_info();
mutex_unlock(&lasat_info_mutex); lasat_init_board_info();
}
return 0; return 0;
} }
extern int lasat_boot_to_service; extern int lasat_boot_to_service;
#ifdef CONFIG_SYSCTL
static ctl_table lasat_table[] = { static ctl_table lasat_table[] = {
{ {
.ctl_name = CTL_UNNUMBERED, .ctl_name = CTL_UNNUMBERED,
...@@ -349,8 +281,8 @@ static ctl_table lasat_table[] = { ...@@ -349,8 +281,8 @@ static ctl_table lasat_table[] = {
.data = &lasat_board_info.li_prid, .data = &lasat_board_info.li_prid,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_lasat_eeprom_value, .proc_handler = &proc_lasat_prid,
.strategy = &sysctl_lasat_eeprom_value .strategy = &sysctl_lasat_prid
}, },
#ifdef CONFIG_INET #ifdef CONFIG_INET
{ {
...@@ -363,7 +295,7 @@ static ctl_table lasat_table[] = { ...@@ -363,7 +295,7 @@ static ctl_table lasat_table[] = {
.strategy = &sysctl_lasat_intvec .strategy = &sysctl_lasat_intvec
}, },
{ {
.ctl_name = LASAT_NETMASK, .ctl_name = CTL_UNNUMBERED,
.procname = "netmask", .procname = "netmask",
.data = &lasat_board_info.li_eeprom_info.netmask, .data = &lasat_board_info.li_eeprom_info.netmask,
.maxlen = sizeof(int), .maxlen = sizeof(int),
...@@ -371,15 +303,6 @@ static ctl_table lasat_table[] = { ...@@ -371,15 +303,6 @@ static ctl_table lasat_table[] = {
.proc_handler = &proc_lasat_ip, .proc_handler = &proc_lasat_ip,
.strategy = &sysctl_lasat_intvec .strategy = &sysctl_lasat_intvec
}, },
{
.ctl_name = CTL_UNNUMBERED,
.procname = "bcastaddr",
.data = &lasat_bcastaddr,
.maxlen = sizeof(lasat_bcastaddr),
.mode = 0600,
.proc_handler = &proc_dostring,
.strategy = &sysctl_string
},
#endif #endif
{ {
.ctl_name = CTL_UNNUMBERED, .ctl_name = CTL_UNNUMBERED,
...@@ -448,9 +371,12 @@ static int __init lasat_register_sysctl(void) ...@@ -448,9 +371,12 @@ static int __init lasat_register_sysctl(void)
lasat_table_header = lasat_table_header =
register_sysctl_table(lasat_root_table); register_sysctl_table(lasat_root_table);
if (!lasat_table_header) {
printk(KERN_ERR "Unable to register LASAT sysctl\n");
return -ENOMEM;
}
return 0; return 0;
} }
__initcall(lasat_register_sysctl); __initcall(lasat_register_sysctl);
#endif /* CONFIG_SYSCTL */
/*
* LASAT sysctl values
*/
#ifndef _LASAT_SYSCTL_H
#define _LASAT_SYSCTL_H
/* /proc/sys/lasat */
enum {
LASAT_CPU_HZ = 1,
LASAT_BUS_HZ,
LASAT_MODEL,
LASAT_PRID,
LASAT_IPADDR,
LASAT_NETMASK,
LASAT_BCAST,
LASAT_PASSWORD,
LASAT_SBOOT,
LASAT_RTC,
LASAT_NAMESTR,
LASAT_TYPESTR,
};
#endif /* _LASAT_SYSCTL_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment