[svn-commits] sruffell: branch linux/sruffell/chan_list r9340 - in /linux/team/sruffell/cha...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Sep 17 14:11:52 CDT 2010


Author: sruffell
Date: Fri Sep 17 14:11:39 2010
New Revision: 9340

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9340
Log:
dahdi: When DACS is enabled, hold a pointer directly to the crossed channel.

This both removes the need to reference the 'chans'
__dahdi_process_putaudio_chunk and __dahdi_process_getaudio_chunk, and
allows the dahdi_receive / dahdi_transmit logic to be streamlined.  DACS
channels can no longer be echocanceled if crossed.  However, if a
channel was DACSed with dahi_cfg it couldn't have been echocanceled
anyway since the echo cancelers are disabled on the channel by default.

This change was originally contained in a patch kpfleming had floating
around. I split it up and merged it.

Signed-off-by: Shaun Ruffell <sruffell at digium.com>
Signed-off-by: Kevin P. Fleming <kpfleming at digium.com>

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

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=9340&r1=9339&r2=9340
==============================================================================
--- 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:39 2010
@@ -576,6 +576,14 @@
 	memset(conf_sums_next, 0, maxconfs * sizeof(sumtype));
 }
 
+/**
+ * is_chan_dacsed() - True if chan is sourcing it's data from another channel.
+ *
+ */
+static inline bool is_chan_dacsed(const struct dahdi_chan *const chan)
+{
+	return (NULL != chan->dacs_chan);
+}
 
 /**
  * can_dacs_chans() - Returns true if it may be possible to dacs two channels.
@@ -1425,15 +1433,15 @@
 	oldconf = chan->confna;
 	  /* initialize conference variables */
 	chan->_confn = 0;
-	if ((chan->sig & __DAHDI_SIG_DACS) != __DAHDI_SIG_DACS) {
-		chan->confna = 0;
-		chan->confmode = 0;
-	}
+	if ((chan->sig & __DAHDI_SIG_DACS) != __DAHDI_SIG_DACS)
+		chan->dacs_chan = NULL;
+
 	chan->confmute = 0;
 	/* release conference resource, if any to release */
 	if (oldconf) dahdi_check_conf(oldconf);
 	chan->gotgs = 0;
 	reset_conf(chan);
+	chan->dacs_chan = NULL;
 
 	if (is_gain_allocated(chan))
 		rxgain = chan->rxgain;
@@ -2143,19 +2151,17 @@
 			pos->master = pos;
 
 		if ((pos->confna == chan->channo) &&
-		    is_monitor_mode(pos->confmode) &&
-		    ((pos->confmode & DAHDI_CONF_MODE_MASK) ==
-		      DAHDI_CONF_DIGITALMON)) {
+		    is_monitor_mode(pos->confmode)) {
 			/* Take them out of conference with us */
 			/* release conference resource if any */
-			if (pos->confna) {
+			if (pos->confna)
 				dahdi_check_conf(pos->confna);
-				if (pos->span)
-					dahdi_disable_dacs(pos);
-			}
+
+			dahdi_disable_dacs(pos);
 			pos->confna = 0;
 			pos->_confn = 0;
 			pos->confmode = 0;
+			pos->dacs_chan = NULL;
 		}
 	}
 	chan->channo = -1;
@@ -2738,6 +2744,8 @@
 
 	/* Reset conferences */
 	reset_conf(chan);
+
+	chan->dacs_chan = NULL;
 
 	/* I/O Mask, etc */
 	chan->iomask = 0;
@@ -4380,6 +4388,7 @@
 			/* Setup conference properly */
 			chan->confmode = DAHDI_CONF_DIGITALMON;
 			chan->confna = ch.idlebits;
