X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fmon%2Fmon_main.c;h=394bbf2f68d44f0b81807773be8a12e992fb690c;hb=refs%2Fheads%2Fvserver;hp=c34944c75047e2e50307f15af5abcf1f5c4931a7;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index c34944c75..394bbf2f6 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "usb_mon.h" #include "../core/hcd.h" @@ -23,7 +24,7 @@ static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus); static void mon_bus_drop(struct kref *r); static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus); -DECLARE_MUTEX(mon_lock); +DEFINE_MUTEX(mon_lock); static struct dentry *mon_dir; /* /dbg/usbmon */ static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ @@ -96,6 +97,7 @@ static void mon_submit(struct usb_bus *ubus, struct urb *urb) 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_submit(r->r_data, urb); @@ -112,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; } @@ -151,6 +165,7 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb) } 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); @@ -162,7 +177,6 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb) /* * Stop monitoring. - * Obviously this must be well locked, so no need to play with mb's. */ static void mon_stop(struct mon_bus *mbus) { @@ -196,14 +210,14 @@ static void mon_bus_remove(struct usb_bus *ubus) { struct mon_bus *mbus = ubus->mon_bus; - down(&mon_lock); + mutex_lock(&mon_lock); list_del(&mbus->bus_link); debugfs_remove(mbus->dent_t); debugfs_remove(mbus->dent_s); mon_dissolve(mbus, ubus); kref_put(&mbus->ref, mon_bus_drop); - up(&mon_lock); + mutex_unlock(&mon_lock); } static int mon_notify(struct notifier_block *self, unsigned long action, @@ -251,7 +265,6 @@ static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus) ubus->mon_bus = NULL; mbus->u_bus = NULL; mb(); - // usb_bus_put(ubus); } /* @@ -276,20 +289,19 @@ static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus) char name[NAMESZ]; int rc; - if ((mbus = kmalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) + if ((mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) goto err_alloc; - memset(mbus, 0, sizeof(struct mon_bus)); kref_init(&mbus->ref); spin_lock_init(&mbus->lock); INIT_LIST_HEAD(&mbus->r_list); /* - * This usb_bus_get here is superfluous, because we receive - * a notification if usb_bus is about to be removed. + * We don't need to take a reference to ubus, because we receive + * a notification if the bus is about to be removed. */ - // usb_bus_get(ubus); mbus->u_bus = ubus; ubus->mon_bus = mbus; + mbus->uses_dma = ubus->uses_dma; rc = snprintf(name, NAMESZ, "%dt", ubus->busnum); if (rc <= 0 || rc >= NAMESZ) @@ -307,9 +319,9 @@ static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus) goto err_create_s; mbus->dent_s = d; - down(&mon_lock); + mutex_lock(&mon_lock); list_add_tail(&mbus->bus_link, &mon_buses); - up(&mon_lock); + mutex_unlock(&mon_lock); return; err_create_s: @@ -347,11 +359,11 @@ static int __init mon_init(void) usb_register_notify(&mon_nb); - down(&usb_bus_list_lock); + mutex_lock(&usb_bus_list_lock); list_for_each_entry (ubus, &usb_bus_list, bus_list) { mon_bus_init(mondir, ubus); } - up(&usb_bus_list_lock); + mutex_unlock(&usb_bus_list_lock); return 0; } @@ -363,7 +375,7 @@ static void __exit mon_exit(void) usb_unregister_notify(&mon_nb); usb_mon_deregister(); - down(&mon_lock); + mutex_lock(&mon_lock); while (!list_empty(&mon_buses)) { p = mon_buses.next; mbus = list_entry(p, struct mon_bus, bus_link); @@ -387,7 +399,7 @@ static void __exit mon_exit(void) mon_dissolve(mbus, mbus->u_bus); kref_put(&mbus->ref, mon_bus_drop); } - up(&mon_lock); + mutex_unlock(&mon_lock); debugfs_remove(mon_dir); }