2005-04-16 15:20:36 -07:00
/*
* The USB Monitor , inspired by Dave Harding ' s USBMon .
*
* This is the ' s ' or ' stat ' reader which debugs usbmon itself .
* Note that this code blows through locks , so make sure that
* / dbg / usbmon / 0 s is well protected from non - root users .
*
*/
# include <linux/kernel.h>
# include <linux/usb.h>
# include <asm/uaccess.h>
# include "usb_mon.h"
# define STAT_BUF_SIZE 80
struct snap {
int slen ;
char str [ STAT_BUF_SIZE ] ;
} ;
static int mon_stat_open ( struct inode * inode , struct file * file )
{
struct mon_bus * mbus ;
struct snap * sp ;
if ( ( sp = kmalloc ( sizeof ( struct snap ) , GFP_KERNEL ) ) = = NULL )
return - ENOMEM ;
2006-09-27 01:50:46 -07:00
mbus = inode - > i_private ;
2005-04-16 15:20:36 -07:00
sp - > slen = snprintf ( sp - > str , STAT_BUF_SIZE ,
2006-06-09 20:10:10 -07:00
" nreaders %d events %u text_lost %u \n " ,
mbus - > nreaders , mbus - > cnt_events , mbus - > cnt_text_lost ) ;
2005-04-16 15:20:36 -07:00
file - > private_data = sp ;
return 0 ;
}
static ssize_t mon_stat_read ( struct file * file , char __user * buf ,
size_t nbytes , loff_t * ppos )
{
struct snap * sp = file - > private_data ;
loff_t pos = * ppos ;
int cnt ;
if ( pos < 0 | | pos > = sp - > slen )
return 0 ;
if ( nbytes = = 0 )
return 0 ;
if ( ( cnt = sp - > slen - pos ) > nbytes )
cnt = nbytes ;
if ( copy_to_user ( buf , sp - > str + pos , cnt ) )
return - EFAULT ;
* ppos = pos + cnt ;
return cnt ;
}
static int mon_stat_release ( struct inode * inode , struct file * file )
{
2008-04-14 21:27:00 +08:00
struct snap * sp = file - > private_data ;
file - > private_data = NULL ;
kfree ( sp ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
2006-08-05 20:37:11 -03:00
const struct file_operations mon_fops_stat = {
2005-04-16 15:20:36 -07:00
. owner = THIS_MODULE ,
. open = mon_stat_open ,
. llseek = no_llseek ,
. read = mon_stat_read ,
/* .write = mon_stat_write, */
/* .poll = mon_stat_poll, */
/* .ioctl = mon_stat_ioctl, */
. release = mon_stat_release ,
} ;