浏览代码

[PATCH] USB: implement error event in usbmon

Implement the "error" event in usbmon.

Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Pete Zaitcev 19 年之前
父节点
当前提交
12e72feab5
共有 3 个文件被更改,包括 44 次插入4 次删除
  1. 16 4
      drivers/usb/mon/mon_main.c
  2. 27 0
      drivers/usb/mon/mon_text.c
  3. 1 0
      drivers/usb/mon/usb_mon.h

+ 16 - 4
drivers/usb/mon/mon_main.c

@@ -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;
 	struct mon_bus *mbus;
+	unsigned long flags;
+	struct list_head *pos;
+	struct mon_reader *r;
 
 
 	mbus = ubus->mon_bus;
 	mbus = ubus->mon_bus;
 	if (mbus == NULL)
 	if (mbus == NULL)
 		goto out_unlocked;
 		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;
 	return;
 
 
+out_locked:
+	spin_unlock_irqrestore(&mbus->lock, flags);
 out_unlocked:
 out_unlocked:
 	return;
 	return;
 }
 }

+ 27 - 0
drivers/usb/mon/mon_text.c

@@ -182,6 +182,32 @@ static void mon_text_complete(void *data, struct urb *urb)
 	mon_text_event(rp, urb, 'C');
 	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.
  * 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.m_bus = mbus;
 	rp->r.r_data = rp;
 	rp->r.r_data = rp;
 	rp->r.rnf_submit = mon_text_submit;
 	rp->r.rnf_submit = mon_text_submit;
+	rp->r.rnf_error = mon_text_error;
 	rp->r.rnf_complete = mon_text_complete;
 	rp->r.rnf_complete = mon_text_complete;
 
 
 	snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum,
 	snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum,

+ 1 - 0
drivers/usb/mon/usb_mon.h

@@ -40,6 +40,7 @@ struct mon_reader {
 	void *r_data;		/* Use container_of instead? */
 	void *r_data;		/* Use container_of instead? */
 
 
 	void (*rnf_submit)(void *data, struct urb *urb);
 	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);
 	void (*rnf_complete)(void *data, struct urb *urb);
 };
 };