[dahdi-commits] sruffell: branch linux/sruffell/chan_list r9345 - /linux/team/sruffell/chan_l...

SVN commits to the DAHDI project dahdi-commits at lists.digium.com
Fri Sep 17 14:11:53 CDT 2010


Author: sruffell
Date: Fri Sep 17 14:11:42 2010
New Revision: 9345

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9345
Log:
dahdi: Remove three maxchans/DAHDI_MAX_CHANNELS references.

In dahdi_chec_conf, dahdi_chan_unreg, and dahdi_ioctl_confdiag maxchans
and DAHDI_MAX_CHANNELS was used to scan through all the channels.  Since
the channels are stored on the list of spans and list of pseudo
channels, we can directly iterate through those lists.  This also paves
the way for removing the arbitrary limit on the number of channels in
the driver.

Modified:
    linux/team/sruffell/chan_list/drivers/dahdi/dahdi-base.c

Modified: linux/team/sruffell/chan_list/drivers/dahdi/dahdi-base.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/sruffell/chan_list/drivers/dahdi/dahdi-base.c?view=diff&rev=9345&r1=9344&r2=9345
==============================================================================
--- linux/team/sruffell/chan_list/drivers/dahdi/dahdi-base.c (original)
+++ linux/team/sruffell/chan_list/drivers/dahdi/dahdi-base.c Fri Sep 17 14:11:42 2010
@@ -440,6 +440,33 @@
 static LIST_HEAD(span_list);
 
 static struct dahdi_chan *chans[DAHDI_MAX_CHANNELS];
+
+static unsigned long
+__for_each_channel(unsigned long (*func)(struct dahdi_chan *chan,
+					 unsigned long data),
+		   unsigned long data)
+{
+	int res;
+	struct dahdi_span *s;
+	struct pseudo_chan *pseudo;
+
+	list_for_each_entry(s, &span_list, node) {
+		unsigned long x;
+		for (x = 0; x < s->channels; x++) {
+			struct dahdi_chan *const chan = s->chans[x];
+			res = func(chan, data);
+			if (res)
+				return res;
+		}
+	}
+
+	list_for_each_entry(pseudo, &pseudo_chans, node) {
+		res = func(&pseudo->chan, data);
+		if (res)
+			return res;
+	}
+	return 0;
+}
 
 static struct dahdi_chan *chan_from_num(unsigned int channo)
 {
@@ -1002,9 +1029,21 @@
 	return a;
 }
 
+static unsigned long _chan_in_conf(struct dahdi_chan *chan, unsigned long x)
+{
+	const int confmode = chan->confmode & DAHDI_CONF_MODE_MASK;
+	return (chan && (chan->confna == x) &&
+	    (confmode == DAHDI_CONF_CONF ||
+	     confmode == DAHDI_CONF_CONFANN ||
+	     confmode == DAHDI_CONF_CONFMON ||
+	     confmode == DAHDI_CONF_CONFANNMON ||
+	     confmode == DAHDI_CONF_REALANDPSEUDO)) ? 1 : 0;
+}
+
 static void dahdi_check_conf(int x)
 {
-	int y;
+	unsigned long res;
+	unsigned long flags;
 
 	/* return if no valid conf number */
 	if (x <= 0)
@@ -1014,18 +1053,11 @@
 	if (!confalias[x])
 		return;
 
-	for (y = 0; y < maxchans; y++) {
-		struct dahdi_chan *const chan = chan_from_num(y);
-		const int confmode = chan->confmode & DAHDI_CONF_MODE_MASK;
-		if (chan && (chan->confna == x) &&
-		    (confmode == DAHDI_CONF_CONF ||
-		     confmode == DAHDI_CONF_CONFANN ||
-		     confmode == DAHDI_CONF_CONFMON ||
-		     confmode == DAHDI_CONF_CONFANNMON ||
-		     confmode == DAHDI_CONF_REALANDPSEUDO)) {
-			return;
-		}
-	}
+	read_lock_irqsave(&chan_lock, flags);
+	res = __for_each_channel(_chan_in_conf, x);
+	read_unlock_irqrestore(&chan_lock, flags);
+	if (res)
+		return;
 
 	/* If we get here, nobody is in the conference anymore.  Clear it out
 	   both forward and reverse */
@@ -2134,10 +2166,41 @@
 	}
 }
 
+static unsigned long _chan_cleanup(struct dahdi_chan *pos, unsigned long data)
+{
+	unsigned long flags;
+	struct dahdi_chan *const chan = (struct dahdi_chan *)data;
+
+	++maxchans;
+
+	/* Remove anyone pointing to us as master
+	   and make them their own thing */
+	if (pos->master == chan)
+		pos->master = pos;
+
+	if (((pos->confna == chan->channo) &&
+	    is_monitor_mode(pos->confmode)) ||
+	    (pos->dacs_chan == chan)) {
+		/* Take them out of conference with us */
+		/* release conference resource if any */
+		if (pos->confna)
+			dahdi_check_conf(pos->confna);
+
+		dahdi_disable_dacs(pos);
+		spin_lock_irqsave(&pos->lock, flags);
+		pos->confna = 0;
+		pos->_confn = 0;
+		pos->confmode = 0;
+		pos->conf_chan = NULL;
+		pos->dacs_chan = NULL;
+		spin_unlock_irqrestore(&pos->lock, flags);
+	}
+
+	return 0;
+}
 
 static void dahdi_chan_unreg(struct dahdi_chan *chan)
 {
-	int x;
 	unsigned long flags;
 
 	might_sleep();
@@ -2171,34 +2234,13 @@
 		module_printk(KERN_NOTICE, "HUH???  PPP still attached??\n");
 	}
 #endif
