[svn-commits] kpfleming: linux/trunk r4436 - in /linux/trunk: drivers/dahdi/ drivers/dahdi/...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Jun 20 17:40:12 CDT 2008


Author: kpfleming
Date: Fri Jun 20 17:40:11 2008
New Revision: 4436

URL: http://svn.digium.com/view/dahdi?view=rev&rev=4436
Log:
merge modular_ec branch, which adds modular echocan support and lots of minor fixes and improvements... seems to work properly, except the usecount on the echocan modules never increments above zero, so they are unloadable when they should not be

Added:
    linux/trunk/drivers/dahdi/dahdi_echocan_jpah.c
      - copied unchanged from r4435, linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_jpah.c
    linux/trunk/drivers/dahdi/dahdi_echocan_kb1.c
      - copied unchanged from r4435, linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_kb1.c
    linux/trunk/drivers/dahdi/dahdi_echocan_mg2.c
      - copied unchanged from r4435, linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_mg2.c
    linux/trunk/drivers/dahdi/dahdi_echocan_sec.c
      - copied unchanged from r4435, linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_sec.c
    linux/trunk/drivers/dahdi/dahdi_echocan_sec2.c
      - copied unchanged from r4435, linux/team/kpfleming/modular_ec/drivers/dahdi/dahdi_echocan_sec2.c
    linux/trunk/drivers/dahdi/hpec/dahdi_echocan_hpec.c
      - copied unchanged from r4435, linux/team/kpfleming/modular_ec/drivers/dahdi/hpec/dahdi_echocan_hpec.c
Removed:
    linux/trunk/drivers/dahdi/hpec/hpec_dahdi.h
    linux/trunk/drivers/dahdi/jpah.h
    linux/trunk/drivers/dahdi/kb1ec.h
    linux/trunk/drivers/dahdi/kb1ec_const.h
    linux/trunk/drivers/dahdi/mg2ec.h
    linux/trunk/drivers/dahdi/mg2ec_const.h
    linux/trunk/drivers/dahdi/sec-2.h
    linux/trunk/drivers/dahdi/sec.h
Modified:
    linux/trunk/drivers/dahdi/Kbuild
    linux/trunk/drivers/dahdi/Kconfig
    linux/trunk/drivers/dahdi/dahdi-base.c
    linux/trunk/drivers/dahdi/dahdi_config.h
    linux/trunk/drivers/dahdi/dahdi_dummy.c
    linux/trunk/drivers/dahdi/dahdi_dynamic.c
    linux/trunk/drivers/dahdi/dahdi_dynamic_eth.c
    linux/trunk/drivers/dahdi/dahdi_dynamic_loc.c
    linux/trunk/drivers/dahdi/dahdi_transcode.c
    linux/trunk/drivers/dahdi/datamods/syncppp.c
    linux/trunk/drivers/dahdi/fir.h
    linux/trunk/drivers/dahdi/hpec/   (props changed)
    linux/trunk/drivers/dahdi/pciradio.c
    linux/trunk/drivers/dahdi/tor2.c
    linux/trunk/drivers/dahdi/wcfxo.c
    linux/trunk/drivers/dahdi/wct1xxp.c
    linux/trunk/drivers/dahdi/wct4xxp/base.c
    linux/trunk/drivers/dahdi/wctc4xxp/base.c
    linux/trunk/drivers/dahdi/wctdm.c
    linux/trunk/drivers/dahdi/wctdm24xxp/base.c
    linux/trunk/drivers/dahdi/wcte11xp.c
    linux/trunk/drivers/dahdi/wcte12xp/base.c
    linux/trunk/include/dahdi/kernel.h

Modified: linux/trunk/drivers/dahdi/Kbuild
URL: http://svn.digium.com/view/dahdi/linux/trunk/drivers/dahdi/Kbuild?view=diff&rev=4436&r1=4435&r2=4436
==============================================================================
--- linux/trunk/drivers/dahdi/Kbuild (original)
+++ linux/trunk/drivers/dahdi/Kbuild Fri Jun 20 17:40:11 2008
@@ -1,7 +1,3 @@
-ifdef ECHO_CAN_NAME
-	ECHO_CAN_CFLAGS	:= -DECHO_CAN_FROMENV -DECHO_CAN_$(ECHO_CAN_NAME)
-endif
-
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI)			+= dahdi.o
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DUMMY)		+= dahdi_dummy.o
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC)		+= dahdi_dynamic.o
@@ -24,8 +20,13 @@
 
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_XPP)		+= xpp/
 
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_JPAH)	+= dahdi_echocan_jpah.o
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_STEVE)	+= dahdi_echocan_sec.o
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_STEVE2)	+= dahdi_echocan_sec2.o
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_KB1)	+= dahdi_echocan_kb1.o
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_MG2)	+= dahdi_echocan_mg2.o
+
 CFLAGS_MODULE += -I$(src)
-EXTRA_CFLAGS += $(ECHO_CAN_CFLAGS)
 
 ifndef HOTPLUG_FIRMWARE
 ifneq (,$(filter y m,$(CONFIG_FW_LOADER)))
@@ -45,23 +46,25 @@
 
 dahdi-objs := dahdi-base.o
 
+dahdi_echocan_hpec-objs := hpec/dahdi_echocan_hpec.o
+CFLAGS_dahdi_echocan_hpec.o := -I$(src)/hpec
+
 ifeq ($(ARCH),i386)
 ifneq ($(wildcard $(src)/hpec/hpec_x86_32.o_shipped),)
 HPEC_PRESENT=yes
-dahdi-objs += hpec/hpec_x86_32.o
+dahdi_echocan_hpec-objs += hpec/hpec_x86_32.o
 endif
 endif
 
 ifeq ($(ARCH),x86_64)
 ifneq ($(wildcard $(src)/hpec/hpec_x86_64.o_shipped),)
 HPEC_PRESENT=yes
-dahdi-objs += hpec/hpec_x86_64.o
+dahdi_echocan_hpec-objs += hpec/hpec_x86_64.o
 endif
 endif
 
 ifeq ($(HPEC_PRESENT),yes)
-EXTRA_CFLAGS += -DECHO_CAN_HPEC -I$(src)/hpec
-$(obj)/dahdi-base.o: $(src)/hpec/hpec_dahdi.h $(src)/hpec/hpec_user.h
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_HPEC)	+= dahdi_echocan_hpec.o
 endif
 
 $(obj)/pciradio.o: $(obj)/radfw.h

Modified: linux/trunk/drivers/dahdi/Kconfig
URL: http://svn.digium.com/view/dahdi/linux/trunk/drivers/dahdi/Kconfig?view=diff&rev=4436&r1=4435&r2=4436
==============================================================================
--- linux/trunk/drivers/dahdi/Kconfig (original)
+++ linux/trunk/drivers/dahdi/Kconfig Fri Jun 20 17:40:11 2008
@@ -14,7 +14,60 @@
 
 	  If unsure, say Y.
 
