[svn-commits] tzafrir: branch linux/tzafrir/sysfs r6541 - in /linux/team/tzafrir/sysfs: ./ ...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Apr 29 18:29:37 CDT 2009


Author: tzafrir
Date: Wed Apr 29 18:29:33 2009
New Revision: 6541

URL: http://svn.digium.com/svn-view/dahdi?view=rev&rev=6541
Log:
* Remove 'echocancel' sysfs attribute for now
* Re-enable automerge

Merged revisions 6523-6529 via svnmerge from 
http://svn.digium.com/svn/dahdi/linux/trunk

........
  r6523 | sruffell | 2009-04-29 20:48:25 +0300 (Wed, 29 Apr 2009) | 1 line
  
  voicebus: Removing unused code blocks and space in flag definitions.
........
  r6524 | sruffell | 2009-04-29 20:48:27 +0300 (Wed, 29 Apr 2009) | 12 lines
  
  dahdi_dummy: Remove real-time clock support.
  
  This removes support for using the real-time clock as a timing source in
  dahdi_dummy.  Instead, the normal kernel timers method is now more accurate
  since it keeps track of how much real time has passed to determine how many
  times to call dahdi_receive and dahdi_transmit.  This method was originally
  suggested by bmd.
  
  (closes issue #13930)
  (closes issue #14884)
  Reported by: tzafrir
  Tested by: dbackeberg, ask
........
  r6525 | sruffell | 2009-04-29 20:48:29 +0300 (Wed, 29 Apr 2009) | 10 lines
  
  wcte12xp: Update cmdqueue processing.
  
  The command queue for reading from the registers on the framer is now stored in
  a linked_list instead of an array.  Allows for the locks to protect this
  structure to be held for shorter periods of time and reduces the need to cycle
  through all the elements in the array to decide if there is a command in the
  queue to process. Remove the usecount and dead members from struct t1 since the
  module reference count will allow us to know when it's safe to free up the
  memory. This change also moves alarm processing out of the interrupt handler and
  removes the need for special interrupt handling of commands.
........
  r6526 | sruffell | 2009-04-29 20:48:32 +0300 (Wed, 29 Apr 2009) | 7 lines
  
  wctc4xxp: Change netif_rx_xxx to napi_xxx
  
  The netif_rx_xxx functions were dropped from the linux kernel source on
  2009-01-21 in commit 288379f050284087578b77e04f040b57db3db3f8.
  
  (closes issue #14963)
  Reported by: tzafrir
........
  r6527 | sruffell | 2009-04-29 20:48:39 +0300 (Wed, 29 Apr 2009) | 6 lines
  
  voicebus: Move common vpmadt032 interface into voicebus module.
  
  The voicebus library was previously linked into both the wcte12xp and wctdm24xxp
  drivers.  It is now broken out into it's own module and the common parts of the
  vpmadt032 interface are now located in that module to reduce duplication between
  the wcte12xp and wctdm24xxp drivers.
........
  r6528 | sruffell | 2009-04-29 21:09:41 +0300 (Wed, 29 Apr 2009) | 1 line
  
  wct4xxp: Fix problem when timing source is via external cable.
........
  r6529 | sruffell | 2009-04-29 21:24:04 +0300 (Wed, 29 Apr 2009) | 15 lines
  
  echocan: Improve interface for echo cancelers.
  
  Echo cancelers are now able to report if they are able to automatically disable
  their NLP portions in the presence of tones in the audio stream.   Also, the
  interface is changed to allow user space to just disable the NLP portion of the
  echo canceler.  These changes improve fax and modem handling in DAHDI.
  
  This commit merges in the changes on
  http://svn.digium.com/svn/dahdi/linux/team/kpfleming/echocan_work
  
  Patch by: kpfleming
  
  Also contains improvements to CED tone detection.
  (closes issue #13286)
  Reported by: viniciusfontes
........


Added:
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/
      - copied from r6529, linux/trunk/drivers/dahdi/voicebus/
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/GpakApi.c
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/voicebus/GpakApi.c
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/GpakApi.h
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/voicebus/GpakApi.h
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/GpakCust.c
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/voicebus/GpakCust.c
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/GpakCust.h
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/voicebus/GpakCust.h
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/GpakHpi.h
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/voicebus/GpakHpi.h
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/Kbuild
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/voicebus/Kbuild
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/gpakErrs.h
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/voicebus/gpakErrs.h
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/gpakenum.h
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/voicebus/gpakenum.h
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/voicebus.c
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/voicebus/voicebus.c
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/voicebus.h
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/voicebus/voicebus.h
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/vpmadtreg.c
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/voicebus/vpmadtreg.c
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/vpmadtreg.h
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/voicebus/vpmadtreg.h
    linux/team/tzafrir/sysfs/drivers/dahdi/vpmadt032_loader/
      - copied from r6529, linux/trunk/drivers/dahdi/vpmadt032_loader/
    linux/team/tzafrir/sysfs/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c
      - copied unchanged from r6529, linux/trunk/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c
Removed:
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus.c
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus.h
    linux/team/tzafrir/sysfs/drivers/dahdi/wctdm24xxp/GpakApi.c
    linux/team/tzafrir/sysfs/drivers/dahdi/wctdm24xxp/GpakApi.h
    linux/team/tzafrir/sysfs/drivers/dahdi/wctdm24xxp/GpakCust.c
    linux/team/tzafrir/sysfs/drivers/dahdi/wctdm24xxp/GpakCust.h
    linux/team/tzafrir/sysfs/drivers/dahdi/wctdm24xxp/GpakHpi.h
    linux/team/tzafrir/sysfs/drivers/dahdi/wctdm24xxp/gpakErrs.h
    linux/team/tzafrir/sysfs/drivers/dahdi/wctdm24xxp/gpakenum.h
    linux/team/tzafrir/sysfs/drivers/dahdi/wctdm24xxp/voicebus.c
    linux/team/tzafrir/sysfs/drivers/dahdi/wcte12xp/GpakApi.c
    linux/team/tzafrir/sysfs/drivers/dahdi/wcte12xp/GpakApi.h
    linux/team/tzafrir/sysfs/drivers/dahdi/wcte12xp/GpakErrs.h
    linux/team/tzafrir/sysfs/drivers/dahdi/wcte12xp/gpakenum.h
    linux/team/tzafrir/sysfs/drivers/dahdi/wcte12xp/voicebus.c
    linux/team/tzafrir/sysfs/drivers/dahdi/wcte12xp/vpmadt032.c
    linux/team/tzafrir/sysfs/drivers/dahdi/wcte12xp/vpmadt032.h
Modified:
    linux/team/tzafrir/sysfs/   (props changed)
    linux/team/tzafrir/sysfs/Makefile
    linux/team/tzafrir/sysfs/drivers/dahdi/Kbuild
    linux/team/tzafrir/sysfs/drivers/dahdi/Kconfig
    linux/team/tzafrir/sysfs/drivers/dahdi/adt_lec.c
    linux/team/tzafrir/sysfs/drivers/dahdi/dahdi-base.c
    linux/team/tzafrir/sysfs/drivers/dahdi/dahdi-sysfs-chan.c
    linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_dummy.c
    linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_echocan_jpah.c
    linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_echocan_kb1.c
    linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_echocan_mg2.c
    linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_echocan_oslec.c
    linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_echocan_sec.c
    linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_echocan_sec2.c
    linux/team/tzafrir/sysfs/drivers/dahdi/ecdis.h
    linux/team/tzafrir/sysfs/drivers/dahdi/firmware/Makefile
    linux/team/tzafrir/sysfs/drivers/dahdi/hpec/dahdi_echocan_hpec.c
    linux/team/tzafrir/sysfs/drivers/dahdi/hpec/hpec.h
    linux/team/tzafrir/sysfs/drivers/dahdi/wcb4xxp/base.c
    linux/team/tzafrir/sysfs/drivers/dahdi/wcb4xxp/wcb4xxp.h
    linux/team/tzafrir/sysfs/drivers/dahdi/wct4xxp/base.c
    linux/team/tzafrir/sysfs/drivers/dahdi/wctc4xxp/base.c
    linux/team/tzafrir/sysfs/drivers/dahdi/wctdm24xxp/Kbuild
    linux/team/tzafrir/sysfs/drivers/dahdi/wctdm24xxp/base.c
    linux/team/tzafrir/sysfs/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
    linux/team/tzafrir/sysfs/drivers/dahdi/wcte12xp/Kbuild
    linux/team/tzafrir/sysfs/drivers/dahdi/wcte12xp/base.c
    linux/team/tzafrir/sysfs/drivers/dahdi/wcte12xp/wcte12xp.h
    linux/team/tzafrir/sysfs/include/dahdi/dahdi_config.h
    linux/team/tzafrir/sysfs/include/dahdi/kernel.h
    linux/team/tzafrir/sysfs/include/dahdi/user.h

Propchange: linux/team/tzafrir/sysfs/
------------------------------------------------------------------------------
    automerge = *

Propchange: linux/team/tzafrir/sysfs/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Apr 29 18:29:33 2009
@@ -1,1 +1,1 @@
-/linux/trunk:1-6514
+/linux/trunk:1-6540

Modified: linux/team/tzafrir/sysfs/Makefile
URL: http://svn.digium.com/svn-view/dahdi/linux/team/tzafrir/sysfs/Makefile?view=diff&rev=6541&r1=6540&r2=6541
==============================================================================
--- linux/team/tzafrir/sysfs/Makefile (original)
+++ linux/team/tzafrir/sysfs/Makefile Wed Apr 29 18:29:33 2009
@@ -1,7 +1,7 @@
 #
 # Makefile for DAHDI Linux kernel modules
 #
-# Copyright (C) 2001-2008 Digium, Inc.
+# Copyright (C) 2001-2009 Digium, Inc.
 #
 #
 
@@ -98,7 +98,7 @@
 	fi
 	@rm -f $@.tmp
 
-prereq: include/dahdi/version.h
+prereq: include/dahdi/version.h firmware-loaders
 
 stackcheck: checkstack modules
 	./checkstack kernel/*.ko kernel/*/*.ko
@@ -130,6 +130,9 @@
 
 uninstall-firmware:
 	$(MAKE) -C drivers/dahdi/firmware hotplug-uninstall DESTDIR=$(DESTDIR)
+
+firmware-loaders:
+	$(MAKE) -C drivers/dahdi/firmware firmware-loaders
 
 install-include:
 	for hdr in $(INST_HEADERS); do \
@@ -233,6 +236,7 @@
 dist-clean: clean
 	@rm -f include/dahdi/version.h
 	@$(MAKE) -C drivers/dahdi/firmware dist-clean
+	@rm -f drivers/dahdi/vpmadt032_loader/*.o_shipped
 
 firmware-download:
 	@$(MAKE) -C drivers/dahdi/firmware all
@@ -245,6 +249,6 @@
 README.html: README
 	$(ASCIIDOC_CMD) -o $@ $<
 
-.PHONY: distclean dist-clean clean all install devices modules stackcheck install-udev update install-modules install-include uninstall-modules firmware-download install-xpp-firm
+.PHONY: distclean dist-clean clean all install devices modules stackcheck install-udev update install-modules install-include uninstall-modules firmware-download install-xpp-firm firmware-loaders
 
 FORCE:

Modified: linux/team/tzafrir/sysfs/drivers/dahdi/Kbuild
URL: http://svn.digium.com/svn-view/dahdi/linux/team/tzafrir/sysfs/drivers/dahdi/Kbuild?view=diff&rev=6541&r1=6540&r2=6541
==============================================================================
--- linux/team/tzafrir/sysfs/drivers/dahdi/Kbuild (original)
+++ linux/team/tzafrir/sysfs/drivers/dahdi/Kbuild Wed Apr 29 18:29:33 2009
@@ -10,6 +10,7 @@
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM24XXP)	+= wctdm24xxp/
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE12XP)		+= wcte12xp/
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM)		+= wctdm.o
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VOICEBUS)		+= voicebus/
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCB4XXP)		+= wcb4xxp/
 
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT1XXP)		+= wct1xxp.o
@@ -64,6 +65,32 @@
 
 dahdi-objs := dahdi-base.o dahdi-sysfs.o dahdi-sysfs-chan.o
 
+###############################################################################
+# VPMADT032 Loader
+###############################################################################
+
+dahdi_vpmadt032_loader-objs := vpmadt032_loader/dahdi_vpmadt032_loader.o 
+
+ifeq ($(ARCH),i386)
+  ifneq ($(wildcard $(src)/vpmadt032_loader/vpmadt032_x86_32.o_shipped),)
+    VPMADT032_LOADER_PRESENT=yes
+    dahdi_vpmadt032_loader-objs += vpmadt032_loader/vpmadt032_x86_32.o
+    obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VPMADT032_LOADER)	+= dahdi_vpmadt032_loader.o
+  endif
+else
+  ifeq ($(ARCH),x86_64)
+    ifneq ($(wildcard $(src)/vpmadt032_loader/vpmadt032_x86_64.o_shipped),)
+       VPMADT032_LOADER_PRESENT=yes
+       dahdi_vpmadt032_loader-objs += vpmadt032_loader/vpmadt032_x86_64.o
+       obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VPMADT032_LOADER)	+= dahdi_vpmadt032_loader.o
+    endif
+  endif
+endif
+
+###############################################################################
+# HPEC Support 
+###############################################################################
+
 dahdi_echocan_hpec-objs := hpec/dahdi_echocan_hpec.o
 CFLAGS_dahdi_echocan_hpec.o := -I$(src)/hpec
 

Modified: linux/team/tzafrir/sysfs/drivers/dahdi/Kconfig
URL: http://svn.digium.com/svn-view/dahdi/linux/team/tzafrir/sysfs/drivers/dahdi/Kconfig?view=diff&rev=6541&r1=6540&r2=6541
==============================================================================
--- linux/team/tzafrir/sysfs/drivers/dahdi/Kconfig (original)
+++ linux/team/tzafrir/sysfs/drivers/dahdi/Kconfig Wed Apr 29 18:29:33 2009
@@ -123,9 +123,24 @@
 
 	  If unsure, say Y.
 
+config DAHDI_VOICEBUS
+	tristate "VoiceBus(tm) Interface Library"
+	depends on PCI
+	default DAHDI
+	---help---
+	   This driver provides the common interface for telephony cards that
+	   use the VoiceBus(tm) interface.  It also contains common supporting
+	   libraries for the VPMADT032 hardware echo cancelation module that
+	   is available for the VoiceBus cards.
+
+	   To compile this driver as a module, choose M here: the module will
+	   be called voicebus.
+
+	   If unsure, say Y.
+
 config DAHDI_WCTDM24XXP
 	tristate "Digium Wildcard VoiceBus analog card Support"
-	depends on DAHDI && PCI
+	depends on DAHDI && DAHDI_VOICEBUS
 	default DAHDI
 	---help---
 	  This driver provides support for the following Digium
@@ -145,7 +160,7 @@
 
 config DAHDI_WCTE12XP
 	tristate "Digium Wildcard VoiceBus digital card Support"
-	depends on DAHDI && PCI
+	depends on DAHDI && DAHDI_VOICEBUS
 	default DAHDI
 	---help---
 	  This driver provides support for the following Digium

Modified: linux/team/tzafrir/sysfs/drivers/dahdi/adt_lec.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/tzafrir/sysfs/drivers/dahdi/adt_lec.c?view=diff&rev=6541&r1=6540&r2=6541
==============================================================================
--- linux/team/tzafrir/sysfs/drivers/dahdi/adt_lec.c (original)
+++ linux/team/tzafrir/sysfs/drivers/dahdi/adt_lec.c Wed Apr 29 18:29:33 2009
@@ -1,7 +1,7 @@
 /*
  * ADT Line Echo Canceller Parameter Parsing
  *
- * Copyright (C) 2008 Digium, Inc.
+ * Copyright (C) 2008-2009 Digium, Inc.
  *
  * Kevin P. Fleming <kpfleming at digium.com>
  *
@@ -33,10 +33,13 @@
 	params->tap_length = tap_length;
 }
 
-static int adt_lec_parse_params(struct adt_lec_params *params, struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p)
+static int adt_lec_parse_params(struct adt_lec_params *params,
+	struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p)
 {
 	unsigned int x;
 	char *c;
+
+	params->tap_length = ecp->tap_length;
 
 	for (x = 0; x < ecp->param_count; x++) {
 		for (c = p[x].name; *c; c++)

Modified: linux/team/tzafrir/sysfs/drivers/dahdi/dahdi-base.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/tzafrir/sysfs/drivers/dahdi/dahdi-base.c?view=diff&rev=6541&r1=6540&r2=6541
==============================================================================
--- linux/team/tzafrir/sysfs/drivers/dahdi/dahdi-base.c (original)
+++ linux/team/tzafrir/sysfs/drivers/dahdi/dahdi-base.c Wed Apr 29 18:29:33 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 */
 
@@ -73,16 +63,18 @@
 
 #include "dahdi-sysfs.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"
@@ -145,8 +137,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);
 
@@ -380,62 +372,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);
 }
 
 /* Is this span our syncronization master? */
@@ -671,8 +663,12 @@
 				chan->chan_alarms);
 
 		if (chan->ec_factory)
