Index: dahdi-base.c =================================================================== --- dahdi-base.c (revision 4909) +++ dahdi-base.c (working copy) @@ -230,7 +230,8 @@ static sumtype *conf_sums; static sumtype *conf_sums_prev; -static struct dahdi_span *master; +static struct dahdi_span *master = NULL; +static struct dahdi_span *pref_master = NULL; static struct file_operations dahdi_fops; struct file_operations *dahdi_transcode_fops = NULL; @@ -3221,6 +3222,47 @@ spin_unlock_irqrestore(&chan->lock, flags); } +static inline int __can_be_master (struct dahdi_span *span) { + if (span && !span->alarms && (span->flags & DAHDI_FLAG_RUNNING)) + return 1; + return 0; +} + +/* + pavel[AT]parabel.ru + 1. trying preffered master SPAN + 2. trying non-zero channel SPANS + 3. trying zero-channel SPANS (dahdi_dummy,...) +*/ +static void dahdi_checkmaster (void) { + struct dahdi_span *dummy = NULL; + struct dahdi_span *newmaster = NULL; + struct dahdi_span *curmaster = master; + int x; + + if (__can_be_master(pref_master)) { + newmaster = pref_master; + } else { + /* Switch to other master if current master in alarm */ + for (x=1; xchannels > 0) { + newmaster = spans[x]; + break; //We're happy now. + } else { + if (!dummy) + dummy = spans[x]; + } + + } + } + } + + master = (newmaster) ? newmaster : dummy; + if (master != curmaster) + module_printk(KERN_INFO, "Master changed to %s\n", (master)? master->name: "no master"); +} + void dahdi_alarm_notify(struct dahdi_span *span) { int x; @@ -3237,16 +3279,8 @@ span->lastalarms = span->alarms; for (x = 0; x < span->channels; x++) dahdi_alarm_channel(span->chans[x], span->alarms); - /* Switch to other master if current master in alarm */ - for (x=1; xalarms && (spans[x]->flags & DAHDI_FLAG_RUNNING)) { - if(master != spans[x]) - module_printk(KERN_NOTICE, "Master changed to %s\n", spans[x]->name); - master = spans[x]; - break; - } - } } + dahdi_checkmaster (); } #define VALID_SPAN(j) do { \ @@ -3729,6 +3763,7 @@ spin_unlock_irqrestore(&spans[j]->chans[x]->lock, flags); spans[j]->chans[x]->rxhooksig = DAHDI_RXSIG_INITIAL; } + dahdi_checkmaster (); } return 0; case DAHDI_SHUTDOWN: @@ -5374,14 +5409,10 @@ "%d channels\n", span->spanno, span->name, span->channels); } - if (!master || prefmaster) { - master = span; - if (debug) { - module_printk(KERN_NOTICE, "Span ('%s') is new master\n", - span->name); - } - } + if (prefmaster) + pref_master = span; + return 0; } @@ -5389,7 +5420,6 @@ { int x; int new_maxspans; - static struct dahdi_span *new_master; #ifdef CONFIG_PROC_FS char tempfile[17]; @@ -5426,23 +5456,17 @@ for (x=0;xchannels;x++) dahdi_chan_unreg(span->chans[x]); new_maxspans = 0; - new_master = master; /* FIXME: locking */ if (master == span) - new_master = NULL; + master = NULL; + if (pref_master == span) + pref_master = NULL; for (x=1;xname: "no master"); - master = new_master; - + dahdi_checkmaster (); return 0; }