-if DAHDI
+config DAHDI_ECHOCAN
+       tristate "DADHI Echo Cancelers (software)"
+       depends on DAHDI
+       default DAHDI
+
+config DAHDI_ECHOCAN_MG2
+       tristate "DADHI MG2 Echo Canceler"
+       depends on DAHDI_ECHOCAN
+       default DAHDI_ECHOCAN
+	---help---
+	  To compile this driver as a module, choose M here: the
+	  module will be called dahdi_echocancel_mg2.
+
+	  If unsure, say Y.
+
+config DAHDI_ECHOCAN_KB1
+       tristate "DADHI KB1 Echo Canceler"
+       depends on DAHDI_ECHOCAN
+       default DAHDI_ECHOCAN
+	---help---
+	  To compile this driver as a module, choose M here: the
+	  module will be called dahdi_echocancel_kb1.
+
+	  If unsure, say Y.
+
+config DAHDI_ECHOCAN_SEC
+       tristate "DADHI SEC Echo Canceler"
+       depends on DAHDI_ECHOCAN
+       default DAHDI_ECHOCAN
+	---help---
+	  To compile this driver as a module, choose M here: the
+	  module will be called dahdi_echocancel_sec.
+
+	  If unsure, say Y.
+
+config DAHDI_ECHOCAN_SEC2
+       tristate "DADHI SEC2 Echo Canceler"
+       depends on DAHDI_ECHOCAN
+       default DAHDI_ECHOCAN
+	---help---
+	  To compile this driver as a module, choose M here: the
+	  module will be called dahdi_echocancel_sec2.
+
+	  If unsure, say Y.
+
+config DAHDI_ECHOCAN_HPEC
+       tristate "DADHI HPEC Echo Canceler"
+       depends on DAHDI_ECHOCAN
+       default DAHDI_ECHOCAN
+	---help---
+	  To compile this driver as a module, choose M here: the
+	  module will be called dahdi_echocancel_hpec.
+
+	  If unsure, say Y.
 
 config DAHDI_WCTDM
 	tristate "Digium Wildcard TDM400P Support"
@@ -48,6 +101,7 @@
 
 config DAHDI_TRANSCODE
 	tristate "DAHDI transcoding support"
+	depends on DAHDI
 	default DAHDI
 	---help---
 	  DAHDI transcoding infrastructure.
@@ -59,7 +113,7 @@
 
 config DAHDI_WCTC4XXP
 	tristate "Digium Wildcard TC400B Support"
-	depends on DAHDI && DAHDI_TRANSCODE && PCI
+	depends on DAHDI_TRANSCODE && PCI
 	default DAHDI
 	---help---
 	  This driver provides support for the Digium Wildcard TC400B.
@@ -210,5 +264,3 @@
 	  If unsure, say Y.
 
 source "drivers/dahdi/xpp/Kconfig"
-
-endif # DAHDI

Modified: linux/trunk/drivers/dahdi/dahdi-base.c
URL: http://svn.digium.com/view/dahdi/linux/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=4436&r1=4435&r2=4436
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Fri Jun 20 17:40:11 2008
@@ -47,6 +47,7 @@
 #include <linux/ctype.h>
 #include <linux/kmod.h>
 #include <linux/moduleparam.h>
+#include <linux/list.h>
 
 #ifdef CONFIG_DAHDI_NET
 #include <linux/netdevice.h>
@@ -60,6 +61,8 @@
 #endif
 
 #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
@@ -82,6 +85,8 @@
 #include <dahdi/version.h>
 #include <dahdi/kernel.h>
 #include <dahdi/user.h>
+
+#include "hpec/hpec_user.h"
 
 /* Get helper arithmetic */
 #include "arith.h"
@@ -141,12 +146,14 @@
 EXPORT_SYMBOL(dahdi_register_chardev);
 EXPORT_SYMBOL(dahdi_unregister_chardev);
 
+EXPORT_SYMBOL(dahdi_register_echocan);
+EXPORT_SYMBOL(dahdi_unregister_echocan);
+
+EXPORT_SYMBOL(dahdi_set_hpec_ioctl);
+
 #ifdef CONFIG_PROC_FS
 static struct proc_dir_entry *proc_entries[DAHDI_MAX_SPANS]; 
 #endif
-
-/* udev necessary data structures.  Yeah! */
-#ifdef CONFIG_DAHDI_UDEV
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
 #define CLASS_DEV_CREATE(class, devt, device, name) \
@@ -165,8 +172,6 @@
 #define class_device_create class_simple_device_add
 #define class_device_destroy(a, b) class_simple_device_remove(b)
 #endif
-
-#endif /* CONFIG_DAHDI_UDEV */
 
 static int deftaps = 64;
 
@@ -329,23 +334,68 @@
 
 static struct dahdi_zone *tone_zones[DAHDI_TONE_ZONE_MAX];
 
