usbmon: Add class for binary interface
authorPete Zaitcev <zaitcev@redhat.com>
Thu, 3 May 2007 23:51:16 +0000 (16:51 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 12 Jul 2007 23:29:47 +0000 (16:29 -0700)
Add a class which allows for an easier integration with udev.

This code was originally written by Paolo Abeni, and arrived to my tree
as a part of big patch to add binary API on December 18. As I understand,
Paolo always meant the class to be a part of the whole thing. This is his
udev rule to go along with the patch:

KERNEL=="usbmon[0-9]*", NAME="usbmon%n", MODE="0440",OWNER="root",GROUP="bin"

Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/mon/mon_bin.c
drivers/usb/mon/mon_main.c
drivers/usb/mon/mon_text.c
drivers/usb/mon/usb_mon.h

index 0af11a66207cf3e88bb151f2e067c024c5eeea46..c03dfd7a9d36f8fe460869158d78f2a599e1f28e 100644 (file)
@@ -4,7 +4,7 @@
  * This is a binary format reader.
  *
  * Copyright (C) 2006 Paolo Abeni (paolo.abeni@email.it)
- * Copyright (C) 2006 Pete Zaitcev (zaitcev@redhat.com)
+ * Copyright (C) 2006,2007 Pete Zaitcev (zaitcev@redhat.com)
  */
 
 #include <linux/kernel.h>
@@ -172,6 +172,7 @@ static inline struct mon_bin_hdr *MON_OFF2HDR(const struct mon_reader_bin *rp,
 
 #define MON_RING_EMPTY(rp)     ((rp)->b_cnt == 0)
 
+static struct class *mon_bin_class;
 static dev_t mon_bin_dev0;
 static struct cdev mon_bin_cdev;
 
@@ -1144,10 +1145,38 @@ static void mon_free_buff(struct mon_pgmap *map, int npages)
                free_page((unsigned long) map[n].ptr);
 }
 
+int mon_bin_add(struct mon_bus *mbus, const struct usb_bus *ubus)
+{
+       struct device *dev;
+       unsigned minor = ubus? ubus->busnum: 0;
+
+       if (minor >= MON_BIN_MAX_MINOR)
+               return 0;
+
+       dev = device_create(mon_bin_class, ubus? ubus->controller: NULL,
+                       MKDEV(MAJOR(mon_bin_dev0), minor), "usbmon%d", minor);
+       if (IS_ERR(dev))
+               return 0;
+
+       mbus->classdev = dev;
+       return 1;
+}
+
+void mon_bin_del(struct mon_bus *mbus)
+{
+       device_destroy(mon_bin_class, mbus->classdev->devt);
+}
+
 int __init mon_bin_init(void)
 {
        int rc;
 
+       mon_bin_class = class_create(THIS_MODULE, "usbmon");
+       if (IS_ERR(mon_bin_class)) {
+               rc = PTR_ERR(mon_bin_class);
+               goto err_class;
+       }
+
        rc = alloc_chrdev_region(&mon_bin_dev0, 0, MON_BIN_MAX_MINOR, "usbmon");
        if (rc < 0)
                goto err_dev;
@@ -1164,6 +1193,8 @@ int __init mon_bin_init(void)
 err_add:
        unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR);
 err_dev:
+       class_destroy(mon_bin_class);
+err_class:
        return rc;
 }
 
@@ -1171,4 +1202,5 @@ void mon_bin_exit(void)
 {
        cdev_del(&mon_bin_cdev);
        unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR);
+       class_destroy(mon_bin_class);
 }
index 8977ec0d0f9928218ada7a44fdb62cfd142aa072..ce61d8b0fd866b4ea91346296d828667d30a9468 100644 (file)
@@ -220,6 +220,8 @@ static void mon_bus_remove(struct usb_bus *ubus)
        list_del(&mbus->bus_link);
        if (mbus->text_inited)
                mon_text_del(mbus);
+       if (mbus->bin_inited)
+               mon_bin_del(mbus);
 
        mon_dissolve(mbus, ubus);
        kref_put(&mbus->ref, mon_bus_drop);
@@ -301,8 +303,8 @@ static void mon_bus_init(struct usb_bus *ubus)
        mbus->u_bus = ubus;
        ubus->mon_bus = mbus;
 
-       mbus->text_inited = mon_text_add(mbus, ubus->busnum);
-       // mon_bin_add(...)
+       mbus->text_inited = mon_text_add(mbus, ubus);
+       mbus->bin_inited = mon_bin_add(mbus, ubus);
 
        mutex_lock(&mon_lock);
        list_add_tail(&mbus->bus_link, &mon_buses);
