[svn-commits] sruffell: linux/trunk r9607 - /linux/trunk/drivers/dahdi/dahdi-base.c

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


Author: sruffell
Date: Mon Jan  3 12:28:06 2011
New Revision: 9607

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9607
Log:
dahdi: Drop 'chans' reference in chan_from_num.

Part of getting rid of global chans array.  We need to search the list
of spans and the list of pseudo channels.  While this is slower than a
direct index into a 'chans' array, the places where this function is
called are not in the 'hot' path but instead part of channel
configuration and conferencing setup.

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

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=9607&r1=9606&r2=9607
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Mon Jan  3 12:28:06 2011
@@ -476,9 +476,54 @@
 
 static struct dahdi_chan *chans[DAHDI_MAX_CHANNELS];
 
-static inline struct dahdi_chan *chan_from_num(unsigned int channo)
-{
-	return valid_channo(channo) ? chans[channo] : NULL;
+static struct dahdi_chan *chan_from_num(unsigned int channo)
+{
+	struct dahdi_span *s;
+	struct pseudo_chan *pseudo;
+
+	if (!unlikely(valid_channo(channo)))
+		return NULL;
+
+	mutex_lock(&registration_mutex);
+
+	/* When searching for the channel amongst the spans, we can use the
+	 * fact that channels on a span must be numbered consecutively to skip
+	 * checking each individual channel. */
+	list_for_each_entry(s, &span_list, node) {
+		unsigned int basechan;
+		struct dahdi_chan *chan;
+
+		if (unlikely(!s->channels))
+			continue;
+
+		basechan = s->chans[0]->channo;
+		if (channo >= (basechan + s->channels))
+			continue;
+
+		if (unlikely(channo < basechan)) {
+			/* Looks like they are asking for a channel that has
+			 * already been removed. */
+			mutex_unlock(&registration_mutex);
+			return NULL;
+		}
+
+		chan = s->chans[channo - basechan];
+		WARN_ON(chan->channo != channo);
+		mutex_unlock(&registration_mutex);
+		return chan;
+	}
+
+	/* If we didn't find the channel on the list of real channels, then
+	 * it's most likely a pseudo channel. */
+	list_for_each_entry(pseudo, &pseudo_chans, node) {
+		if (pseudo->chan.channo == channo) {
+			mutex_unlock(&registration_mutex);
+			return &pseudo->chan;
+		}
+	}
+
+	mutex_unlock(&registration_mutex);
+	return NULL;
 }
 
 static inline struct dahdi_chan *chan_from_file(struct file *file)




More information about the svn-commits mailing list