-#define NUM_SIGS	10	
-
-
-/* Echo cancellation */
-#if defined(ECHO_CAN_HPEC)
-#include "hpec/hpec_dahdi.h"
-#elif defined(ECHO_CAN_STEVE)
-#include "sec.h"
-#elif defined(ECHO_CAN_STEVE2)
-#include "sec-2.h"
-#elif defined(ECHO_CAN_KB1)
-#include "kb1ec.h"
-#elif defined(ECHO_CAN_MG2)
-#include "mg2ec.h"
-#elif defined(ECHO_CAN_JP1)
-#include "jpah.h"
-#endif
+#define NUM_SIGS	10
+
+#ifdef DEFINE_RWLOCK
+static DEFINE_RWLOCK(echocan_list_lock);
+#else
+static rwlock_t echocan_list_lock = RW_LOCK_UNLOCKED;
+#endif
+
+LIST_HEAD(echocan_list);
+
+struct echocan {
+	const struct dahdi_echocan *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);
+
+	/* make sure it isn't already registered */
+	list_for_each_entry(cur, &echocan_list, list) {
+		if (cur->ec == ec) {
+			write_unlock(&echocan_list_lock);
+			return -EPERM;
+		}
+	}
+
+	if (!(cur = kmalloc(sizeof(*cur), GFP_KERNEL))) {
+		write_unlock(&echocan_list_lock);
+		return -ENOMEM;
+	}
+
+	memset(cur, 0, sizeof(*cur));
+
+	cur->ec = ec;
+	INIT_LIST_HEAD(&cur->list);
+
+	list_add_tail(&cur->list, &echocan_list);
+
+	write_unlock(&echocan_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) {
+		if (cur->ec == ec) {
+			list_del(&cur->list);
+			break;
+		}
+	}
+
+	write_unlock(&echocan_list_lock);
+}
 
 static inline void rotate_sums(void)
 {
@@ -361,26 +411,26 @@
   /* return quiescent (idle) signalling states, for the various signalling types */
 static int dahdi_q_sig(struct dahdi_chan *chan)
 {
-int	x;
-
-static unsigned int in_sig[NUM_SIGS][2] = {
-	{ DAHDI_SIG_NONE, 0},
-	{ DAHDI_SIG_EM, 0 | (DAHDI_ABIT << 8)},
-	{ DAHDI_SIG_FXSLS,DAHDI_BBIT | (DAHDI_BBIT << 8)},
-	{ DAHDI_SIG_FXSGS,DAHDI_ABIT | DAHDI_BBIT | ((DAHDI_ABIT | DAHDI_BBIT) << 8)},
-	{ DAHDI_SIG_FXSKS,DAHDI_BBIT | DAHDI_BBIT | ((DAHDI_ABIT | DAHDI_BBIT) << 8)},
-	{ DAHDI_SIG_FXOLS,0 | (DAHDI_ABIT << 8)},
-	{ DAHDI_SIG_FXOGS,DAHDI_BBIT | ((DAHDI_ABIT | DAHDI_BBIT) << 8)},
-	{ DAHDI_SIG_FXOKS,0 | (DAHDI_ABIT << 8)},
-	{ DAHDI_SIG_SF, 0},
-	{ DAHDI_SIG_EM_E1, DAHDI_DBIT | ((DAHDI_ABIT | DAHDI_DBIT) << 8) },
+	int	x;
+
+	static unsigned int in_sig[NUM_SIGS][2] = {
+		{ DAHDI_SIG_NONE, 0},
+		{ DAHDI_SIG_EM, 0 | (DAHDI_ABIT << 8)},
+		{ DAHDI_SIG_FXSLS,DAHDI_BBIT | (DAHDI_BBIT << 8)},
+		{ DAHDI_SIG_FXSGS,DAHDI_ABIT | DAHDI_BBIT | ((DAHDI_ABIT | DAHDI_BBIT) << 8)},
+		{ DAHDI_SIG_FXSKS,DAHDI_BBIT | DAHDI_BBIT | ((DAHDI_ABIT | DAHDI_BBIT) << 8)},
+		{ DAHDI_SIG_FXOLS,0 | (DAHDI_ABIT << 8)},
+		{ DAHDI_SIG_FXOGS,DAHDI_BBIT | ((DAHDI_ABIT | DAHDI_BBIT) << 8)},
+		{ DAHDI_SIG_FXOKS,0 | (DAHDI_ABIT << 8)},
+		{ DAHDI_SIG_SF, 0},
+		{ DAHDI_SIG_EM_E1, DAHDI_DBIT | ((DAHDI_ABIT | DAHDI_DBIT) << 8) },
 	} ;
-
+	
 	/* must have span to begin with */
 	if (!chan->span) return(-1);
-	  /* if RBS does not apply, return error */
+	/* if RBS does not apply, return error */
 	if (!(chan->span->flags & DAHDI_FLAG_RBS) || 
-		!chan->span->rbsbits) return(-1);
+	    !chan->span->rbsbits) return(-1);
 	if (chan->sig == DAHDI_SIG_CAS)
 		return chan->idlebits;
 	for (x=0;x<NUM_SIGS;x++) {
@@ -540,15 +590,20 @@
 							len += sprintf(page + len, "Master ");
 					}
 				}
-				if ((chans[x]->flags & DAHDI_FLAG_OPEN)) {
+				if (test_bit(DAHDI_FLAGBIT_OPEN, &chans[x]->flags)) {
 					len += sprintf(page + len, "(In use) ");
 				}
 #ifdef	OPTIMIZE_CHANMUTE
-				if ((chans[x]->chanmute)) {
+				if (chans[x]->chanmute) {
 					len += sprintf(page + len, "(no pcm) ");
 				}
 #endif
 				len += fill_alarm_string(page + len, count - len, chans[x]->chan_alarms);
+
+				if (chans[x]->ec_factory) {
+					len += sprintf(page + len, " (EC: %s) ", chans[x]->ec_factory->name);
+				}
+
 				len += sprintf(page + len, "\n");
 			}
 			if (len <= off) { /* If everything printed so far is before beginning of request */
@@ -930,11 +985,68 @@
 	return ret;
 }
 
+static const struct dahdi_echocan *find_echocan(const char *name)
+{
+	struct echocan *cur;
+	char name_upper[strlen(name) + 1];
+	char *c;
+	const char *d;
+	char modname_buf[128] = "dahdi_echocan_";
+	unsigned int tried_once = 0;
+	int res;
+
+	for (c = name_upper, d = name; *d; c++, d++) {
+		*c = toupper(*d);
+	}
+
+	*c = '\0';
+
+retry:
+	read_lock(&echocan_list_lock);
+
+	list_for_each_entry(cur, &echocan_list, list) {
+		if (!strcmp(name_upper, cur->ec->name)) {
+			if ((res = try_module_get(cur->owner))) {
+				read_unlock(&echocan_list_lock);
+				return cur->ec;
+			} else {
+				read_unlock(&echocan_list_lock);
+				return NULL;
+			}
+		}
+	}
+
+	read_unlock(&echocan_list_lock);
+
+	if (tried_once) {
+		return NULL;
+	}
+
+	/* couldn't find it, let's try to load it */
+
+	for (c = &modname_buf[strlen(modname_buf)], d = name; *d; c++, d++) {
+		*c = tolower(*d);
+	}
+
+	request_module(modname_buf);
+
+	tried_once = 1;
+
+	/* and try one more time */
+	goto retry;
+}
+
+static void release_echocan(const struct dahdi_echocan *ec)
+{
+	module_put(ec->owner);
+}
+
 static void close_channel(struct dahdi_chan *chan)
 {
 	unsigned long flags;
 	void *rxgain = NULL;
-	struct echo_can_state *ec = NULL;
+	struct echo_can_state *ec_state;
+	const struct dahdi_echocan *ec_current;
 	int oldconf;
 	short *readchunkpreec;
 #ifdef CONFIG_DAHDI_PPP
@@ -949,8 +1061,10 @@
 	ppp = chan->ppp;
 	chan->ppp = NULL;
 #endif
-	ec = chan->ec;
-	chan->ec = NULL;
+	ec_state = chan->ec_state;
+	chan->ec_state = NULL;
+	ec_current = chan->ec_current;
+	chan->ec_current = NULL;
 	readchunkpreec = chan->readchunkpreec;
 	chan->readchunkpreec = NULL;
 	chan->curtone = NULL;
@@ -1007,14 +1121,17 @@
 	if (chan->span && chan->span->dacs && oldconf)
 		chan->span->dacs(chan, NULL);
 
+	if (ec_state) {
+		ec_current->echo_can_free(ec_state);
+		release_echocan(ec_current);
+	}
+
 	spin_unlock_irqrestore(&chan->lock, flags);
 
 	hw_echocancel_off(chan);
 
 	if (rxgain)
 		kfree(rxgain);
-	if (ec)
-		echo_can_free(ec);
 	if (readchunkpreec)
 		kfree(readchunkpreec);
 
@@ -1074,7 +1191,7 @@
 	write_unlock(&zone_lock);
 
 	if (!res)
-		printk(KERN_INFO "Registered tone zone %d (%s)\n", num, zone->name);
+		module_printk(KERN_INFO, "Registered tone zone %d (%s)\n", num, zone->name);
 
 	return res;
 }
@@ -1098,7 +1215,7 @@
 		if (__warnonce) {
 			__warnonce = 0;
 			/* The tonezones are loaded by ztcfg based on /etc/dahdi.conf. */
-			printk(KERN_WARNING "DAHDI: Cannot start tones until tone zone is loaded.\n");
+			module_printk(KERN_WARNING, "DAHDI: Cannot start tones until tone zone is loaded.\n");
 		}
 		/* Note that no tone zone exists at the moment */
 		res = -ENODATA;
@@ -1274,7 +1391,7 @@
 	}
 	write_unlock_irqrestore(&chan_lock, flags);	
 	if (x >= DAHDI_MAX_CHANNELS)
-		printk(KERN_ERR "No more channels available\n");
+		module_printk(KERN_ERR, "No more channels available\n");
 	return res;
 }
 
