2006-12-06 17:25:33 -06:00
/* cytune.c -- Tune Cyclades driver
*
* Copyright 1995 Nick Simicich ( njs @ scifi . emi . net )
*
* Modifications by Rik Faith ( faith @ cs . unc . edu )
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement :
* This product includes software developed by the Nick Simicich
* 4. Neither the name of the Nick Simicich nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY NICK SIMICICH AND CONTRIBUTORS ` ` AS IS ' ' AND
* ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL NICK SIMICICH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
* LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE .
*
*/
2006-12-06 17:25:39 -06:00
/*
2006-12-06 17:25:46 -06:00
* 1999 - 02 - 22 Arkadiusz Mi <EFBFBD> kiewicz < misiek @ pld . ORG . PL >
2006-12-06 17:25:39 -06:00
* - added Native Language Support
* Sun Mar 21 1999 - Arnaldo Carvalho de Melo < acme @ conectiva . com . br >
* - fixed strerr ( errno ) in gettext calls
*/
2006-12-06 17:25:33 -06:00
# include <stdio.h>
# include <stdlib.h>
# include <sys/types.h>
# include <sys/time.h>
# include <sys/ioctl.h>
# include <unistd.h>
2006-12-06 17:25:34 -06:00
# include <string.h>
2006-12-06 17:25:33 -06:00
# include <fcntl.h>
# include <errno.h>
2006-12-06 17:25:39 -06:00
# include <signal.h>
2006-12-06 17:25:33 -06:00
# include <linux/tty.h>
# include <termios.h>
2006-12-06 17:25:39 -06:00
# include "../defines.h" /* for NEED_tqueue_h */
# ifdef NEED_tqueue_h
# include <linux/tqueue.h> /* required for old kernels (for struct tq_struct) */
2006-12-06 17:25:35 -06:00
/* compilation errors on other kernels */
# endif
2006-12-06 17:25:33 -06:00
# include <linux/cyclades.h>
#if 0
# ifndef XMIT
# include <linux / version.h>
# if LINUX_VERSION_CODE > 66056
# define XMIT
# endif
# endif
# endif
2006-12-06 17:25:39 -06:00
# include "nls.h"
2006-12-06 17:25:33 -06:00
/* Until it gets put in the kernel,
toggle by hand . */
# undef XMIT
struct cyclades_control {
struct cyclades_monitor c ;
int cfile ;
int maxmax ;
double maxtran ;
double maxxmit ;
unsigned long threshold_value ;
unsigned long timeout_value ;
} ;
struct cyclades_control * cmon ;
int cmon_index ;
# define mvtime(tvpto, tvpfrom) (((tvpto)->tv_sec = (tvpfrom)->tv_sec),(tvpto)->tv_usec = (tvpfrom)->tv_usec)
2006-12-06 17:25:43 -06:00
static inline double
dtime ( struct timeval * tvpnew , struct timeval * tvpold ) {
2006-12-06 17:25:33 -06:00
double diff ;
diff = ( double ) tvpnew - > tv_sec - ( double ) tvpold - > tv_sec ;
diff + = ( ( double ) tvpnew - > tv_usec - ( double ) tvpold - > tv_usec ) / 1000000 ;
return diff ;
}
static int global_argc , global_optind ;
static char * * * global_argv ;
2006-12-06 17:25:43 -06:00
static void
2006-12-06 17:25:44 -06:00
summary ( int sig ) {
2006-12-06 17:25:33 -06:00
struct cyclades_control * cc ;
2006-12-06 17:25:44 -06:00
int argc , local_optind ;
2006-12-06 17:25:33 -06:00
char * * argv ;
int i , j ;
argc = global_argc ;
argv = * global_argv ;
2006-12-06 17:25:44 -06:00
local_optind = global_optind ;
2006-12-06 17:25:33 -06:00
2006-12-06 17:25:44 -06:00
if ( sig > 0 ) {
for ( i = local_optind ; i < argc ; i + + ) {
j = i - local_optind ;
2006-12-06 17:25:33 -06:00
cc = & cmon [ cmon_index ] ;
2006-12-06 17:25:39 -06:00
fprintf ( stderr , _ ( " File %s, For threshold value %lu, Maximum characters in fifo were %d, \n and the maximum transfer rate in characters/second was %f \n " ) ,
2006-12-06 17:25:33 -06:00
argv [ i ] ,
cc - > threshold_value ,
cc - > maxmax ,
cc - > maxtran ) ;
}
exit ( 0 ) ;
}
cc = & cmon [ cmon_index ] ;
2006-12-06 17:25:44 -06:00
if ( cc - > threshold_value > 0 & & sig ! = - 1 ) {
2006-12-06 17:25:39 -06:00
fprintf ( stderr , _ ( " File %s, For threshold value %lu and timrout value %lu, Maximum characters in fifo were %d, \n and the maximum transfer rate in characters/second was %f \n " ) ,
2006-12-06 17:25:44 -06:00
argv [ cmon_index + local_optind ] ,
2006-12-06 17:25:33 -06:00
cc - > threshold_value ,
cc - > timeout_value ,
cc - > maxmax ,
cc - > maxtran ) ;
}
cc - > maxmax = 0 ;
cc - > maxtran = 0.0 ;
cc - > threshold_value = 0 ;
cc - > timeout_value = 0 ;
}
static int query = 0 ;
static int interval = 1 ;
static int set = 0 ;
static int set_val = - 1 ;
static int get = 0 ;
static int set_def = 0 ;
static int set_def_val = - 1 ;
static int get_def = 0 ;
static int set_time = 0 ;
static int set_time_val = - 1 ;
static int set_def_time = 0 ;
static int set_def_time_val = - 1 ;
int main ( int argc , char * argv [ ] ) {
struct timeval lasttime , thistime ;
2006-12-06 17:25:34 -06:00
struct timezone tz = { 0 , 0 } ;
2006-12-06 17:25:33 -06:00
double diff ;
int errflg = 0 ;
int file ;
int numfiles ;
struct cyclades_monitor cywork ;
int i ;
unsigned long threshold_value ;
unsigned long timeout_value ;
double xfer_rate ;
# ifdef XMIT
double xmit_rate ;
# endif
global_argc = argc ; /* For signal routine. */
global_argv = & argv ; /* For signal routine. */
2006-12-06 17:25:39 -06:00
setlocale ( LC_ALL , " " ) ;
bindtextdomain ( PACKAGE , LOCALEDIR ) ;
textdomain ( PACKAGE ) ;
2006-12-06 17:25:53 -06:00
while ( ( i = getopt ( argc , argv , " qs:S:t:T:gGi: " ) ) ! = - 1 ) {
2006-12-06 17:25:33 -06:00
switch ( i ) {
case ' q ' :
query = 1 ;
break ;
case ' i ' :
interval = atoi ( optarg ) ;
if ( interval < = 0 ) {
2006-12-06 17:25:39 -06:00
fprintf ( stderr , _ ( " Invalid interval value: %s \n " ) , optarg ) ;
2006-12-06 17:25:33 -06:00
errflg + + ;
}
break ;
case ' s ' :
+ + set ;
set_val = atoi ( optarg ) ;
if ( set_val < = 0 | | set_val > 12 ) {
2006-12-06 17:25:39 -06:00
fprintf ( stderr , _ ( " Invalid set value: %s \n " ) , optarg ) ;
2006-12-06 17:25:33 -06:00
errflg + + ;
}
break ;
case ' S ' :
+ + set_def ;
set_def_val = atoi ( optarg ) ;
if ( set_def_val < 0 | | set_def_val > 12 ) {
2006-12-06 17:25:39 -06:00
fprintf ( stderr , _ ( " Invalid default value: %s \n " ) , optarg ) ;
2006-12-06 17:25:33 -06:00
errflg + + ;
}
break ;
case ' t ' :
+ + set_time ;
set_time_val = atoi ( optarg ) ;
if ( set_time_val < = 0 | | set_time_val > 255 ) {
2006-12-06 17:25:39 -06:00
fprintf ( stderr , _ ( " Invalid set time value: %s \n " ) , optarg ) ;
2006-12-06 17:25:33 -06:00
errflg + + ;
}
break ;
case ' T ' :
+ + set_def_time ;
set_def_time_val = atoi ( optarg ) ;
if ( set_def_time_val < 0 | | set_def_time_val > 255 ) {
2006-12-06 17:25:39 -06:00
fprintf ( stderr , _ ( " Invalid default time value: %s \n " ) , optarg ) ;
2006-12-06 17:25:33 -06:00
errflg + + ;
}
break ;
case ' g ' : + + get ; break ;
case ' G ' : + + get_def ; break ;
default :
errflg + + ;
}
}
numfiles = argc - optind ;
if ( errflg | | ( numfiles = = 0 )
| | ( ! query & & ! set & & ! set_def & &
! get & & ! get_def & & ! set_time & & ! set_def_time ) | |
( set & & set_def ) | | ( set_time & & set_def_time ) | |
( get & & get_def ) ) {
fprintf ( stderr ,
2006-12-06 17:25:39 -06:00
_ ( " Usage: %s [-q [-i interval]] ([-s value]|[-S value]) ([-t value]|[-T value]) [-g|-G] file [file...] \n " ) ,
2006-12-06 17:25:33 -06:00
argv [ 0 ] ) ;
exit ( 1 ) ;
}
global_optind = optind ; /* For signal routine. */
if ( set | | set_def ) {
2006-12-06 17:25:49 -06:00
for ( i = optind ; i < argc ; i + + ) {
2006-12-06 17:25:33 -06:00
file = open ( argv [ i ] , O_RDONLY ) ;
if ( file = = - 1 ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't open %s: %s \n " ) , argv [ i ] , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
if ( ioctl ( file ,
set ? CYSETTHRESH : CYSETDEFTHRESH ,
set ? set_val : set_def_val ) ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't set %s to threshold %d: %s \n " ) ,
argv [ i ] , set ? set_val : set_def_val , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
2006-12-06 17:25:49 -06:00
close ( file ) ;
2006-12-06 17:25:33 -06:00
}
}
if ( set_time | | set_def_time ) {
2006-12-06 17:25:49 -06:00
for ( i = optind ; i < argc ; i + + ) {
2006-12-06 17:25:33 -06:00
file = open ( argv [ i ] , O_RDONLY ) ;
if ( file = = - 1 ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't open %s: %s \n " ) , argv [ i ] , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
if ( ioctl ( file ,
set_time ? CYSETTIMEOUT : CYSETDEFTIMEOUT ,
set_time ? set_time_val : set_def_time_val ) ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't set %s to time threshold %d: %s \n " ) ,
argv [ i ] , set_time ? set_time_val : set_def_time_val , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
2006-12-06 17:25:49 -06:00
close ( file ) ;
2006-12-06 17:25:33 -06:00
}
}
if ( get | | get_def ) {
2006-12-06 17:25:49 -06:00
for ( i = optind ; i < argc ; i + + ) {
2006-12-06 17:25:33 -06:00
file = open ( argv [ i ] , O_RDONLY ) ;
if ( file = = - 1 ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't open %s: %s \n " ) , argv [ i ] , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
if ( ioctl ( file , get ? CYGETTHRESH : CYGETDEFTHRESH , & threshold_value ) ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't get threshold for %s: %s \n " ) ,
argv [ i ] , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
if ( ioctl ( file , get ? CYGETTIMEOUT : CYGETDEFTIMEOUT , & timeout_value ) ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't get timeout for %s: %s \n " ) ,
argv [ i ] , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
2006-12-06 17:25:49 -06:00
close ( file ) ;
if ( get )
printf ( _ ( " %s: %ld current threshold and %ld current timeout \n " ) ,
argv [ i ] , threshold_value , timeout_value ) ;
else
printf ( _ ( " %s: %ld default threshold and %ld default timeout \n " ) ,
argv [ i ] , threshold_value , timeout_value ) ;
2006-12-06 17:25:33 -06:00
}
}
if ( ! query ) return 0 ; /* must have been something earlier */
/* query stuff after this line */
cmon = ( struct cyclades_control * ) malloc ( sizeof ( struct cyclades_control )
* numfiles ) ;
if ( ! cmon ) {
2006-12-06 17:25:39 -06:00
perror ( _ ( " malloc failed " ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
if ( signal ( SIGINT , summary ) | |
signal ( SIGQUIT , summary ) | |
signal ( SIGTERM , summary ) ) {
2006-12-06 17:25:39 -06:00
perror ( _ ( " Can't set signal handler " ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
if ( gettimeofday ( & lasttime , & tz ) ) {
2006-12-06 17:25:39 -06:00
perror ( _ ( " gettimeofday failed " ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
for ( i = optind ; i < argc ; i + + ) {
cmon_index = i - optind ;
cmon [ cmon_index ] . cfile = open ( argv [ i ] , O_RDONLY ) ;
if ( - 1 = = cmon [ cmon_index ] . cfile ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't open %s: %s \n " ) , argv [ i ] , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
if ( ioctl ( cmon [ cmon_index ] . cfile , CYGETMON , & cmon [ cmon_index ] . c ) ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't issue CYGETMON on %s: %s \n " ) ,
argv [ i ] , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
summary ( - 1 ) ;
if ( ioctl ( cmon [ cmon_index ] . cfile , CYGETTHRESH , & threshold_value ) ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't get threshold for %s: %s \n " ) ,
argv [ i ] , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
if ( ioctl ( cmon [ cmon_index ] . cfile , CYGETTIMEOUT , & timeout_value ) ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't get timeout for %s: %s \n " ) ,
argv [ i ] , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
}
while ( 1 ) {
sleep ( interval ) ;
if ( gettimeofday ( & thistime , & tz ) ) {
2006-12-06 17:25:39 -06:00
perror ( _ ( " gettimeofday failed " ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
diff = dtime ( & thistime , & lasttime ) ;
mvtime ( & lasttime , & thistime ) ;
for ( i = optind ; i < argc ; i + + ) {
cmon_index = i - optind ;
if ( ioctl ( cmon [ cmon_index ] . cfile , CYGETMON , & cywork ) ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't issue CYGETMON on %s: %s \n " ) ,
argv [ i ] , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
if ( ioctl ( cmon [ cmon_index ] . cfile , CYGETTHRESH , & threshold_value ) ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't get threshold for %s: %s \n " ) ,
argv [ i ] , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
if ( ioctl ( cmon [ cmon_index ] . cfile , CYGETTIMEOUT , & timeout_value ) ) {
2006-12-06 17:25:39 -06:00
int errsv = errno ;
fprintf ( stderr , _ ( " Can't get timeout for %s: %s \n " ) ,
argv [ i ] , strerror ( errsv ) ) ;
2006-12-06 17:25:33 -06:00
exit ( 1 ) ;
}
xfer_rate = cywork . char_count / diff ;
# ifdef XMIT
xmit_rate = cywork . send_count / diff ;
# endif
if ( threshold_value ! = cmon [ cmon_index ] . threshold_value | |
timeout_value ! = cmon [ cmon_index ] . timeout_value ) {
summary ( - 2 ) ;
/* Note that the summary must come before the setting of */
/* threshold_value */
cmon [ cmon_index ] . threshold_value = threshold_value ;
cmon [ cmon_index ] . timeout_value = timeout_value ;
} else {
/* Don't record this first cycle after change */
if ( xfer_rate > cmon [ cmon_index ] . maxtran )
cmon [ cmon_index ] . maxtran = xfer_rate ;
# ifdef XMIT
if ( xmit_rate > cmon [ cmon_index ] . maxxmit )
cmon [ cmon_index ] . maxxmit = xmit_rate ;
# endif
if ( cywork . char_max > cmon [ cmon_index ] . maxmax )
cmon [ cmon_index ] . maxmax = cywork . char_max ;
}
# ifdef XMIT
2006-12-06 17:25:49 -06:00
printf ( _ ( " %s: %lu ints, %lu/%lu chars; fifo: %lu thresh, %lu tmout, "
" %lu max, %lu now \n " ) ,
2006-12-06 17:25:33 -06:00
argv [ i ] ,
cywork . int_count , cywork . char_count , cywork . send_count ,
threshold_value , timeout_value ,
cywork . char_max , cywork . char_last ) ;
2006-12-06 17:25:39 -06:00
printf ( _ ( " %f int/sec; %f rec, %f send (char/sec) \n " ) ,
2006-12-06 17:25:33 -06:00
cywork . int_count / diff ,
xfer_rate ,
xmit_rate ) ;
# else
2006-12-06 17:25:49 -06:00
printf ( _ ( " %s: %lu ints, %lu chars; fifo: %lu thresh, %lu tmout, "
" %lu max, %lu now \n " ) ,
2006-12-06 17:25:33 -06:00
argv [ i ] ,
cywork . int_count , cywork . char_count ,
threshold_value , timeout_value ,
cywork . char_max , cywork . char_last ) ;
2006-12-06 17:25:39 -06:00
printf ( _ ( " %f int/sec; %f rec (char/sec) \n " ) ,
2006-12-06 17:25:33 -06:00
cywork . int_count / diff ,
xfer_rate ) ;
# endif
memcpy ( & cmon [ cmon_index ] . c , & cywork , sizeof ( struct cyclades_monitor ) ) ;
}
}
return 0 ;
}