Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+7 −6
Original line number Original line Diff line number Diff line
@@ -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)
			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)
{
{
	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)
	/* 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);
}
}
+49 −123
Original line number Original line Diff line number Diff line
@@ -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,
{
{
	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,
{
{
	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,
{
{
	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,
			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,
{
{
	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,
{
{
	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,
		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[] = {
		.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[] = {
		.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[] = {
		.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)


	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 */

arch/mips/lasat/sysctl.h

deleted100644 → 0
+0 −24
Original line number Original line Diff line number Diff line
/*
 * 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 */