@@ -1305,15 +1422,15 @@
 	int res;
 #endif
 	if (!ms) {
-		printk("dahdi_net_open: nothing??\n");
+		module_printk(KERN_NOTICE, "dahdi_net_open: nothing??\n");
 		return -EINVAL;
 	}
-	if (ms->flags & DAHDI_FLAG_OPEN) {
-		printk("%s is already open!\n", ms->name);
+	if (test_bit(DAHDI_FLAGBIT_OPEN, &ms->flags)) {
+		module_printk(KERN_NOTICE, "%s is already open!\n", ms->name);
 		return -EBUSY;
 	}
 	if (!(ms->flags & DAHDI_FLAG_NETDEV)) {
-		printk("%s is not a net device!\n", ms->name);
+		module_printk(KERN_NOTICE, "%s is not a net device!\n", ms->name);
 		return -EINVAL;
 	}
 	ms->txbufpolicy = DAHDI_POLICY_IMMEDIATE;
@@ -1330,7 +1447,7 @@
 	netif_start_queue(ztchan_to_dev(ms));
 
 #ifdef CONFIG_DAHDI_DEBUG
-	printk("DAHDINET: Opened channel %d name %s\n", ms->channo, ms->name);
+	module_printk(KERN_NOTICE, "DAHDINET: Opened channel %d name %s\n", ms->channo, ms->name);
 #endif
 	return 0;
 }
@@ -1366,19 +1483,19 @@
 	struct dahdi_chan *ms = hdlc_to_ztchan(hdlc);
 	if (!ms) {
 #ifdef NEW_HDLC_INTERFACE
-		printk("dahdi_net_stop: nothing??\n");
+		module_printk(KERN_NOTICE, "dahdi_net_stop: nothing??\n");
 		return 0;
 #else
-		printk("dahdi_net_close: nothing??\n");
+		module_printk(KERN_NOTICE, "dahdi_net_close: nothing??\n");
 		return;
 #endif
 	}
 	if (!(ms->flags & DAHDI_FLAG_NETDEV)) {
 #ifdef NEW_HDLC_INTERFACE
-		printk("dahdi_net_stop: %s is not a net device!\n", ms->name);
+		module_printk(KERN_NOTICE, "dahdi_net_stop: %s is not a net device!\n", ms->name);
 		return 0;
 #else
-		printk("dahdi_net_close: %s is not a net device!\n", ms->name);
+		module_printk(KERN_NOTICE, "dahdi_net_close: %s is not a net device!\n", ms->name);
 		return;
 #endif
 	}
@@ -1456,7 +1573,7 @@
 	/* See if we have any buffers */
 	spin_lock_irqsave(&ss->lock, flags);
 	if (skb->len > ss->blocksize - 2) {
-		printk(KERN_ERR "dahdi_xmit(%s): skb is too large (%d > %d)\n", dev->name, skb->len, ss->blocksize -2);
+		module_printk(KERN_ERR, "dahdi_xmit(%s): skb is too large (%d > %d)\n", dev->name, skb->len, ss->blocksize -2);
 		stats->tx_dropped++;
 		retval = 0;
 	} else if (ss->inwritebuf >= 0) {
@@ -1494,7 +1611,7 @@
 		stats->tx_packets++;
 		stats->tx_bytes += ss->writen[oldbuf];
 #ifdef CONFIG_DAHDI_DEBUG
-		printk("Buffered %d bytes to go out in buffer %d\n", ss->writen[oldbuf], oldbuf);
+		module_printk(KERN_NOTICE, "Buffered %d bytes to go out in buffer %d\n", ss->writen[oldbuf], oldbuf);
 		for (x=0;x<ss->writen[oldbuf];x++)
 		     printk("%02x ", ss->writebuf[oldbuf][x]);
 		printk("\n");
@@ -1540,11 +1657,11 @@
 
 	/* See if we have any buffers */
 	spin_lock_irqsave(&ss->lock, flags);
-	if (!(ss->flags & DAHDI_FLAG_OPEN)) {
-		printk("Can't transmit on closed channel\n");
+	if (!(test_bit(DAHDI_FLAGBIT_OPEN, &ss->flags))) {
+		module_printk(KERN_ERR, "Can't transmit on closed channel\n");
 		retval = 1;
 	} else if (skb->len > ss->blocksize - 4) {
-		printk(KERN_ERR "dahdi_ppp_xmit(%s): skb is too large (%d > %d)\n", ss->name, skb->len, ss->blocksize -2);
+		module_printk(KERN_ERR, "dahdi_ppp_xmit(%s): skb is too large (%d > %d)\n", ss->name, skb->len, ss->blocksize -2);
 		retval = 1;
 	} else if (ss->inwritebuf >= 0) {
 		/* We have a place to put this packet */
@@ -1595,7 +1712,7 @@
 			ss->outwritebuf = oldbuf;
 		}
 #ifdef CONFIG_DAHDI_DEBUG
-		printk("Buffered %d bytes (skblen = %d) to go out in buffer %d\n", ss->writen[oldbuf], skb->len, oldbuf);
+		module_printk(KERN_NOTICE, "Buffered %d bytes (skblen = %d) to go out in buffer %d\n", ss->writen[oldbuf], skb->len, oldbuf);
 		for (x=0;x<ss->writen[oldbuf];x++)
 		     printk("%02x ", ss->writebuf[oldbuf][x]);
 		printk("\n");
@@ -1644,7 +1761,7 @@
 	}
 #ifdef CONFIG_DAHDI_PPP
 	if (chan->ppp) {
-		printk("HUH???  PPP still attached??\n");
+		module_printk(KERN_NOTICE, "HUH???  PPP still attached??\n");
 	}
 #endif
 	maxchans = 0;
@@ -1717,8 +1834,8 @@
 		int x;
 		if (amnt > chan->readn[res])
 			myamnt = chan->readn[res];
-		printk("dahdi_chan_read(unit: %d, inwritebuf: %d, outwritebuf: %d amnt: %d\n", 
-			unit, chan->inwritebuf, chan->outwritebuf, myamnt);
+		module_printk(KERN_NOTICE, "dahdi_chan_read(unit: %d, inwritebuf: %d, outwritebuf: %d amnt: %d\n", 
+			      unit, chan->inwritebuf, chan->outwritebuf, myamnt);
 		printk("\t("); for (x = 0; x < myamnt; x++) printk((x ? " %02x" : "%02x"), (unsigned char)usrbuf[x]);
 		printk(")\n");
 	}