-			len += snprintf(page+len, count-len, " (EC: %s) ",
+			len += snprintf(page+len, count-len, "(SWEC: %s) ",
 					chan->ec_factory->name);
+
+		if (chan->ec_state)
+			len += snprintf(page+len, count-len, "(EC: %s) ",
+					chan->ec_state->ops->name);
 
 		len += snprintf(page+len, count-len, "\n");
 
@@ -1088,28 +1084,9 @@
 }
 
 
-static inline int hw_echocancel_off(struct dahdi_chan *chan)
-{
-	int ret = 0;
-
-	if (!chan->span)
-		return -ENODEV;
-
-	if (chan->span->echocan) {
-		ret = chan->span->echocan(chan, 0);
-	} else if (chan->span->echocan_with_params) {
-		struct dahdi_echocanparams ecp = {
-			.tap_length = 0,
-		};
-		ret = chan->span->echocan_with_params(chan, &ecp, NULL);
-	}
-
-	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;
@@ -1123,26 +1100,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;
@@ -1162,10 +1139,11 @@
 	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);
+	if (ec)
+		module_put(ec->owner);
 #endif
 }
 
@@ -1181,8 +1159,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
@@ -1260,13 +1238,11 @@
 		chan->span->dacs(chan, NULL);
 
 	if (ec_state) {
-		ec_current->echo_can_free(ec_state);
+		ec_state->ops->echocan_free(chan, ec_state);
 		release_echocan(ec_current);
 	}
 
 	spin_unlock_irqrestore(&chan->lock, flags);
