1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * The USB Monitor, inspired by Dave Harding's USBMon. 3*1da177e4SLinus Torvalds * 4*1da177e4SLinus Torvalds * This is the 's' or 'stat' reader which debugs usbmon itself. 5*1da177e4SLinus Torvalds * Note that this code blows through locks, so make sure that 6*1da177e4SLinus Torvalds * /dbg/usbmon/0s is well protected from non-root users. 7*1da177e4SLinus Torvalds * 8*1da177e4SLinus Torvalds */ 9*1da177e4SLinus Torvalds 10*1da177e4SLinus Torvalds #include <linux/kernel.h> 11*1da177e4SLinus Torvalds #include <linux/usb.h> 12*1da177e4SLinus Torvalds #include <asm/uaccess.h> 13*1da177e4SLinus Torvalds 14*1da177e4SLinus Torvalds #include "usb_mon.h" 15*1da177e4SLinus Torvalds 16*1da177e4SLinus Torvalds #define STAT_BUF_SIZE 80 17*1da177e4SLinus Torvalds 18*1da177e4SLinus Torvalds struct snap { 19*1da177e4SLinus Torvalds int slen; 20*1da177e4SLinus Torvalds char str[STAT_BUF_SIZE]; 21*1da177e4SLinus Torvalds }; 22*1da177e4SLinus Torvalds 23*1da177e4SLinus Torvalds static int mon_stat_open(struct inode *inode, struct file *file) 24*1da177e4SLinus Torvalds { 25*1da177e4SLinus Torvalds struct mon_bus *mbus; 26*1da177e4SLinus Torvalds struct snap *sp; 27*1da177e4SLinus Torvalds 28*1da177e4SLinus Torvalds if ((sp = kmalloc(sizeof(struct snap), GFP_KERNEL)) == NULL) 29*1da177e4SLinus Torvalds return -ENOMEM; 30*1da177e4SLinus Torvalds 31*1da177e4SLinus Torvalds mbus = inode->u.generic_ip; 32*1da177e4SLinus Torvalds 33*1da177e4SLinus Torvalds sp->slen = snprintf(sp->str, STAT_BUF_SIZE, 34*1da177e4SLinus Torvalds "nreaders %d text_lost %u\n", 35*1da177e4SLinus Torvalds mbus->nreaders, mbus->cnt_text_lost); 36*1da177e4SLinus Torvalds 37*1da177e4SLinus Torvalds file->private_data = sp; 38*1da177e4SLinus Torvalds return 0; 39*1da177e4SLinus Torvalds } 40*1da177e4SLinus Torvalds 41*1da177e4SLinus Torvalds static ssize_t mon_stat_read(struct file *file, char __user *buf, 42*1da177e4SLinus Torvalds size_t nbytes, loff_t *ppos) 43*1da177e4SLinus Torvalds { 44*1da177e4SLinus Torvalds struct snap *sp = file->private_data; 45*1da177e4SLinus Torvalds loff_t pos = *ppos; 46*1da177e4SLinus Torvalds int cnt; 47*1da177e4SLinus Torvalds 48*1da177e4SLinus Torvalds if (pos < 0 || pos >= sp->slen) 49*1da177e4SLinus Torvalds return 0; 50*1da177e4SLinus Torvalds if (nbytes == 0) 51*1da177e4SLinus Torvalds return 0; 52*1da177e4SLinus Torvalds if ((cnt = sp->slen - pos) > nbytes) 53*1da177e4SLinus Torvalds cnt = nbytes; 54*1da177e4SLinus Torvalds if (copy_to_user(buf, sp->str + pos, cnt)) 55*1da177e4SLinus Torvalds return -EFAULT; 56*1da177e4SLinus Torvalds *ppos = pos + cnt; 57*1da177e4SLinus Torvalds return cnt; 58*1da177e4SLinus Torvalds } 59*1da177e4SLinus Torvalds 60*1da177e4SLinus Torvalds static int mon_stat_release(struct inode *inode, struct file *file) 61*1da177e4SLinus Torvalds { 62*1da177e4SLinus Torvalds return 0; 63*1da177e4SLinus Torvalds } 64*1da177e4SLinus Torvalds 65*1da177e4SLinus Torvalds struct file_operations mon_fops_stat = { 66*1da177e4SLinus Torvalds .owner = THIS_MODULE, 67*1da177e4SLinus Torvalds .open = mon_stat_open, 68*1da177e4SLinus Torvalds .llseek = no_llseek, 69*1da177e4SLinus Torvalds .read = mon_stat_read, 70*1da177e4SLinus Torvalds /* .write = mon_stat_write, */ 71*1da177e4SLinus Torvalds /* .poll = mon_stat_poll, */ 72*1da177e4SLinus Torvalds /* .ioctl = mon_stat_ioctl, */ 73*1da177e4SLinus Torvalds .release = mon_stat_release, 74*1da177e4SLinus Torvalds }; 75