This patch create the bus0 to the usbmon interface. Bus0 provides events
for all attached USB buses to any kind of reader (text, binary). 

Signed-off-by: Paolo Abeni <[EMAIL PROTECTED]>

---

This is test implementation to collect comments and suggestion on the
subject. The patch is against linux 2.6.21-rc1.

A dummy mon_bus structure is created at usbmon initialization time. This
is not attached to any real USB bus, but real mon readers can attach to
it. 

When any event is received from usbmon, the bus0 readers list is walked
and attached readers are invoked. Then the event is processed as usual.

There are a couple of things that should be polished: 
- mon_bus->u_bus can now be null and must be tested every time it's
used.
- at event reception two spinlock must be hold and released: one for
bus0 and one for bus-n. Previously only one lock was needed. 

diff -uprN linux-2.6.21-rc1-mon/drivers/usb/mon/mon_bin.c 
linux-2.6.21-rc1-monbus0/drivers/usb/mon/mon_bin.c
--- linux-2.6.21-rc1-mon/drivers/usb/mon/mon_bin.c      2007-02-27 
09:58:04.000000000 +0100
+++ linux-2.6.21-rc1-monbus0/drivers/usb/mon/mon_bin.c  2007-02-28 
09:51:07.000000000 +0100
@@ -441,7 +441,7 @@ static void mon_bin_event(struct mon_rea
        /* We use the fact that usb_pipein() returns 0x80 */
        ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe);
        ep->devnum = usb_pipedevice(urb->pipe);
-       ep->busnum = rp->r.m_bus->u_bus->busnum;
+       ep->busnum = urb->dev->bus->busnum;
        ep->id = (unsigned long) urb;
        ep->ts_sec = ts.tv_sec;
        ep->ts_usec = ts.tv_usec;
@@ -501,7 +501,7 @@ static void mon_bin_error(void *data, st
        /* We use the fact that usb_pipein() returns 0x80 */
        ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe);
        ep->devnum = usb_pipedevice(urb->pipe);
-       ep->busnum = rp->r.m_bus->u_bus->busnum;
+       ep->busnum = urb->dev->bus->busnum;
        ep->id = (unsigned long) urb;
        ep->status = error;
 