@@ -1820,14 +1937,14 @@
 	}
 
 #ifdef CONFIG_DAHDI_DEBUG
-	printk("dahdi_chan_write(unit: %d, res: %d, outwritebuf: %d amnt: %d\n",
-		unit, chan->res, chan->outwritebuf, amnt);
+	module_printk(KERN_NOTICE, "dahdi_chan_write(unit: %d, res: %d, outwritebuf: %d amnt: %d\n",
+		      unit, chan->res, chan->outwritebuf, amnt);
 #endif
 #if 0
  	if ((unit == 24) || (unit == 48) || (unit == 16) || (unit == 47)) { 
  		int x;
- 		printk("dahdi_chan_write/in(unit: %d, res: %d, outwritebuf: %d amnt: %d, txdisable: %d)\n",
- 			unit, res, chan->outwritebuf, amnt, chan->txdisable);
+ 		module_printk(KERN_NOTICE, "dahdi_chan_write/in(unit: %d, res: %d, outwritebuf: %d amnt: %d, txdisable: %d)\n",
+			      unit, res, chan->outwritebuf, amnt, chan->txdisable);
  		printk("\t("); for (x = 0; x < amnt; x++) printk((x ? " %02x" : "%02x"), (unsigned char)usrbuf[x]);
  		printk(")\n");
  	}
@@ -1960,15 +2077,15 @@
 	/* if no span, return doing nothing */
 	if (!chan->span) return;
 	if (!chan->span->flags & DAHDI_FLAG_RBS) {
-		printk("dahdi_rbs: Tried to set RBS hook state on non-RBS channel %s\n", chan->name);
+		module_printk(KERN_NOTICE, "dahdi_rbs: Tried to set RBS hook state on non-RBS channel %s\n", chan->name);
 		return;
 	}
 	if ((txsig > 3) || (txsig < 0)) {
-		printk("dahdi_rbs: Tried to set RBS hook state %d (> 3) on  channel %s\n", txsig, chan->name);
+		module_printk(KERN_NOTICE, "dahdi_rbs: Tried to set RBS hook state %d (> 3) on  channel %s\n", txsig, chan->name);
 		return;
 	}
 	if (!chan->span->rbsbits && !chan->span->hooksig) {
-		printk("dahdi_rbs: Tried to set RBS hook state %d on channel %s while span %s lacks rbsbits or hooksig function\n",
+		module_printk(KERN_NOTICE, "dahdi_rbs: Tried to set RBS hook state %d on channel %s while span %s lacks rbsbits or hooksig function\n",
 			txsig, chan->name, chan->span->name);
 		return;
 	}
@@ -2007,7 +2124,7 @@
 		for (x=0;x<NUM_SIGS;x++) {
 			if (outs[x][0] == chan->sig) {
 #ifdef CONFIG_DAHDI_DEBUG
-				printk("Setting bits to %d for channel %s state %d in %d signalling\n", outs[x][txsig + 1], chan->name, txsig, chan->sig);
+				module_printk(KERN_NOTICE, "Setting bits to %d for channel %s state %d in %d signalling\n", outs[x][txsig + 1], chan->name, txsig, chan->sig);
 #endif
 				chan->txhooksig = txsig;
 				chan->txsig = outs[x][txsig+1];
@@ -2017,7 +2134,7 @@
 			}
 		}
 	}
-	printk("dahdi_rbs: Don't know RBS signalling type %d on channel %s\n", chan->sig, chan->name);
+	module_printk(KERN_NOTICE, "dahdi_rbs: Don't know RBS signalling type %d on channel %s\n", chan->sig, chan->name);
 }
 
 static int dahdi_cas_setbits(struct dahdi_chan *chan, int bits)
@@ -2028,7 +2145,7 @@
 		chan->txsig = bits;
 		chan->span->rbsbits(chan, bits);
 	} else {
-		printk("Huh?  CAS setbits, but no RBS bits function\n");
+		module_printk(KERN_NOTICE, "Huh?  CAS setbits, but no RBS bits function\n");
 	}
 	return 0;
 }
@@ -2102,7 +2219,9 @@
 	int res;
 	unsigned long flags;
 	void *rxgain=NULL;
-	struct echo_can_state *ec=NULL;
+	struct echo_can_state *ec_state;
+	const struct dahdi_echocan *ec_current;
+
 	if ((res = dahdi_reallocbufs(chan, DAHDI_DEFAULT_BLOCKSIZE, DAHDI_DEFAULT_NUM_BUFS)))
 		return res;
 
@@ -2111,9 +2230,10 @@
 	chan->rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
 	chan->txbufpolicy = DAHDI_POLICY_IMMEDIATE;
 
-	/* Free up the echo canceller if there is one */
-	ec = chan->ec;
-	chan->ec = NULL;
+	ec_state = chan->ec_state;
+	chan->ec_state = NULL;
+	ec_current = chan->ec_current;
+	chan->ec_current = NULL;
 	chan->echocancel = 0;
 	chan->echostate = ECHO_STATE_IDLE;
 	chan->echolastupdate = 0;
@@ -2210,15 +2330,20 @@
 		chan->ringcadence[1] = DAHDI_RINGOFFTIME;
 	}
 
+	if (ec_state) {
+		ec_current->echo_can_free(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);
-	if (ec)
-		echo_can_free(ec);
+
 	return 0;
 }
 
@@ -2263,7 +2388,7 @@
 		}
 		spin_unlock_irqrestore(&zaptimerlock, flags);
 		if (!cur) {
-			printk("DAHDI Timer: Not on list??\n");
+			module_printk(KERN_NOTICE, "Timer: Not on list??\n");
 			return 0;
 		}
 		kfree(t);
