2007-08-22 00:34:16 +04: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>
# include <linux/uaccess.h>
2007-10-12 02:46:08 +04:00
# include <asm/time.h>
2008-06-15 05:17:11 +04:00
# ifdef CONFIG_DS1603
2007-08-22 00:34:16 +04:00
# include "ds1603.h"
2008-06-15 05:17:11 +04:00
# endif
2007-08-22 00:34:16 +04:00
/* Strategy function to write EEPROM after changing string entry */
2008-10-16 09:04:23 +04:00
int sysctl_lasatstring ( ctl_table * table ,
2007-08-22 00:34:16 +04:00
void * oldval , size_t * oldlenp ,
void * newval , size_t newlen )
{
int r ;
2008-10-16 09:04:23 +04:00
r = sysctl_string ( table , oldval , oldlenp , newval , newlen ) ;
2008-06-15 05:17:11 +04:00
if ( r < 0 )
2007-08-22 00:34:16 +04:00
return r ;
2008-06-15 05:17:11 +04:00
2007-08-22 00:34:16 +04:00
if ( newval & & newlen )
lasat_write_eeprom_info ( ) ;
2008-06-15 05:17:11 +04:00
return 0 ;
2007-08-22 00:34:16 +04:00
}
/* 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 ;
r = proc_dostring ( table , write , filp , buffer , lenp , ppos ) ;
2008-06-15 05:17:11 +04:00
if ( ( ! write ) | | r )
2007-08-22 00:34:16 +04:00
return r ;
2008-06-15 05:17:11 +04:00
2007-08-22 00:34:16 +04:00
lasat_write_eeprom_info ( ) ;
return 0 ;
}
/* proc function to write EEPROM after changing int entry */
int proc_dolasatint ( ctl_table * table , int write , struct file * filp ,
void * buffer , size_t * lenp , loff_t * ppos )
{
int r ;
r = proc_dointvec ( table , write , filp , buffer , lenp , ppos ) ;
2008-06-15 05:17:11 +04:00
if ( ( ! write ) | | r )
2007-08-22 00:34:16 +04:00
return r ;
2008-06-15 05:17:11 +04:00
2007-08-22 00:34:16 +04:00
lasat_write_eeprom_info ( ) ;
return 0 ;
}
2008-06-15 05:17:11 +04:00
# ifdef CONFIG_DS1603
2007-08-22 00:34:16 +04:00
static int rtctmp ;
/* proc function to read/write RealTime Clock */
int proc_dolasatrtc ( ctl_table * table , int write , struct file * filp ,
void * buffer , size_t * lenp , loff_t * ppos )
{
int r ;
if ( ! write ) {
2007-10-12 02:46:08 +04:00
rtctmp = read_persistent_clock ( ) ;
2007-08-22 00:34:16 +04:00
/* check for time < 0 and set to 0 */
if ( rtctmp < 0 )
rtctmp = 0 ;
}
r = proc_dointvec ( table , write , filp , buffer , lenp , ppos ) ;
2008-06-15 05:17:11 +04:00
if ( r )
2007-08-22 00:34:16 +04:00
return r ;
2008-06-15 05:17:11 +04:00
if ( write )
rtc_mips_set_mmss ( rtctmp ) ;
2007-08-22 00:34:16 +04:00
return 0 ;
}
# endif
/* Sysctl for setting the IP addresses */
2008-10-16 09:04:23 +04:00
int sysctl_lasat_intvec ( ctl_table * table ,
2007-08-22 00:34:16 +04:00
void * oldval , size_t * oldlenp ,
void * newval , size_t newlen )
{
int r ;
2008-10-16 09:04:23 +04:00
r = sysctl_intvec ( table , oldval , oldlenp , newval , newlen ) ;
2008-06-15 05:17:11 +04:00
if ( r < 0 )
2007-08-22 00:34:16 +04:00
return r ;
2008-06-15 05:17:11 +04:00
2007-08-22 00:34:16 +04:00
if ( newval & & newlen )
lasat_write_eeprom_info ( ) ;
2008-06-15 05:17:11 +04:00
return 0 ;
2007-08-22 00:34:16 +04:00
}
# ifdef CONFIG_DS1603
/* Same for RTC */
2008-10-16 09:04:23 +04:00
int sysctl_lasat_rtc ( ctl_table * table ,
2007-08-22 00:34:16 +04:00
void * oldval , size_t * oldlenp ,
void * newval , size_t newlen )
{
int r ;
2007-10-12 02:46:08 +04:00
rtctmp = read_persistent_clock ( ) ;
2007-08-22 00:34:16 +04:00
if ( rtctmp < 0 )
rtctmp = 0 ;
2008-10-16 09:04:23 +04:00
r = sysctl_intvec ( table , oldval , oldlenp , newval , newlen ) ;
2008-06-15 05:17:11 +04:00
if ( r < 0 )
2007-08-22 00:34:16 +04:00
return r ;
if ( newval & & newlen )
2007-10-12 02:46:08 +04:00
rtc_mips_set_mmss ( rtctmp ) ;
2007-08-22 00:34:16 +04:00
2008-06-15 05:17:11 +04:00
return r ;
2007-08-22 00:34:16 +04:00
}
# endif
# ifdef CONFIG_INET
int proc_lasat_ip ( ctl_table * table , int write , struct file * filp ,
void * buffer , size_t * lenp , loff_t * ppos )
{
unsigned int ip ;
char * p , c ;
int len ;
2008-06-15 05:17:11 +04:00
char ipbuf [ 32 ] ;
2007-08-22 00:34:16 +04:00
if ( ! table - > data | | ! table - > maxlen | | ! * lenp | |
( * ppos & & ! write ) ) {
* lenp = 0 ;
return 0 ;
}
if ( write ) {
len = 0 ;
p = buffer ;
while ( len < * lenp ) {
2008-06-15 05:17:11 +04:00
if ( get_user ( c , p + + ) )
2007-08-22 00:34:16 +04:00
return - EFAULT ;
if ( c = = 0 | | c = = ' \n ' )
break ;
len + + ;
}
2008-06-15 05:17:11 +04:00
if ( len > = sizeof ( ipbuf ) - 1 )
len = sizeof ( ipbuf ) - 1 ;
if ( copy_from_user ( ipbuf , buffer , len ) )
2007-08-22 00:34:16 +04:00
return - EFAULT ;
2008-06-15 05:17:11 +04:00
ipbuf [ len ] = 0 ;
2007-08-22 00:34:16 +04:00
* ppos + = * lenp ;
/* Now see if we can convert it to a valid IP */
2008-06-15 05:17:11 +04:00
ip = in_aton ( ipbuf ) ;
2007-08-22 00:34:16 +04:00
* ( unsigned int * ) ( table - > data ) = ip ;
lasat_write_eeprom_info ( ) ;
} else {
ip = * ( unsigned int * ) ( table - > data ) ;
2008-06-15 05:17:11 +04:00
sprintf ( ipbuf , " %d.%d.%d.%d " ,
2007-08-22 00:34:16 +04:00
( ip ) & 0xff ,
( ip > > 8 ) & 0xff ,
( ip > > 16 ) & 0xff ,
( ip > > 24 ) & 0xff ) ;
2008-06-15 05:17:11 +04:00
len = strlen ( ipbuf ) ;
2007-08-22 00:34:16 +04:00
if ( len > * lenp )
len = * lenp ;
if ( len )
2008-06-15 05:17:11 +04:00
if ( copy_to_user ( buffer , ipbuf , len ) )
2007-08-22 00:34:16 +04:00
return - EFAULT ;
if ( len < * lenp ) {
2008-06-15 05:17:11 +04:00
if ( put_user ( ' \n ' , ( ( char * ) buffer ) + len ) )
2007-08-22 00:34:16 +04:00
return - EFAULT ;
len + + ;
}
* lenp = len ;
* ppos + = len ;
}
return 0 ;
}
2008-06-15 05:17:11 +04:00
# endif
2007-08-22 00:34:16 +04:00
2008-10-16 09:04:23 +04:00
static int sysctl_lasat_prid ( ctl_table * table ,
2007-08-22 00:34:16 +04:00
void * oldval , size_t * oldlenp ,
void * newval , size_t newlen )
{
int r ;
2008-10-16 09:04:23 +04:00
r = sysctl_intvec ( table , oldval , oldlenp , newval , newlen ) ;
2008-06-15 05:17:11 +04:00
if ( r < 0 )
2007-08-22 00:34:16 +04:00
return r ;
if ( newval & & newlen ) {
2008-06-15 05:17:11 +04:00
lasat_board_info . li_eeprom_info . prid = * ( int * ) newval ;
2007-08-22 00:34:16 +04:00
lasat_write_eeprom_info ( ) ;
lasat_init_board_info ( ) ;
}
return 0 ;
}
2008-06-15 05:17:11 +04:00
int proc_lasat_prid ( ctl_table * table , int write , struct file * filp ,
2007-08-22 00:34:16 +04:00
void * buffer , size_t * lenp , loff_t * ppos )
{
int r ;
r = proc_dointvec ( table , write , filp , buffer , lenp , ppos ) ;
2008-06-15 05:17:11 +04:00
if ( r < 0 )
2007-08-22 00:34:16 +04:00
return r ;
2008-06-15 05:17:11 +04:00
if ( write ) {
lasat_board_info . li_eeprom_info . prid =
lasat_board_info . li_prid ;
lasat_write_eeprom_info ( ) ;
lasat_init_board_info ( ) ;
2007-08-22 00:34:16 +04:00
}
return 0 ;
}
extern int lasat_boot_to_service ;
static ctl_table lasat_table [ ] = {
{
. 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 ,
2008-06-15 05:17:11 +04:00
. proc_handler = & proc_lasat_prid ,
. strategy = & sysctl_lasat_prid
2007-08-22 00:34:16 +04:00
} ,
# ifdef CONFIG_INET
{
. 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
} ,
{
2008-06-15 05:17:11 +04:00
. ctl_name = CTL_UNNUMBERED ,
2007-08-22 00:34:16 +04:00
. procname = " netmask " ,
. data = & lasat_board_info . li_eeprom_info . netmask ,
. maxlen = sizeof ( int ) ,
. mode = 0644 ,
. proc_handler = & proc_lasat_ip ,
. strategy = & sysctl_lasat_intvec
} ,
# endif
{
. 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
} ,
# ifdef CONFIG_DS1603
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " rtc " ,
. data = & rtctmp ,
. maxlen = sizeof ( int ) ,
. mode = 0644 ,
. proc_handler = & proc_dolasatrtc ,
. strategy = & sysctl_lasat_rtc
} ,
# endif
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " namestr " ,
. data = & lasat_board_info . li_namestr ,
. maxlen = sizeof ( lasat_board_info . li_namestr ) ,
. mode = 0444 ,
2008-06-15 05:17:11 +04:00
. proc_handler = & proc_dostring ,
2007-08-22 00:34:16 +04:00
. 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
} ,
{ }
} ;
static ctl_table lasat_root_table [ ] = {
{
. ctl_name = CTL_UNNUMBERED ,
. procname = " lasat " ,
. mode = 0555 ,
. child = lasat_table
} ,
{ }
} ;
static int __init lasat_register_sysctl ( void )
{
struct ctl_table_header * lasat_table_header ;
lasat_table_header =
register_sysctl_table ( lasat_root_table ) ;
2008-06-15 05:17:11 +04:00
if ( ! lasat_table_header ) {
printk ( KERN_ERR " Unable to register LASAT sysctl \n " ) ;
return - ENOMEM ;
}
2007-08-22 00:34:16 +04:00
return 0 ;
}
__initcall ( lasat_register_sysctl ) ;