2005-04-16 15:20:36 -07:00
/*
* Thomas Horsten < thh @ lasat . com >
* Copyright ( C ) 2000 LASAT Networks A / S .
*
* This program is free software ; you can distribute it and / or modify it
* under the terms of the GNU General Public License ( Version 2 ) as
* published by the Free Software Foundation .
*
* This program is distributed in the hope it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* for more details .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 59 Temple Place - Suite 330 , Boston MA 02111 - 1307 , USA .
*
* Routines specific to the LASAT boards
*/
# include <linux/types.h>
# include <asm/lasat/lasat.h>
# include <linux/module.h>
# include <linux/sysctl.h>
# include <linux/stddef.h>
# include <linux/init.h>
# include <linux/fs.h>
# include <linux/ctype.h>
# include <linux/string.h>
# include <linux/net.h>
# include <linux/inet.h>
2006-03-26 01:37:14 -08:00
# include <linux/mutex.h>
2005-04-16 15:20:36 -07:00
# include <asm/uaccess.h>
# include "sysctl.h"
# include "ds1603.h"
2006-03-26 01:37:14 -08:00
static DEFINE_MUTEX ( lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
2005-09-03 15:56:17 -07:00
/* Strategy function to write EEPROM after changing string entry */
2005-04-16 15:20:36 -07:00
int sysctl_lasatstring ( ctl_table * table , int * name , int nlen ,
void * oldval , size_t * oldlenp ,
2006-12-10 02:19:10 -08:00
void * newval , size_t newlen )
2005-04-16 15:20:36 -07:00
{
int r ;
2006-03-26 01:37:14 -08:00
mutex_lock ( & lasat_info_mutex ) ;
2005-09-03 15:56:17 -07:00
r = sysctl_string ( table , name ,
2006-12-10 02:19:10 -08:00
nlen , oldval , oldlenp , newval , newlen ) ;
2005-04-16 15:20:36 -07:00
if ( r < 0 ) {
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return r ;
}
if ( newval & & newlen ) {
lasat_write_eeprom_info ( ) ;
}
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return 1 ;
}
/* And the same for proc */
int proc_dolasatstring ( ctl_table * table , int write , struct file * filp ,
void * buffer , size_t * lenp , loff_t * ppos )
{
int r ;
2006-03-26 01:37:14 -08:00
mutex_lock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
r = proc_dostring ( table , write , filp , buffer , lenp , ppos ) ;
if ( ( ! write ) | | r ) {
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return r ;
}
lasat_write_eeprom_info ( ) ;
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
2005-09-03 15:56:17 -07:00
/* proc function to write EEPROM after changing int entry */
2005-04-16 15:20:36 -07:00
int proc_dolasatint ( ctl_table * table , int write , struct file * filp ,
void * buffer , size_t * lenp , loff_t * ppos )
{
int r ;
2006-03-26 01:37:14 -08:00
mutex_lock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
r = proc_dointvec ( table , write , filp , buffer , lenp , ppos ) ;
if ( ( ! write ) | | r ) {
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return r ;
}
lasat_write_eeprom_info ( ) ;
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
static int rtctmp ;
# ifdef CONFIG_DS1603
2005-09-03 15:56:17 -07:00
/* proc function to read/write RealTime Clock */
2005-04-16 15:20:36 -07:00
int proc_dolasatrtc ( ctl_table * table , int write , struct file * filp ,
void * buffer , size_t * lenp , loff_t * ppos )
{
int r ;
2006-03-26 01:37:14 -08:00
mutex_lock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
if ( ! write ) {
rtctmp = ds1603_read ( ) ;
/* check for time < 0 and set to 0 */
if ( rtctmp < 0 )
rtctmp = 0 ;
}
r = proc_dointvec ( table , write , filp , buffer , lenp , ppos ) ;
if ( ( ! write ) | | r ) {
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return r ;
}
ds1603_set ( rtctmp ) ;
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
# endif
/* Sysctl for setting the IP addresses */
int sysctl_lasat_intvec ( ctl_table * table , int * name , int nlen ,
void * oldval , size_t * oldlenp ,
2006-12-10 02:19:10 -08:00
void * newval , size_t newlen )
2005-04-16 15:20:36 -07:00
{
int r ;
2006-03-26 01:37:14 -08:00
mutex_lock ( & lasat_info_mutex ) ;
2006-12-10 02:19:10 -08:00
r = sysctl_intvec ( table , name , nlen , oldval , oldlenp , newval , newlen ) ;
2005-04-16 15:20:36 -07:00
if ( r < 0 ) {
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return r ;
}
if ( newval & & newlen ) {
lasat_write_eeprom_info ( ) ;
}
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return 1 ;
}
# ifdef CONFIG_DS1603
/* Same for RTC */
int sysctl_lasat_rtc ( ctl_table * table , int * name , int nlen ,
void * oldval , size_t * oldlenp ,
2006-12-10 02:19:10 -08:00
void * newval , size_t newlen )
2005-04-16 15:20:36 -07:00
{
int r ;
2006-03-26 01:37:14 -08:00
mutex_lock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
rtctmp = ds1603_read ( ) ;
if ( rtctmp < 0 )
rtctmp = 0 ;
2006-12-10 02:19:10 -08:00
r = sysctl_intvec ( table , name , nlen , oldval , oldlenp , newval , newlen ) ;
2005-04-16 15:20:36 -07:00
if ( r < 0 ) {
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return r ;
}
if ( newval & & newlen ) {
ds1603_set ( rtctmp ) ;
}
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return 1 ;
}
# endif
# ifdef CONFIG_INET
static char lasat_bcastaddr [ 16 ] ;
void update_bcastaddr ( void )
{
unsigned int ip ;
2005-09-03 15:56:17 -07:00
ip = ( lasat_board_info . li_eeprom_info . ipaddr &
lasat_board_info . li_eeprom_info . netmask ) |
2005-04-16 15:20:36 -07:00
~ 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 ,
void * buffer , size_t * lenp , loff_t * ppos )
{
int len ;
unsigned int ip ;
char * p , c ;
if ( ! table - > data | | ! table - > maxlen | | ! * lenp | |
( * ppos & & ! write ) ) {
* lenp = 0 ;
return 0 ;
}
2006-03-26 01:37:14 -08:00
mutex_lock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
if ( write ) {
len = 0 ;
p = buffer ;
while ( len < * lenp ) {
if ( get_user ( c , p + + ) ) {
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return - EFAULT ;
}
if ( c = = 0 | | c = = ' \n ' )
break ;
len + + ;
}
2005-09-03 15:56:17 -07:00
if ( len > = sizeof ( proc_lasat_ipbuf ) - 1 )
2005-04-16 15:20:36 -07:00
len = sizeof ( proc_lasat_ipbuf ) - 1 ;
if ( copy_from_user ( proc_lasat_ipbuf , buffer , len ) )
{
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return - EFAULT ;
}
proc_lasat_ipbuf [ len ] = 0 ;
* ppos + = * lenp ;
/* Now see if we can convert it to a valid IP */
ip = in_aton ( proc_lasat_ipbuf ) ;
* ( unsigned int * ) ( table - > data ) = ip ;
lasat_write_eeprom_info ( ) ;
} else {
ip = * ( unsigned int * ) ( table - > data ) ;
sprintf ( proc_lasat_ipbuf , " %d.%d.%d.%d " ,
( ip ) & 0xff ,
( ip > > 8 ) & 0xff ,
( ip > > 16 ) & 0xff ,
( ip > > 24 ) & 0xff ) ;
len = strlen ( proc_lasat_ipbuf ) ;
if ( len > * lenp )
len = * lenp ;
if ( len )
if ( copy_to_user ( buffer , proc_lasat_ipbuf , len ) ) {
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return - EFAULT ;
}
if ( len < * lenp ) {
if ( put_user ( ' \n ' , ( ( char * ) buffer ) + len ) ) {
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return - EFAULT ;
}
len + + ;
}
* lenp = len ;
* ppos + = len ;
}
update_bcastaddr ( ) ;
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
# endif /* defined(CONFIG_INET) */
2005-09-03 15:56:17 -07:00
static int sysctl_lasat_eeprom_value ( ctl_table * table , int * name , int nlen ,
void * oldval , size_t * oldlenp ,
2006-12-10 02:19:10 -08:00
void * newval , size_t newlen )
2005-04-16 15:20:36 -07:00
{
int r ;
2006-03-26 01:37:14 -08:00
mutex_lock ( & lasat_info_mutex ) ;
2006-12-10 02:19:10 -08:00
r = sysctl_intvec ( table , name , nlen , oldval , oldlenp , newval , newlen ) ;
2005-04-16 15:20:36 -07:00
if ( r < 0 ) {
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return r ;
}
if ( newval & & newlen )
{
if ( name & & * name = = LASAT_PRID )
lasat_board_info . li_eeprom_info . prid = * ( int * ) newval ;
lasat_write_eeprom_info ( ) ;
lasat_init_board_info ( ) ;
}
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
int proc_lasat_eeprom_value ( ctl_table * table , int write , struct file * filp ,
void * buffer , size_t * lenp , loff_t * ppos )
{
int r ;
2006-03-26 01:37:14 -08:00
mutex_lock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
r = proc_dointvec ( table , write , filp , buffer , lenp , ppos ) ;
if ( ( ! write ) | | r ) {
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return r ;
}
2006-12-08 02:37:20 -08:00
if ( filp & & filp - > f_path . dentry )
2005-04-16 15:20:36 -07:00
{
2006-12-08 02:37:20 -08:00
if ( ! strcmp ( filp - > f_path . dentry - > d_name . name , " prid " ) )
2005-04-16 15:20:36 -07:00
lasat_board_info . li_eeprom_info . prid = lasat_board_info . li_prid ;
2006-12-08 02:37:20 -08:00
if ( ! strcmp ( filp - > f_path . dentry - > d_name . name , " debugaccess " ) )
2005-04-16 15:20:36 -07:00
lasat_board_info . li_eeprom_info . debugaccess = lasat_board_info . li_debugaccess ;
}
2005-09-03 15:56:17 -07:00
lasat_write_eeprom_info ( ) ;
2006-03-26 01:37:14 -08:00
mutex_unlock ( & lasat_info_mutex ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
extern int lasat_boot_to_service ;
# ifdef CONFIG_SYSCTL
static ctl_table lasat_table [ ] = {
2007-02-14 00:33:44 -08:00
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " cpu-hz " ,
. data = & lasat_board_info . li_cpu_hz ,
. maxlen = sizeof ( int ) ,
. mode = 0444 ,
. proc_handler = & proc_dointvec ,
. strategy = & sysctl_intvec
} ,
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " bus-hz " ,
. data = & lasat_board_info . li_bus_hz ,
. maxlen = sizeof ( int ) ,
. mode = 0444 ,
. proc_handler = & proc_dointvec ,
. strategy = & sysctl_intvec
} ,
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " bmid " ,
. data = & lasat_board_info . li_bmid ,
. maxlen = sizeof ( int ) ,
. mode = 0444 ,
. proc_handler = & proc_dointvec ,
. strategy = & sysctl_intvec
} ,
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " prid " ,
. data = & lasat_board_info . li_prid ,
. maxlen = sizeof ( int ) ,
. mode = 0644 ,
. proc_handler = & proc_lasat_eeprom_value ,
. strategy = & sysctl_lasat_eeprom_value
} ,
2005-04-16 15:20:36 -07:00
# ifdef CONFIG_INET
2007-02-14 00:33:44 -08:00
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " ipaddr " ,
. data = & lasat_board_info . li_eeprom_info . ipaddr ,
. maxlen = sizeof ( int ) ,
. mode = 0644 ,
. proc_handler = & proc_lasat_ip ,
. strategy = & sysctl_lasat_intvec
} ,
{
. ctl_name = LASAT_NETMASK ,
. procname = " netmask " ,
. data = & lasat_board_info . li_eeprom_info . netmask ,
. maxlen = sizeof ( int ) ,
. mode = 0644 ,
. proc_handler = & proc_lasat_ip ,
. 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
} ,
2005-04-16 15:20:36 -07:00
# endif
2007-02-14 00:33:44 -08:00
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " passwd_hash " ,
. data = & lasat_board_info . li_eeprom_info . passwd_hash ,
. maxlen = sizeof ( lasat_board_info . li_eeprom_info . passwd_hash ) ,
. mode = 0600 ,
. proc_handler = & proc_dolasatstring ,
. strategy = & sysctl_lasatstring
} ,
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " boot-service " ,
. data = & lasat_boot_to_service ,
. maxlen = sizeof ( int ) ,
. mode = 0644 ,
. proc_handler = & proc_dointvec ,
. strategy = & sysctl_intvec
} ,
2005-04-16 15:20:36 -07:00
# ifdef CONFIG_DS1603
2007-02-14 00:33:44 -08:00
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " rtc " ,
. data = & rtctmp ,
. maxlen = sizeof ( int ) ,
. mode = 0644 ,
. proc_handler = & proc_dolasatrtc ,
. strategy = & sysctl_lasat_rtc
} ,
2005-04-16 15:20:36 -07:00
# endif
2007-02-14 00:33:44 -08:00
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " namestr " ,
. data = & lasat_board_info . li_namestr ,
. maxlen = sizeof ( lasat_board_info . li_namestr ) ,
. mode = 0444 ,
. proc_handler = & proc_dostring ,
. strategy = & sysctl_string
} ,
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " typestr " ,
. data = & lasat_board_info . li_typestr ,
. maxlen = sizeof ( lasat_board_info . li_typestr ) ,
. mode = 0444 ,
. proc_handler = & proc_dostring ,
. strategy = & sysctl_string
} ,
{ }
2005-04-16 15:20:36 -07:00
} ;
static ctl_table lasat_root_table [ ] = {
2007-02-14 00:33:44 -08:00
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " lasat " ,
. mode = 0555 ,
. child = lasat_table
} ,
{ }
2005-04-16 15:20:36 -07:00
} ;
static int __init lasat_register_sysctl ( void )
{
struct ctl_table_header * lasat_table_header ;
lasat_table_header =
2007-02-14 00:34:09 -08:00
register_sysctl_table ( lasat_root_table ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
__initcall ( lasat_register_sysctl ) ;
# endif /* CONFIG_SYSCTL */