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
This commit is contained in:
Shaun Ruffell 2011-01-03 18:26:08 +00:00
parent 28f559e2ac
commit c050ca9065
3 changed files with 54 additions and 26 deletions

View File

@ -437,6 +437,11 @@ static inline unsigned int span_count(void)
return maxspans; 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 maxchans = 0;
static int maxconfs = 0; static int maxconfs = 0;
@ -3466,8 +3471,18 @@ void dahdi_alarm_notify(struct dahdi_span *span)
/* Switch to other master if current master in alarm */ /* Switch to other master if current master in alarm */
for (x=1; x<maxspans; x++) { for (x=1; x<maxspans; x++) {
struct dahdi_span *const s = spans[x]; struct dahdi_span *const s = spans[x];
if (s && !s->alarms && (s->flags & DAHDI_FLAG_RUNNING)) { if (!s)
if ((debug & DEBUG_MAIN) && (master != 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, module_printk(KERN_NOTICE,
"Master changed to %s\n", "Master changed to %s\n",
s->name); s->name);
@ -3475,7 +3490,7 @@ void dahdi_alarm_notify(struct dahdi_span *span)
master = s; master = s;
break; break;
} }
}
/* Report more detailed alarms */ /* Report more detailed alarms */
if (debug & DEBUG_MAIN) { if (debug & DEBUG_MAIN) {
if (span->alarms & DAHDI_ALARM_LOS) { 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); "%d channels\n", span->spanno, span->name, span->channels);
} }
if (!master || prefmaster) { if (!master && can_provide_timing(span)) {
master = span; master = span;
if (debug & DEBUG_MAIN) { if (debug & DEBUG_MAIN) {
module_printk(KERN_NOTICE, "Span ('%s') is new master\n", module_printk(KERN_NOTICE, "Span ('%s') is new master\n",
@ -6184,8 +6199,7 @@ unreg_channels:
int dahdi_unregister(struct dahdi_span *span) int dahdi_unregister(struct dahdi_span *span)
{ {
int x; int x;
int new_maxspans; unsigned long flags;
struct dahdi_span *new_master;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
char tempfile[17]; char tempfile[17];
@ -6221,23 +6235,34 @@ int dahdi_unregister(struct dahdi_span *span)
clear_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags); clear_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
for (x=0;x<span->channels;x++) for (x=0;x<span->channels;x++)
dahdi_chan_unreg(span->chans[x]); dahdi_chan_unreg(span->chans[x]);
new_maxspans = 0;
new_master = master; /* FIXME: locking */ if (master == span) {
if (master == span) struct dahdi_span *new_master = NULL;
new_master = NULL; int new_maxspans = 0;
spin_lock_irqsave(&chan_lock, flags);
for (x = 1; x < DAHDI_MAX_SPANS; x++) { for (x = 1; x < DAHDI_MAX_SPANS; x++) {
if (spans[x]) { struct dahdi_span *const cur = spans[x];
new_maxspans = x+1; if (!cur)
if (!new_master) continue;
new_master = spans[x];
new_maxspans = x;
if (can_provide_timing(cur)) {
new_master = cur;
break;
} }
} }
maxspans = new_maxspans; maxspans = new_maxspans;
if (master != new_master) spin_unlock_irqrestore(&chan_lock, flags);
if (debug & DEBUG_MAIN)
module_printk(KERN_NOTICE, "%s: Span ('%s') is new master\n", __FUNCTION__, if (debug & DEBUG_MAIN) {
(new_master)? new_master->name: "no master"); module_printk(KERN_NOTICE, "%s: Span ('%s') is new "
"master\n", __func__,
(new_master) ? new_master->name :
"no master");
}
master = new_master; master = new_master;
}
return 0; return 0;
} }

View File

@ -221,6 +221,8 @@ static int dahdi_dynamic_local_create(struct dahdi_dynamic *dyn,
printk(KERN_INFO "TDMoL: Added new interface for %s, " printk(KERN_INFO "TDMoL: Added new interface for %s, "
"key %d id %d\n", span->name, d->key, d->id); "key %d id %d\n", span->name, d->key, d->id);
span->cannot_provide_timing = 1;
return 0; return 0;
CLEAR_AND_DEL_FROM_PEERS: CLEAR_AND_DEL_FROM_PEERS:

View File

@ -863,6 +863,7 @@ struct dahdi_span {
int deflaw; /*!< Default law (DAHDI_MULAW or DAHDI_ALAW) */ int deflaw; /*!< Default law (DAHDI_MULAW or DAHDI_ALAW) */
int alarms; /*!< Pending alarms on span */ int alarms; /*!< Pending alarms on span */
unsigned long flags; unsigned long flags;
u8 cannot_provide_timing:1;
int irq; /*!< IRQ for this span's hardware */ int irq; /*!< IRQ for this span's hardware */
int lbo; /*!< Span Line-Buildout */ int lbo; /*!< Span Line-Buildout */
int lineconfig; /*!< Span line configuration */ int lineconfig; /*!< Span line configuration */