Commit ce7cd137 authored by Pete Zaitcev's avatar Pete Zaitcev Committed by Greg Kroah-Hartman

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: default avatarPete Zaitcev <zaitcev@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 49cdee0e
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* This is a binary format reader. * This is a binary format reader.
* *
* Copyright (C) 2006 Paolo Abeni (paolo.abeni@email.it) * 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> #include <linux/kernel.h>
...@@ -172,6 +172,7 @@ static inline struct mon_bin_hdr *MON_OFF2HDR(const struct mon_reader_bin *rp, ...@@ -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) #define MON_RING_EMPTY(rp) ((rp)->b_cnt == 0)
static struct class *mon_bin_class;
static dev_t mon_bin_dev0; static dev_t mon_bin_dev0;
static struct cdev mon_bin_cdev; static struct cdev mon_bin_cdev;
...@@ -1144,10 +1145,38 @@ static void mon_free_buff(struct mon_pgmap *map, int npages) ...@@ -1144,10 +1145,38 @@ static void mon_free_buff(struct mon_pgmap *map, int npages)
free_page((unsigned long) map[n].ptr); 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 __init mon_bin_init(void)
{ {
int rc; 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"); rc = alloc_chrdev_region(&mon_bin_dev0, 0, MON_BIN_MAX_MINOR, "usbmon");
if (rc < 0) if (rc < 0)
goto err_dev; goto err_dev;
...@@ -1164,6 +1193,8 @@ int __init mon_bin_init(void) ...@@ -1164,6 +1193,8 @@ int __init mon_bin_init(void)
err_add: err_add:
unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR); unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR);
err_dev: err_dev:
class_destroy(mon_bin_class);
err_class:
return rc; return rc;
} }
...@@ -1171,4 +1202,5 @@ void mon_bin_exit(void) ...@@ -1171,4 +1202,5 @@ void mon_bin_exit(void)
{ {
cdev_del(&mon_bin_cdev); cdev_del(&mon_bin_cdev);
unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR); unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR);
class_destroy(mon_bin_class);
} }
...@@ -220,6 +220,8 @@ static void mon_bus_remove(struct usb_bus *ubus) ...@@ -220,6 +220,8 @@ static void mon_bus_remove(struct usb_bus *ubus)
list_del(&mbus->bus_link); list_del(&mbus->bus_link);
if (mbus->text_inited) if (mbus->text_inited)
mon_text_del(mbus); mon_text_del(mbus);
if (mbus->bin_inited)
mon_bin_del(mbus);
mon_dissolve(mbus, ubus); mon_dissolve(mbus, ubus);
kref_put(&mbus->ref, mon_bus_drop); kref_put(&mbus->ref, mon_bus_drop);
...@@ -301,8 +303,8 @@ static void mon_bus_init(struct usb_bus *ubus) ...@@ -301,8 +303,8 @@ static void mon_bus_init(struct usb_bus *ubus)
mbus->u_bus = ubus; mbus->u_bus = ubus;
ubus->mon_bus = mbus; ubus->mon_bus = mbus;
mbus->text_inited = mon_text_add(mbus, ubus->busnum); mbus->text_inited = mon_text_add(mbus, ubus);
// mon_bin_add(...) mbus->bin_inited = mon_bin_add(mbus, ubus);
mutex_lock(&mon_lock); mutex_lock(&mon_lock);
list_add_tail(&mbus->bus_link, &mon_buses); list_add_tail(&mbus->bus_link, &mon_buses);
...@@ -321,8 +323,8 @@ static void mon_bus0_init(void) ...@@ -321,8 +323,8 @@ static void mon_bus0_init(void)
spin_lock_init(&mbus->lock); spin_lock_init(&mbus->lock);
INIT_LIST_HEAD(&mbus->r_list); INIT_LIST_HEAD(&mbus->r_list);
mbus->text_inited = mon_text_add(mbus, 0); mbus->text_inited = mon_text_add(mbus, NULL);
// mbus->bin_inited = mon_bin_add(mbus, 0); mbus->bin_inited = mon_bin_add(mbus, NULL);
} }
/* /*
...@@ -403,6 +405,8 @@ static void __exit mon_exit(void) ...@@ -403,6 +405,8 @@ static void __exit mon_exit(void)
if (mbus->text_inited) if (mbus->text_inited)
mon_text_del(mbus); mon_text_del(mbus);
if (mbus->bin_inited)
mon_bin_del(mbus);
/* /*
* This never happens, because the open/close paths in * This never happens, because the open/close paths in
...@@ -423,6 +427,8 @@ static void __exit mon_exit(void) ...@@ -423,6 +427,8 @@ static void __exit mon_exit(void)
mbus = &mon_bus0; mbus = &mon_bus0;
if (mbus->text_inited) if (mbus->text_inited)
mon_text_del(mbus); mon_text_del(mbus);
if (mbus->bin_inited)
mon_bin_del(mbus);
mutex_unlock(&mon_lock); mutex_unlock(&mon_lock);
......
...@@ -655,20 +655,24 @@ static const struct file_operations mon_fops_text_u = { ...@@ -655,20 +655,24 @@ static const struct file_operations mon_fops_text_u = {
.release = mon_text_release, .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; struct dentry *d;
enum { NAMESZ = 10 }; enum { NAMESZ = 10 };
char name[NAMESZ]; char name[NAMESZ];
int busnum = ubus? ubus->busnum: 0;
int rc; int rc;
if (ubus != NULL) {
rc = snprintf(name, NAMESZ, "%dt", busnum); rc = snprintf(name, NAMESZ, "%dt", busnum);
if (rc <= 0 || rc >= NAMESZ) if (rc <= 0 || rc >= NAMESZ)
goto err_print_t; goto err_print_t;
d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_t); d = debugfs_create_file(name, 0600, mon_dir, mbus,
&mon_fops_text_t);
if (d == NULL) if (d == NULL)
goto err_create_t; goto err_create_t;
mbus->dent_t = d; mbus->dent_t = d;
}
rc = snprintf(name, NAMESZ, "%du", busnum); rc = snprintf(name, NAMESZ, "%du", busnum);
if (rc <= 0 || rc >= NAMESZ) if (rc <= 0 || rc >= NAMESZ)
...@@ -694,8 +698,10 @@ int mon_text_add(struct mon_bus *mbus, int busnum) ...@@ -694,8 +698,10 @@ int mon_text_add(struct mon_bus *mbus, int busnum)
mbus->dent_u = NULL; mbus->dent_u = NULL;
err_create_u: err_create_u:
err_print_u: err_print_u:
if (ubus != NULL) {
debugfs_remove(mbus->dent_t); debugfs_remove(mbus->dent_t);
mbus->dent_t = NULL; mbus->dent_t = NULL;
}
err_create_t: err_create_t:
err_print_t: err_print_t:
return 0; return 0;
...@@ -704,6 +710,7 @@ int mon_text_add(struct mon_bus *mbus, int busnum) ...@@ -704,6 +710,7 @@ int mon_text_add(struct mon_bus *mbus, int busnum)
void mon_text_del(struct mon_bus *mbus) void mon_text_del(struct mon_bus *mbus)
{ {
debugfs_remove(mbus->dent_u); debugfs_remove(mbus->dent_u);
if (mbus->dent_t != NULL)
debugfs_remove(mbus->dent_t); debugfs_remove(mbus->dent_t);
debugfs_remove(mbus->dent_s); debugfs_remove(mbus->dent_s);
} }
......
...@@ -20,9 +20,11 @@ struct mon_bus { ...@@ -20,9 +20,11 @@ struct mon_bus {
struct usb_bus *u_bus; struct usb_bus *u_bus;
int text_inited; int text_inited;
int bin_inited;
struct dentry *dent_s; /* Debugging file */ struct dentry *dent_s; /* Debugging file */
struct dentry *dent_t; /* Text interface file */ struct dentry *dent_t; /* Text interface file */
struct dentry *dent_u; /* Second text interface file */ struct dentry *dent_u; /* Second text interface file */
struct device *classdev; /* Device in usbmon class */
/* Ref */ /* Ref */
int nreaders; /* Under mon_lock AND mbus->lock */ int nreaders; /* Under mon_lock AND mbus->lock */
...@@ -52,9 +54,10 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r); ...@@ -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); 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_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); int __init mon_text_init(void);
void mon_text_exit(void); void mon_text_exit(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment