[svn-commits] sruffell: branch linux/sruffell/staging r6503 - in /linux/team/sruffell/stagi...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Apr 27 11:00:12 CDT 2009


Author: sruffell
Date: Mon Apr 27 11:00:10 2009
New Revision: 6503

URL: http://svn.digium.com/svn-view/dahdi?view=rev&rev=6503
Log:
Changes on echocan_work up to:
https://origsvn.digium.com/svn/dahdi/linux/team/kpfleming/echocan_work@6486

Modified:
    linux/team/sruffell/staging/drivers/dahdi/dahdi-base.c
    linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_jpah.c
    linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_kb1.c
    linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_mg2.c
    linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_oslec.c
    linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_sec.c
    linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_sec2.c
    linux/team/sruffell/staging/drivers/dahdi/ecdis.h
    linux/team/sruffell/staging/drivers/dahdi/hpec/dahdi_echocan_hpec.c
    linux/team/sruffell/staging/drivers/dahdi/hpec/hpec.h
    linux/team/sruffell/staging/include/dahdi/dahdi_config.h
    linux/team/sruffell/staging/include/dahdi/kernel.h
    linux/team/sruffell/staging/include/dahdi/user.h

Modified: linux/team/sruffell/staging/drivers/dahdi/dahdi-base.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/sruffell/staging/drivers/dahdi/dahdi-base.c?view=diff&rev=6503&r1=6502&r2=6503
==============================================================================
--- linux/team/sruffell/staging/drivers/dahdi/dahdi-base.c (original)
+++ linux/team/sruffell/staging/drivers/dahdi/dahdi-base.c Mon Apr 27 11:00:10 2009
@@ -47,21 +47,11 @@
 #include <linux/moduleparam.h>
 #include <linux/list.h>
 
+#include <linux/ppp_defs.h>
+
 #include <asm/atomic.h>
 
 #define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
-
-#ifndef CONFIG_OLD_HDLC_API
-#define NEW_HDLC_INTERFACE
-#endif
-
-#define __ECHO_STATE_MUTE			(1 << 8)
-#define ECHO_STATE_IDLE				(0)
-#define ECHO_STATE_PRETRAINING		(1 | (__ECHO_STATE_MUTE))
-#define ECHO_STATE_STARTTRAINING	(2 | (__ECHO_STATE_MUTE))
-#define ECHO_STATE_AWAITINGECHO		(3 | (__ECHO_STATE_MUTE))
-#define ECHO_STATE_TRAINING			(4 | (__ECHO_STATE_MUTE))
-#define ECHO_STATE_ACTIVE			(5)
 
 /* #define BUF_MUNGE */
 
@@ -71,16 +61,18 @@
 #include <dahdi/kernel.h>
 #include "ecdis.h"
 
-#ifdef CONFIG_DAHDI_NET
-#include <linux/netdevice.h>
-#endif /* CONFIG_DAHDI_NET */
-
-#include <linux/ppp_defs.h>
+#ifndef CONFIG_OLD_HDLC_API
+#define NEW_HDLC_INTERFACE
+#endif
 
 #ifdef CONFIG_DAHDI_PPP
 #include <linux/netdevice.h>
 #include <linux/if.h>
 #include <linux/if_ppp.h>
+#endif
+
+#ifdef CONFIG_DAHDI_NET
+#include <linux/netdevice.h>
 #endif
 
 #include "hpec/hpec_user.h"
@@ -143,8 +135,8 @@
 EXPORT_SYMBOL(dahdi_register_chardev);
 EXPORT_SYMBOL(dahdi_unregister_chardev);
 
-EXPORT_SYMBOL(dahdi_register_echocan);
-EXPORT_SYMBOL(dahdi_unregister_echocan);
+EXPORT_SYMBOL(dahdi_register_echocan_factory);
+EXPORT_SYMBOL(dahdi_unregister_echocan_factory);
 
 EXPORT_SYMBOL(dahdi_set_hpec_ioctl);
 
@@ -378,62 +370,62 @@
 #define NUM_SIGS	10
 
 #ifdef DEFINE_RWLOCK
-static DEFINE_RWLOCK(echocan_list_lock);
+static DEFINE_RWLOCK(ecfactory_list_lock);
 #else
