summaryrefslogtreecommitdiff
path: root/drivers/dahdi/dahdi-base.c
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2009-06-29 04:47:26 +0000
committerShaun Ruffell <sruffell@digium.com>2009-06-29 04:47:26 +0000
commit4f43a0107801d766c66176ab18ab0114da6ec996 (patch)
treea2f5705ee17f67c32490de0570a3feda9c77a650 /drivers/dahdi/dahdi-base.c
parentd654f837038811fc9e11d1e30a98983c8cff74e5 (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.c23
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 */