@@ -2456,7 +2581,7 @@
 	if (unit == 255) {
 		chan = file->private_data;
 		if (!chan) {
-			printk("No pseudo channel structure to read?\n");
+			module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
 			return -EINVAL;
 		}
 		return dahdi_chan_read(file, usrbuf, count, chan->channo);
@@ -2487,7 +2612,7 @@
 	if (unit == 255) {
 		chan = file->private_data;
 		if (!chan) {
-			printk("No pseudo channel structure to read?\n");
+			module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
 			return -EINVAL;
 		}
 		return dahdi_chan_write(file, usrbuf, count, chan->channo);
@@ -2544,7 +2669,7 @@
 	data += sizeof(th);
 
 	if ((th.count < 0) || (th.count > MAX_TONES)) {
-		printk("Too many tones included\n");
+		module_printk(KERN_NOTICE, "Too many tones included\n");
 		return -EINVAL;
 	}
 
@@ -2579,7 +2704,7 @@
 
 		if (space < sizeof(*t)) {
 			kfree(slab);
-			printk("Insufficient tone zone space\n");
+			module_printk(KERN_NOTICE, "Insufficient tone zone space\n");
 			return -EINVAL;
 		}
 
@@ -2603,7 +2728,7 @@
 			
 			/* Make sure the "next" one is sane */
 			if ((next[x] >= th.count) || (next[x] < 0)) {
-				printk("Invalid 'next' pointer: %d\n", next[x]);
+				module_printk(KERN_NOTICE, "Invalid 'next' pointer: %d\n", next[x]);
 				kfree(slab);
 				return -EINVAL;
 			}
@@ -2628,7 +2753,7 @@
 			td.tone -= DAHDI_TONE_MFR2_REV_BASE;
 			t = &z->mfr2_rev[td.tone];
 		} else {
-			printk("Invalid tone (%d) defined\n", td.tone);
+			module_printk(KERN_NOTICE, "Invalid tone (%d) defined\n", td.tone);
 			kfree(slab);
 			return -EINVAL;
 		}
@@ -2720,7 +2845,7 @@
 		if (__warnonce) {
 			__warnonce = 0;
 			/* The tonezones are loaded by ztcfg based on /etc/dahdi.conf. */
-			printk(KERN_WARNING "DAHDI: Cannot get dtmf tone until tone zone is loaded.\n");
+			module_printk(KERN_WARNING, "Cannot get dtmf tone until tone zone is loaded.\n");
 		}
 		return NULL;
 	}
@@ -2937,7 +3062,7 @@
 			res = dahdi_specchan_release(inode, file, chan->channo);
 			dahdi_free_pseudo(chan);
 		} else {
-			printk("Pseudo release and no private data??\n");
+			module_printk(KERN_NOTICE, "Pseudo release and no private data??\n");
 			res = 0;
 		}
 		return res;