+
+	write_lock_irqsave(&chan_lock, flags);
 	maxchans = 0;
-	for (x = 1; x < DAHDI_MAX_CHANNELS; x++) {
-		struct dahdi_chan *const pos = chan_from_num(x);
-		if (!pos)
-			continue;
-		maxchans = x + 1;
-		/* Remove anyone pointing to us as master
-		   and make them their own thing */
-		if (pos->master == chan)
-			pos->master = pos;
-
-		if ((pos->confna == chan->channo) &&
-		    is_monitor_mode(pos->confmode)) {
-			/* Take them out of conference with us */
-			/* release conference resource if any */
-			if (pos->confna)
-				dahdi_check_conf(pos->confna);
-
-			dahdi_disable_dacs(pos);
-			pos->confna = 0;
-			pos->_confn = 0;
-			pos->confmode = 0;
-			pos->dacs_chan = NULL;
-			pos->conf_chan = NULL;
-		}
-	}
+	__for_each_channel(_chan_cleanup, (unsigned long)chan);
+	write_unlock_irqrestore(&chan_lock, flags);
+
 	chan->channo = -1;
-	write_unlock_irqrestore(&chan_lock, flags);
 }
 
 static ssize_t dahdi_chan_read(struct file *file, char __user *usrbuf,
@@ -5140,11 +5182,12 @@
 static int dahdi_ioctl_confdiag(struct file *file, unsigned long data)
 {
 	struct dahdi_chan *chan;
+	unsigned long flags;
 	int rv;
 	int i;
 	int j;
 	int c;
-	int k;
+	int k = 0;
 
 	chan = chan_from_file(file);
 	if (!chan)
@@ -5157,39 +5200,48 @@
 
 	/* loop thru the interesting ones */
 	for (i = ((j) ? j : 1); i <= ((j) ? j : DAHDI_MAX_CONF); i++) {
+		struct dahdi_span *s;
+		struct pseudo_chan *pseudo;
 		c = 0;
-		for (k = 1; k < DAHDI_MAX_CHANNELS; k++) {
-			struct dahdi_chan *const pos = chan_from_num(k);
-			/* skip if no pointer */
-			if (!pos)
+		read_lock_irqsave(&chan_lock, flags);
+		list_for_each_entry(s, &span_list, node) {
+			for (k = 0; k < s->channels; k++) {
+				chan = s->chans[k];
+				if (chan->confna != i)
+					continue;
+				if (!c)
+					module_printk(KERN_NOTICE, "Conf #%d:\n", i);
+				c = 1;
+				module_printk(KERN_NOTICE, "chan %d, mode %x\n",
+					      chan->channo, chan->confmode);
+			}
+		}
+		list_for_each_entry(pseudo, &pseudo_chans, node) {
+			/* skip if not in this conf */
+			if (pseudo->chan.confna != i)
 				continue;
-			/* skip if not in this conf */
-			if (pos->confna != i)
-				continue;
-			if (!c) {
-				module_printk(KERN_NOTICE,
-					      "Conf #%d:\n", i);
-			}
+			if (!c)
+				module_printk(KERN_NOTICE, "Conf #%d:\n", i);
 			c = 1;
 			module_printk(KERN_NOTICE, "chan %d, mode %x\n",
-				      k, pos->confmode);
-		}
+				      k, pseudo->chan.confmode);
+		}
+		read_unlock_irqrestore(&chan_lock, flags);
 		rv = 0;
 		for (k = 1; k <= DAHDI_MAX_CONF; k++) {
-			if (conf_links[k].dst == i) {
-				if (!c) {
-					c = 1;
-					module_printk(KERN_NOTICE,
-						      "Conf #%d:\n", i);
-				}
-				if (!rv) {
-					rv = 1;
-					module_printk(KERN_NOTICE,
-						      "Snooping on:\n");
-				}
-				module_printk(KERN_NOTICE, "conf %d\n",
-					      conf_links[k].src);
+			if (conf_links[k].dst != i)
+				continue;
+
+			if (!c) {
+				c = 1;
+				module_printk(KERN_NOTICE, "Conf #%d:\n", i);
 			}
+			if (!rv) {
+				rv = 1;
+				module_printk(KERN_NOTICE, "Snooping on:\n");
+			}
+			module_printk(KERN_NOTICE, "conf %d\n",
+				      conf_links[k].src);
 		}
 		if (c)
 			module_printk(KERN_NOTICE, "\n");




More information about the dahdi-commits mailing list