-
-	hw_echocancel_off(chan);
 
 	if (rxgain)
 		kfree(rxgain);
@@ -2457,8 +2433,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;
@@ -2472,10 +2448,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;
@@ -2570,15 +2542,13 @@
 	}
 
 	if (ec_state) {
-		ec_current->echo_can_free(ec_state);
+		ec_state->ops->echocan_free(chan, ec_state);
 		release_echocan(ec_current);
 	}
 
 	spin_unlock_irqrestore(&chan->lock, flags);
 
 	set_tone_zone(chan, -1);
-
-	hw_echocancel_off(chan);
 
 	if (rxgain)
 		kfree(rxgain);
@@ -3445,7 +3415,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;
@@ -3686,7 +3655,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;
@@ -3694,54 +3670,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;
 	}
@@ -3859,7 +3833,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;
@@ -4180,19 +4154,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) {
@@ -4200,7 +4174,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;
@@ -4862,8 +4836,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;
@@ -4878,25 +4852,14 @@
 		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(chan, ec_state);
 			release_echocan(ec_current);
 		}
-		hw_echocancel_off(chan);
 
 		return 0;
 	}
-
-	/* if parameters were supplied and this channel's span provides an echocan,
-	   but not one that takes params, then we must punt here and return an error */
-	if (ecp->param_count && chan->span && chan->span->echocan &&
-	    !chan->span->echocan_with_params)
-		return -EINVAL;
 
 	params = kmalloc(sizeof(params[0]) * DAHDI_MAX_ECHOCANPARAMS, GFP_KERNEL);
 
