[svn-commits] sruffell: linux/trunk r9581 - in /linux/trunk: drivers/dahdi/ include/dahdi/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Jan 3 18:26:14 UTC 2011


Author: sruffell
Date: Mon Jan  3 12:26:08 2011
New Revision: 9581

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9581
Log:
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 at digium.com>
Acked-by: Kinsey Moore <kmoore at digium.com>

Modified:
    linux/trunk/drivers/dahdi/dahdi-base.c
    linux/trunk/drivers/dahdi/dahdi_dynamic_loc.c
    linux/trunk/include/dahdi/kernel.h

Modified: linux/trunk/drivers/dahdi/dahdi-base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=9581&r1=9580&r2=9581
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Mon Jan  3 12:26:08 2011
@@ -435,6 +435,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;
@@ -3466,16 +3471,26 @@
 		/* 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 @@
 				"%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 @@
 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 @@
 	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;
 }

Modified: linux/trunk/drivers/dahdi/dahdi_dynamic_loc.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi_dynamic_loc.c?view=diff&rev=9581&r1=9580&r2=9581
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi_dynamic_loc.c (original)
+++ linux/trunk/drivers/dahdi/dahdi_dynamic_loc.c Mon Jan  3 12:26:08 2011
@@ -221,6 +221,8 @@
 
 	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:

Modified: linux/trunk/include/dahdi/kernel.h
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/include/dahdi/kernel.h?view=diff&rev=9581&r1=9580&r2=9581
==============================================================================
--- linux/trunk/include/dahdi/kernel.h (original)
+++ linux/trunk/include/dahdi/kernel.h Mon Jan  3 12:26:08 2011
@@ -863,6 +863,7 @@
 	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 */




More information about the svn-commits mailing list