+			chan->dacs_chan = dacs_chan;
 			res = dahdi_chan_dacs(chan, dacs_chan);
 		} else {
 			dahdi_disable_dacs(chan);
@@ -6721,29 +6730,6 @@
 			for (x=0;x<DAHDI_CHUNKSIZE;x++)
 				txb[x] = DAHDI_LIN2X(getlin[x], ms);
 			break;
-		case DAHDI_CONF_DIGITALMON:
-			/* Real digital monitoring, but still echo cancel if desired */
-			if (!conf_chan)
-				break;
-			if (is_pseudo_chan(conf_chan)) {
-				if (ms->ec_state) {
-					for (x=0;x<DAHDI_CHUNKSIZE;x++)
-						txb[x] = DAHDI_LIN2X(conf_chan->getlin[x], ms);
-				} else {
-					memcpy(txb, conf_chan->getraw, DAHDI_CHUNKSIZE);
-				}
-			} else {
-				if (ms->ec_state) {
-					for (x = 0; x < DAHDI_CHUNKSIZE; x++)
-						txb[x] = DAHDI_LIN2X(conf_chan->putlin[x], ms);
-				} else {
-					memcpy(txb, conf_chan->putraw,
-					       DAHDI_CHUNKSIZE);
-				}
-			}
-			for (x=0;x<DAHDI_CHUNKSIZE;x++)
-				getlin[x] = DAHDI_XLAW(txb[x], ms);
-			break;
 		}
 	}
 	if (ms->confmute || (ms->ec_state && (ms->ec_state->status.mode) & __ECHO_MODE_MUTE)) {
@@ -7798,16 +7784,6 @@
 			for (x=0;x<DAHDI_CHUNKSIZE;x++)
 				rxb[x] = DAHDI_LIN2X((int)conf_sums_prev[ms->_confn][x], ms);
 			break;
-		case DAHDI_CONF_DIGITALMON:
-			  /* if not a pseudo-channel, ignore */
-			if (!is_pseudo_chan(ms))
-				break;
-			/* Add monitored channel */
-			if (is_pseudo_chan(conf_chan))
-				memcpy(rxb, conf_chan->getraw, DAHDI_CHUNKSIZE);
-			else
-				memcpy(rxb, conf_chan->putraw, DAHDI_CHUNKSIZE);
-			break;
 		}
 	}
 }
@@ -8479,54 +8455,56 @@
 	unsigned long flags;
 	unsigned int x;
 
