From ce7cd137fced114d49178b73d468b82096a107fb Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Thu, 3 May 2007 16:51:16 -0700 Subject: [PATCH] usbmon: Add class for binary interface 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 Signed-off-by: Greg Kroah-Hartman --- drivers/usb/mon/mon_bin.c | 34 +++++++++++++++++++++++++++++++++- drivers/usb/mon/mon_main.c | 14 ++++++++++---- drivers/usb/mon/mon_text.c | 29 ++++++++++++++++++----------- drivers/usb/mon/usb_mon.h | 7 +++++-- 4 files changed, 66 insertions(+), 18 deletions(-) diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 0af11a66207c..c03dfd7a9d36 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -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 @@ -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); } diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index 8977ec0d0f99..ce61d8b0fd86 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c @@ -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); diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index ec0cc51e39ac..982b773d71e6 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -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); } diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h index 13d63255283e..f68ad6d99ad7 100644 --- a/drivers/usb/mon/usb_mon.h +++ b/drivers/usb/mon/usb_mon.h @@ -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);