aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/mon/mon_text.c
diff options
context:
space:
mode:
authorPete Zaitcev <zaitcev@redhat.com>2006-12-30 22:43:10 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 15:44:34 -0800
commit6f23ee1fefdc1f80bd8a3ab04a1c41ab2dec14c9 (patch)
tree36a5241c29333580de3e3c75e2c62edc1cdf583c /drivers/usb/mon/mon_text.c
parenta8ef36bc0a5fe973bddaa54a5a07cda29e04a602 (diff)
USB: add binary API to usbmon
This patch adds a new, "binary" API in addition to the old, text API usbmon had before. The new API allows for less CPU use, and it allows to capture all data from a packet where old API only captured 32 bytes at most. There are some limitations and conditions to this, e.g. in case someone constructs a URB with 1GB of data, it's not likely to be captured, because even the huge buffers of the new reader are finite. Nonetheless, I expect this new capability to capture all data for all real life scenarios. The downside is, a special user mode application is required where cat(1) worked before. I have sample code at http://people.redhat.com/zaitcev/linux/ and Paolo Abeni is working on patching libpcap. This patch was initially written by Paolo and later I tweaked it, and we had a little back-and-forth. So this is a jointly authored patch, but I am submitting this I am responsible for the bugs. Signed-off-by: Paolo Abeni <paolo.abeni@email.it> Signed-off-by: Pete Zaitcev <zaitcev@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/mon/mon_text.c')
-rw-r--r--drivers/usb/mon/mon_text.c67
1 files changed, 66 insertions, 1 deletions
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 05cf2c9a8f8..d38a1279d9d 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -9,6 +9,7 @@
#include <linux/usb.h>
#include <linux/time.h>
#include <linux/mutex.h>
+#include <linux/debugfs.h>
#include <asm/uaccess.h>
#include "usb_mon.h"
@@ -63,6 +64,8 @@ struct mon_reader_text {
char slab_name[SLAB_NAME_SZ];
};
+static struct dentry *mon_dir; /* Usually /sys/kernel/debug/usbmon */
+
static void mon_text_ctor(void *, struct kmem_cache *, unsigned long);
/*
@@ -436,7 +439,7 @@ static int mon_text_release(struct inode *inode, struct file *file)
return 0;
}
-const struct file_operations mon_fops_text = {
+static const struct file_operations mon_fops_text = {
.owner = THIS_MODULE,
.open = mon_text_open,
.llseek = no_llseek,
@@ -447,6 +450,47 @@ const struct file_operations mon_fops_text = {
.release = mon_text_release,
};
+int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus)
+{
+ struct dentry *d;
+ enum { NAMESZ = 10 };
+ char name[NAMESZ];
+ int rc;
+
+ rc = snprintf(name, NAMESZ, "%dt", ubus->busnum);
+ if (rc <= 0 || rc >= NAMESZ)
+ goto err_print_t;
+ d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text);
+ if (d == NULL)
+ goto err_create_t;
+ mbus->dent_t = d;
+
+ /* XXX The stats do not belong to here (text API), but oh well... */
+ rc = snprintf(name, NAMESZ, "%ds", ubus->busnum);
+ if (rc <= 0 || rc >= NAMESZ)
+ goto err_print_s;
+ d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_stat);
+ if (d == NULL)
+ goto err_create_s;
+ mbus->dent_s = d;
+
+ return 1;
+
+err_create_s:
+err_print_s:
+ debugfs_remove(mbus->dent_t);
+ mbus->dent_t = NULL;
+err_create_t:
+err_print_t:
+ return 0;
+}
+
+void mon_text_del(struct mon_bus *mbus)
+{
+ debugfs_remove(mbus->dent_t);
+ debugfs_remove(mbus->dent_s);
+}
+
/*
* Slab interface: constructor.
*/
@@ -459,3 +503,24 @@ static void mon_text_ctor(void *mem, struct kmem_cache *slab, unsigned long sfla
memset(mem, 0xe5, sizeof(struct mon_event_text));
}
+int __init mon_text_init(void)
+{
+ struct dentry *mondir;
+
+ mondir = debugfs_create_dir("usbmon", NULL);
+ if (IS_ERR(mondir)) {
+ printk(KERN_NOTICE TAG ": debugfs is not available\n");
+ return -ENODEV;
+ }
+ if (mondir == NULL) {
+ printk(KERN_NOTICE TAG ": unable to create usbmon directory\n");
+ return -ENODEV;
+ }
+ mon_dir = mondir;
+ return 0;
+}
+
+void __exit mon_text_exit(void)
+{
+ debugfs_remove(mon_dir);
+}