@@ -4910,6 +4873,7 @@
 		goto exit_with_free;
 	}
 
+	/* free any echocan that may be on the channel already */
 	spin_lock_irqsave(&chan->lock, flags);
 	ec_state = chan->ec_state;
 	chan->ec_state = NULL;
@@ -4917,34 +4881,31 @@
 	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(chan, ec_state);
 		release_echocan(ec_current);
 	}
 
+	switch (ecp->tap_length) {
+	case 32:
+	case 64:
+	case 128:
+	case 256:
+	case 512:
+	case 1024:
+		break;
+	default:
+		ecp->tap_length = deftaps;
+	}
+
 	ret = -ENODEV;
+	ec_current = NULL;
 
 	/* attempt to use the span's echo canceler; fall back to built-in
 	   if it fails (but not if an error occurs) */
-	if (chan->span) {
-		if (chan->span->echocan_with_params)
-			ret = chan->span->echocan_with_params(chan, ecp, params);
-		else if (chan->span->echocan)
-			ret = chan->span->echocan(chan, ecp->tap_length);
-	}
+	if (chan->span && chan->span->echocan_create)
+		ret = chan->span->echocan_create(chan, ecp, params, &ec);
 
 	if ((ret == -ENODEV) && chan->ec_factory) {
-		switch (ecp->tap_length) {
-		case 32:
-		case 64:
-		case 128:
-		case 256:
-		case 512:
-		case 1024:
-			break;
-		default:
-			ecp->tap_length = deftaps;
-		}
-
 #ifdef USE_ECHOCAN_REFCOUNT
 		/* try to get another reference to the module providing
 		   this channel's echo canceler */
@@ -4958,21 +4919,32 @@
 		   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(chan, 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;
+		}
+	}
+
+	if (ec) {
 		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);
 	}
 