-	for (x=0;x<span->channels;x++) {
+	for (x = 0; x < span->channels; x++) {
 		struct dahdi_chan *const chan = span->chans[x];
 		spin_lock_irqsave(&chan->lock, flags);
-		if (chan->flags & DAHDI_FLAG_NOSTDTXRX) {
+		if (unlikely(chan->flags & DAHDI_FLAG_NOSTDTXRX)) {
 			spin_unlock_irqrestore(&chan->lock, flags);
 			continue;
 		}
 		if (chan == chan->master) {
+			if (is_chan_dacsed(chan)) {
+				struct dahdi_chan *const src = chan->dacs_chan;
+				memcpy(chan->writechunk, src->readchunk,
+				       DAHDI_CHUNKSIZE);
+				if (chan->sig == DAHDI_SIG_DACS_RBS) {
+					/* Just set bits for our destination */
+					if (chan->txsig != src->rxsig) {
+						chan->txsig = src->rxsig;
+						span->ops->rbsbits(chan, src->rxsig);
+					}
+				}
+				/* there is no further processing to do for DACS channels, so
+				 * jump to the next channel in the span
+				 */
+				spin_unlock_irqrestore(&chan->lock, flags);
+				continue;
+			} else if (chan->nextslave) {
+				u_char data[DAHDI_CHUNKSIZE];
+				int pos = DAHDI_CHUNKSIZE;
+				int y;
+				struct dahdi_chan *z;
+				/* Process master/slaves one way */
+				for (y = 0; y < DAHDI_CHUNKSIZE; y++) {
+					/* Process slaves for this byte too */
+					for (z = chan; z; z = z->nextslave) {
+						if (pos == DAHDI_CHUNKSIZE) {
+							/* Get next chunk */
+							__dahdi_transmit_chunk(chan, data);
+							pos = 0;
+						}
+						z->writechunk[y] = data[pos++];
+					}
+				}
+			} else {
+				/* Process a normal channel */
+				__dahdi_real_transmit(chan);
+			}
 			if (chan->otimer) {
 				chan->otimer -= DAHDI_CHUNKSIZE;
 				if (chan->otimer <= 0)
 					__rbs_otimer_expire(chan);
 			}
-			if (chan->flags & DAHDI_FLAG_AUDIO) {
-				__dahdi_real_transmit(chan);
-			} else {
-				if (chan->nextslave) {
-					u_char data[DAHDI_CHUNKSIZE];
-					int pos = DAHDI_CHUNKSIZE;
-					int y;
-					struct dahdi_chan *z;
-					/* Process master/slaves one way */
-					for (y = 0; y < DAHDI_CHUNKSIZE; y++) {
-						/* Process slaves for this byte too */
-						for (z = chan; z; z = z->nextslave) {
-							if (pos == DAHDI_CHUNKSIZE) {
-								/* Get next chunk */
-								__dahdi_transmit_chunk(chan, data);
-								pos = 0;
-							}
-							z->writechunk[y] = data[pos++];
-						}
-					}
-				} else {
-					/* Process independents elsewise */
-					__dahdi_real_transmit(chan);
-				}
-			}
-			if (chan->sig == DAHDI_SIG_DACS_RBS) {
-				struct dahdi_chan *const conf =
-							chans[chan->confna];
-				if (conf && (chan->txsig != conf->rxsig)) {
-				    	/* Just set bits for our destination */
-					chan->txsig = conf->rxsig;
-					span->ops->rbsbits(chan, conf->rxsig);
-				}
-			}
-
 		}
 		spin_unlock_irqrestore(&chan->lock, flags);
 	}
@@ -8777,7 +8755,11 @@
 			continue;
 		}
 		if (chan->master == chan) {
-			if (chan->nextslave) {
+			if (is_chan_dacsed(chan)) {
+				/* this channel is in DACS mode, there is nothing to do here */
+				spin_unlock_irqrestore(&chan->lock, flags);
+				continue;
+			} else if (chan->nextslave) {
 				/* Must process each slave at the same time */
 				u_char data[DAHDI_CHUNKSIZE];
 				int pos = 0;

Modified: linux/team/sruffell/chan_list/include/dahdi/kernel.h
URL: http://svnview.digium.com/svn/dahdi/linux/team/sruffell/chan_list/include/dahdi/kernel.h?view=diff&rev=9340&r1=9339&r2=9340
==============================================================================
--- linux/team/sruffell/chan_list/include/dahdi/kernel.h (original)
+++ linux/team/sruffell/chan_list/include/dahdi/kernel.h Fri Sep 17 14:11:39 2010
@@ -424,6 +424,9 @@
 	u_char sreadchunk[DAHDI_MAX_CHUNKSIZE];	/*!< Preallocated static area */
 	short *readchunkpreec;
 
+	/* Channel from which to read when DACSed. */
+	struct dahdi_chan *dacs_chan;
+
 	/*! Pointer to tx and rx gain tables */
 	const u_char *rxgain;
 	const u_char *txgain;
@@ -521,7 +524,7 @@
 	short	conflast[DAHDI_MAX_CHUNKSIZE];			/*!< Last conference sample -- base part of channel */
 	short	conflast1[DAHDI_MAX_CHUNKSIZE];		/*!< Last conference sample  -- pseudo part of channel */
 	short	conflast2[DAHDI_MAX_CHUNKSIZE];		/*!< Previous last conference sample -- pseudo part of channel */
-	
+
 
 	/*! The echo canceler module that should be used to create an
 	   instance when this channel needs one */




More information about the svn-commits mailing list