diff options
author | Shaun Ruffell <sruffell@digium.com> | 2009-06-29 04:47:26 +0000 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2009-06-29 04:47:26 +0000 |
commit | 4f43a0107801d766c66176ab18ab0114da6ec996 (patch) | |
tree | a2f5705ee17f67c32490de0570a3feda9c77a650 /drivers/dahdi/dahdi-base.c | |
parent | d654f837038811fc9e11d1e30a98983c8cff74e5 (diff) |
echocan: Properly keep the reference counts for the echocan modules.
(closes issue #13504)
(closes issue #15327)
Reported by: sruffell, tzafrir
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@6785 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/dahdi-base.c')
-rw-r--r-- | drivers/dahdi/dahdi-base.c | 23 |
1 files changed, 5 insertions, 18 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c index 632d0d2..ac411dc 100644 --- a/drivers/dahdi/dahdi-base.c +++ b/drivers/dahdi/dahdi-base.c @@ -183,13 +183,6 @@ static struct class_simple *dahdi_class = NULL; #define class_destroy class_simple_destroy #endif -/* - * See issue http://bugs.digium.com/view.php?id=13504 for more information. - * on why reference counting on the echo canceller modules is disabled - * currently. - */ -#undef USE_ECHOCAN_REFCOUNT - static int deftaps = 64; static int debug; @@ -383,7 +376,6 @@ static LIST_HEAD(ecfactory_list); struct ecfactory { const struct dahdi_echocan_factory *ec; - struct module *owner; struct list_head list; }; @@ -391,6 +383,8 @@ int dahdi_register_echocan_factory(const struct dahdi_echocan_factory *ec) { struct ecfactory *cur; + WARN_ON(!ec->owner); + write_lock(&ecfactory_list_lock); /* make sure it isn't already registered */ @@ -1108,18 +1102,13 @@ retry: list_for_each_entry(cur, &ecfactory_list, list) { if (!strcmp(name_upper, cur->ec->name)) { -#ifdef USE_ECHOCAN_REFCOUNT - if (try_module_get(cur->owner)) { + if (try_module_get(cur->ec->owner)) { read_unlock(&ecfactory_list_lock); return cur->ec; } else { read_unlock(&ecfactory_list_lock); return NULL; } -#else - read_unlock(&ecfactory_list_lock); - return cur->ec; -#endif } } @@ -1145,10 +1134,8 @@ retry: static void release_echocan(const struct dahdi_echocan_factory *ec) { -#ifdef USE_ECHOCAN_REFCOUNT if (ec) module_put(ec->owner); -#endif } /** @@ -1864,6 +1851,8 @@ static void dahdi_chan_unreg(struct dahdi_chan *chan) might_sleep(); + release_echocan(chan->ec_factory); + #ifdef CONFIG_DAHDI_NET if (chan->flags & DAHDI_FLAG_NETDEV) { unregister_hdlc_device(chan->hdlcnetdev->netdev); @@ -4910,14 +4899,12 @@ static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams ret = chan->span->echocan_create(chan, ecp, params, &ec); if ((ret == -ENODEV) && chan->ec_factory) { -#ifdef USE_ECHOCAN_REFCOUNT /* try to get another reference to the module providing this channel's echo canceler */ if (!try_module_get(chan->ec_factory->owner)) { module_printk(KERN_ERR, "Cannot get a reference to the '%s' echo canceler\n", chan->ec_factory->name); goto exit_with_free; } -#endif /* got the reference, copy the pointer and use it for making an echo canceler instance if possible */ |