-static rwlock_t echocan_list_lock = RW_LOCK_UNLOCKED;
-#endif
-
-static LIST_HEAD(echocan_list);
-
-struct echocan {
-	const struct dahdi_echocan *ec;
+static rwlock_t ecfactory_list_lock = __RW_LOCK_UNLOCKED();
+#endif
+
+static LIST_HEAD(ecfactory_list);
+
+struct ecfactory {
+	const struct dahdi_echocan_factory *ec;
 	struct module *owner;
 	struct list_head list;
 };
 
-int dahdi_register_echocan(const struct dahdi_echocan *ec)
-{
-	struct echocan *cur;
-
-	write_lock(&echocan_list_lock);
+int dahdi_register_echocan_factory(const struct dahdi_echocan_factory *ec)
+{
+	struct ecfactory *cur;
+
+	write_lock(&ecfactory_list_lock);
 
 	/* make sure it isn't already registered */
-	list_for_each_entry(cur, &echocan_list, list) {
+	list_for_each_entry(cur, &ecfactory_list, list) {
 		if (cur->ec == ec) {
-			write_unlock(&echocan_list_lock);
+			write_unlock(&ecfactory_list_lock);
 			return -EPERM;
 		}
 	}
 
 	if (!(cur = kzalloc(sizeof(*cur), GFP_KERNEL))) {
-		write_unlock(&echocan_list_lock);
+		write_unlock(&ecfactory_list_lock);
 		return -ENOMEM;
 	}
 
 	cur->ec = ec;
 	INIT_LIST_HEAD(&cur->list);
 
-	list_add_tail(&cur->list, &echocan_list);
-
-	write_unlock(&echocan_list_lock);
+	list_add_tail(&cur->list, &ecfactory_list);
+
+	write_unlock(&ecfactory_list_lock);
 
 	return 0;
 }
 
-void dahdi_unregister_echocan(const struct dahdi_echocan *ec)
-{
-	struct echocan *cur, *next;
-
-	write_lock(&echocan_list_lock);
-
-	list_for_each_entry_safe(cur, next, &echocan_list, list) {
+void dahdi_unregister_echocan_factory(const struct dahdi_echocan_factory *ec)
+{
+	struct ecfactory *cur, *next;
+
+	write_lock(&ecfactory_list_lock);
+
+	list_for_each_entry_safe(cur, next, &ecfactory_list, list) {
 		if (cur->ec == ec) {
 			list_del(&cur->list);
 			break;
 		}
 	}
 
-	write_unlock(&echocan_list_lock);
+	write_unlock(&ecfactory_list_lock);
 }
 
 static inline void rotate_sums(void)
@@ -1099,9 +1091,9 @@
 	return ret;
 }
 
-static const struct dahdi_echocan *find_echocan(const char *name)
-{
-	struct echocan *cur;
+static const struct dahdi_echocan_factory *find_echocan(const char *name)
+{
+	struct ecfactory *cur;
 	char name_upper[strlen(name) + 1];
 	char *c;
 	const char *d;
@@ -1115,26 +1107,26 @@
 	*c = '\0';
 
 retry:
-	read_lock(&echocan_list_lock);
-
-	list_for_each_entry(cur, &echocan_list, list) {
+	read_lock(&ecfactory_list_lock);
+
+	list_for_each_entry(cur, &ecfactory_list, list) {
 		if (!strcmp(name_upper, cur->ec->name)) {
 #ifdef USE_ECHOCAN_REFCOUNT
 			if (try_module_get(cur->owner)) {
-				read_unlock(&echocan_list_lock);
+				read_unlock(&ecfactory_list_lock);
 				return cur->ec;
 			} else {
-				read_unlock(&echocan_list_lock);
+				read_unlock(&ecfactory_list_lock);
 				return NULL;
 			}
 #else
-			read_unlock(&echocan_list_lock);
+			read_unlock(&ecfactory_list_lock);
 			return cur->ec;
 #endif
 		}
 	}
 
-	read_unlock(&echocan_list_lock);
+	read_unlock(&ecfactory_list_lock);
 
 	if (tried_once) {
 		return NULL;
@@ -1154,7 +1146,7 @@
 	goto retry;
 }
 
-static void release_echocan(const struct dahdi_echocan *ec)
+static void release_echocan(const struct dahdi_echocan_factory *ec)
 {
 #ifdef USE_ECHOCAN_REFCOUNT
 	module_put(ec->owner);
@@ -1173,8 +1165,8 @@
 {
 	unsigned long flags;
 	void *rxgain = NULL;
-	struct echo_can_state *ec_state;
-	const struct dahdi_echocan *ec_current;
+	struct dahdi_echocan_state *ec_state;
+	const struct dahdi_echocan_factory *ec_current;
 	int oldconf;
 	short *readchunkpreec;
 #ifdef CONFIG_DAHDI_PPP
@@ -1252,7 +1244,7 @@
 		chan->span->dacs(chan, NULL);
 
 	if (ec_state) {
-		ec_current->echo_can_free(ec_state);
+		ec_state->ops->echocan_free(ec_state);
 		release_echocan(ec_current);
 	}
 
@@ -2449,8 +2441,8 @@
 	int res;
 	unsigned long flags;
 	void *rxgain=NULL;
-	struct echo_can_state *ec_state;
-	const struct dahdi_echocan *ec_current;
+	struct dahdi_echocan_state *ec_state;
+	const struct dahdi_echocan_factory *ec_current;
 
 	if ((res = dahdi_reallocbufs(chan, DAHDI_DEFAULT_BLOCKSIZE, DAHDI_DEFAULT_NUM_BUFS)))
 		return res;
@@ -2464,10 +2456,6 @@
 	chan->ec_state = NULL;
 	ec_current = chan->ec_current;
 	chan->ec_current = NULL;
-	chan->echocancel = 0;
-	chan->echostate = ECHO_STATE_IDLE;
-	chan->echolastupdate = 0;
-	chan->echotimer = 0;
 
 	chan->txdisable = 0;
 	chan->rxdisable = 0;
@@ -2562,7 +2550,7 @@
 	}
 
 	if (ec_state) {
-		ec_current->echo_can_free(ec_state);
+		ec_state->ops->echocan_free(ec_state);
 		release_echocan(ec_current);
 	}
 
@@ -3437,7 +3425,6 @@
 	struct dahdi_chan *chan;
 	unsigned long flags;
 	unsigned char *txgain, *rxgain;
-	struct dahdi_chan *mychan;
 	int i,j;
 	int return_master = 0;
 	size_t size_to_copy;
@@ -3678,7 +3665,14 @@
 		break;
 	case DAHDI_CHANDIAG_V1: /* Intentional drop through. */
 	case DAHDI_CHANDIAG:
-		get_user(j, (int *)data); /* get channel number from user */
+	{
+		/* there really is no need to initialize this structure because when it is used it has
+		 * already been completely overwritten, but apparently the compiler cannot figure that
+		 * out and warns about uninitialized usage... so initialize it.
+		 */
+		struct dahdi_echocan_state ec_state = { .ops = NULL, };
+
+		get_user(j, (int *) data); /* get channel number from user */
 		/* make sure its a valid channel number */
 		if ((j < 1) || (j >= maxchans))
 			return -EINVAL;
@@ -3686,54 +3680,52 @@
 		if (!chans[j])
 			return -EINVAL;
 
-		if (!(mychan = kmalloc(sizeof(*mychan), GFP_KERNEL)))
+		chan = kmalloc(sizeof(*chan), GFP_KERNEL);
+		if (!chan)
 			return -ENOMEM;
 
 		/* lock channel */
 		spin_lock_irqsave(&chans[j]->lock, flags);
 		/* make static copy of channel */
-		memcpy(mychan, chans[j], sizeof(*mychan));
+		*chan = *chans[j];
+		if (chan->ec_state) {
+			ec_state = *chan->ec_state;
+		}
 		/* release it. */
 		spin_unlock_irqrestore(&chans[j]->lock, flags);
 
 		module_printk(KERN_INFO, "Dump of DAHDI Channel %d (%s,%d,%d):\n\n",j,
-			mychan->name,mychan->channo,mychan->chanpos);
-		module_printk(KERN_INFO, "flags: %x hex, writechunk: %08lx, readchunk: %08lx\n",
-			(unsigned int) mychan->flags, (long) mychan->writechunk, (long) mychan->readchunk);
-		module_printk(KERN_INFO, "rxgain: %08lx, txgain: %08lx, gainalloc: %d\n",
-			(long) mychan->rxgain, (long)mychan->txgain, mychan->gainalloc);
-		module_printk(KERN_INFO, "span: %08lx, sig: %x hex, sigcap: %x hex\n",
-			(long)mychan->span, mychan->sig, mychan->sigcap);
+			      chan->name, chan->channo, chan->chanpos);
+		module_printk(KERN_INFO, "flags: %x hex, writechunk: %p, readchunk: %p\n",
+			      (unsigned int) chan->flags, chan->writechunk, chan->readchunk);
+		module_printk(KERN_INFO, "rxgain: %p, txgain: %p, gainalloc: %d\n",
+			      chan->rxgain, chan->txgain, chan->gainalloc);
+		module_printk(KERN_INFO, "span: %p, sig: %x hex, sigcap: %x hex\n",
+			      chan->span, chan->sig, chan->sigcap);
 		module_printk(KERN_INFO, "inreadbuf: %d, outreadbuf: %d, inwritebuf: %d, outwritebuf: %d\n",
-			mychan->inreadbuf, mychan->outreadbuf, mychan->inwritebuf, mychan->outwritebuf);
+			      chan->inreadbuf, chan->outreadbuf, chan->inwritebuf, chan->outwritebuf);
 		module_printk(KERN_INFO, "blocksize: %d, numbufs: %d, txbufpolicy: %d, txbufpolicy: %d\n",
-			mychan->blocksize, mychan->numbufs, mychan->txbufpolicy, mychan->rxbufpolicy);
+			      chan->blocksize, chan->numbufs, chan->txbufpolicy, chan->rxbufpolicy);
 		module_printk(KERN_INFO, "txdisable: %d, rxdisable: %d, iomask: %d\n",
-			mychan->txdisable, mychan->rxdisable, mychan->iomask);
-		module_printk(KERN_INFO, "curzone: %08lx, tonezone: %d, curtone: %08lx, tonep: %d\n",
-			(long) mychan->curzone, mychan->tonezone, (long) mychan->curtone, mychan->tonep);
+			      chan->txdisable, chan->rxdisable, chan->iomask);
+		module_printk(KERN_INFO, "curzone: %p, tonezone: %d, curtone: %p, tonep: %d\n",
+			      chan->curzone, chan->tonezone, chan->curtone, chan->tonep);
 		module_printk(KERN_INFO, "digitmode: %d, txdialbuf: %s, dialing: %d, aftdialtimer: %d, cadpos. %d\n",
-			mychan->digitmode, mychan->txdialbuf, mychan->dialing,
-				mychan->afterdialingtimer, mychan->cadencepos);
+			      chan->digitmode, chan->txdialbuf, chan->dialing,
+			      chan->afterdialingtimer, chan->cadencepos);
 		module_printk(KERN_INFO, "confna: %d, confn: %d, confmode: %d, confmute: %d\n",
-			mychan->confna, mychan->_confn, mychan->confmode, mychan->confmute);
-		module_printk(KERN_INFO, "ec: %08lx, echocancel: %d, deflaw: %d, xlaw: %08lx\n",
-			(long) mychan->ec_state, mychan->echocancel, mychan->deflaw, (long) mychan->xlaw);
-		module_printk(KERN_INFO, "echostate: %02x, echotimer: %d, echolastupdate: %d\n",
-			(int) mychan->echostate, mychan->echotimer, mychan->echolastupdate);
+			      chan->confna, chan->_confn, chan->confmode, chan->confmute);
+		module_printk(KERN_INFO, "ec: %p, deflaw: %d, xlaw: %p\n",
+			      chan->ec_state, chan->deflaw, chan->xlaw);
+		if (chan->ec_state) {
+			module_printk(KERN_INFO, "echostate: %02x, echotimer: %d, echolastupdate: %d\n",
+				      ec_state.status.mode, ec_state.status.pretrain_timer, ec_state.status.last_train_tap);
+		}
 		module_printk(KERN_INFO, "itimer: %d, otimer: %d, ringdebtimer: %d\n\n",
-			mychan->itimer, mychan->otimer, mychan->ringdebtimer);
-#if 0
-		if (mychan->ec_state) {
-			int x;
-			/* Dump the echo canceller parameters */
-			for (x=0;x<mychan->ec_state->taps;x++) {
-				module_printk(KERN_INFO, "tap %d: %d\n", x, mychan->ec_state->fir_taps[x]);
-			}
-		}
-#endif
-		kfree(mychan);
-		break;
+			      chan->itimer, chan->otimer, chan->ringdebtimer);
+		kfree(chan);
+		break;
+	}
 	default:
 		return -ENOTTY;
 	}
