2005-04-17 02:20:36 +04:00
/*
* Kernel CAPI 2.0 Module - / proc / capi handling
*
* Copyright 1999 by Carsten Paeth < calle @ calle . de >
* Copyright 2002 by Kai Germaschewski < kai @ germaschewski . name >
*
* This software may be used and distributed according to the terms
* of the GNU General Public License , incorporated herein by reference .
*
*/
# include "kcapi.h"
# include <linux/proc_fs.h>
# include <linux/seq_file.h>
# include <linux/init.h>
2010-02-08 13:12:10 +03:00
static char * state2str ( unsigned short state )
2005-04-17 02:20:36 +04:00
{
2010-02-08 13:12:10 +03:00
switch ( state ) {
case CAPI_CTR_DETECTED : return " detected " ;
case CAPI_CTR_LOADING : return " loading " ;
case CAPI_CTR_RUNNING : return " running " ;
2005-04-17 02:20:36 +04:00
default : return " ??? " ;
}
}
// /proc/capi
// ===========================================================================
// /proc/capi/controller:
// cnr driver cardstate name driverinfo
// /proc/capi/contrstats:
// cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
// ---------------------------------------------------------------------------
static void * controller_start ( struct seq_file * seq , loff_t * pos )
2010-02-08 13:12:14 +03:00
__acquires ( capi_controller_lock )
2005-04-17 02:20:36 +04:00
{
2010-02-08 13:12:14 +03:00
mutex_lock ( & capi_controller_lock ) ;
2005-04-17 02:20:36 +04:00
if ( * pos < CAPI_MAXCONTR )
2010-02-08 13:12:10 +03:00
return & capi_controller [ * pos ] ;
2005-04-17 02:20:36 +04:00
return NULL ;
}
static void * controller_next ( struct seq_file * seq , void * v , loff_t * pos )
{
+ + * pos ;
if ( * pos < CAPI_MAXCONTR )
2010-02-08 13:12:10 +03:00
return & capi_controller [ * pos ] ;
2005-04-17 02:20:36 +04:00
return NULL ;
}
static void controller_stop ( struct seq_file * seq , void * v )
2010-02-08 13:12:14 +03:00
__releases ( capi_controller_lock )
2005-04-17 02:20:36 +04:00
{
2010-02-08 13:12:14 +03:00
mutex_unlock ( & capi_controller_lock ) ;
2005-04-17 02:20:36 +04:00
}
static int controller_show ( struct seq_file * seq , void * v )
{
struct capi_ctr * ctr = * ( struct capi_ctr * * ) v ;
if ( ! ctr )
return 0 ;
seq_printf ( seq , " %d %-10s %-8s %-16s %s \n " ,
ctr - > cnr , ctr - > driver_name ,
2010-02-08 13:12:10 +03:00
state2str ( ctr - > state ) ,
2005-04-17 02:20:36 +04:00
ctr - > name ,
ctr - > procinfo ? ctr - > procinfo ( ctr ) : " " ) ;
return 0 ;
}
static int contrstats_show ( struct seq_file * seq , void * v )
{
struct capi_ctr * ctr = * ( struct capi_ctr * * ) v ;
if ( ! ctr )
return 0 ;
seq_printf ( seq , " %d %lu %lu %lu %lu \n " ,
ctr - > cnr ,
ctr - > nrecvctlpkt ,
ctr - > nrecvdatapkt ,
ctr - > nsentctlpkt ,
ctr - > nsentdatapkt ) ;
return 0 ;
}
2009-09-23 03:43:43 +04:00
static const struct seq_operations seq_controller_ops = {
2005-04-17 02:20:36 +04:00
. start = controller_start ,
. next = controller_next ,
. stop = controller_stop ,
. show = controller_show ,
} ;
2009-09-23 03:43:43 +04:00
static const struct seq_operations seq_contrstats_ops = {
2005-04-17 02:20:36 +04:00
. start = controller_start ,
. next = controller_next ,
. stop = controller_stop ,
. show = contrstats_show ,
} ;
static int seq_controller_open ( struct inode * inode , struct file * file )
{
return seq_open ( file , & seq_controller_ops ) ;
}
static int seq_contrstats_open ( struct inode * inode , struct file * file )
{
return seq_open ( file , & seq_contrstats_ops ) ;
}
2007-02-12 11:55:32 +03:00
static const struct file_operations proc_controller_ops = {
2008-04-29 12:02:30 +04:00
. owner = THIS_MODULE ,
2005-04-17 02:20:36 +04:00
. open = seq_controller_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = seq_release ,
} ;
2007-02-12 11:55:32 +03:00
static const struct file_operations proc_contrstats_ops = {
2008-04-29 12:02:30 +04:00
. owner = THIS_MODULE ,
2005-04-17 02:20:36 +04:00
. open = seq_contrstats_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = seq_release ,
} ;
// /proc/capi/applications:
// applid l3cnt dblkcnt dblklen #ncci recvqueuelen
// /proc/capi/applstats:
// applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
// ---------------------------------------------------------------------------
2010-02-08 13:12:15 +03:00
static void * applications_start ( struct seq_file * seq , loff_t * pos )
__acquires ( capi_controller_lock )
2005-04-17 02:20:36 +04:00
{
2010-02-08 13:12:15 +03:00
mutex_lock ( & capi_controller_lock ) ;
2005-04-17 02:20:36 +04:00
if ( * pos < CAPI_MAXAPPL )
return & capi_applications [ * pos ] ;
return NULL ;
}
static void *
applications_next ( struct seq_file * seq , void * v , loff_t * pos )
{
+ + * pos ;
if ( * pos < CAPI_MAXAPPL )
return & capi_applications [ * pos ] ;
return NULL ;
}
2010-02-08 13:12:15 +03:00
static void applications_stop ( struct seq_file * seq , void * v )
__releases ( capi_controller_lock )
2005-04-17 02:20:36 +04:00
{
2010-02-08 13:12:15 +03:00
mutex_unlock ( & capi_controller_lock ) ;
2005-04-17 02:20:36 +04:00
}
static int
applications_show ( struct seq_file * seq , void * v )
{
struct capi20_appl * ap = * ( struct capi20_appl * * ) v ;
if ( ! ap )
return 0 ;
seq_printf ( seq , " %u %d %d %d \n " ,
ap - > applid ,
ap - > rparam . level3cnt ,
ap - > rparam . datablkcnt ,
ap - > rparam . datablklen ) ;
return 0 ;
}
static int
applstats_show ( struct seq_file * seq , void * v )
{
struct capi20_appl * ap = * ( struct capi20_appl * * ) v ;
if ( ! ap )
return 0 ;
seq_printf ( seq , " %u %lu %lu %lu %lu \n " ,
ap - > applid ,
ap - > nrecvctlpkt ,
ap - > nrecvdatapkt ,
ap - > nsentctlpkt ,
ap - > nsentdatapkt ) ;
return 0 ;
}
2009-09-23 03:43:43 +04:00
static const struct seq_operations seq_applications_ops = {
2005-04-17 02:20:36 +04:00
. start = applications_start ,
. next = applications_next ,
. stop = applications_stop ,
. show = applications_show ,
} ;
2009-09-23 03:43:43 +04:00
static const struct seq_operations seq_applstats_ops = {
2005-04-17 02:20:36 +04:00
. start = applications_start ,
. next = applications_next ,
. stop = applications_stop ,
. show = applstats_show ,
} ;
static int
seq_applications_open ( struct inode * inode , struct file * file )
{
return seq_open ( file , & seq_applications_ops ) ;
}
static int
seq_applstats_open ( struct inode * inode , struct file * file )
{
return seq_open ( file , & seq_applstats_ops ) ;
}
2007-02-12 11:55:32 +03:00
static const struct file_operations proc_applications_ops = {
2008-04-29 12:02:30 +04:00
. owner = THIS_MODULE ,
2005-04-17 02:20:36 +04:00
. open = seq_applications_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = seq_release ,
} ;
2007-02-12 11:55:32 +03:00
static const struct file_operations proc_applstats_ops = {
2008-04-29 12:02:30 +04:00
. owner = THIS_MODULE ,
2005-04-17 02:20:36 +04:00
. open = seq_applstats_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = seq_release ,
} ;
// ---------------------------------------------------------------------------
static void * capi_driver_start ( struct seq_file * seq , loff_t * pos )
2010-02-08 13:12:11 +03:00
__acquires ( & capi_drivers_lock )
2005-04-17 02:20:36 +04:00
{
2010-02-08 13:12:11 +03:00
mutex_lock ( & capi_drivers_lock ) ;
2007-07-17 15:04:18 +04:00
return seq_list_start ( & capi_drivers , * pos ) ;
2005-04-17 02:20:36 +04:00
}
static void * capi_driver_next ( struct seq_file * seq , void * v , loff_t * pos )
{
2007-07-17 15:04:18 +04:00
return seq_list_next ( v , & capi_drivers , pos ) ;
2005-04-17 02:20:36 +04:00
}
static void capi_driver_stop ( struct seq_file * seq , void * v )
2010-02-08 13:12:11 +03:00
__releases ( & capi_drivers_lock )
2005-04-17 02:20:36 +04:00
{
2010-02-08 13:12:11 +03:00
mutex_unlock ( & capi_drivers_lock ) ;
2005-04-17 02:20:36 +04:00
}
static int capi_driver_show ( struct seq_file * seq , void * v )
{
2007-07-17 15:04:18 +04:00
struct capi_driver * drv = list_entry ( v , struct capi_driver , list ) ;
2005-04-17 02:20:36 +04:00
seq_printf ( seq , " %-32s %s \n " , drv - > name , drv - > revision ) ;
return 0 ;
}
2009-09-23 03:43:43 +04:00
static const struct seq_operations seq_capi_driver_ops = {
2005-04-17 02:20:36 +04:00
. start = capi_driver_start ,
. next = capi_driver_next ,
. stop = capi_driver_stop ,
. show = capi_driver_show ,
} ;
static int
seq_capi_driver_open ( struct inode * inode , struct file * file )
{
int err ;
err = seq_open ( file , & seq_capi_driver_ops ) ;
return err ;
}
2007-02-12 11:55:32 +03:00
static const struct file_operations proc_driver_ops = {
2008-04-29 12:02:30 +04:00
. owner = THIS_MODULE ,
2005-04-17 02:20:36 +04:00
. open = seq_capi_driver_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = seq_release ,
} ;
// ---------------------------------------------------------------------------
void __init
kcapi_proc_init ( void )
{
proc_mkdir ( " capi " , NULL ) ;
proc_mkdir ( " capi/controllers " , NULL ) ;
2008-04-29 12:02:30 +04:00
proc_create ( " capi/controller " , 0 , NULL , & proc_controller_ops ) ;
proc_create ( " capi/contrstats " , 0 , NULL , & proc_contrstats_ops ) ;
proc_create ( " capi/applications " , 0 , NULL , & proc_applications_ops ) ;
proc_create ( " capi/applstats " , 0 , NULL , & proc_applstats_ops ) ;
proc_create ( " capi/driver " , 0 , NULL , & proc_driver_ops ) ;
2005-04-17 02:20:36 +04:00
}
void __exit
kcapi_proc_exit ( void )
{
remove_proc_entry ( " capi/driver " , NULL ) ;
remove_proc_entry ( " capi/controller " , NULL ) ;
remove_proc_entry ( " capi/contrstats " , NULL ) ;
remove_proc_entry ( " capi/applications " , NULL ) ;
remove_proc_entry ( " capi/applstats " , NULL ) ;
remove_proc_entry ( " capi/controllers " , NULL ) ;
remove_proc_entry ( " capi " , NULL ) ;
}