summaryrefslogtreecommitdiff
path: root/drivers/dahdi/dahdi_dynamic.c
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2011-01-03 18:26:04 +0000
committerShaun Ruffell <sruffell@digium.com>2011-01-03 18:26:04 +0000
commitd1a00799a8f80d93128f0adeae41b85cc25ace47 (patch)
tree6fb8d8f32a16d7ea13b053748bfaf129904bf17b /drivers/dahdi/dahdi_dynamic.c
parent29ea9fb2ca66e8e4637c3ced8946ac0c9b3a3fbb (diff)
dahdi_dynamic: Do not depend on BKL for serialization of dspan creation.
Also makes it safe to unregister a dynamic driver when there aren't any open channels on the dynamic spans. Signed-off-by: Shaun Ruffell <sruffell@digium.com> Acked-by: Kinsey Moore <kmoore@digium.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9580 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/dahdi_dynamic.c')
-rw-r--r--drivers/dahdi/dahdi_dynamic.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/dahdi/dahdi_dynamic.c b/drivers/dahdi/dahdi_dynamic.c
index 1162c43..5e0d459 100644
--- a/drivers/dahdi/dahdi_dynamic.c
+++ b/drivers/dahdi/dahdi_dynamic.c
@@ -90,6 +90,7 @@ static struct tasklet_struct dahdi_dynamic_tlet;
static void dahdi_dynamic_tasklet(unsigned long data);
#endif
+static DEFINE_MUTEX(dspan_mutex);
static DEFINE_SPINLOCK(dspan_lock);
static DEFINE_SPINLOCK(driver_lock);
@@ -456,7 +457,7 @@ static struct dahdi_dynamic_driver *find_driver(const char *name)
return found;
}
-static int destroy_dynamic(struct dahdi_dynamic_span *dds)
+static int _destroy_dynamic(struct dahdi_dynamic_span *dds)
{
unsigned long flags;
struct dahdi_dynamic *d;
@@ -486,6 +487,15 @@ static int destroy_dynamic(struct dahdi_dynamic_span *dds)
return 0;
}
+static int destroy_dynamic(struct dahdi_dynamic_span *dds)
+{
+ int ret;
+ mutex_lock(&dspan_mutex);
+ ret = _destroy_dynamic(dds);
+ mutex_unlock(&dspan_mutex);
+ return ret;
+}
+
static int dahdi_dynamic_rbsbits(struct dahdi_chan *chan, int bits)
{
/* Don't have to do anything */
@@ -541,7 +551,7 @@ static const struct dahdi_span_ops dynamic_ops = {
.sync_tick = dahdi_dynamic_sync_tick,
};
-static int create_dynamic(struct dahdi_dynamic_span *dds)
+static int _create_dynamic(struct dahdi_dynamic_span *dds)
{
int res = 0;
struct dahdi_dynamic *d;
@@ -673,6 +683,15 @@ static int create_dynamic(struct dahdi_dynamic_span *dds)
return x;
}
+static int create_dynamic(struct dahdi_dynamic_span *dds)
+{
+ int ret;
+ mutex_lock(&dspan_mutex);
+ ret = _create_dynamic(dds);
+ mutex_unlock(&dspan_mutex);
+ return ret;
+}
+
#ifdef ENABLE_TASKLETS
static void dahdi_dynamic_tasklet(unsigned long data)
{
@@ -740,6 +759,8 @@ void dahdi_dynamic_unregister_driver(struct dahdi_dynamic_driver *dri)
struct dahdi_dynamic *d, *n;
unsigned long flags;
+ mutex_lock(&dspan_mutex);
+
list_for_each_entry_safe(d, n, &dspan_list, list) {
if (d->driver == dri) {
if (d->pvt) {
@@ -764,6 +785,8 @@ void dahdi_dynamic_unregister_driver(struct dahdi_dynamic_driver *dri)
list_del_rcu(&dri->list);
spin_unlock_irqrestore(&driver_lock, flags);
synchronize_rcu();
+
+ mutex_unlock(&dspan_mutex);
}
EXPORT_SYMBOL(dahdi_dynamic_unregister_driver);