diff options
author | Shaun Ruffell <sruffell@digium.com> | 2011-01-03 18:26:04 +0000 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2011-01-03 18:26:04 +0000 |
commit | d1a00799a8f80d93128f0adeae41b85cc25ace47 (patch) | |
tree | 6fb8d8f32a16d7ea13b053748bfaf129904bf17b /drivers/dahdi/dahdi_dynamic.c | |
parent | 29ea9fb2ca66e8e4637c3ced8946ac0c9b3a3fbb (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.c | 27 |
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); |