@@ -2991,7 +3116,7 @@
 		for (x=1; x<maxspans; x++) {
 			if (spans[x] && !spans[x]->alarms && (spans[x]->flags & DAHDI_FLAG_RUNNING)) {
 				if(master != spans[x])
-					printk("DAHDI: Master changed to %s\n", spans[x]->name);
+					module_printk(KERN_NOTICE, "Master changed to %s\n", spans[x]->name);
 				master = spans[x];
 				break;
 			}
@@ -3336,39 +3461,39 @@
 		/* release it. */
 		spin_unlock_irqrestore(&chans[j]->lock, flags);
 
-		printk(KERN_INFO "Dump of DAHDI Channel %d (%s,%d,%d):\n\n",j,
+		module_printk(KERN_INFO, "Dump of DAHDI Channel %d (%s,%d,%d):\n\n",j,
 			mychan->name,mychan->channo,mychan->chanpos);
-		printk(KERN_INFO "flags: %x hex, writechunk: %08lx, readchunk: %08lx\n",
+		module_printk(KERN_INFO, "flags: %x hex, writechunk: %08lx, readchunk: %08lx\n",
 			(unsigned int) mychan->flags, (long) mychan->writechunk, (long) mychan->readchunk);
-		printk(KERN_INFO "rxgain: %08lx, txgain: %08lx, gainalloc: %d\n",
+		module_printk(KERN_INFO, "rxgain: %08lx, txgain: %08lx, gainalloc: %d\n",
 			(long) mychan->rxgain, (long)mychan->txgain, mychan->gainalloc);
-		printk(KERN_INFO "span: %08lx, sig: %x hex, sigcap: %x hex\n",
+		module_printk(KERN_INFO, "span: %08lx, sig: %x hex, sigcap: %x hex\n",
 			(long)mychan->span, mychan->sig, mychan->sigcap);
-		printk(KERN_INFO "inreadbuf: %d, outreadbuf: %d, inwritebuf: %d, outwritebuf: %d\n",
+		module_printk(KERN_INFO, "inreadbuf: %d, outreadbuf: %d, inwritebuf: %d, outwritebuf: %d\n",
 			mychan->inreadbuf, mychan->outreadbuf, mychan->inwritebuf, mychan->outwritebuf);
-		printk(KERN_INFO "blocksize: %d, numbufs: %d, txbufpolicy: %d, txbufpolicy: %d\n",
+		module_printk(KERN_INFO, "blocksize: %d, numbufs: %d, txbufpolicy: %d, txbufpolicy: %d\n",
 			mychan->blocksize, mychan->numbufs, mychan->txbufpolicy, mychan->rxbufpolicy);
-		printk(KERN_INFO "txdisable: %d, rxdisable: %d, iomask: %d\n",
+		module_printk(KERN_INFO, "txdisable: %d, rxdisable: %d, iomask: %d\n",
 			mychan->txdisable, mychan->rxdisable, mychan->iomask);
-		printk(KERN_INFO "curzone: %08lx, tonezone: %d, curtone: %08lx, tonep: %d\n",
+		module_printk(KERN_INFO, "curzone: %08lx, tonezone: %d, curtone: %08lx, tonep: %d\n",
 			(long) mychan->curzone, mychan->tonezone, (long) mychan->curtone, mychan->tonep);
-		printk(KERN_INFO "digitmode: %d, txdialbuf: %s, dialing: %d, aftdialtimer: %d, cadpos. %d\n",
+		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);
-		printk(KERN_INFO "confna: %d, confn: %d, confmode: %d, confmute: %d\n",
+		module_printk(KERN_INFO, "confna: %d, confn: %d, confmode: %d, confmute: %d\n",
 			mychan->confna, mychan->_confn, mychan->confmode, mychan->confmute);
-		printk(KERN_INFO "ec: %08lx, echocancel: %d, deflaw: %d, xlaw: %08lx\n",
-			(long) mychan->ec, mychan->echocancel, mychan->deflaw, (long) mychan->xlaw);
-		printk(KERN_INFO "echostate: %02x, echotimer: %d, echolastupdate: %d\n",
+		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);
-		printk(KERN_INFO "itimer: %d, otimer: %d, ringdebtimer: %d\n\n",
+		module_printk(KERN_INFO, "itimer: %d, otimer: %d, ringdebtimer: %d\n\n",
 			mychan->itimer, mychan->otimer, mychan->ringdebtimer);
 #if 0
-		if (mychan->ec) {
+		if (mychan->ec_state) {
 			int x;
 			/* Dump the echo canceller parameters */
-			for (x=0;x<mychan->ec->taps;x++) {
-				printk(KERN_INFO "tap %d: %d\n", x, mychan->ec->fir_taps[x]);
+			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
@@ -3387,6 +3512,13 @@
 	dahdi_dynamic_ioctl = func;
 }
 
+static int (*dahdi_hpec_ioctl)(unsigned int cmd, unsigned long data);
+
+void dahdi_set_hpec_ioctl(int (*func)(unsigned int cmd, unsigned long data)) 
+{
+	dahdi_hpec_ioctl = func;
+}
+
 static void recalc_slaves(struct dahdi_chan *chan)
 {
 	int x;
@@ -3397,15 +3529,15 @@
 		return;
 
 #ifdef CONFIG_DAHDI_DEBUG
-	printk("Recalculating slaves on %s\n", chan->name);
+	module_printk(KERN_NOTICE, "Recalculating slaves on %s\n", chan->name);
 #endif
 
 	/* Link all slaves appropriately */
 	for (x=chan->chanpos;x<chan->span->channels;x++)
 		if (chan->span->chans[x].master == chan) {
 #ifdef CONFIG_DAHDI_DEBUG
-			printk("Channel %s, slave to %s, last is %s, its next will be %d\n", 
-			       chan->span->chans[x].name, chan->name, last->name, x);
+			module_printk(KERN_NOTICE, "Channel %s, slave to %s, last is %s, its next will be %d\n", 
+				      chan->span->chans[x].name, chan->name, last->name, x);
 #endif
 			last->nextslave = x;
 			last = &chan->span->chans[x];
@@ -3413,7 +3545,7 @@
 	/* Terminate list */
 	last->nextslave = 0;
 #ifdef CONFIG_DAHDI_DEBUG
-	printk("Done Recalculating slaves on %s (last is %s)\n", chan->name, last->name);
+	module_printk(KERN_NOTICE, "Done Recalculating slaves on %s (last is %s)\n", chan->name, last->name);
 #endif
 }
 
@@ -3481,6 +3613,34 @@
 			res =  spans[j]->shutdown(spans[j]);
 		spans[j]->flags &= ~DAHDI_FLAG_RUNNING;
 		return 0;
+	case DAHDI_ATTACH_ECHOCAN:
+	{
+		struct dahdi_attach_echocan ae;
+		const struct dahdi_echocan *new = NULL, *old;
+
+		if (copy_from_user(&ae, (struct dahdi_attach_echocan *) data, sizeof(ae))) {
+			return -EFAULT;
+		}
+
+		VALID_CHANNEL(ae.chan);
+
+		if (ae.echocan[0]) {
+			if (!(new = find_echocan(ae.echocan))) {
+				return -EINVAL;
+			}
+		}
+
+		spin_lock_irqsave(&chans[ae.chan]->lock, flags);
+		old = chans[ae.chan]->ec_factory;
+		chans[ae.chan]->ec_factory = new;
+		spin_unlock_irqrestore(&chans[ae.chan]->lock, flags);
+
+		if (old) {
+			release_echocan(old);
+		}
+
+		break;
+	}
 	case DAHDI_CHANCONFIG:
 	{
 		struct dahdi_chanconfig ch;
@@ -3510,7 +3670,7 @@
 		if (chans[ch.chan]->flags & DAHDI_FLAG_NETDEV) {
 			if (ztchan_to_dev(chans[ch.chan])->flags & IFF_UP) {
 				spin_unlock_irqrestore(&chans[ch.chan]->lock, flags);
-				printk(KERN_WARNING "Can't switch HDLC net mode on channel %s, since current interface is up\n", chans[ch.chan]->name);
+				module_printk(KERN_WARNING, "Can't switch HDLC net mode on channel %s, since current interface is up\n", chans[ch.chan]->name);
 				return -EBUSY;
 			}
 			spin_unlock_irqrestore(&chans[ch.chan]->lock, flags);
@@ -3523,9 +3683,9 @@
 		}
 #else
 		if (ch.sigtype == DAHDI_SIG_HDLCNET) {
-				spin_unlock_irqrestore(&chans[ch.chan]->lock, flags);
-				printk(KERN_WARNING "DAHDI networking not supported by this build.\n");
-				return -ENOSYS;
+			spin_unlock_irqrestore(&chans[ch.chan]->lock, flags);
+			module_printk(KERN_WARNING, "DAHDI networking not supported by this build.\n");
+			return -ENOSYS;
 		}
 #endif			
 		sigcap = chans[ch.chan]->sigcap;
@@ -3535,15 +3695,17 @@
 			sigcap |= (DAHDI_SIG_HDLCRAW | DAHDI_SIG_HDLCFCS | DAHDI_SIG_HDLCNET | DAHDI_SIG_DACS);
 		
 		if ((sigcap & ch.sigtype) != ch.sigtype)
-			res =  -EINVAL;	
+			res = -EINVAL;	
 		
 		if (!res && chans[ch.chan]->span->chanconfig)
 			res = chans[ch.chan]->span->chanconfig(chans[ch.chan], ch.sigtype);
+
 		if (chans[ch.chan]->master) {
 			/* Clear the master channel */
 			recalc_slaves(chans[ch.chan]->master);
 			chans[ch.chan]->nextslave = 0;
 		}
+
 		if (!res) {
 			chans[ch.chan]->sig = ch.sigtype;
 			if (chans[ch.chan]->sig == DAHDI_SIG_CAS)
@@ -3579,12 +3741,13 @@
 				chans[ch.chan]->confna = ch.idlebits;
 				if (chans[ch.chan]->span && 
 				    chans[ch.chan]->span->dacs && 
-					chans[ch.idlebits] && 
-					chans[ch.chan]->span && 
-					(chans[ch.chan]->span->dacs == chans[ch.idlebits]->span->dacs)) 
+				    chans[ch.idlebits] && 
+				    chans[ch.chan]->span && 
+				    (chans[ch.chan]->span->dacs == chans[ch.idlebits]->span->dacs)) 
 					chans[ch.chan]->span->dacs(chans[ch.chan], chans[ch.idlebits]);
-			} else if (chans[ch.chan]->span && chans[ch.chan]->span->dacs)
+			} else if (chans[ch.chan]->span && chans[ch.chan]->span->dacs) {
 				chans[ch.chan]->span->dacs(chans[ch.chan], NULL);
+			}
 			chans[ch.chan]->master = newmaster;
 			/* Note new slave if we are not our own master */
 			if (newmaster != chans[ch.chan]) {
@@ -3594,8 +3757,9 @@
 				chans[ch.chan]->flags &= ~DAHDI_FLAG_FCS;
 				chans[ch.chan]->flags &= ~DAHDI_FLAG_HDLC;
 				chans[ch.chan]->flags |= DAHDI_FLAG_NOSTDTXRX;
-			} else
+			} else {
 				chans[ch.chan]->flags &= ~DAHDI_FLAG_NOSTDTXRX;
+			}
 
 			if ((ch.sigtype & DAHDI_SIG_MTP2) == DAHDI_SIG_MTP2)
 				chans[ch.chan]->flags |= DAHDI_FLAG_MTP2;
@@ -3604,12 +3768,13 @@
 		}
 #ifdef CONFIG_DAHDI_NET
 		if (!res && 
-			(newmaster == chans[ch.chan]) && 
-		        (chans[ch.chan]->sig == DAHDI_SIG_HDLCNET)) {
+		    (newmaster == chans[ch.chan]) && 
+		    (chans[ch.chan]->sig == DAHDI_SIG_HDLCNET)) {
 			chans[ch.chan]->hdlcnetdev = dahdi_hdlc_alloc();
 			if (chans[ch.chan]->hdlcnetdev) {
 /*				struct hdlc_device *hdlc = chans[ch.chan]->hdlcnetdev;
 				struct net_device *d = hdlc_to_dev(hdlc); mmm...get it right later --byg */
+
 				chans[ch.chan]->hdlcnetdev->netdev = alloc_hdlcdev(chans[ch.chan]->hdlcnetdev);
 				if (chans[ch.chan]->hdlcnetdev->netdev) {
 					chans[ch.chan]->hdlcnetdev->chan = chans[ch.chan];
@@ -3628,13 +3793,13 @@
 					res = dahdi_register_hdlc_device(chans[ch.chan]->hdlcnetdev->netdev, ch.netdev_name);
 					spin_lock_irqsave(&chans[ch.chan]->lock, flags);
 				} else {
-					printk("Unable to allocate hdlc: *shrug*\n");
+					module_printk(KERN_NOTICE, "Unable to allocate hdlc: *shrug*\n");
 					res = -1;
 				}
 				if (!res)
 					chans[ch.chan]->flags |= DAHDI_FLAG_NETDEV;
 			} else {
-				printk("Unable to allocate netdev: out of memory\n");
+				module_printk(KERN_NOTICE, "Unable to allocate netdev: out of memory\n");
 				res = -1;
 			}
 		}
@@ -3642,7 +3807,7 @@
 		if ((chans[ch.chan]->sig == DAHDI_SIG_HDLCNET) && 
 		    (chans[ch.chan] == newmaster) &&
 		    !(chans[ch.chan]->flags & DAHDI_FLAG_NETDEV))
-			printk("Unable to register HDLC device for channel %s\n", chans[ch.chan]->name);
+			module_printk(KERN_NOTICE, "Unable to register HDLC device for channel %s\n", chans[ch.chan]->name);
 		if (!res) {
 			/* Setup default law */
 			chans[ch.chan]->deflaw = ch.deflaw;
@@ -3654,13 +3819,15 @@
 			/* And hangup */
 			dahdi_hangup(chans[ch.chan]);
 			y = dahdi_q_sig(chans[ch.chan]) & 0xff;
-			if (y >= 0) chans[ch.chan]->rxsig = (unsigned char)y;
+			if (y >= 0)
+				chans[ch.chan]->rxsig = (unsigned char) y;
 			chans[ch.chan]->rxhooksig = DAHDI_RXSIG_INITIAL;
 		}
 #ifdef CONFIG_DAHDI_DEBUG
-		printk("Configured channel %s, flags %04x, sig %04x\n", chans[ch.chan]->name, chans[ch.chan]->flags, chans[ch.chan]->sig);
+		module_printk(KERN_NOTICE, "Configured channel %s, flags %04x, sig %04x\n", chans[ch.chan]->name, chans[ch.chan]->flags, chans[ch.chan]->sig);
 #endif			
 		spin_unlock_irqrestore(&chans[ch.chan]->lock, flags);
+
 		return res;
 	}
 	case DAHDI_SFCONFIG:
@@ -3765,10 +3932,27 @@
 	case DAHDI_GETVERSION:
 	{
 		struct dahdi_versioninfo vi;
+		struct echocan *cur;
+		size_t space = sizeof(vi.echo_canceller) - 1;
 
 		memset(&vi, 0, sizeof(vi));
 		dahdi_copy_string(vi.version, DAHDI_VERSION, sizeof(vi.version));
-		echo_can_identify(vi.echo_canceller, sizeof(vi.echo_canceller) - 1);
+		read_lock(&echocan_list_lock);
+		list_for_each_entry(cur, &echocan_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)) {
+				strncat(vi.echo_canceller + strlen(vi.echo_canceller), ", ", space);
+				space -= 2;
+				if (space < 1) {
+					break;
+				}
+			}
+		}
+		read_unlock(&echocan_list_lock);
 		if (copy_to_user((struct dahdi_versioninfo *) data, &vi, sizeof(vi)))
 			return -EFAULT;
 		break;
@@ -3811,7 +3995,7 @@
 			spin_lock_irqsave(&spans[maint.spanno]->lock, flags);
 			break;
 		default:
-			printk("DAHDI: Unknown maintenance event: %d\n", maint.command);
+			module_printk(KERN_NOTICE, "Unknown maintenance event: %d\n", maint.command);
 		}
 		dahdi_alarm_notify(spans[maint.spanno]);  /* process alarm-related events */
 		spin_unlock_irqrestore(&spans[maint.spanno]->lock, flags);
@@ -3819,19 +4003,24 @@
 	}
 	case DAHDI_DYNAMIC_CREATE:
 	case DAHDI_DYNAMIC_DESTROY:
-		if (dahdi_dynamic_ioctl)
+		if (dahdi_dynamic_ioctl) {
 			return dahdi_dynamic_ioctl(cmd, data);
-		else {
+		} else {
 			request_module("dahdi_dynamic");
 			if (dahdi_dynamic_ioctl)
 				return dahdi_dynamic_ioctl(cmd, data);
 		}
 		return -ENOSYS;
-#if defined(ECHO_CAN_HPEC)
 	case DAHDI_EC_LICENSE_CHALLENGE:
 	case DAHDI_EC_LICENSE_RESPONSE:
-		return hpec_license_ioctl(cmd, data);
-#endif /* defined(ECHO_CAN_HPEC) */
+		if (dahdi_hpec_ioctl) {
+			return dahdi_hpec_ioctl(cmd, data);
+		} else {
+			request_module("dahdi_echocan_hpec");
+			if (dahdi_hpec_ioctl)

[... 1376 lines stripped ...]



More information about the svn-commits mailing list