@@ -516,7 +516,6 @@ static void mon_bin_error(void *data, st
 static int mon_bin_open(struct inode *inode, struct file *file)
 {
        struct mon_bus *mbus;
-       struct usb_bus *ubus;
        struct mon_reader_bin *rp;
        size_t size;
        int rc;
@@ -526,7 +525,9 @@ static int mon_bin_open(struct inode *in
                mutex_unlock(&mon_lock);
                return -ENODEV;
        }
-       if ((ubus = mbus->u_bus) == NULL) {
+
+       /* mbus->u_bus is 0 for busnum == 0 */
+       if ((mbus->busnum != 0) && (mbus->u_bus == NULL)) {
                printk(KERN_ERR TAG ": consistency error on open\n");
                mutex_unlock(&mon_lock);
                return -ENODEV;
diff -uprN linux-2.6.21-rc1-mon/drivers/usb/mon/mon_main.c 
linux-2.6.21-rc1-monbus0/drivers/usb/mon/mon_main.c
--- linux-2.6.21-rc1-mon/drivers/usb/mon/mon_main.c     2007-02-27 
09:34:05.000000000 +0100
+++ linux-2.6.21-rc1-monbus0/drivers/usb/mon/mon_main.c 2007-02-28 
09:19:10.000000000 +0100
@@ -25,6 +25,8 @@ static void mon_bus_init(struct usb_bus 
 
 DEFINE_MUTEX(mon_lock);
 
+static struct mon_bus *bus0;           /* Pseudo bus used to collect events 
+                                        * from all real USB buses */
 static LIST_HEAD(mon_buses);           /* All buses we know: struct mon_bus */
 
 /*
@@ -38,7 +40,7 @@ void mon_reader_add(struct mon_bus *mbus
        struct usb_bus *ubus;
 
        spin_lock_irqsave(&mbus->lock, flags);
-       if (mbus->nreaders == 0) {
+       if ((mbus->nreaders == 0) && mbus->u_bus) {
                ubus = mbus->u_bus;
                if (ubus->monitored) {
                        /*
@@ -78,18 +80,10 @@ void mon_reader_del(struct mon_bus *mbus
        kref_put(&mbus->ref, mon_bus_drop);
 }
 
-/*
- */
-static void mon_submit(struct usb_bus *ubus, struct urb *urb)
+static void mon_bus_submit(struct mon_bus *mbus, struct urb *urb)
 {
-       struct mon_bus *mbus;
        unsigned long flags;
        struct list_head *pos;
-       struct mon_reader *r;
-
-       mbus = ubus->mon_bus;
-       if (mbus == NULL)
-               goto out_unlocked;
 
        spin_lock_irqsave(&mbus->lock, flags);
        if (mbus->nreaders == 0)
@@ -97,31 +91,32 @@ static void mon_submit(struct usb_bus *u
 
        mbus->cnt_events++;
        list_for_each (pos, &mbus->r_list) {
-               r = list_entry(pos, struct mon_reader, r_link);
+               struct mon_reader *r = list_entry(pos, struct mon_reader, 
r_link);
                r->rnf_submit(r->r_data, urb);
        }
 
-       spin_unlock_irqrestore(&mbus->lock, flags);
-       return;
-
 out_locked:
        spin_unlock_irqrestore(&mbus->lock, flags);
-out_unlocked:
        return;
 }
 
 /*
  */
-static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error)
+static void mon_submit(struct usb_bus *ubus, struct urb *urb)
 {
        struct mon_bus *mbus;
-       unsigned long flags;
-       struct list_head *pos;
-       struct mon_reader *r;
+       mon_bus_submit(bus0, urb);
 
        mbus = ubus->mon_bus;
        if (mbus == NULL)
-               goto out_unlocked;
+               return;
+       mon_bus_submit(mbus, urb);
+}
+
+static void mon_bus_submit_error(struct mon_bus *mbus, struct urb *urb, int 
error)
+{
+       unsigned long flags;
+       struct list_head *pos;
 
        spin_lock_irqsave(&mbus->lock, flags);
        if (mbus->nreaders == 0)
@@ -129,27 +124,49 @@ static void mon_submit_error(struct usb_
 
        mbus->cnt_events++;
        list_for_each (pos, &mbus->r_list) {
-               r = list_entry(pos, struct mon_reader, r_link);
+               struct mon_reader *r = list_entry(pos, struct mon_reader, 
r_link);
                r->rnf_error(r->r_data, urb, error);
        }
 
-       spin_unlock_irqrestore(&mbus->lock, flags);
-       return;
-
 out_locked:
        spin_unlock_irqrestore(&mbus->lock, flags);
-out_unlocked:
        return;
 }
 
 /*
  */
-static void mon_complete(struct usb_bus *ubus, struct urb *urb)
+static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error)
 {
        struct mon_bus *mbus;
+       mon_bus_submit_error(bus0, urb, error);
+
+       mbus = ubus->mon_bus;
+       if (mbus == NULL)
+               return;
+       mon_bus_submit(mbus, urb);
+}
+
+static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb)
+{
        unsigned long flags;
        struct list_head *pos;
-       struct mon_reader *r;
+
+       spin_lock_irqsave(&mbus->lock, flags);
+       mbus->cnt_events++;
+       list_for_each (pos, &mbus->r_list) {
+               struct mon_reader *r = list_entry(pos, struct mon_reader, 
r_link);
+               r->rnf_complete(r->r_data, urb);
+       }
+       spin_unlock_irqrestore(&mbus->lock, flags);
+
+}
+
+/*
+ */
+static void mon_complete(struct usb_bus *ubus, struct urb *urb)
+{
+       struct mon_bus *mbus;
+       mon_bus_complete(bus0, urb);
 
        mbus = ubus->mon_bus;
        if (mbus == NULL) {
@@ -162,13 +179,7 @@ static void mon_complete(struct usb_bus 
                return;
        }
 
-       spin_lock_irqsave(&mbus->lock, flags);
-       mbus->cnt_events++;
-       list_for_each (pos, &mbus->r_list) {
-               r = list_entry(pos, struct mon_reader, r_link);
-               r->rnf_complete(r->r_data, urb);
-       }
-       spin_unlock_irqrestore(&mbus->lock, flags);
+       mon_bus_complete(mbus, urb);
 }
 
 /* int (*unlink_urb) (struct urb *urb, int status); */
@@ -255,14 +266,15 @@ static void mon_dissolve(struct mon_bus 
        /*
         * Never happens, but...
         */
-       if (ubus->monitored) {
+       if (ubus && ubus->monitored) {
                printk(KERN_ERR TAG ": bus %d is dissolved while monitored\n",
                    ubus->busnum);
                ubus->monitored = 0;
                mb();
        }
 
-       ubus->mon_bus = NULL;
+       if (ubus)
+               ubus->mon_bus = NULL;
        mbus->u_bus = NULL;
        mb();
 }
@@ -296,11 +308,18 @@ static void mon_bus_init(struct usb_bus 
         * a notification if the bus is about to be removed.
         */
        mbus->u_bus = ubus;
-       ubus->mon_bus = mbus;
+       if (ubus) {
+               ubus->mon_bus = mbus;
+               mbus->busnum = ubus->busnum;
+       }
+       else {
+               bus0 = mbus;
+               mbus->busnum = 0;
+       }
        mbus->uses_dma = ubus->uses_dma;
 
-       mbus->text_inited = mon_text_add(mbus, ubus);
-       mbus->bin_inited = mon_bin_add(mbus, ubus);
+       mbus->text_inited = mon_text_add(mbus);
+       mbus->bin_inited = mon_bin_add(mbus);
 
        mutex_lock(&mon_lock);
        list_add_tail(&mbus->bus_link, &mon_buses);
@@ -338,6 +357,8 @@ static int __init mon_init(void)
        struct usb_bus *ubus;
        int rc;
 
+       /* add 'bus 0' */
+       mon_bus_init(0);
        if ((rc = mon_text_init()) != 0)
                goto err_text;
        if ((rc = mon_bin_init()) != 0)
diff -uprN linux-2.6.21-rc1-mon/drivers/usb/mon/usb_mon.h 
linux-2.6.21-rc1-monbus0/drivers/usb/mon/usb_mon.h
--- linux-2.6.21-rc1-mon/drivers/usb/mon/usb_mon.h      2007-02-27 
09:34:05.000000000 +0100
+++ linux-2.6.21-rc1-monbus0/drivers/usb/mon/usb_mon.h  2007-02-28 
09:28:36.000000000 +0100
@@ -18,6 +18,7 @@ struct mon_bus {
        struct list_head bus_link;
        spinlock_t lock;
        struct usb_bus *u_bus;
+       int busnum;
 
        int text_inited;
        int bin_inited;


 
 
 --
 Email.it, the professional e-mail, gratis per te: http://www.email.it/f
 
 Sponsor:
 Video Corsi GRATIS - Scopri come imparare velocemente e senza stress 
(Internet, Informatica, Web Marketing, Hobby
 Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=5145&d=28-2

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to