@@ -3851,7 +3843,7 @@
 	case DAHDI_ATTACH_ECHOCAN:
 	{
 		struct dahdi_attach_echocan ae;
-		const struct dahdi_echocan *new = NULL, *old;
+		const struct dahdi_echocan_factory *new = NULL, *old;
 
 		if (copy_from_user(&ae, (struct dahdi_attach_echocan *) data, sizeof(ae))) {
 			return -EFAULT;
@@ -4172,19 +4164,19 @@
 	case DAHDI_GETVERSION:
 	{
 		struct dahdi_versioninfo vi;
-		struct echocan *cur;
+		struct ecfactory *cur;
 		size_t space = sizeof(vi.echo_canceller) - 1;
 
 		memset(&vi, 0, sizeof(vi));
 		dahdi_copy_string(vi.version, DAHDI_VERSION, sizeof(vi.version));
-		read_lock(&echocan_list_lock);
-		list_for_each_entry(cur, &echocan_list, list) {
+		read_lock(&ecfactory_list_lock);
+		list_for_each_entry(cur, &ecfactory_list, list) {
 			strncat(vi.echo_canceller + strlen(vi.echo_canceller), cur->ec->name, space);
 			space -= strlen(cur->ec->name);
 			if (space < 1) {
 				break;
 			}
-			if (cur->list.next && (cur->list.next != &echocan_list)) {
+			if (cur->list.next && (cur->list.next != &ecfactory_list)) {
 				strncat(vi.echo_canceller + strlen(vi.echo_canceller), ", ", space);
 				space -= 2;
 				if (space < 1) {
@@ -4192,7 +4184,7 @@
 				}
 			}
 		}
-		read_unlock(&echocan_list_lock);
+		read_unlock(&ecfactory_list_lock);
 		if (copy_to_user((struct dahdi_versioninfo *) data, &vi, sizeof(vi)))
 			return -EFAULT;
 		break;
@@ -4854,8 +4846,8 @@
 
 static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, void *data)
 {
-	struct echo_can_state *ec = NULL, *ec_state;
-	const struct dahdi_echocan *ec_current;
+	struct dahdi_echocan_state *ec = NULL, *ec_state;
+	const struct dahdi_echocan_factory *ec_current;
 	struct dahdi_echocanparam *params;
 	int ret;
 	unsigned long flags;
@@ -4870,13 +4862,9 @@
 		chan->ec_state = NULL;
 		ec_current = chan->ec_current;
 		chan->ec_current = NULL;
-		chan->echocancel = 0;
-		chan->echostate = ECHO_STATE_IDLE;
-		chan->echolastupdate = 0;
-		chan->echotimer = 0;
 		spin_unlock_irqrestore(&chan->lock, flags);
 		if (ec_state) {
-			ec_current->echo_can_free(ec_state);
+			ec_state->ops->echocan_free(ec_state);
 			release_echocan(ec_current);
 		}
 		hw_echocancel_off(chan);
@@ -4909,7 +4897,7 @@
 	chan->ec_current = NULL;
 	spin_unlock_irqrestore(&chan->lock, flags);
 	if (ec_state) {
-		ec_current->echo_can_free(ec_state);
+		ec_state->ops->echocan_free(ec_state);
 		release_echocan(ec_current);
 	}
 
@@ -4950,21 +4938,30 @@
 		   an echo canceler instance if possible */
 		ec_current = chan->ec_factory;
 
-		if ((ret = ec_current->echo_can_create(ecp, params, &ec))) {
+		ret = ec_current->echocan_create(ecp, params, &ec);
+		if (ret) {
 			release_echocan(ec_current);
 
 			goto exit_with_free;
 		}
+		if (!ec) {
+			module_printk(KERN_ERR, "%s failed to allocate an " \
+				"dahdi_echocan_state instance.\n",
+				ec_current->name);
+			ret = -EFAULT;
+			goto exit_with_free;
+		}
 
 		spin_lock_irqsave(&chan->lock, flags);
-		chan->echocancel = ecp->tap_length;
 		chan->ec_current = ec_current;
 		chan->ec_state = ec;
-		chan->echostate = ECHO_STATE_IDLE;
-		chan->echolastupdate = 0;
-		chan->echotimer = 0;
-		echo_can_disable_detector_init(&chan->txecdis);
-		echo_can_disable_detector_init(&chan->rxecdis);
+		ec->status.mode = ECHO_MODE_ACTIVE;
+		if (!ec->features.CED_tx_detect) {
+			echo_can_disable_detector_init(&chan->ec_state->txecdis);
+		}
+		if (!ec->features.CED_rx_detect) {
+			echo_can_disable_detector_init(&chan->ec_state->rxecdis);
+		}
 		spin_unlock_irqrestore(&chan->lock, flags);
 	}
 
@@ -4972,6 +4969,44 @@
 	kfree(params);
 
 	return ret;
+}
+
+static void set_echocan_fax_mode(struct dahdi_chan *chan, unsigned int channo, const char *reason, unsigned int enable)
+{
+	if (enable) {
+		if (!chan->ec_state)
+			module_printk(KERN_NOTICE, "Ignoring FAX mode request because of %s for channel %d with no echo canceller\n", reason, channo);
+		else if (chan->ec_state->status.mode == ECHO_MODE_FAX)
+			module_printk(KERN_NOTICE, "Ignoring FAX mode request because of %s for echo canceller already in FAX mode on channel %d\n", reason, channo);
+		else if (chan->ec_state->status.mode != ECHO_MODE_ACTIVE)
+			module_printk(KERN_NOTICE, "Ignoring FAX mode request because of %s for echo canceller not in active mode on channel %d\n", reason, channo);
+		else if (chan->ec_state->features.NLP_toggle) {
+			module_printk(KERN_NOTICE, "Disabled echo canceller NLP because of %s on channel %d\n", reason, channo);
+			dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_DISABLED);
+			chan->ec_state->ops->echocan_NLP_toggle(chan->ec_state, 0);
+			chan->ec_state->status.mode = ECHO_MODE_FAX;
+		} else {
+			module_printk(KERN_NOTICE, "Idled echo canceller because of %s on channel %d\n", reason, channo);
+			chan->ec_state->status.mode = ECHO_MODE_IDLE;
+		}
+	} else {
+		if (!chan->ec_state)
+			module_printk(KERN_NOTICE, "Ignoring voice mode request because of %s for channel %d with no echo canceller\n", reason, channo);
+		else if (chan->ec_state->status.mode == ECHO_MODE_ACTIVE)
+			module_printk(KERN_NOTICE, "Ignoring voice mode request because of %s for echo canceller already in voice mode on channel %d\n", reason, channo);
+		else if ((chan->ec_state->status.mode != ECHO_MODE_FAX) &&
+			 (chan->ec_state->status.mode != ECHO_MODE_IDLE))
+			module_printk(KERN_NOTICE, "Ignoring voice mode request because of %s for echo canceller not in FAX or idle mode on channel %d\n", reason, channo);
+		else if (chan->ec_state->features.NLP_toggle) {
+			module_printk(KERN_NOTICE, "Enabled echo canceller NLP because of %s on channel %d\n", reason, channo);
+			dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_ENABLED);
+			chan->ec_state->ops->echocan_NLP_toggle(chan->ec_state, 1);
+			chan->ec_state->status.mode = ECHO_MODE_ACTIVE;
+		} else {
+			module_printk(KERN_NOTICE, "Activated echo canceller because of %s on channel %d\n", reason, channo);
+			chan->ec_state->status.mode = ECHO_MODE_ACTIVE;
+		}
+	}
 }
 
 static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit)
@@ -5020,8 +5055,8 @@
 			/* Coming out of audio mode, also clear all
 			   conferencing and gain related info as well
 			   as echo canceller */
-			struct echo_can_state *ec_state;
-			const struct dahdi_echocan *ec_current;
+			struct dahdi_echocan_state *ec_state;
+			const struct dahdi_echocan_factory *ec_current;
 
 			spin_lock_irqsave(&chan->lock, flags);
 			chan->flags &= ~DAHDI_FLAG_AUDIO;
@@ -5054,7 +5089,7 @@
 			spin_unlock_irqrestore(&chan->lock, flags);
 
 			if (ec_state) {
-				ec_current->echo_can_free(ec_state);
+				ec_state->ops->echocan_free(ec_state);
 				release_echocan(ec_current);
 			}
 
@@ -5074,8 +5109,8 @@
 			if (!chan->ppp) {
 				chan->ppp = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL);
 				if (chan->ppp) {
-					struct echo_can_state *tec;
-					const struct dahdi_echocan *ec_current;
+					struct dahdi_echocan_state *tec;
+					const struct dahdi_echocan_factory *ec_current;
 
 					chan->ppp->private = chan;
 					chan->ppp->ops = &ztppp_ops;
@@ -5100,10 +5135,6 @@
 					chan->ec_state = NULL;
 					ec_current = chan->ec_current;
 					chan->ec_current = NULL;
-					chan->echocancel = 0;
-					chan->echostate = ECHO_STATE_IDLE;
-					chan->echolastupdate = 0;
-					chan->echotimer = 0;
 					/* Make sure there's no gain */
 					if (chan->gainalloc)
 						kfree(chan->rxgain);
@@ -5115,7 +5146,7 @@
 					hw_echocancel_off(chan);
 
 					if (tec) {
-						ec_current->echo_can_free(tec);
+						tec->ops->echocan_free(tec);
 						release_echocan(ec_current);
 					}
 				} else
@@ -5201,21 +5232,31 @@
 		j <<= 3;
 		if (chan->ec_state) {
 			/* Start pretraining stage */
-			chan->echostate = ECHO_STATE_PRETRAINING;
-			chan->echotimer = j;
+			spin_lock_irqsave(&chan->lock, flags);
+			chan->ec_state->status.mode = ECHO_MODE_PRETRAINING;
+			chan->ec_state->status.pretrain_timer = j;
+			spin_unlock_irqrestore(&chan->lock, flags);
 		} else
 			return -EINVAL;
+		break;
+	case DAHDI_ECHOCANCEL_FAX_MODE:
+		if (!chan->ec_state) {
+			return -EINVAL;
+		} else {
+			get_user(j, (int *) data);
+			spin_lock_irqsave(&chan->lock, flags);
+			set_echocan_fax_mode(chan, chan->channo, "ioctl", j ? 1 : 0);
+			spin_unlock_irqrestore(&chan->lock, flags);
+		}
 		break;
 	case DAHDI_SETTXBITS:
 		if (chan->sig != DAHDI_SIG_CAS)
 			return -EINVAL;
 		get_user(j,(int *)data);
 		dahdi_cas_setbits(chan, j);
-		rv = 0;
 		break;
 	case DAHDI_GETRXBITS:
 		put_user(chan->rxsig, (int *)data);
-		rv = 0;
 		break;
 	case DAHDI_LOOPBACK:
 		get_user(j, (int *)data);
@@ -5225,7 +5266,6 @@
 		else
 			chan->flags &= ~DAHDI_FLAG_LOOPED;
 		spin_unlock_irqrestore(&chan->lock, flags);
-		rv = 0;
 		break;
 	case DAHDI_HOOK:
 		get_user(j,(int *)data);
@@ -5286,7 +5326,6 @@
 				rv = schluffen(&chan->txstateq);
 				if (rv) return rv;
 #endif
-				rv = 0;
 				break;
 			case DAHDI_WINK:
 				spin_lock_irqsave(&chan->lock, flags);
@@ -5741,26 +5780,17 @@
 	/* Okay, now we've got something to transmit */
 	for (x=0;x<DAHDI_CHUNKSIZE;x++)
 		getlin[x] = DAHDI_XLAW(txb[x], ms);
-#ifndef NO_ECHOCAN_DISABLE
-	if (ms->ec_state) {
-		for (x=0;x<DAHDI_CHUNKSIZE;x++) {
-			/* Check for echo cancel disabling tone */
-			if (echo_can_disable_detector_update(&ms->txecdis, getlin[x])) {
-				module_printk(KERN_NOTICE, "Disabled echo canceller because of tone (tx) on channel %d\n", ss->channo);
-				ms->echocancel = 0;
-				ms->echostate = ECHO_STATE_IDLE;
-				ms->echolastupdate = 0;
-				ms->echotimer = 0;
-				ms->ec_current->echo_can_free(ms->ec_state);
-				ms->ec_state = NULL;
-				release_echocan(ms->ec_current);
-				ms->ec_current = NULL;
-				__qevent(ss, DAHDI_EVENT_EC_DISABLED);
+
+	if (ms->ec_state && (ms->ec_state->status.mode == ECHO_MODE_ACTIVE) && !ms->ec_state->features.CED_tx_detect) {
+		for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
+			if (echo_can_disable_detector_update(&ms->ec_state->txecdis, getlin[x])) {
+				set_echocan_fax_mode(ms, ss->channo, "CED tx detected", 1);
+				dahdi_qevent_nolock(ms, DAHDI_EVENT_TX_CED_DETECTED);
 				break;
 			}
 		}
 	}
-#endif
+
 	if ((!ms->confmute && !ms->dialing) || (ms->flags & DAHDI_FLAG_PSEUDO)) {
 		/* Handle conferencing on non-clear channel and non-HDLC channels */
 		switch(ms->confmode & DAHDI_CONF_MODE_MASK) {
@@ -5945,13 +5975,13 @@
 			break;
 		}
 	}
-	if (ms->confmute || (ms->echostate & __ECHO_STATE_MUTE)) {
+	if (ms->confmute || (ms->ec_state && (ms->ec_state->status.mode) & __ECHO_MODE_MUTE)) {
 		txb[0] = DAHDI_LIN2X(0, ms);
 		memset(txb + 1, txb[0], DAHDI_CHUNKSIZE - 1);
-		if (ms->echostate == ECHO_STATE_STARTTRAINING) {
+		if (ms->ec_state && (ms->ec_state->status.mode == ECHO_MODE_STARTTRAINING)) {
 			/* Transmit impulse now */
 			txb[0] = DAHDI_LIN2X(16384, ms);
-			ms->echostate = ECHO_STATE_AWAITINGECHO;
+			ms->ec_state->status.mode = ECHO_MODE_AWAITINGECHO;
 		}
 	}
 	/* save value from last chunk */
@@ -6545,6 +6575,47 @@
 	spin_unlock_irqrestore(&chan->lock, flags);
 }
 
+static void process_echocan_events(struct dahdi_chan *chan)
+{
+	union dahdi_echocan_events events = chan->ec_state->events;
+
+	if (events.CED_tx_detected) {
+		dahdi_qevent_nolock(chan, DAHDI_EVENT_TX_CED_DETECTED);
+		if (chan->ec_state) {
+			if (chan->ec_state->status.mode == ECHO_MODE_ACTIVE)
+				set_echocan_fax_mode(chan, chan->channo, "CED tx detected", 1);
+			else
+				module_printk(KERN_NOTICE, "Detected CED tone (tx) on channel %d\n", chan->channo);
+		}
+	}
+
+	if (events.CED_rx_detected) {
+		dahdi_qevent_nolock(chan, DAHDI_EVENT_RX_CED_DETECTED);
+		if (chan->ec_state) {
+			if (chan->ec_state->status.mode == ECHO_MODE_ACTIVE)
+				set_echocan_fax_mode(chan, chan->channo, "CED rx detected", 1);
+			else
+				module_printk(KERN_NOTICE, "Detected CED tone (rx) on channel %d\n", chan->channo);
+		}
+	}
+
+	if (events.CNG_tx_detected)
+		dahdi_qevent_nolock(chan, DAHDI_EVENT_TX_CNG_DETECTED);
+
+	if (events.CNG_rx_detected)
+		dahdi_qevent_nolock(chan, DAHDI_EVENT_RX_CNG_DETECTED);
+
+	if (events.NLP_auto_disabled) {
+		dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_DISABLED);
+		chan->ec_state->status.mode = ECHO_MODE_FAX;
+	}
+
+	if (events.NLP_auto_enabled) {
+		dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_ENABLED);
+		chan->ec_state->status.mode = ECHO_MODE_ACTIVE;
+	}
+}
+
 static inline void __dahdi_ec_chunk(struct dahdi_chan *ss, unsigned char *rxchunk, const unsigned char *txchunk)
 {
 	short rxlin, txlin;
@@ -6565,39 +6636,44 @@
 #if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP)
 		dahdi_kernel_fpu_begin();
 #endif
-		if (ss->echostate & __ECHO_STATE_MUTE) {
+		if (ss->ec_state->status.mode & __ECHO_MODE_MUTE) {
 			/* Special stuff for training the echo can */
 			for (x=0;x<DAHDI_CHUNKSIZE;x++) {
 				rxlin = DAHDI_XLAW(rxchunk[x], ss);
 				txlin = DAHDI_XLAW(txchunk[x], ss);
-				if (ss->echostate == ECHO_STATE_PRETRAINING) {
-					if (--ss->echotimer <= 0) {
-						ss->echotimer = 0;
-						ss->echostate = ECHO_STATE_STARTTRAINING;
+				if (ss->ec_state->status.mode == ECHO_MODE_PRETRAINING) {
+					if (--ss->ec_state->status.pretrain_timer <= 0) {
+						ss->ec_state->status.pretrain_timer = 0;
+						ss->ec_state->status.mode = ECHO_MODE_STARTTRAINING;
 					}
 				}
-				if ((ss->echostate == ECHO_STATE_AWAITINGECHO) && (txlin > 8000)) {
-					ss->echolastupdate = 0;
-					ss->echostate = ECHO_STATE_TRAINING;
+				if ((ss->ec_state->status.mode == ECHO_MODE_AWAITINGECHO) && (txlin > 8000)) {
+					ss->ec_state->status.last_train_tap = 0;
+					ss->ec_state->status.mode = ECHO_MODE_TRAINING;
 				}
-				if (ss->echostate == ECHO_STATE_TRAINING) {
-					if (ss->ec_current->echo_can_traintap(ss->ec_state, ss->echolastupdate++, rxlin)) {
+				if (ss->ec_state->status.mode == ECHO_MODE_TRAINING) {
+					if (ss->ec_state->ops->echocan_traintap(ss->ec_state, ss->ec_state->status.last_train_tap++, rxlin)) {
 #if 0
-						module_printk(KERN_NOTICE, "Finished training (%d taps trained)!\n", ss->echolastupdate);
-#endif
-						ss->echostate = ECHO_STATE_ACTIVE;
+						module_printk(KERN_NOTICE, "Finished training (%d taps trained)!\n", ss->ec_state->status.last_train_tap);
+#endif
+						ss->ec_state->status.mode = ECHO_MODE_ACTIVE;
 					}
 				}
 				rxlin = 0;
 				rxchunk[x] = DAHDI_LIN2X((int)rxlin, ss);
 			}
-		} else {
+		} else if (ss->ec_state->status.mode != ECHO_MODE_IDLE) {
 			short rxlins[DAHDI_CHUNKSIZE], txlins[DAHDI_CHUNKSIZE];
+
 			for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
 				rxlins[x] = DAHDI_XLAW(rxchunk[x], ss);
 				txlins[x] = DAHDI_XLAW(txchunk[x], ss);
 			}
-			ss->ec_current->echo_can_array_update(ss->ec_state, rxlins, txlins);
+			ss->ec_state->events.all = 0;
+			ss->ec_state->ops->echocan_array_update(ss->ec_state, rxlins, txlins, DAHDI_CHUNKSIZE);
+			if (ss->ec_state->events.all) {
+				process_echocan_events(ss);
+			}
 			for (x = 0; x < DAHDI_CHUNKSIZE; x++)
 				rxchunk[x] = DAHDI_LIN2X((int) rxlins[x], ss);
 		}
@@ -6692,24 +6768,16 @@
 		putlin[x] = DAHDI_XLAW(rxb[x], ms);
 	}
 
-#ifndef NO_ECHOCAN_DISABLE
-	if (ms->ec_state) {
-		for (x=0;x<DAHDI_CHUNKSIZE;x++) {
-			if (echo_can_disable_detector_update(&ms->rxecdis, putlin[x])) {
-				module_printk(KERN_NOTICE, "Disabled echo canceller because of tone (rx) on channel %d\n", ss->channo);
-				ms->echocancel = 0;
-				ms->echostate = ECHO_STATE_IDLE;
-				ms->echolastupdate = 0;
-				ms->echotimer = 0;
-				ms->ec_current->echo_can_free(ms->ec_state);
-				ms->ec_state = NULL;
-				release_echocan(ms->ec_current);
-				ms->ec_current = NULL;
+	if (ms->ec_state && (ms->ec_state->status.mode == ECHO_MODE_ACTIVE) && !ms->ec_state->features.CED_rx_detect) {
+		for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
+			if (echo_can_disable_detector_update(&ms->ec_state->rxecdis, putlin[x])) {
+				set_echocan_fax_mode(ms, ss->channo, "CED rx detected", 1);
+				dahdi_qevent_nolock(ms, DAHDI_EVENT_RX_CED_DETECTED);
 				break;
 			}
 		}
 	}
-#endif
+
 	/* if doing rx tone decoding */
 	if (ms->rxp1 && ms->rxp2 && ms->rxp3)
 	{

Modified: linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_jpah.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_jpah.c?view=diff&rev=6503&r1=6502&r2=6503
==============================================================================
--- linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_jpah.c (original)
+++ linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_jpah.c Mon Apr 27 11:00:10 2009
@@ -40,84 +40,97 @@
 #define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
 #define debug_printk(level, fmt, args...) if (debug >= level) printk("%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args)
 
-struct echo_can_state {
+static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
+			   struct dahdi_echocan_state **ec);
+static void echo_can_free(struct dahdi_echocan_state *ec);
+static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
+static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
+
+static const struct dahdi_echocan_factory my_factory = {
+	.name = "JPAH",
+	.owner = THIS_MODULE,
+	.echocan_create = echo_can_create,
+};
+
+static const struct dahdi_echocan_ops my_ops = {
+	.echocan_free = echo_can_free,
+	.echocan_array_update = echo_can_array_update,
+	.echocan_traintap = echo_can_traintap,
+};
+
+struct ec_pvt {
+	struct dahdi_echocan_state dahdi;
 	int blah;
 };
 
+#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi)
+
 static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct echo_can_state **ec)
+			   struct dahdi_echocan_state **ec)
 {
-	unsigned int x;
-	char *c;
+	struct ec_pvt *pvt;
 
-	if ((*ec = kmalloc(sizeof(**ec), GFP_KERNEL))) {
-		memset(ec, 0, sizeof(**ec));
-	}
-
-	for (x = 0; x < ecp->param_count; x++) {
-		for (c = p[x].name; *c; c++)
-			*c = tolower(*c);
-		printk(KERN_WARNING "Unknown parameter supplied to JPAH echo canceler: '%s'\n", p[x].name);
-		kfree(*ec);
-
+	if (ecp->param_count > 0) {
+		printk(KERN_WARNING "JPAH does not support parameters; failing request\n");
 		return -EINVAL;
 	}
 
+	pvt = kzalloc(sizeof(*pvt), GFP_KERNEL);
+	if (!pvt)
+		return -ENOMEM;
+
+	pvt->dahdi.ops = &my_ops;
+
+	*ec = &pvt->dahdi;
 	return 0;
 }
 
-static void echo_can_free(struct echo_can_state *ec)
+static void echo_can_free(struct dahdi_echocan_state *ec)
 {
-	kfree(ec);
+	struct ec_pvt *pvt = dahdi_to_pvt(ec);
+
+	kfree(pvt);
 }
 
-static void echo_can_update(struct echo_can_state *ec, short *isig, short *iref)
+static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
 {
-	unsigned int x;
+	struct ec_pvt *pvt = dahdi_to_pvt(ec);
+	u32 x;
 
-	for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
-		if (ec->blah < 2) {
-			ec->blah++;
+	for (x = 0; x < size; x++) {
+		if (pvt->blah < 2) {
+			pvt->blah++;
 
 			*isig++ = 0;
 		} else {
-			ec->blah = 0;
+			pvt->blah = 0;
 			
 			isig++;
 		}
 	}
 }
 
-static int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
+static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val)
 {
 	return 0;
 }
 
-static const struct dahdi_echocan me = {
-	.name = "JPAH",
-	.owner = THIS_MODULE,
-	.echo_can_create = echo_can_create,
-	.echo_can_free = echo_can_free,
-	.echo_can_array_update = echo_can_update,
-	.echo_can_traintap = echo_can_traintap,
-};
-
 static int __init mod_init(void)
 {
-	if (dahdi_register_echocan(&me)) {
+	if (dahdi_register_echocan_factory(&my_factory)) {
 		module_printk(KERN_ERR, "could not register with DAHDI core\n");
 
 		return -EPERM;
 	}
 
-	module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
+	module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", my_factory.name);
 
 	return 0;
 }
 
 static void __exit mod_exit(void)
 {
-	dahdi_unregister_echocan(&me);
+	dahdi_unregister_echocan_factory(&my_factory);
 }
 
 module_param(debug, int, S_IRUGO | S_IWUSR);

Modified: linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_kb1.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_kb1.c?view=diff&rev=6503&r1=6502&r2=6503
==============================================================================
--- linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_kb1.c (original)
+++ linux/team/sruffell/staging/drivers/dahdi/dahdi_echocan_kb1.c Mon Apr 27 11:00:10 2009
@@ -142,8 +142,32 @@
 	short *buf_d;			
 } echo_can_cb_s;
 
-/* Echo canceller definition */
-struct echo_can_state {
+static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
+			   struct dahdi_echocan_state **ec);
+static void echo_can_free(struct dahdi_echocan_state *ec);
+static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
+static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
+static void echocan_NLP_toggle(struct dahdi_echocan_state *ec, unsigned int enable);
+
+static const struct dahdi_echocan_factory my_factory = {
+	.name = "KB1",
+	.owner = THIS_MODULE,
+	.echocan_create = echo_can_create,
+};
+
+static const struct dahdi_echocan_features my_features = {
+	.NLP_toggle = 1,
+};
+
+static const struct dahdi_echocan_ops my_ops = {
+	.echocan_free = echo_can_free,
+	.echocan_array_update = echo_can_array_update,
+	.echocan_traintap = echo_can_traintap,
+	.echocan_NLP_toggle = echocan_NLP_toggle,
+};
+
+struct ec_pvt {
+	struct dahdi_echocan_state dahdi;
 	/* an arbitrary ID for this echo can - this really should be settable from the calling channel... */
 	int id;
 
@@ -208,7 +232,10 @@
 	int avg_Lu_i_ok;
 #endif 
 	unsigned int aggressive:1;
+	int use_nlp;
 };
+
+#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi)
 
 static inline void init_cb_s(echo_can_cb_s *cb, int len, void *where)
 {
@@ -236,77 +263,79 @@
 	return cb->buf_d[cb->idx_d + pos];
 }
 
-static inline void init_cc(struct echo_can_state *ec, int N, int maxy, int maxu) 
-{
-
-	void *ptr = ec;
+static inline void init_cc(struct ec_pvt *pvt, int N, int maxy, int maxu)
+{
+	void *ptr = pvt;
 	unsigned long tmp;
+
 	/* Double-word align past end of state */
-	ptr += sizeof(struct echo_can_state);
+	ptr += sizeof(*pvt);
 	tmp = (unsigned long)ptr;
 	tmp += 3;
 	tmp &= ~3L;
 	ptr = (void *)tmp;
 
 	/* Reset parameters */
-	ec->N_d = N;
-	ec->beta2_i = DEFAULT_BETA1_I;
+	pvt->N_d = N;
+	pvt->beta2_i = DEFAULT_BETA1_I;
   
 	/* Allocate coefficient memory */
-	ec->a_i = ptr;
-	ptr += (sizeof(int) * ec->N_d);
-	ec->a_s = ptr;
-	ptr += (sizeof(short) * ec->N_d);
+	pvt->a_i = ptr;
+	ptr += (sizeof(int) * pvt->N_d);
+	pvt->a_s = ptr;
+	ptr += (sizeof(short) * pvt->N_d);
 
 	/* Reset Y circular buffer (short version) */
-	init_cb_s(&ec->y_s, maxy, ptr);
+	init_cb_s(&pvt->y_s, maxy, ptr);
 	ptr += (sizeof(short) * (maxy) * 2);
   
 	/* Reset Sigma circular buffer (short version for FIR filter) */
-	init_cb_s(&ec->s_s, (1 << DEFAULT_ALPHA_ST_I), ptr);
+	init_cb_s(&pvt->s_s, (1 << DEFAULT_ALPHA_ST_I), ptr);
 	ptr += (sizeof(short) * (1 << DEFAULT_ALPHA_ST_I) * 2);
 
-	init_cb_s(&ec->u_s, maxu, ptr);
+	init_cb_s(&pvt->u_s, maxu, ptr);
 	ptr += (sizeof(short) * maxu * 2);
 
 	/* Allocate a buffer for the reference signal power computation */
-	init_cb_s(&ec->y_tilde_s, ec->N_d, ptr);
+	init_cb_s(&pvt->y_tilde_s, pvt->N_d, ptr);
 
 	/* Reset the absolute time index */
-	ec->i_d = (int)0;
+	pvt->i_d = (int)0;
   
 	/* Reset the power computations (for y and u) */
-	ec->Ly_i = DEFAULT_CUTOFF_I;
-	ec->Lu_i = DEFAULT_CUTOFF_I;
+	pvt->Ly_i = DEFAULT_CUTOFF_I;
+	pvt->Lu_i = DEFAULT_CUTOFF_I;
 
 #ifdef MEC2_STATS
 	/* set the identity */
-	ec->id = (int)&ptr;
+	pvt->id = (int)&ptr;
   
 	/* Reset performance stats */
-	ec->cntr_nearend_speech_frames = (int)0;
-	ec->cntr_residualcorrected_frames = (int)0;
-	ec->cntr_residualcorrected_framesskipped = (int)0;
-	ec->cntr_coeff_updates = (int)0;
-	ec->cntr_coeff_missedupdates = (int)0;
-
-	ec->avg_Lu_i_toolow = (int)0;
-	ec->avg_Lu_i_ok = (int)0;
+	pvt->cntr_nearend_speech_frames = (int)0;
+	pvt->cntr_residualcorrected_frames = (int)0;
+	pvt->cntr_residualcorrected_framesskipped = (int)0;
+	pvt->cntr_coeff_updates = (int)0;
+	pvt->cntr_coeff_missedupdates = (int)0;
+
+	pvt->avg_Lu_i_toolow = (int)0;
+	pvt->avg_Lu_i_ok = (int)0;
 #endif
 
 	/* Reset the near-end speech detector */
-	ec->s_tilde_i = (int)0;
-	ec->y_tilde_i = (int)0;
-	ec->HCNTR_d = (int)0;
-
-}
-
-static void echo_can_free(struct echo_can_state *ec)
-{
-	kfree(ec);
-}
-
-static inline short sample_update(struct echo_can_state *ec, short iref, short isig) 
+	pvt->s_tilde_i = (int)0;
+	pvt->y_tilde_i = (int)0;
+	pvt->HCNTR_d = (int)0;
+
+}
+
+static void echo_can_free(struct dahdi_echocan_state *ec)
+{
+	struct ec_pvt *pvt = dahdi_to_pvt(ec);
+
+	kfree(pvt);
+}
+
+static inline short sample_update(struct ec_pvt *pvt, short iref, short isig)
 {
 	/* Declare local variables that are used more than once */
 	/* ... */
@@ -335,17 +364,17 @@
 	/* Update the Far-end receive signal circular buffers and accumulators */
 	/* ------------------------------------------------------------------- */
 	/* Delete the oldest sample from the power estimate accumulator */
-	ec->y_tilde_i -= abs(get_cc_s(&ec->y_s, (1 << DEFAULT_ALPHA_YT_I) - 1 )) >> DEFAULT_ALPHA_YT_I;
+	pvt->y_tilde_i -= abs(get_cc_s(&pvt->y_s, (1 << DEFAULT_ALPHA_YT_I) - 1)) >> DEFAULT_ALPHA_YT_I;
 	/* Add the new sample to the power estimate accumulator */
-	ec->y_tilde_i += abs(iref) >> DEFAULT_ALPHA_ST_I;
+	pvt->y_tilde_i += abs(iref) >> DEFAULT_ALPHA_ST_I;
 	/* Push a copy of the new sample into its circular buffer */
-	add_cc_s(&ec->y_s, iref);
+	add_cc_s(&pvt->y_s, iref);
  
 
 	/* eq. (2): compute r in fixed-point */
-	rs = CONVOLVE2(ec->a_s, 
-  			ec->y_s.buf_d + ec->y_s.idx_d, 
-  			ec->N_d);
+	rs = CONVOLVE2(pvt->a_s,
+		       pvt->y_s.buf_d + pvt->y_s.idx_d,
+		       pvt->N_d);
 	rs >>= 15;
 
 	/* eq. (3): compute the output value (see figure 3) and the error
@@ -355,27 +384,27 @@
 	u = isig - rs;
   
 	/* Push a copy of the output value sample into its circular buffer */
-	add_cc_s(&ec->u_s, u);
+	add_cc_s(&pvt->u_s, u);
 
 
 	/* Update the Near-end hybrid signal circular buffers and accumulators */
 	/* ------------------------------------------------------------------- */
 	/* Delete the oldest sample from the power estimate accumulator */
-	ec->s_tilde_i -= abs(get_cc_s(&ec->s_s, (1 << DEFAULT_ALPHA_ST_I) - 1 ));
+	pvt->s_tilde_i -= abs(get_cc_s(&pvt->s_s, (1 << DEFAULT_ALPHA_ST_I) - 1));
 	/* Add the new sample to the power estimate accumulator */
-	ec->s_tilde_i += abs(isig);
+	pvt->s_tilde_i += abs(isig);
 	/* Push a copy of the new sample into it's circular buffer */
-	add_cc_s(&ec->s_s, isig);
+	add_cc_s(&pvt->s_s, isig);
 
 
 	/* Push a copy of the current short-time average of the far-end receive signal into it's circular buffer */
-	add_cc_s(&ec->y_tilde_s, ec->y_tilde_i);		
+	add_cc_s(&pvt->y_tilde_s, pvt->y_tilde_i);
 

[... 3047 lines stripped ...]



More information about the svn-commits mailing list