@@ -4980,6 +4952,56 @@
 	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_automatic) {
+			/* for echocans that automatically do the right thing, just
+			 * mark it as being in FAX mode without making any
+			 * changes, as none are necessary.
+			*/
+			chan->ec_state->status.mode = ECHO_MODE_FAX;
+		} 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_automatic) {
+			/* for echocans that automatically do the right thing, just
+			 * mark it as being in active mode without making any
+			 * changes, as none are necessary.
+			*/
+			chan->ec_state->status.mode = ECHO_MODE_ACTIVE;
+		} 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)
@@ -5028,8 +5050,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;
@@ -5062,12 +5084,9 @@
 			spin_unlock_irqrestore(&chan->lock, flags);
 
 			if (ec_state) {
-				ec_current->echo_can_free(ec_state);
+				ec_state->ops->echocan_free(chan, ec_state);
 				release_echocan(ec_current);
 			}
-
-			/* Disable any native echo cancellation as well */
-			hw_echocancel_off(chan);
 
 			if (rxgain)
 				kfree(rxgain);
@@ -5082,8 +5101,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;
@@ -5108,10 +5127,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);
@@ -5120,10 +5135,9 @@
 					chan->gainalloc = 0;
 					chan->flags &= ~DAHDI_FLAG_AUDIO;
 					chan->flags |= (DAHDI_FLAG_PPP | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS);
