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
This commit is contained in:
parent
593787e3b3
commit
28f559e2ac
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user