[PATCH] USB: implement error event in usbmon
authorPete Zaitcev <zaitcev@redhat.com>
Sat, 10 Jun 2006 05:03:32 +0000 (22:03 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 21 Jun 2006 22:04:17 +0000 (15:04 -0700)
Implement the "error" event in usbmon.

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

index 86db92b4915b550a08fd6acd31861b647c376c74..275a66f8305878b2f435506e675a851454b586af 100644 (file)
@@ -114,20 +114,32 @@ out_unlocked:
 
 /*
  */
-static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int err)
+static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error)
 {
        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;
 
-       /*
-        * XXX Capture the error code and the 'E' event.
-        */
+       spin_lock_irqsave(&mbus->lock, flags);
+       if (mbus->nreaders == 0)
+               goto out_locked;
 
+       mbus->cnt_events++;
+       list_for_each (pos, &mbus->r_list) {
+               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;
 }
index 9f9236bf62d24117bf909a71eecb87ba16401d0d..e02c1a30c4cd4d65d852ce010d522c05e594c256 100644 (file)
@@ -182,6 +182,32 @@ static void mon_text_complete(void *data, struct urb *urb)
        mon_text_event(rp, urb, 'C');
 }
 
+static void mon_text_error(void *data, struct urb *urb, int error)
+{
+       struct mon_reader_text *rp = data;
+       struct mon_event_text *ep;
+
+       if (rp->nevents >= EVENT_MAX ||
+           (ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) {
+               rp->r.m_bus->cnt_text_lost++;
+               return;
+       }
+
+       ep->type = 'E';
+       ep->pipe = urb->pipe;
+       ep->id = (unsigned long) urb;
+       ep->tstamp = 0;
+       ep->length = 0;
+       ep->status = error;
+
+       ep->setup_flag = '-';
+       ep->data_flag = 'E';
+
+       rp->nevents++;
+       list_add_tail(&ep->e_link, &rp->e_list);
+       wake_up(&rp->wait);
+}
+
 /*
  * Fetch next event from the circular buffer.
  */
@@ -235,6 +261,7 @@ static int mon_text_open(struct inode *inode, struct file *file)
        rp->r.m_bus = mbus;
        rp->r.r_data = rp;
        rp->r.rnf_submit = mon_text_submit;
+       rp->r.rnf_error = mon_text_error;
        rp->r.rnf_complete = mon_text_complete;
 
        snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum,
index 92702835b1e5b8ac86c2f34f06f5f97c570163c9..33678c24ebeed5713b06a9eb1fd32d3283effc67 100644 (file)
@@ -40,6 +40,7 @@ struct mon_reader {
        void *r_data;           /* Use container_of instead? */
 
        void (*rnf_submit)(void *data, struct urb *urb);
+       void (*rnf_error)(void *data, struct urb *urb, int error);
        void (*rnf_complete)(void *data, struct urb *urb);
 };