-					hw_echocancel_off(chan);
 
 					if (tec) {
-						ec_current->echo_can_free(tec);
+						tec->ops->echocan_free(chan, tec);
 						release_echocan(ec_current);
 					}
 				} else
@@ -5209,21 +5223,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);
@@ -5233,7 +5257,6 @@
 		else
 			chan->flags &= ~DAHDI_FLAG_LOOPED;
 		spin_unlock_irqrestore(&chan->lock, flags);
-		rv = 0;
 		break;
 	case DAHDI_HOOK:
 		get_user(j,(int *)data);
@@ -5294,7 +5317,6 @@
 				rv = schluffen(&chan->txstateq);
 				if (rv) return rv;
 #endif
-				rv = 0;
 				break;
 			case DAHDI_WINK:
 				spin_lock_irqsave(&chan->lock, flags);
@@ -5475,13 +5497,6 @@
 		span->deflaw = DAHDI_LAW_MULAW;
 	}
 
-	if (span->echocan && span->echocan_with_params) {
-		module_printk(KERN_NOTICE, "Span %s implements both echocan "
-				"and echocan_with_params functions, preserving only "
-				"echocan_with_params, please fix driver!\n", span->name);
-		span->echocan = NULL;
-	}
-
 	for (x = 0; x < span->channels; x++) {
 		span->chans[x]->span = span;
 		dahdi_chan_reg(span->chans[x]);
@@ -5766,26 +5781,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++) {

[... 8634 lines stripped ...]



More information about the svn-commits mailing list