From 3a008f8418bd95f985bb7e33501b4e1d4cafce3d Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Mon, 3 Jan 2011 18:26:04 +0000 Subject: 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 Acked-by: Kinsey Moore git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9580 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/dahdi_dynamic.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'drivers/dahdi/dahdi_dynamic.c') 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); -- cgit v1.2.3