@@ -321,8 +323,8 @@ static void mon_bus0_init(void)
        spin_lock_init(&mbus->lock);
        INIT_LIST_HEAD(&mbus->r_list);
 
-       mbus->text_inited = mon_text_add(mbus, 0);
-       // mbus->bin_inited = mon_bin_add(mbus, 0);
+       mbus->text_inited = mon_text_add(mbus, NULL);
+       mbus->bin_inited = mon_bin_add(mbus, NULL);
 }
 
 /*
@@ -403,6 +405,8 @@ static void __exit mon_exit(void)
 
                if (mbus->text_inited)
                        mon_text_del(mbus);
+               if (mbus->bin_inited)
+                       mon_bin_del(mbus);
 
                /*
                 * This never happens, because the open/close paths in
@@ -423,6 +427,8 @@ static void __exit mon_exit(void)
        mbus = &mon_bus0;
        if (mbus->text_inited)
                mon_text_del(mbus);
+       if (mbus->bin_inited)
+               mon_bin_del(mbus);
 
        mutex_unlock(&mon_lock);
 
index ec0cc51e39acc42b0576b15c99bced374228fc2e..982b773d71e69f186210322e98c434ba78425d21 100644 (file)
@@ -655,20 +655,24 @@ static const struct file_operations mon_fops_text_u = {
        .release =      mon_text_release,
 };
 
-int mon_text_add(struct mon_bus *mbus, int busnum)
+int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus)
 {
        struct dentry *d;
        enum { NAMESZ = 10 };
        char name[NAMESZ];
+       int busnum = ubus? ubus->busnum: 0;
        int rc;
 
-       rc = snprintf(name, NAMESZ, "%dt", busnum);
-       if (rc <= 0 || rc >= NAMESZ)
-               goto err_print_t;
-       d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_t);
-       if (d == NULL)
-               goto err_create_t;
-       mbus->dent_t = d;
+       if (ubus != NULL) {
+               rc = snprintf(name, NAMESZ, "%dt", busnum);
+               if (rc <= 0 || rc >= NAMESZ)
+                       goto err_print_t;
+               d = debugfs_create_file(name, 0600, mon_dir, mbus,
+                                                            &mon_fops_text_t);
+               if (d == NULL)
+                       goto err_create_t;
+               mbus->dent_t = d;
+       }
 
        rc = snprintf(name, NAMESZ, "%du", busnum);
        if (rc <= 0 || rc >= NAMESZ)
@@ -694,8 +698,10 @@ err_print_s:
        mbus->dent_u = NULL;
 err_create_u:
 err_print_u:
-       debugfs_remove(mbus->dent_t);
-       mbus->dent_t = NULL;
+       if (ubus != NULL) {
+               debugfs_remove(mbus->dent_t);
+               mbus->dent_t = NULL;
+       }
 err_create_t:
 err_print_t:
        return 0;
@@ -704,7 +710,8 @@ err_print_t:
 void mon_text_del(struct mon_bus *mbus)
 {
        debugfs_remove(mbus->dent_u);
-       debugfs_remove(mbus->dent_t);
+       if (mbus->dent_t != NULL)
+               debugfs_remove(mbus->dent_t);
        debugfs_remove(mbus->dent_s);
 }
 
index 13d63255283e8682e2c4fe032f80be2dcc5248fa..f68ad6d99ad7563581919fb024c37a4c5259a6e7 100644 (file)
@@ -20,9 +20,11 @@ struct mon_bus {
        struct usb_bus *u_bus;
 
        int text_inited;
+       int bin_inited;
        struct dentry *dent_s;          /* Debugging file */
        struct dentry *dent_t;          /* Text interface file */
        struct dentry *dent_u;          /* Second text interface file */
+       struct device *classdev;        /* Device in usbmon class */
 
        /* Ref */
        int nreaders;                   /* Under mon_lock AND mbus->lock */
@@ -52,9 +54,10 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r);
 
 struct mon_bus *mon_bus_lookup(unsigned int num);
 
-int /*bool*/ mon_text_add(struct mon_bus *mbus, int busnum);
+int /*bool*/ mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus);
 void mon_text_del(struct mon_bus *mbus);
-// void mon_bin_add(struct mon_bus *);
+int /*bool*/ mon_bin_add(struct mon_bus *mbus, const struct usb_bus *ubus);
+void mon_bin_del(struct mon_bus *mbus);
 
 int __init mon_text_init(void);
 void mon_text_exit(void);