summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2011-01-03 18:26:08 +0000
committerShaun Ruffell <sruffell@digium.com>2011-01-03 18:26:08 +0000
commit217203f930b427a756e50c09b141eeea1ee9b3a0 (patch)
tree929730b84f0d3957e496504358f7f69db4eeedfa
parent3a008f8418bd95f985bb7e33501b4e1d4cafce3d (diff)
dahdi: Allow spans to advertise if they can provide any timing.
Some spans, specifically dynamic local spans, should never be the timing master since they are dependent on some other timing source driving them. The bit in 'struct dahdi_span' is named cannot provide timing so that by default the other drivers will set it to 0. This is loosely related to issue #13205 but doesn't address any of the other elements of that issue about how to allow the user to configure what the master span order of succession is. (issue #13205) Reported by: biohumanoid 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@9581 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/dahdi-base.c81
-rw-r--r--drivers/dahdi/dahdi_dynamic_loc.c2
-rw-r--r--include/dahdi/kernel.h1
3 files changed, 56 insertions, 28 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c
index 9d60f1c..f0ec082 100644
--- a/drivers/dahdi/dahdi-base.c
+++ b/drivers/dahdi/dahdi-base.c
@@ -437,6 +437,11 @@ static inline unsigned int span_count(void)
return maxspans;
}
+static inline bool can_provide_timing(const struct dahdi_span *const s)
+{
+ return !s->cannot_provide_timing;
+}
+
static int maxchans = 0;
static int maxconfs = 0;
@@ -3466,16 +3471,26 @@ void dahdi_alarm_notify(struct dahdi_span *span)
/* Switch to other master if current master in alarm */
for (x=1; x<maxspans; x++) {
struct dahdi_span *const s = spans[x];
- if (s && !s->alarms && (s->flags & DAHDI_FLAG_RUNNING)) {
- if ((debug & DEBUG_MAIN) && (master != s)) {
- module_printk(KERN_NOTICE,
- "Master changed to %s\n",
- s->name);
- }
- master = s;
- break;
+ if (!s)
+ continue;
+ if (s->alarms)
+ continue;
+ if (!test_bit(DAHDI_FLAGBIT_RUNNING, &s->flags))
+ continue;
+ if (!can_provide_timing(s))
+ continue;
+ if (master == s)
+ continue;
+
+ if (debug & DEBUG_MAIN) {
+ module_printk(KERN_NOTICE,
+ "Master changed to %s\n",
+ s->name);
}
+ master = s;
+ break;
}
+
/* Report more detailed alarms */
if (debug & DEBUG_MAIN) {
if (span->alarms & DAHDI_ALARM_LOS) {
@@ -6158,7 +6173,7 @@ int dahdi_register(struct dahdi_span *span, int prefmaster)
"%d channels\n", span->spanno, span->name, span->channels);
}
- if (!master || prefmaster) {
+ if (!master && can_provide_timing(span)) {
master = span;
if (debug & DEBUG_MAIN) {
module_printk(KERN_NOTICE, "Span ('%s') is new master\n",
@@ -6184,8 +6199,7 @@ unreg_channels:
int dahdi_unregister(struct dahdi_span *span)
{
int x;
- int new_maxspans;
- struct dahdi_span *new_master;
+ unsigned long flags;
#ifdef CONFIG_PROC_FS
char tempfile[17];
@@ -6221,23 +6235,34 @@ int dahdi_unregister(struct dahdi_span *span)
clear_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
for (x=0;x<span->channels;x++)
dahdi_chan_unreg(span->chans[x]);
- new_maxspans = 0;
- new_master = master; /* FIXME: locking */
- if (master == span)
- new_master = NULL;
- for (x=1;x<DAHDI_MAX_SPANS;x++) {
- if (spans[x]) {
- new_maxspans = x+1;
- if (!new_master)
- new_master = spans[x];
- }
- }
- maxspans = new_maxspans;
- if (master != new_master)
- if (debug & DEBUG_MAIN)
- module_printk(KERN_NOTICE, "%s: Span ('%s') is new master\n", __FUNCTION__,
- (new_master)? new_master->name: "no master");
- master = new_master;
+
+ if (master == span) {
+ struct dahdi_span *new_master = NULL;
+ int new_maxspans = 0;
+
+ spin_lock_irqsave(&chan_lock, flags);
+ for (x = 1; x < DAHDI_MAX_SPANS; x++) {
+ struct dahdi_span *const cur = spans[x];
+ if (!cur)
+ continue;
+
+ new_maxspans = x;
+ if (can_provide_timing(cur)) {
+ new_master = cur;
+ break;
+ }
+ }
+ maxspans = new_maxspans;
+ spin_unlock_irqrestore(&chan_lock, flags);
+
+ if (debug & DEBUG_MAIN) {
+ module_printk(KERN_NOTICE, "%s: Span ('%s') is new "
+ "master\n", __func__,
+ (new_master) ? new_master->name :
+ "no master");
+ }
+ master = new_master;
+ }
return 0;
}
diff --git a/drivers/dahdi/dahdi_dynamic_loc.c b/drivers/dahdi/dahdi_dynamic_loc.c
index 6337780..98cb7b1 100644
--- a/drivers/dahdi/dahdi_dynamic_loc.c
+++ b/drivers/dahdi/dahdi_dynamic_loc.c
@@ -221,6 +221,8 @@ static int dahdi_dynamic_local_create(struct dahdi_dynamic *dyn,
printk(KERN_INFO "TDMoL: Added new interface for %s, "
"key %d id %d\n", span->name, d->key, d->id);
+
+ span->cannot_provide_timing = 1;
return 0;
CLEAR_AND_DEL_FROM_PEERS:
diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h
index 584eb8c..f181444 100644
--- a/include/dahdi/kernel.h
+++ b/include/dahdi/kernel.h
@@ -863,6 +863,7 @@ struct dahdi_span {
int deflaw; /*!< Default law (DAHDI_MULAW or DAHDI_ALAW) */
int alarms; /*!< Pending alarms on span */
unsigned long flags;
+ u8 cannot_provide_timing:1;
int irq; /*!< IRQ for this span's hardware */
int lbo; /*!< Span Line-Buildout */
int lineconfig; /*!< Span line configuration */