summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin P. Fleming <kpfleming@digium.com>2008-06-20 22:40:11 +0000
committerKevin P. Fleming <kpfleming@digium.com>2008-06-20 22:40:11 +0000
commitd653250809bfefc4427705e3d9fe45c54586ccf3 (patch)
tree8b22eb3a57540633e0f0c783a8a9c79e7d49bd9e
parenta8cc1e7138795a0ea33afea701317c1d6054a84d (diff)
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
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@4436 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/Kbuild21
-rw-r--r--drivers/dahdi/Kconfig60
-rw-r--r--drivers/dahdi/dahdi-base.c728
-rw-r--r--drivers/dahdi/dahdi_config.h45
-rw-r--r--drivers/dahdi/dahdi_dummy.c4
-rw-r--r--drivers/dahdi/dahdi_dynamic.c6
-rw-r--r--drivers/dahdi/dahdi_dynamic_eth.c4
-rw-r--r--drivers/dahdi/dahdi_dynamic_loc.c5
-rw-r--r--drivers/dahdi/dahdi_echocan_jpah.c130
-rw-r--r--drivers/dahdi/dahdi_echocan_kb1.c (renamed from drivers/dahdi/kb1ec.h)162
-rw-r--r--drivers/dahdi/dahdi_echocan_mg2.c (renamed from drivers/dahdi/mg2ec.h)176
-rw-r--r--drivers/dahdi/dahdi_echocan_sec.c (renamed from drivers/dahdi/sec.h)103
-rw-r--r--drivers/dahdi/dahdi_echocan_sec2.c (renamed from drivers/dahdi/sec-2.h)226
-rw-r--r--drivers/dahdi/dahdi_transcode.c12
-rw-r--r--drivers/dahdi/datamods/syncppp.c3
-rw-r--r--drivers/dahdi/fir.h8
-rw-r--r--drivers/dahdi/hpec/dahdi_echocan_hpec.c (renamed from drivers/dahdi/hpec/hpec_dahdi.h)86
-rw-r--r--drivers/dahdi/jpah.h104
-rw-r--r--drivers/dahdi/kb1ec_const.h72
-rw-r--r--drivers/dahdi/mg2ec_const.h88
-rw-r--r--drivers/dahdi/pciradio.c5
-rw-r--r--drivers/dahdi/tor2.c4
-rw-r--r--drivers/dahdi/wcfxo.c4
-rw-r--r--drivers/dahdi/wct1xxp.c4
-rw-r--r--drivers/dahdi/wct4xxp/base.c7
-rw-r--r--drivers/dahdi/wctc4xxp/base.c5
-rw-r--r--drivers/dahdi/wctdm.c6
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c6
-rw-r--r--drivers/dahdi/wcte11xp.c4
-rw-r--r--drivers/dahdi/wcte12xp/base.c4
-rw-r--r--include/dahdi/kernel.h63
31 files changed, 1192 insertions, 963 deletions
diff --git a/drivers/dahdi/Kbuild b/drivers/dahdi/Kbuild
index b25ad29..0157d83 100644
--- a/drivers/dahdi/Kbuild
+++ b/drivers/dahdi/Kbuild
@@ -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_PCIRADIO) += pciradio.o
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 @@ endif
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
diff --git a/drivers/dahdi/Kconfig b/drivers/dahdi/Kconfig
index 4402e58..22a448a 100644
--- a/drivers/dahdi/Kconfig
+++ b/drivers/dahdi/Kconfig
@@ -14,7 +14,60 @@ menuconfig DAHDI
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_WCT4XXP
config DAHDI_TRANSCODE
tristate "DAHDI transcoding support"
+ depends on DAHDI
default DAHDI
---help---
DAHDI transcoding infrastructure.
@@ -59,7 +113,7 @@ config DAHDI_TRANSCODE
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 @@ config DAHDI_WCTE11XP
If unsure, say Y.
source "drivers/dahdi/xpp/Kconfig"
-
-endif # DAHDI
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c
index fa733de..8b13454 100644
--- a/drivers/dahdi/dahdi-base.c
+++ b/drivers/dahdi/dahdi-base.c
@@ -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>
@@ -61,6 +62,8 @@
#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
@@ -83,6 +86,8 @@
#include <dahdi/kernel.h>
#include <dahdi/user.h>
+#include "hpec/hpec_user.h"
+
/* Get helper arithmetic */
#include "arith.h"
#if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP)
@@ -141,13 +146,15 @@ EXPORT_SYMBOL(dahdi_alarm_channel);
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) \
class_device_create(class, NULL, devt, device, name)
@@ -166,8 +173,6 @@ static struct class_simple *dahdi_class = NULL;
#define class_device_destroy(a, b) class_simple_device_remove(b)
#endif
-#endif /* CONFIG_DAHDI_UDEV */
-
static int deftaps = 64;
static int debug;
@@ -329,24 +334,69 @@ static rwlock_t chan_lock = RW_LOCK_UNLOCKED;
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"
+#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)
{
/* Rotate where we sum and so forth */
@@ -361,26 +411,26 @@ static inline void rotate_sums(void)
/* 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 @@ static int dahdi_proc_read(char *page, char **start, off_t off, int count, int *
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 @@ static inline int hw_echocancel_off(struct dahdi_chan *chan)
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 @@ static void close_channel(struct dahdi_chan *chan)
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 @@ static void close_channel(struct dahdi_chan *chan)
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 @@ static int dahdi_register_tone_zone(int num, struct dahdi_zone *zone)
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 @@ static int start_tone(struct dahdi_chan *chan, int tone)
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 @@ static int dahdi_chan_reg(struct dahdi_chan *chan)
}
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 @@ static int dahdi_net_open(hdlc_device *hdlc)
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 @@ static int dahdi_net_open(hdlc_device *hdlc)
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 @@ static void dahdi_net_close(hdlc_device *hdlc)
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 @@ static int dahdi_xmit(hdlc_device *hdlc, struct sk_buff *skb)
/* 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 @@ static int dahdi_xmit(hdlc_device *hdlc, struct sk_buff *skb)
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 @@ static int dahdi_ppp_xmit(struct ppp_channel *ppp, struct sk_buff *skb)
/* 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 @@ static int dahdi_ppp_xmit(struct ppp_channel *ppp, struct sk_buff *skb)
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 @@ static void dahdi_chan_unreg(struct dahdi_chan *chan)
}
#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 @@ static ssize_t dahdi_chan_read(struct file *file, char *usrbuf, size_t count, in
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 @@ static ssize_t dahdi_chan_write(struct file *file, const char *usrbuf, size_t co
}
#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 @@ who cares what the sig bits are as long as they are stable */
/* 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 @@ who cares what the sig bits are as long as they are stable */
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 @@ who cares what the sig bits are as long as they are stable */
}
}
}
- 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 @@ static int dahdi_cas_setbits(struct dahdi_chan *chan, int bits)
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 @@ static int initialize_channel(struct dahdi_chan *chan)
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 @@ static int initialize_channel(struct dahdi_chan *chan)
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 @@ static int initialize_channel(struct dahdi_chan *chan)
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 @@ static int dahdi_timer_release(struct inode *inode, struct file *file)
}
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 @@ static ssize_t dahdi_read(struct file *file, char *usrbuf, size_t count, loff_t
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 @@ static ssize_t dahdi_write(struct file *file, const char *usrbuf, size_t count,
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 @@ static int ioctl_load_zone(unsigned long data)
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 @@ static int ioctl_load_zone(unsigned long data)
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 @@ static int ioctl_load_zone(unsigned long data)
/* 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 @@ static int ioctl_load_zone(unsigned long data)
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 @@ struct dahdi_tone *dahdi_mf_tone(const struct dahdi_chan *chan, char digit, int
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 @@ static int dahdi_release(struct inode *inode, struct file *file)
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 @@ void dahdi_alarm_notify(struct dahdi_span *span)
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 @@ static int dahdi_common_ioctl(struct inode *node, struct file *file, unsigned in
/* 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 @@ void dahdi_set_dynamic_ioctl(int (*func)(unsigned int cmd, unsigned long data))
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 @@ static void recalc_slaves(struct dahdi_chan *chan)
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 @@ static void recalc_slaves(struct dahdi_chan *chan)
/* 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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
}
#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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
}
#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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
/* 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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
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 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
}
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)
+ return dahdi_hpec_ioctl(cmd, data);
+ }
+ return -ENOSYS;
default:
return dahdi_common_ioctl(inode, file, cmd, data, 0);
}
@@ -3861,7 +4050,7 @@ static int ioctl_dahdi_dial(struct dahdi_chan *chan, unsigned long data)
if (!chan->curzone) {
spin_unlock_irqrestore(&chan->lock, flags);
/* The tone zones are loaded by ztcfg from /etc/dahdi.conf */
- printk(KERN_WARNING "DAHDI: Cannot dial until a tone zone is loaded.\n");
+ module_printk(KERN_WARNING, "Cannot dial until a tone zone is loaded.\n");
return -ENODATA;
}
switch (tdo->op) {
@@ -4296,24 +4485,23 @@ static int dahdi_chanandpseudo_ioctl(struct inode *inode, struct file *file, uns
if (!chans[k]) continue;
/* skip if not in this conf */
if (chans[k]->confna != i) continue;
- if (!c) printk("Conf #%d:\n",i);
+ if (!c) module_printk(KERN_NOTICE, "Conf #%d:\n",i);
c = 1;
- printk("chan %d, mode %x\n",
- k,chans[k]->confmode);
+ module_printk(KERN_NOTICE, "chan %d, mode %x\n", k,chans[k]->confmode);
}
rv = 0;
for(k = 1; k <= DAHDI_MAX_CONF; k++)
{
if (conf_links[k].dst == i)
{
- if (!c) printk("Conf #%d:\n",i);
+ if (!c) module_printk(KERN_NOTICE, "Conf #%d:\n",i);
c = 1;
- if (!rv) printk("Snooping on:\n");
+ if (!rv) module_printk(KERN_NOTICE, "Snooping on:\n");
rv = 1;
- printk("conf %d\n",conf_links[k].src);
+ module_printk(KERN_NOTICE, "conf %d\n",conf_links[k].src);
}
}
- if (c) printk("\n");
+ if (c) module_printk(KERN_NOTICE, "\n");
}
break;
case DAHDI_CHANNO: /* get channel number of stream */
@@ -4413,7 +4601,8 @@ static void do_ppp_calls(unsigned long data)
static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, void *data)
{
- struct echo_can_state *ec = NULL, *tec;
+ struct echo_can_state *ec = NULL, *ec_state;
+ const struct dahdi_echocan *ec_current;
struct dahdi_echocanparam *params;
int ret;
unsigned long flags;
@@ -4424,16 +4613,20 @@ static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams
if (ecp->tap_length == 0) {
/* disable mode, don't need to inspect params */
spin_lock_irqsave(&chan->lock, flags);
- tec = 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;
chan->echotimer = 0;
spin_unlock_irqrestore(&chan->lock, flags);
+ if (ec_state) {
+ ec_current->echo_can_free(ec_state);
+ release_echocan(ec_current);
+ }
hw_echocancel_off(chan);
- if (tec)
- echo_can_free(tec);
return 0;
}
@@ -4457,13 +4650,16 @@ static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams
}
spin_lock_irqsave(&chan->lock, flags);
- tec = chan->ec;
- chan->ec = NULL;
+ ec_state = chan->ec_state;
+ chan->ec_state = NULL;
+ ec_current = chan->ec_current;
+ chan->ec_current = NULL;
spin_unlock_irqrestore(&chan->lock, flags);
+ if (ec_state) {
+ ec_current->echo_can_free(ec_state);
+ release_echocan(ec_current);
+ }
- if (tec)
- echo_can_free(tec);
-
ret = -ENODEV;
/* attempt to use the span's echo canceler; fall back to built-in
@@ -4475,7 +4671,9 @@ static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams
ret = chan->span->echocan(chan, ecp->tap_length);
}
- if (ret == -ENODEV) {
+ if ((ret == -ENODEV) && chan->ec_factory) {
+ const struct dahdi_echocan *ec_current;
+
switch (ecp->tap_length) {
case 32:
case 64:
@@ -4488,12 +4686,27 @@ static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams
ecp->tap_length = deftaps;
}
- if ((ret = echo_can_create(ecp, params, &ec)))
+ /* try to get another reference to the module providing
+ this channel's echo canceler */
+ if (!try_module_get(chan->ec_factory->owner)) {
+ module_printk(KERN_ERR, "Cannot get a reference to the '%s' echo canceler\n", chan->ec_factory->name);
goto exit_with_free;
+ }
+
+ /* got the reference, copy the pointer and use it for making
+ an echo canceler instance if possible */
+ ec_current = chan->ec_current;
+
+ if ((ret = ec_current->echo_can_create(ecp, params, &ec))) {
+ release_echocan(ec_current);
+
+ goto exit_with_free;
+ }
spin_lock_irqsave(&chan->lock, flags);
chan->echocancel = ecp->tap_length;
- chan->ec = ec;
+ chan->ec_current = ec_current;
+ chan->ec_state = ec;
chan->echostate = ECHO_STATE_IDLE;
chan->echolastupdate = 0;
chan->echotimer = 0;
@@ -4504,6 +4717,7 @@ static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams
exit_with_free:
kfree(params);
+
return ret;
}
@@ -4515,7 +4729,6 @@ static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int
int ret;
int oldconf;
void *rxgain=NULL;
- struct echo_can_state *ec;
if (!chan)
return -ENOSYS;
@@ -4553,6 +4766,9 @@ static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int
/* 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;
+
spin_lock_irqsave(&chan->lock, flags);
chan->flags &= ~DAHDI_FLAG_AUDIO;
/* save old conf number, if any */
@@ -4567,8 +4783,10 @@ static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int
memset(chan->conflast, 0, sizeof(chan->conflast));
memset(chan->conflast1, 0, sizeof(chan->conflast1));
memset(chan->conflast2, 0, sizeof(chan->conflast2));
- ec = chan->ec;
- chan->ec = NULL;
+ ec_state = chan->ec_state;
+ chan->ec_state = NULL;
+ ec_current = chan->ec_current;
+ chan->ec_current = NULL;
/* release conference resource, if any to release */
reset_conf(chan);
if (chan->gainalloc && chan->rxgain)
@@ -4579,15 +4797,18 @@ static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int
chan->rxgain = defgain;
chan->txgain = defgain;
chan->gainalloc = 0;
- /* Disable any native echo cancellation as well */
spin_unlock_irqrestore(&chan->lock, flags);
+ if (ec_state) {
+ ec_current->echo_can_free(ec_state);
+ release_echocan(ec_current);
+ }
+
+ /* Disable any native echo cancellation as well */
hw_echocancel_off(chan);
if (rxgain)
kfree(rxgain);
- if (ec)
- echo_can_free(ec);
if (oldconf) dahdi_check_conf(oldconf);
}
break;
@@ -4620,8 +4841,8 @@ static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int
chan->ppp = NULL;
return ret;
}
- tec = chan->ec;
- chan->ec = NULL;
+ tec = chan->ec_state;
+ chan->ec_state = NULL;
chan->echocancel = 0;
chan->echostate = ECHO_STATE_IDLE;
chan->echolastupdate = 0;
@@ -4637,7 +4858,7 @@ static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int
hw_echocancel_off(chan);
if (tec)
- echo_can_free(tec);
+ chan->ec->echo_can_free(tec);
} else
return -ENOMEM;
}
@@ -4653,7 +4874,7 @@ static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int
}
}
#else
- printk("DAHDI: DAHDI PPP support not compiled in\n");
+ module_printk(KERN_NOTICE, "PPP support not compiled in\n");
return -ENOSYS;
#endif
break;
@@ -4708,7 +4929,7 @@ static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int
if ((j < 0) || (j >= DAHDI_MAX_PRETRAINING))
return -EINVAL;
j <<= 3;
- if (chan->ec) {
+ if (chan->ec_state) {
/* Start pretraining stage */
chan->echostate = ECHO_STATE_PRETRAINING;
chan->echotimer = j;
@@ -4774,7 +4995,7 @@ static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int
spin_lock_irqsave(&chan->lock, flags);
if (!chan->curzone) {
spin_unlock_irqrestore(&chan->lock, flags);
- printk(KERN_WARNING "DAHDI: Cannot start tone until a tone zone is loaded.\n");
+ module_printk(KERN_WARNING, "Cannot start tone until a tone zone is loaded.\n");
return -ENODATA;
}
if (chan->txstate != DAHDI_TXSTATE_ONHOOK) {
@@ -4866,7 +5087,7 @@ static int dahdi_prechan_ioctl(struct inode *inode, struct file *file, unsigned
int res;
if (chan) {
- printk("Huh? Prechan already has private data??\n");
+ module_printk(KERN_NOTICE, "Huh? Prechan already has private data??\n");
}
switch(cmd) {
case DAHDI_SPECIFY:
@@ -4919,7 +5140,7 @@ static int dahdi_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
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_chanandpseudo_ioctl(inode, file, cmd, data, chan->channo);
@@ -4937,12 +5158,12 @@ int dahdi_register(struct dahdi_span *span, int prefmaster)
if (!span)
return -EINVAL;
if (span->flags & DAHDI_FLAG_REGISTERED) {
- printk(KERN_ERR "Span %s already appears to be registered\n", span->name);
+ module_printk(KERN_ERR, "Span %s already appears to be registered\n", span->name);
return -EBUSY;
}
for (x=1;x<maxspans;x++)
if (spans[x] == span) {
- printk(KERN_ERR "Span %s already in list\n", span->name);
+ module_printk(KERN_ERR, "Span %s already in list\n", span->name);
return -EBUSY;
}
for (x=1;x<DAHDI_MAX_SPANS;x++)
@@ -4953,19 +5174,19 @@ int dahdi_register(struct dahdi_span *span, int prefmaster)
if (maxspans < x + 1)
maxspans = x + 1;
} else {
- printk(KERN_ERR "Too many DAHDI spans registered\n");
+ module_printk(KERN_ERR, "Too many DAHDI spans registered\n");
return -EBUSY;
}
span->flags |= DAHDI_FLAG_REGISTERED;
span->spanno = x;
spin_lock_init(&span->lock);
if (!span->deflaw) {
- printk("DAHDI: Span %s didn't specify default law. Assuming mulaw, please fix driver!\n", span->name);
+ module_printk(KERN_NOTICE, "Span %s didn't specify default law. Assuming mulaw, please fix driver!\n", span->name);
span->deflaw = DAHDI_LAW_MULAW;
}
if (span->echocan && span->echocan_with_params) {
- printk("DAHDI: Span %s implements both echocan and echocan_with_params functions, preserving only echocan_with_params, please fix driver!\n", span->name);
+ 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;
}
@@ -4979,7 +5200,6 @@ int dahdi_register(struct dahdi_span *span, int prefmaster)
proc_entries[span->spanno] = create_proc_read_entry(tempfile, 0444, NULL , dahdi_proc_read, (int *)(long)span->spanno);
#endif
-#ifdef CONFIG_DAHDI_UDEV
for (x = 0; x < span->channels; x++) {
char chan_name[50];
if (span->chans[x].channo < 250) {
@@ -4987,14 +5207,13 @@ int dahdi_register(struct dahdi_span *span, int prefmaster)
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, span->chans[x].channo), NULL, chan_name);
}
}
-#endif /* CONFIG_DAHDI_UDEV */
if (debug)
- printk("Registered Span %d ('%s') with %d channels\n", span->spanno, span->name, span->channels);
+ module_printk(KERN_NOTICE, "Registered Span %d ('%s') with %d channels\n", span->spanno, span->name, span->channels);
if (!master || prefmaster) {
master = span;
if (debug)
- printk("Span ('%s') is new master\n", span->name);
+ module_printk(KERN_NOTICE, "Span ('%s') is new master\n", span->name);
}
return 0;
}
@@ -5010,7 +5229,7 @@ int dahdi_unregister(struct dahdi_span *span)
#endif /* CONFIG_PROC_FS */
if (!(span->flags & DAHDI_FLAG_REGISTERED)) {
- printk(KERN_ERR "Span %s does not appear to be registered\n", span->name);
+ module_printk(KERN_ERR, "Span %s does not appear to be registered\n", span->name);
return -1;
}
/* Shutdown the span if it's running */
@@ -5019,22 +5238,20 @@ int dahdi_unregister(struct dahdi_span *span)
span->shutdown(span);
if (spans[span->spanno] != span) {
- printk(KERN_ERR "Span %s has spanno %d which is something else\n", span->name, span->spanno);
+ module_printk(KERN_ERR, "Span %s has spanno %d which is something else\n", span->name, span->spanno);
return -1;
}
if (debug)
- printk("Unregistering Span '%s' with %d channels\n", span->name, span->channels);
+ module_printk(KERN_NOTICE, "Unregistering Span '%s' with %d channels\n", span->name, span->channels);
#ifdef CONFIG_PROC_FS
sprintf(tempfile, "dahdi/%d", span->spanno);
remove_proc_entry(tempfile, NULL);
#endif /* CONFIG_PROC_FS */
-#ifdef CONFIG_DAHDI_UDEV
for (x = 0; x < span->channels; x++) {
if (span->chans[x].channo < 250)
class_device_destroy(dahdi_class, MKDEV(DAHDI_MAJOR, span->chans[x].channo));
}
-#endif /* CONFIG_DAHDI_UDEV */
spans[span->spanno] = NULL;
span->spanno = 0;
@@ -5055,8 +5272,8 @@ int dahdi_unregister(struct dahdi_span *span)
maxspans = new_maxspans;
if (master != new_master)
if (debug)
- printk("%s: Span ('%s') is new master\n", __FUNCTION__,
- (new_master)? new_master->name: "no master");
+ module_printk(KERN_NOTICE, "%s: Span ('%s') is new master\n", __FUNCTION__,
+ (new_master)? new_master->name: "no master");
master = new_master;
return 0;
@@ -5230,17 +5447,19 @@ static inline void __dahdi_process_getaudio_chunk(struct dahdi_chan *ss, unsigne
for (x=0;x<DAHDI_CHUNKSIZE;x++)
getlin[x] = DAHDI_XLAW(txb[x], ms);
#ifndef NO_ECHOCAN_DISABLE
- if (ms->ec) {
+ 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])) {
- printk("DAHDI Disabled echo canceller because of tone (tx) on channel %d\n", ss->channo);
+ 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;
- echo_can_free(ms->ec);
- ms->ec = NULL;
+ 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);
break;
}
@@ -5412,14 +5631,14 @@ static inline void __dahdi_process_getaudio_chunk(struct dahdi_chan *ss, unsigne
if (!chans[ms->confna])
break;
if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) {
- if (ms->ec) {
+ if (ms->ec_state) {
for (x=0;x<DAHDI_CHUNKSIZE;x++)
txb[x] = DAHDI_LIN2X(chans[ms->confna]->getlin[x], ms);
} else {
memcpy(txb, chans[ms->confna]->getraw, DAHDI_CHUNKSIZE);
}
} else {
- if (ms->ec) {
+ if (ms->ec_state) {
for (x=0;x<DAHDI_CHUNKSIZE;x++)
txb[x] = DAHDI_LIN2X(chans[ms->confna]->putlin[x], ms);
} else {
@@ -5919,7 +6138,7 @@ static void __dahdi_hooksig_pvt(struct dahdi_chan *chan, dahdi_rxsig_t rxsig)
}
chan->kewlonhook = 0;
#ifdef CONFIG_DAHDI_DEBUG
- printk("Off hook on channel %d, itimer = %d, gotgs = %d\n", chan->channo, chan->itimer, chan->gotgs);
+ module_printk(KERN_NOTICE, "Off hook on channel %d, itimer = %d, gotgs = %d\n", chan->channo, chan->itimer, chan->gotgs);
#endif
if (chan->itimer) /* if timer still running */
{
@@ -6045,7 +6264,7 @@ static inline void __dahdi_ec_chunk(struct dahdi_chan *ss, unsigned char *rxchun
}
/* Perform echo cancellation on a chunk if necessary */
- if (ss->ec) {
+ if (ss->ec_state) {
#if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP)
dahdi_kernel_fpu_begin();
#endif
@@ -6065,9 +6284,9 @@ static inline void __dahdi_ec_chunk(struct dahdi_chan *ss, unsigned char *rxchun
ss->echostate = ECHO_STATE_TRAINING;
}
if (ss->echostate == ECHO_STATE_TRAINING) {
- if (echo_can_traintap(ss->ec, ss->echolastupdate++, rxlin)) {
+ if (ss->ec_current->echo_can_traintap(ss->ec_state, ss->echolastupdate++, rxlin)) {
#if 0
- printk("Finished training (%d taps trained)!\n", ss->echolastupdate);
+ module_printk(KERN_NOTICE, "Finished training (%d taps trained)!\n", ss->echolastupdate);
#endif
ss->echostate = ECHO_STATE_ACTIVE;
}
@@ -6076,22 +6295,14 @@ static inline void __dahdi_ec_chunk(struct dahdi_chan *ss, unsigned char *rxchun
rxchunk[x] = DAHDI_LIN2X((int)rxlin, ss);
}
} else {
-#if !defined(DAHDI_EC_ARRAY_UPDATE)
- for (x=0;x<DAHDI_CHUNKSIZE;x++) {
- rxlin = DAHDI_XLAW(rxchunk[x], ss);
- rxlin = echo_can_update(ss->ec, DAHDI_XLAW(txchunk[x], ss), rxlin);
- rxchunk[x] = DAHDI_LIN2X((int) rxlin, ss);
- }
-#else /* defined(DAHDI_EC_ARRAY_UPDATE) */
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);
}
- echo_can_array_update(ss->ec, rxlins, txlins);
+ ss->ec_current->echo_can_array_update(ss->ec_state, rxlins, txlins);
for (x = 0; x < DAHDI_CHUNKSIZE; x++)
rxchunk[x] = DAHDI_LIN2X((int) rxlins[x], ss);
-#endif /* defined(DAHDI_EC_ARRAY_UPDATE) */
}
#if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP)
kernel_fpu_end();
@@ -6109,7 +6320,7 @@ void dahdi_ec_span(struct dahdi_span *span)
{
int x;
for (x = 0; x < span->channels; x++) {
- if (span->chans[x].ec)
+ if (span->chans[x].ec_current)
__dahdi_ec_chunk(&span->chans[x], span->chans[x].readchunk, span->chans[x].writechunk);
}
}
@@ -6185,16 +6396,18 @@ static inline void __dahdi_process_putaudio_chunk(struct dahdi_chan *ss, unsigne
}
#ifndef NO_ECHOCAN_DISABLE
- if (ms->ec) {
+ if (ms->ec_state) {
for (x=0;x<DAHDI_CHUNKSIZE;x++) {
if (echo_can_disable_detector_update(&ms->rxecdis, putlin[x])) {
- printk("DAHDI Disabled echo canceller because of tone (rx) on channel %d\n", ss->channo);
+ 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;
- echo_can_free(ms->ec);
- ms->ec = NULL;
+ ms->ec_current->echo_can_free(ms->ec_state);
+ ms->ec_state = NULL;
+ release_echocan(ms->ec_current);
+ ms->ec_current = NULL;
break;
}
}
@@ -6480,7 +6693,7 @@ static inline void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb, int
/* Pay attention to the possibility of an overrun */
if (ms->readidx[ms->inreadbuf] >= ms->blocksize) {
if (!ss->span->alarms)
- printk(KERN_WARNING "HDLC Receiver overrun on channel %s (master=%s)\n", ss->name, ss->master->name);
+ module_printk(KERN_WARNING, "HDLC Receiver overrun on channel %s (master=%s)\n", ss->name, ss->master->name);
abort=DAHDI_EVENT_OVERRUN;
/* Force the HDLC state back to frame-search mode */
ms->rxhdlc.state = 0;
@@ -6509,7 +6722,7 @@ static inline void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb, int
ms->infcs = PPP_INITFCS;
ms->readn[ms->inreadbuf] = ms->readidx[ms->inreadbuf];
#ifdef CONFIG_DAHDI_DEBUG
- printk("EOF, len is %d\n", ms->readn[ms->inreadbuf]);
+ module_printk(KERN_NOTICE, "EOF, len is %d\n", ms->readn[ms->inreadbuf]);
#endif
#if defined(CONFIG_DAHDI_NET) || defined(CONFIG_DAHDI_PPP)
if (ms->flags & (DAHDI_FLAG_NETDEV | DAHDI_FLAG_PPP)) {
@@ -6554,7 +6767,7 @@ static inline void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb, int
#ifdef CONFIG_DAHDI_PPP
if (!ms->do_ppp_error)
#endif
- printk("Memory squeeze, dropped one\n");
+ module_printk(KERN_NOTICE, "Memory squeeze, dropped one\n");
#endif
}
}
@@ -6574,23 +6787,20 @@ static inline void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb, int
if (ms->flags & DAHDI_FLAG_MTP2) {
comparemessage = (ms->inreadbuf - 1) & (ms->numbufs - 1);
-
- res = memcmp(ms->readbuf[comparemessage], ms->readbuf[ms->inreadbuf], ms->readn[ms->inreadbuf]);
- }
-
- if ((ms->flags & DAHDI_FLAG_MTP2) && !res) {
- /* Our messages are the same, so discard -
- * Don't advance buffers, reset indexes and buffer sizes. */
- ms->readn[ms->inreadbuf] = 0;
- ms->readidx[ms->inreadbuf] = 0;
+ if (!memcmp(ms->readbuf[comparemessage], ms->readbuf[ms->inreadbuf], ms->readn[ms->inreadbuf])) {
+ /* Our messages are the same, so discard -
+ * Don't advance buffers, reset indexes and buffer sizes. */
+ ms->readn[ms->inreadbuf] = 0;
+ ms->readidx[ms->inreadbuf] = 0;
+ }
} else {
ms->inreadbuf = (ms->inreadbuf + 1) % ms->numbufs;
if (ms->inreadbuf == ms->outreadbuf) {
/* Whoops, we're full, and have no where else
- to store into at the moment. We'll drop it
- until there's a buffer available */
+ to store into at the moment. We'll drop it
+ until there's a buffer available */
#ifdef CONFIG_DAHDI_DEBUG
- printk("Out of storage space\n");
+ module_printk(KERN_NOTICE, "Out of storage space\n");
#endif
ms->inreadbuf = -1;
/* Enable the receiver in case they've got POLICY_WHEN_FULL */
@@ -6613,7 +6823,7 @@ out in the later versions, and is put back now. */
/* Notify a blocked reader that there is data available
to be read, unless we're waiting for it to be full */
#ifdef CONFIG_DAHDI_DEBUG
- printk("Notifying reader data in block %d\n", oldbuf);
+ module_printk(KERN_NOTICE, "Notifying reader data in block %d\n", oldbuf);
#endif
wake_up_interruptible(&ms->readbufq);
wake_up_interruptible(&ms->sel);
@@ -6646,12 +6856,12 @@ out in the later versions, and is put back now. */
tasklet_schedule(&ms->ppp_calls);
} else
#endif
-
- if ((ms->flags & DAHDI_FLAG_OPEN) && !ss->span->alarms)
+ if (test_bit(DAHDI_FLAGBIT_OPEN, &ms->flags) && !ss->span->alarms) {
/* Notify the receiver... */
- __qevent(ss->master, abort);
+ __qevent(ss->master, abort);
+ }
#if 0
- printk("torintr_receive: Aborted %d bytes of frame on %d\n", amt, ss->master);
+ module_printk(KERN_NOTICE, "torintr_receive: Aborted %d bytes of frame on %d\n", amt, ss->master);
#endif
}
@@ -6687,7 +6897,7 @@ out in the later versions, and is put back now. */
if (!tmp || (tmp[0] != 0xff) || (tmp[1] != 0x03)) {
/* Invalid SKB -- drop */
if (tmp)
- printk("Received invalid SKB (%02x, %02x)\n", tmp[0], tmp[1]);
+ module_printk(KERN_NOTICE, "Received invalid SKB (%02x, %02x)\n", tmp[0], tmp[1]);
dev_kfree_skb_irq(skb);
} else {
skb_queue_tail(&ms->ppp_rq, skb);
@@ -6707,7 +6917,7 @@ static void __dahdi_hdlc_abort(struct dahdi_chan *ss, int event)
{
if (ss->inreadbuf >= 0)
ss->readidx[ss->inreadbuf] = 0;
- if ((ss->flags & DAHDI_FLAG_OPEN) && !ss->span->alarms)
+ if (test_bit(DAHDI_FLAGBIT_OPEN, &ss->flags) && !ss->span->alarms)
__qevent(ss->master, event);
}
@@ -6728,7 +6938,7 @@ extern void dahdi_hdlc_putbuf(struct dahdi_chan *ss, unsigned char *rxb, int byt
spin_lock_irqsave(&ss->lock, flags);
if (ss->inreadbuf < 0) {
#ifdef CONFIG_DAHDI_DEBUG
- printk("No place to receive HDLC frame\n");
+ module_printk(KERN_NOTICE, "No place to receive HDLC frame\n");
#endif
spin_unlock_irqrestore(&ss->lock, flags);
return;
@@ -6746,7 +6956,7 @@ extern void dahdi_hdlc_putbuf(struct dahdi_chan *ss, unsigned char *rxb, int byt
/* Something isn't fit into buffer */
if (bytes) {
#ifdef CONFIG_DAHDI_DEBUG
- printk("HDLC frame isn't fit into buffer space\n");
+ module_printk(KERN_NOTICE, "HDLC frame isn't fit into buffer space\n");
#endif
__dahdi_hdlc_abort(ss, DAHDI_EVENT_OVERRUN);
}
@@ -6763,7 +6973,7 @@ extern void dahdi_hdlc_finish(struct dahdi_chan *ss)
if ((oldreadbuf = ss->inreadbuf) < 0) {
#ifdef CONFIG_DAHDI_DEBUG
- printk("No buffers to finish\n");
+ module_printk(KERN_NOTICE, "No buffers to finish\n");
#endif
spin_unlock_irqrestore(&ss->lock, flags);
return;
@@ -6771,7 +6981,7 @@ extern void dahdi_hdlc_finish(struct dahdi_chan *ss)
if (!ss->readidx[ss->inreadbuf]) {
#ifdef CONFIG_DAHDI_DEBUG
- printk("Empty HDLC frame received\n");
+ module_printk(KERN_NOTICE, "Empty HDLC frame received\n");
#endif
spin_unlock_irqrestore(&ss->lock, flags);
return;
@@ -6782,7 +6992,7 @@ extern void dahdi_hdlc_finish(struct dahdi_chan *ss)
if (ss->inreadbuf == ss->outreadbuf) {
ss->inreadbuf = -1;
#ifdef CONFIG_DAHDI_DEBUG
- printk("Notifying reader data in block %d\n", oldreadbuf);
+ module_printk(KERN_NOTICE, "Notifying reader data in block %d\n", oldreadbuf);
#endif
ss->rxdisable = 0;
}
@@ -6958,7 +7168,7 @@ static unsigned int dahdi_poll(struct file *file, struct poll_table_struct *wait
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_poll(file, wait_table, chan->channo);
@@ -7222,7 +7432,7 @@ int dahdi_receive(struct dahdi_span *span)
{
if (span->chans[x].pulsecount > 12) {
- printk("Got pulse digit %d on %s???\n",
+ module_printk(KERN_NOTICE, "Got pulse digit %d on %s???\n",
span->chans[x].pulsecount,
span->chans[x].name);
} else if (span->chans[x].pulsecount > 11) {
@@ -7327,12 +7537,8 @@ int dahdi_receive(struct dahdi_span *span)
MODULE_AUTHOR("Mark Spencer <markster@digium.com>");
MODULE_DESCRIPTION("DAHDI Telephony Interface");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
-#ifdef MODULE_VERSION
+MODULE_LICENSE("GPL v2");
MODULE_VERSION(DAHDI_VERSION);
-#endif
module_param(debug, int, 0644);
module_param(deftaps, int, 0644);
@@ -7370,17 +7576,17 @@ static void watchdog_check(unsigned long ignored)
(spans[x]->watchstate == DAHDI_WATCHSTATE_UNKNOWN)) {
spans[x]->watchstate = DAHDI_WATCHSTATE_RECOVERING;
if (spans[x]->watchdog) {
- printk("Kicking span %s\n", spans[x]->name);
+ module_printk(KERN_NOTICE, "Kicking span %s\n", spans[x]->name);
spans[x]->watchdog(spans[x], DAHDI_WATCHDOG_NOINTS);
} else {
- printk("Span %s is dead with no revival\n", spans[x]->name);
+ module_printk(KERN_NOTICE, "Span %s is dead with no revival\n", spans[x]->name);
spans[x]->watchstate = DAHDI_WATCHSTATE_FAILED;
}
}
} else {
if ((spans[x]->watchstate != DAHDI_WATCHSTATE_OK) &&
(spans[x]->watchstate != DAHDI_WATCHSTATE_UNKNOWN))
- printk("Span %s is alive!\n", spans[x]->name);
+ module_printk(KERN_NOTICE, "Span %s is alive!\n", spans[x]->name);
spans[x]->watchstate = DAHDI_WATCHSTATE_OK;
}
spans[x]->watchcounter = DAHDI_WATCHDOG_INIT;
@@ -7388,7 +7594,7 @@ static void watchdog_check(unsigned long ignored)
}
local_irq_restore(flags);
if (!wdcheck) {
- printk("DAHDI watchdog on duty!\n");
+ module_printk(KERN_NOTICE, "watchdog on duty!\n");
wdcheck=1;
}
mod_timer(&watchdogtimer, jiffies + 2);
@@ -7414,22 +7620,18 @@ static void __exit watchdog_cleanup(void)
int dahdi_register_chardev(struct dahdi_chardev *dev)
{
-#ifdef CONFIG_DAHDI_UDEV
char udevname[strlen(dev->name) + 3];
strcpy(udevname, "dahdi");
strcat(udevname, dev->name);
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor), NULL, udevname);
-#endif /* CONFIG_DAHDI_UDEV */
return 0;
}
int dahdi_unregister_chardev(struct dahdi_chardev *dev)
{
-#ifdef CONFIG_DAHDI_UDEV
class_device_destroy(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor));
-#endif /* CONFIG_DAHDI_UDEV */
return 0;
}
@@ -7441,26 +7643,22 @@ static int __init dahdi_init(void) {
proc_entries[0] = proc_mkdir("dahdi", NULL);
#endif
-#ifdef CONFIG_DAHDI_UDEV /* udev support functions */
dahdi_class = class_create(THIS_MODULE, "dahdi");
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 253), NULL, "dahditimer");
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 254), NULL, "dahdichannel");
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 255), NULL, "dahdipseudo");
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 0), NULL, "dahdictl");
-#endif /* CONFIG_DAHDI_UDEV */
if ((res = register_chrdev(DAHDI_MAJOR, "dahdi", &dahdi_fops))) {
- printk(KERN_ERR "Unable to register DAHDI character device handler on %d\n", DAHDI_MAJOR);
+ module_printk(KERN_ERR, "Unable to register DAHDI character device handler on %d\n", DAHDI_MAJOR);
return res;
}
- printk(KERN_INFO "DAHDI Telephony Interface Registered on major %d\n", DAHDI_MAJOR);
- printk(KERN_INFO "DAHDI Version: %s\n", DAHDI_VERSION);
- echo_can_init();
+ module_printk(KERN_INFO, "Telephony Interface Registered on major %d\n", DAHDI_MAJOR);
+ module_printk(KERN_INFO, "Version: %s\n", DAHDI_VERSION);
dahdi_conv_init();
fasthdlc_precalc();
rotate_sums();
- rwlock_init(&chan_lock);
#ifdef CONFIG_DAHDI_WATCHDOG
watchdog_init();
#endif
@@ -7470,31 +7668,27 @@ static int __init dahdi_init(void) {
static void __exit dahdi_cleanup(void) {
int x;
+ unregister_chrdev(DAHDI_MAJOR, "dahdi");
+
#ifdef CONFIG_PROC_FS
remove_proc_entry("dahdi", NULL);
#endif
- printk(KERN_INFO "DAHDI Telephony Interface Unloaded\n");
+ module_printk(KERN_INFO, "Telephony Interface Unloaded\n");
for (x = 0; x < DAHDI_TONE_ZONE_MAX; x++) {
if (tone_zones[x])
kfree(tone_zones[x]);
}
-#ifdef CONFIG_DAHDI_UDEV
class_device_destroy(dahdi_class, MKDEV(DAHDI_MAJOR, 253)); /* timer */
class_device_destroy(dahdi_class, MKDEV(DAHDI_MAJOR, 254)); /* channel */
class_device_destroy(dahdi_class, MKDEV(DAHDI_MAJOR, 255)); /* pseudo */
class_device_destroy(dahdi_class, MKDEV(DAHDI_MAJOR, 0)); /* ctl */
class_destroy(dahdi_class);
-#endif /* CONFIG_DAHDI_UDEV */
-
- unregister_chrdev(DAHDI_MAJOR, "dahdi");
#ifdef CONFIG_DAHDI_WATCHDOG
watchdog_cleanup();
#endif
-
- echo_can_shutdown();
}
module_init(dahdi_init);
diff --git a/drivers/dahdi/dahdi_config.h b/drivers/dahdi/dahdi_config.h
index 327182b..617b4aa 100644
--- a/drivers/dahdi/dahdi_config.h
+++ b/drivers/dahdi/dahdi_config.h
@@ -54,61 +54,22 @@
*/
/* #define CONFIG_DAHDI_MMX */
-/** If defined: the user must define exactly one ECHO_CAN_ var: */
-#ifndef ECHO_CAN_FROMENV
-
-/*
- * Pick your echo canceller: MARK2, MARK3, STEVE, or STEVE2 :)
- *
- */
-/* #define ECHO_CAN_STEVE */
-/* #define ECHO_CAN_STEVE2 */
-/* #define ECHO_CAN_KB1 */
-/* This is the new latest and greatest */
-#define ECHO_CAN_MG2
-
-/*
- * This is only technically an "echo canceller"...
- * It purposely drops 2 out of 3 samples and sounds horrible.
- * You really only want this for testing "echo cancelled" audio.
- */
-/* #define ECHO_CAN_JP1 */
-
-/*
- * Uncomment for aggressive residual echo suppression under
- * MARK2, KB1, and MG2 echo canceler
- */
-/* #define AGGRESSIVE_SUPPRESSOR */
-#endif /* ifndef ECHO_CAN_FROMENV */
/*
* Define to turn off the echo canceler disable tone detector,
- * which will cause dahdi to ignore the 2100 Hz echo cancel disable
+ * which will cause DAHDI to ignore the 2100 Hz echo cancel disable
* tone.
*/
/* #define NO_ECHOCAN_DISABLE */
-/* udev support */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,1)
-#define CONFIG_DAHDI_UDEV
-#endif
-
/* We now use the linux kernel config to detect which options to use */
/* You can still override them below */
#if defined(CONFIG_HDLC) || defined(CONFIG_HDLC_MODULE)
-/* #define CONFIG_DAHDI_NET */ /* NEVER implicitly turn on CONFIG_DAHDI_NET */
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,20)
-#define CONFIG_OLD_HDLC_API
-#else
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,23)
-/* Starting with 2.4.23 the kernel hdlc api changed again */
-/* Now we have to use hdlc_type_trans(skb, dev) instead of htons(ETH_P_HDLC) */
#define DAHDI_HDLC_TYPE_TRANS
-#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3)
#define HDLC_MAINTAINERS_ARE_MORE_STUPID_THAN_I_THOUGHT
#endif
#endif
-#endif
+
#ifdef CONFIG_PPP
#define CONFIG_DAHDI_PPP
#endif
@@ -185,7 +146,7 @@
/*
* Enable sync_tick() calls. Allows low-level drivers to synchronize
- * their internal clocks to the dahdi master clock.
+ * their internal clocks to the DAHDI master clock.
*/
#define DAHDI_SYNC_TICK
diff --git a/drivers/dahdi/dahdi_dummy.c b/drivers/dahdi/dahdi_dummy.c
index 8e9da8a..8263633 100644
--- a/drivers/dahdi/dahdi_dummy.c
+++ b/drivers/dahdi/dahdi_dummy.c
@@ -332,6 +332,4 @@ module_param(rtc_rate, int, 0600);
MODULE_DESCRIPTION("Dummy DAHDI Driver");
MODULE_AUTHOR("Robert Pleh <robert.pleh@hermes.si>");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/dahdi/dahdi_dynamic.c b/drivers/dahdi/dahdi_dynamic.c
index 577b5d7..f29bbda 100644
--- a/drivers/dahdi/dahdi_dynamic.c
+++ b/drivers/dahdi/dahdi_dynamic.c
@@ -626,7 +626,7 @@ static int create_dynamic(DAHDI_DYNAMIC_SPAN *zds)
/* Try loading the right module */
char fn[80];
spin_unlock_irqrestore(&dlock, flags);
- sprintf(fn, "ztd-%s", zds->driver);
+ sprintf(fn, "dahdi_dynamic_%s", zds->driver);
request_module(fn);
spin_lock_irqsave(&dlock, flags);
ztd = find_driver(zds->driver);
@@ -844,9 +844,7 @@ module_param(debug, int, 0600);
MODULE_DESCRIPTION("DAHDI Dynamic Span Support");
MODULE_AUTHOR("Mark Spencer <markster@digium.com>");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
module_init(ztdynamic_init);
module_exit(ztdynamic_cleanup);
diff --git a/drivers/dahdi/dahdi_dynamic_eth.c b/drivers/dahdi/dahdi_dynamic_eth.c
index 32ab956..e36522b 100644
--- a/drivers/dahdi/dahdi_dynamic_eth.c
+++ b/drivers/dahdi/dahdi_dynamic_eth.c
@@ -429,9 +429,7 @@ static void __exit ztdeth_exit(void)
MODULE_DESCRIPTION("DAHDI Dynamic TDMoE Support");
MODULE_AUTHOR("Mark Spencer <markster@digium.com>");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
module_init(ztdeth_init);
module_exit(ztdeth_exit);
diff --git a/drivers/dahdi/dahdi_dynamic_loc.c b/drivers/dahdi/dahdi_dynamic_loc.c
index 7ed9d7e..6d6262b 100644
--- a/drivers/dahdi/dahdi_dynamic_loc.c
+++ b/drivers/dahdi/dahdi_dynamic_loc.c
@@ -263,6 +263,5 @@ static struct dahdi_dynamic_driver ztd_local = {
module_init(ztdlocal_init);
module_exit(ztdlocal_exit);
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/dahdi/dahdi_echocan_jpah.c b/drivers/dahdi/dahdi_echocan_jpah.c
new file mode 100644
index 0000000..cddbc01
--- /dev/null
+++ b/drivers/dahdi/dahdi_echocan_jpah.c
@@ -0,0 +1,130 @@
+/*
+ * ECHO_CAN_JPAH
+ *
+ * by Jason Parker
+ *
+ * Based upon mg2ec.h - sort of.
+ * This "echo can" will completely hose your audio.
+ * Don't use it unless you're absolutely sure you know what you're doing.
+ *
+ * Copyright (C) 2007-2008, Digium, Inc.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/moduleparam.h>
+
+#include <dahdi/kernel.h>
+
+static int debug;
+
+#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 {
+ int blah;
+};
+
+static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
+ struct echo_can_state **ec)
+{
+ unsigned int x;
+ char *c;
+
+ 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);
+
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void echo_can_free(struct echo_can_state *ec)
+{
+ kfree(ec);
+}
+
+static void echo_can_update(struct echo_can_state *ec, short *iref, short *isig)
+{
+ unsigned int x;
+
+ for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
+ if (ec->blah < 2) {
+ ec->blah++;
+
+ *isig++ = 0;
+ } else {
+ ec->blah = 0;
+
+ isig++;
+ }
+ }
+}
+
+static int echo_can_traintap(struct echo_can_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)) {
+ module_printk(KERN_ERR, "could not register with DAHDI core\n");
+
+ return -EPERM;
+ }
+
+ module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
+
+ return 0;
+}
+
+static void __exit mod_exit(void)
+{
+ dahdi_unregister_echocan(&me);
+}
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+
+MODULE_DESCRIPTION("DAHDI Jason Parker Audio Hoser");
+MODULE_AUTHOR("Jason Parker <jparker@digium.com>");
+MODULE_LICENSE("GPL v2");
+
+module_init(mod_init);
+module_exit(mod_exit);
diff --git a/drivers/dahdi/kb1ec.h b/drivers/dahdi/dahdi_echocan_kb1.c
index e56e89e..391ca51 100644
--- a/drivers/dahdi/kb1ec.h
+++ b/drivers/dahdi/dahdi_echocan_kb1.c
@@ -3,7 +3,7 @@
*
* by Kris Boutilier
*
- * Based upon mech2.h
+ * Based upon mec2.h
*
* Copyright (C) 2002, Digium, Inc.
*
@@ -23,15 +23,21 @@
*
*/
-#ifndef _MARK2_ECHO_H
-#define _MARK2_ECHO_H
-
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
#include <linux/ctype.h>
+#include <linux/moduleparam.h>
+
+#include <dahdi/kernel.h>
-#define MALLOC(a) kmalloc((a), GFP_KERNEL)
-#define FREE(a) kfree(a)
+static int debug;
+static int aggressive;
+
+#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)
/* Uncomment to provide summary statistics for overall echo can performance every 4000 samples */
/* #define MEC2_STATS 4000 */
@@ -42,8 +48,71 @@
/* Get optimized routines for math */
#include "arith.h"
-/* Bring in definitions for the various constants and thresholds */
-#include "kb1ec_const.h"
+/*
+ Important constants for tuning kb1 echo can
+ */
+
+/* Convergence (aka. adaptation) speed -- higher means slower */
+#define DEFAULT_BETA1_I 2048
+
+/* Constants for various power computations */
+#define DEFAULT_SIGMA_LY_I 7
+#define DEFAULT_SIGMA_LU_I 7
+#define DEFAULT_ALPHA_ST_I 5 /* near-end speech detection sensitivity factor */
+#define DEFAULT_ALPHA_YT_I 5
+
+#define DEFAULT_CUTOFF_I 128
+
+/* Define the near-end speech hangover counter: if near-end speech
+ * is declared, hcntr is set equal to hangt (see pg. 432)
+ */
+#define DEFAULT_HANGT 600 /* in samples, so 600 samples = 75ms */
+
+/* define the residual error suppression threshold */
+#define DEFAULT_SUPPR_I 16 /* 16 = -24db */
+
+/* This is the minimum reference signal power estimate level
+ * that will result in filter adaptation.
+ * If this is too low then background noise will cause the filter
+ * coefficients to constantly be updated.
+ */
+#define MIN_UPDATE_THRESH_I 4096
+
+/* The number of samples used to update coefficients using the
+ * the block update method (M). It should be related back to the
+ * length of the echo can.
+ * ie. it only updates coefficients when (sample number MOD default_m) = 0
+ *
+ * Getting this wrong may cause an oops. Consider yourself warned!
+ */
+#define DEFAULT_M 16 /* every 16th sample */
+
+/* If AGGRESSIVE supression is enabled, then we start cancelling residual
+ * echos again even while there is potentially the very end of a near-side
+ * signal present.
+ * This defines how many samples of DEFAULT_HANGT can remain before we
+ * kick back in
+ */
+#define AGGRESSIVE_HCNTR 160 /* in samples, so 160 samples = 20ms */
+
+
+/***************************************************************/
+/* The following knobs are not implemented in the current code */
+
+/* we need a dynamic level of suppression varying with the ratio of the
+ power of the echo to the power of the reference signal this is
+ done so that we have a smoother background.
+ we have a higher suppression when the power ratio is closer to
+ suppr_ceil and reduces logarithmically as we approach suppr_floor.
+ */
+#define SUPPR_FLOOR -64
+#define SUPPR_CEIL -24
+
+/* in a second departure, we calculate the residual error suppression
+ * as a percentage of the reference signal energy level. The threshold
+ * is defined in terms of dB below the reference signal.
+ */
+#define RES_SUPR_FACTOR -20
#ifndef NULL
#define NULL 0
@@ -133,20 +202,6 @@ struct echo_can_state {
unsigned int aggressive:1;
};
-static void echo_can_init(void)
-{
- printk("DAHDI Echo Canceller: KB1\n");
-}
-
-static void echo_can_identify(char *buf, size_t len)
-{
- dahdi_copy_string(buf, "KB1", len);
-}
-
-static void echo_can_shutdown(void)
-{
-}
-
static inline void init_cb_s(echo_can_cb_s *cb, int len, void *where)
{
cb->buf_d = (short *)where;
@@ -238,14 +293,13 @@ static inline void init_cc(struct echo_can_state *ec, int N, int maxy, int maxu)
}
-static inline void echo_can_free(struct echo_can_state *ec)
+static void echo_can_free(struct echo_can_state *ec)
{
- FREE(ec);
+ kfree(ec);
}
-static inline short echo_can_update(struct echo_can_state *ec, short iref, short isig)
+static inline short sample_update(struct echo_can_state *ec, short iref, short isig)
{
-
/* Declare local variables that are used more than once */
/* ... */
int k;
@@ -521,6 +575,17 @@ static inline short echo_can_update(struct echo_can_state *ec, short iref, short
return u;
}
+static void echo_can_update(struct echo_can_state *ec, short *iref, short *isig)
+{
+ unsigned int x;
+ short result;
+
+ for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
+ result = sample_update(ec, *iref, *isig);
+ *isig++ = result;
+ }
+}
+
static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
struct echo_can_state **ec)
{
@@ -548,14 +613,12 @@ static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocan
2 * sizeof(short) * (maxu) + /* u_s */
2 * sizeof(short) * ecp->tap_length; /* y_tilde_s */
- if (!(*ec = MALLOC(size)))
+ if (!(*ec = kmalloc(size, GFP_KERNEL)))
return -ENOMEM;
memset(*ec, 0, size);
-#ifdef AGGRESSIVE_SUPPRESSOR
- (*ec)->aggressive = 1;
-#endif
+ (*ec)->aggressive = aggressive;
for (x = 0; x < ecp->param_count; x++) {
for (c = p[x].name; *c; c++)
@@ -575,7 +638,7 @@ static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocan
return 0;
}
-static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
+static int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
{
/* Set the hangover counter to the length of the can to
* avoid adjustments occuring immediately after initial forced training
@@ -594,4 +657,39 @@ static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short va
return 0;
}
-#endif
+static const struct dahdi_echocan me = {
+ .name = "KB1",
+ .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)) {
+ module_printk(KERN_ERR, "could not register with DAHDI core\n");
+
+ return -EPERM;
+ }
+
+ module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
+
+ return 0;
+}
+
+static void __exit mod_exit(void)
+{
+ dahdi_unregister_echocan(&me);
+}
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+module_param(aggressive, int, S_IRUGO | S_IWUSR);
+
+MODULE_DESCRIPTION("DAHDI 'KB1' Echo Canceler");
+MODULE_AUTHOR("Kris Boutilier");
+MODULE_LICENSE("GPL v2");
+
+module_init(mod_init);
+module_exit(mod_exit);
diff --git a/drivers/dahdi/mg2ec.h b/drivers/dahdi/dahdi_echocan_mg2.c
index 55a7caa..9c7d8c6 100644
--- a/drivers/dahdi/mg2ec.h
+++ b/drivers/dahdi/dahdi_echocan_mg2.c
@@ -23,15 +23,21 @@
*
*/
-#ifndef _MG2_ECHO_H
-#define _MG2_ECHO_H
-
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
#include <linux/ctype.h>
+#include <linux/moduleparam.h>
+
+#include <dahdi/kernel.h>
-#define MALLOC(a) kmalloc((a), GFP_KERNEL)
-#define FREE(a) kfree(a)
+static int debug;
+static int aggressive;
+
+#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)
#define ABS(a) abs(a!=-32768?a:-32767)
@@ -56,8 +62,87 @@
/* Get optimized routines for math */
#include "arith.h"
-/* Bring in definitions for the various constants and thresholds */
-#include "mg2ec_const.h"
+/*
+ Important constants for tuning mg2 echo can
+ */
+
+/* Convergence (aka. adaptation) speed -- higher means slower */
+#define DEFAULT_BETA1_I 2048
+
+/* Constants for various power computations */
+#define DEFAULT_SIGMA_LY_I 7
+#define DEFAULT_SIGMA_LU_I 7
+#define DEFAULT_ALPHA_ST_I 5 /* near-end speech detection sensitivity factor */
+#define DEFAULT_ALPHA_YT_I 5
+
+#define DEFAULT_CUTOFF_I 128
+
+/* Define the near-end speech hangover counter: if near-end speech
+ * is declared, hcntr is set equal to hangt (see pg. 432)
+ */
+#define DEFAULT_HANGT 600 /* in samples, so 600 samples = 75ms */
+
+/* define the residual error suppression threshold */
+#define DEFAULT_SUPPR_I 16 /* 16 = -24db */
+
+/* This is the minimum reference signal power estimate level
+ * that will result in filter adaptation.
+ * If this is too low then background noise will cause the filter
+ * coefficients to constantly be updated.
+ */
+#define MIN_UPDATE_THRESH_I 2048
+
+/* The number of samples used to update coefficients using the
+ * the block update method (M). It should be related back to the
+ * length of the echo can.
+ * ie. it only updates coefficients when (sample number MOD default_m) = 0
+ *
+ * Getting this wrong may cause an oops. Consider yourself warned!
+ */
+#define DEFAULT_M 16 /* every 16th sample */
+
+/* If AGGRESSIVE supression is enabled, then we start cancelling residual
+ * echos again even while there is potentially the very end of a near-side
+ * signal present.
+ * This defines how many samples of DEFAULT_HANGT can remain before we
+ * kick back in
+ */
+#define AGGRESSIVE_HCNTR 160 /* in samples, so 160 samples = 20ms */
+
+/* Treat sample as error if it has a different sign as the
+ * input signal and is this number larger in ABS() as
+ * the input-signal */
+#define MAX_SIGN_ERROR 3000
+
+/* Number of coefficients really used for calculating the
+ * simulated echo. The value specifies how many of the
+ * biggest coefficients are used for calculating rs.
+ * This helps on long echo-tails by artificially limiting
+ * the number of coefficients for the calculation and
+ * preventing overflows.
+ * Comment this to deactivate the code */
+#define USED_COEFFS 64
+
+/* Backup coefficients every this number of samples */
+#define BACKUP 256
+
+/***************************************************************/
+/* The following knobs are not implemented in the current code */
+
+/* we need a dynamic level of suppression varying with the ratio of the
+ power of the echo to the power of the reference signal this is
+ done so that we have a smoother background.
+ we have a higher suppression when the power ratio is closer to
+ suppr_ceil and reduces logarithmically as we approach suppr_floor.
+ */
+#define SUPPR_FLOOR -64
+#define SUPPR_CEIL -24
+
+/* in a second departure, we calculate the residual error suppression
+ * as a percentage of the reference signal energy level. The threshold
+ * is defined in terms of dB below the reference signal.
+ */
+#define RES_SUPR_FACTOR -20
#define DC_NORMALIZE
@@ -159,20 +244,6 @@ struct echo_can_state {
};
-static void echo_can_init(void)
-{
- printk("DAHDI Echo Canceller: MG2\n");
-}
-
-static void echo_can_identify(char *buf, size_t len)
-{
- dahdi_copy_string(buf, "MG2", len);
-}
-
-static void echo_can_shutdown(void)
-{
-}
-
static inline void init_cb_s(echo_can_cb_s *cb, int len, void *where)
{
cb->buf_d = (short *)where;
@@ -270,12 +341,12 @@ static inline void init_cc(struct echo_can_state *ec, int N, int maxy, int maxu)
}
-static inline void echo_can_free(struct echo_can_state *ec)
+static void echo_can_free(struct echo_can_state *ec)
{
#if defined(DC_NORMALIZE) && defined(MEC2_DCBIAS_MESSAGE)
printk("EC: DC bias calculated: %d V\n", ec->dc_estimate >> 15);
#endif
- FREE(ec);
+ kfree(ec);
}
#ifdef DC_NORMALIZE
@@ -286,9 +357,8 @@ short inline dc_removal(int *dc_estimate, short samp)
}
#endif
-static inline short echo_can_update(struct echo_can_state *ec, short iref, short isig)
+static inline short sample_update(struct echo_can_state *ec, short iref, short isig)
{
-
/* Declare local variables that are used more than once */
/* ... */
int k;
@@ -642,6 +712,17 @@ static inline short echo_can_update(struct echo_can_state *ec, short iref, short
return u;
}
+static void echo_can_update(struct echo_can_state *ec, short *iref, short *isig)
+{
+ unsigned int x;
+ short result;
+
+ for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
+ result = sample_update(ec, *iref, *isig);
+ *isig++ = result;
+ }
+}
+
static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
struct echo_can_state **ec)
{
@@ -670,14 +751,12 @@ static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocan
2 * sizeof(short) * (maxu) + /* u_s */
2 * sizeof(short) * ecp->tap_length; /* y_tilde_s */
- if (!(*ec = MALLOC(size)))
+ if (!(*ec = kmalloc(size, GFP_KERNEL)))
return -ENOMEM;
memset(*ec, 0, size);
-#ifdef AGGRESSIVE_SUPPRESSOR
- (*ec)->aggressive = 1;
-#endif
+ (*ec)->aggressive = aggressive;
for (x = 0; x < ecp->param_count; x++) {
for (c = p[x].name; *c; c++)
@@ -697,7 +776,7 @@ static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocan
return 0;
}
-static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
+static int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
{
/* Set the hangover counter to the length of the can to
* avoid adjustments occuring immediately after initial forced training
@@ -722,4 +801,39 @@ static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short va
return 0;
}
-#endif
+static const struct dahdi_echocan me = {
+ .name = "MG2",
+ .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)) {
+ module_printk(KERN_ERR, "could not register with DAHDI core\n");
+
+ return -EPERM;
+ }
+
+ module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
+
+ return 0;
+}
+
+static void __exit mod_exit(void)
+{
+ dahdi_unregister_echocan(&me);
+}
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+module_param(aggressive, int, S_IRUGO | S_IWUSR);
+
+MODULE_DESCRIPTION("DAHDI 'MG2' Echo Canceler");
+MODULE_AUTHOR("Michael Gernoth");
+MODULE_LICENSE("GPL v2");
+
+module_init(mod_init);
+module_exit(mod_exit);
diff --git a/drivers/dahdi/sec.h b/drivers/dahdi/dahdi_echocan_sec.c
index 4c8bd69..dd0a7f4 100644
--- a/drivers/dahdi/sec.h
+++ b/drivers/dahdi/dahdi_echocan_sec.c
@@ -37,22 +37,20 @@
Improve double talk detector (iterative!)
*/
-#ifndef _DAHDI_SEC_H
-#define _DAHDI_SEC_H
-
-#ifdef __KERNEL__
#include <linux/kernel.h>
#include <linux/slab.h>
-#define MALLOC(a) kmalloc((a), GFP_KERNEL)
-#define FREE(a) kfree(a)
-#else
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <string.h>
-#define MALLOC(a) malloc(a)
-#define FREE(a) free(a)
-#endif
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/moduleparam.h>
+
+#include <dahdi/kernel.h>
+
+static int debug;
+
+#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)
#include "arith.h"
@@ -100,23 +98,6 @@ struct echo_can_state
was skipped, for test purposes */
};
-static void echo_can_init(void)
-{
- printk("DAHDI Echo Canceller: STEVE%s\n", DAHDI_ECHO_AGGRESSIVE);
-}
-
-static void echo_can_identify(char *buf, size_t len)
-{
- dahdi_copy_string(buf, "STEVE", len);
-}
-
-static void echo_can_shutdown(void)
-{
-}
-
-static void echo_can_free(struct echo_can_state *ec);
-static int16_t echo_can_update(struct echo_can_state *ec, int16_t tx, int16_t rx);
-
/* Original parameters :
#define MIN_TX_POWER_FOR_ADAPTION 256
#define MIN_RX_POWER_FOR_ADAPTION 128
@@ -142,7 +123,7 @@ static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocan
size = sizeof(**ec) + ecp->tap_length * sizeof(int32_t) + ecp->tap_length * 3 * sizeof(int16_t);
- if (!(*ec = MALLOC(size)))
+ if (!(*ec = kmalloc(size, GFP_KERNEL)))
return -ENOMEM;
memset(*ec, 0, size);
@@ -165,13 +146,13 @@ static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocan
}
/*- End of function --------------------------------------------------------*/
-static inline void echo_can_free(struct echo_can_state *ec)
+static void echo_can_free(struct echo_can_state *ec)
{
- FREE(ec);
+ kfree(ec);
}
/*- End of function --------------------------------------------------------*/
-static inline int16_t echo_can_update(struct echo_can_state *ec, int16_t tx, int16_t rx)
+static inline int16_t sample_update(struct echo_can_state *ec, int16_t tx, int16_t rx)
{
int32_t echo_value;
int clean_rx;
@@ -292,7 +273,19 @@ static inline int16_t echo_can_update(struct echo_can_state *ec, int16_t tx, int
}
/*- End of function --------------------------------------------------------*/
-static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
+static void echo_can_update(struct echo_can_state *ec, short *iref, short *isig)
+{
+ unsigned int x;
+ short result;
+
+ for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
+ result = sample_update(ec, *iref, *isig);
+ *isig++ = result;
+ }
+}
+/*- End of function --------------------------------------------------------*/
+
+static int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
{
/* Reset hang counter to avoid adjustments after
initial forced training */
@@ -305,6 +298,40 @@ static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short va
return 1;
return 0;
}
+/*- End of function --------------------------------------------------------*/
-/*- End of file ------------------------------------------------------------*/
-#endif
+static const struct dahdi_echocan me = {
+ .name = "SEC",
+ .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)) {
+ module_printk(KERN_ERR, "could not register with DAHDI core\n");
+
+ return -EPERM;
+ }
+
+ module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
+
+ return 0;
+}
+
+static void __exit mod_exit(void)
+{
+ dahdi_unregister_echocan(&me);
+}
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+
+MODULE_DESCRIPTION("DAHDI 'SEC' Echo Canceler");
+MODULE_AUTHOR("Steve Underwood <steveu@coppice.org>");
+MODULE_LICENSE("GPL");
+
+module_init(mod_init);
+module_exit(mod_exit);
diff --git a/drivers/dahdi/sec-2.h b/drivers/dahdi/dahdi_echocan_sec2.c
index 2a498e1..399d714 100644
--- a/drivers/dahdi/sec-2.h
+++ b/drivers/dahdi/dahdi_echocan_sec2.c
@@ -36,22 +36,20 @@
Improve double talk detector (iterative!)
*/
-#ifndef _DAHDI_SEC_H
-#define _DAHDI_SEC_H
-
-#ifdef __KERNEL__
#include <linux/kernel.h>
#include <linux/slab.h>
-#define MALLOC(a) kmalloc((a), GFP_KERNEL)
-#define FREE(a) kfree(a)
-#else
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <string.h>
-#define MALLOC(a) malloc(a)
-#define FREE(a) free(a)
-#endif
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/moduleparam.h>
+
+#include <dahdi/kernel.h>
+
+static int debug;
+
+#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)
#include "fir.h"
@@ -97,23 +95,6 @@ struct echo_can_state
was skipped, for test purposes */
};
-static void echo_can_free(struct echo_can_state *ec);
-static int16_t echo_can_update(struct echo_can_state *ec, int16_t tx, int16_t rx);
-
-static void echo_can_init(void)
-{
- printk("DAHDI Echo Canceller: STEVE2%s\n", DAHDI_ECHO_AGGRESSIVE);
-}
-
-static void echo_can_identify(char *buf, size_t len)
-{
- dahdi_copy_string(buf, "STEVE2", len);
-}
-
-static void echo_can_shutdown(void)
-{
-}
-
/*
* According to Jim...
*/
@@ -138,7 +119,7 @@ static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocan
size = sizeof(**ec) + ecp->tap_length * sizeof(int32_t) + ecp->tap_length * 3 * sizeof(int16_t);
- if (!(*ec = MALLOC(size)))
+ if (!(*ec = kmalloc(size, GFP_KERNEL)))
return -ENOMEM;
memset(*ec, 0, size);
@@ -160,14 +141,14 @@ static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocan
}
/*- End of function --------------------------------------------------------*/
-static inline void echo_can_free(struct echo_can_state *ec)
+static void echo_can_free(struct echo_can_state *ec)
{
fir16_free(&ec->fir_state);
- FREE(ec);
+ kfree(ec);
}
/*- End of function --------------------------------------------------------*/
-static inline int16_t echo_can_update(struct echo_can_state *ec, int16_t tx, int16_t rx)
+static inline int16_t sample_update(struct echo_can_state *ec, int16_t tx, int16_t rx)
{
int offset1;
int offset2;
@@ -297,143 +278,21 @@ static inline int16_t echo_can_update(struct echo_can_state *ec, int16_t tx, int
return clean_rx;
}
+/*- End of function --------------------------------------------------------*/
-#if 0
-static inline int16_t echo_can_update(struct echo_can_state *ec, int16_t tx, int16_t rx)
+static void echo_can_update(struct echo_can_state *ec, short *iref, short *isig)
{
- int offset;
- int limit;
- int32_t echo_value;
- int clean_rx;
- int nsuppr;
- int i;
- int correction;
-
- ec->tx_history[ec->curr_pos] = tx;
-
- /* Evaluate the echo - i.e. apply the FIR filter */
- /* Assume the gain of the FIR does not exceed unity. Exceeding unity
- would seem like a rather poor thing for an echo cancellor to do :)
- This means we can compute the result with a total disregard for
- overflows. 16bits x 16bits -> 31bits, so no overflow can occur in
- any multiply. While accumulating we may overflow and underflow the
- 32 bit scale often. However, if the gain does not exceed unity,
- everything should work itself out, and the final result will be
- OK, without any saturation logic. */
- /* Overflow is very much possible here, and we do nothing about it because
- of the compute costs */
- /* 16 bit coeffs for the LMS give lousy results (maths good, actual sound
- bad!), but 32 bit coeffs require some shifting. On balance 32 bit seems
- best */
- offset = ec->curr_pos;
- limit = ec->taps - offset;
- echo_value = 0;
- for (i = 0; i < limit; i++)
- echo_value += (ec->fir_taps[i] >> 16)*ec->tx_history[i + offset];
- offset = ec->taps - ec->curr_pos;
- for ( ; i < ec->taps; i++)
- echo_value += (ec->fir_taps[i] >> 16)*ec->tx_history[i - offset];
- echo_value >>= 16;
-
- /* And the answer is..... */
- clean_rx = rx - echo_value;
-
- /* That was the easy part. Now we need to adapt! */
- if (ec->nonupdate_dwell > 0)
- ec->nonupdate_dwell--;
-
- /* If there is very little being transmitted, any attempt to train is
- futile. We would either be training on the far end's noise or signal,
- the channel's own noise, or our noise. Either way, this is hardly good
- training, so don't do it (avoid trouble). */
- /* If the received power is very low, either we are sending very little or
- we are already well adapted. There is little point in trying to improve
- the adaption under these circumstanceson, so don't do it (reduce the
- compute load). */
- if (ec->tx_power > MIN_TX_POWER_FOR_ADAPTION
- &&
- ec->rx_power > MIN_RX_POWER_FOR_ADAPTION)
- {
- /* This is a really crude piece of decision logic, but it does OK
- for now. */
- if (ec->tx_power > 2*ec->rx_power)
- {
- /* There is no far-end speech detected */
- if (ec->nonupdate_dwell == 0)
- {
- /* ... and we are not in the dwell time from previous speech. */
- //nsuppr = saturate((clean_rx << 16)/ec->tx_power);
- nsuppr = clean_rx >> 3;
+ unsigned int x;
+ short result;
- /* Update the FIR taps */
- offset = ec->curr_pos;
- limit = ec->taps - offset;
- ec->latest_correction = 0;
- for (i = 0; i < limit; i++)
- {
- correction = ec->tx_history[i + offset]*nsuppr;
- ec->fir_taps[i] += correction;
- //ec->latest_correction += abs(correction);
- }
- offset = ec->taps - ec->curr_pos;
- for ( ; i < ec->taps; i++)
- {
- correction = ec->tx_history[i - offset]*nsuppr;
- ec->fir_taps[i] += correction;
- //ec->latest_correction += abs(correction);
- }
- }
- else
- {
- ec->latest_correction = -3;
- }
- }
- else
- {
- ec->nonupdate_dwell = NONUPDATE_DWELL_TIME;
- ec->latest_correction = -2;
+ for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
+ result = sample_update(ec, *iref, *isig);
+ *isig++ = result;
}
- }
- else
- {
- ec->nonupdate_dwell = 0;
- ec->latest_correction = -1;
- }
- /* Calculate short term power levels using very simple single pole IIRs */
- /* TODO: Is the nasty modulus approach the fastest, or would a real
- tx*tx power calculation actually be faster? */
- ec->tx_power += ((abs(tx) - ec->tx_power) >> 5);
- ec->rx_power += ((abs(rx) - ec->rx_power) >> 5);
- ec->clean_rx_power += ((abs(clean_rx) - ec->clean_rx_power) >> 5);
-
-#if defined(XYZZY)
- if (ec->use_suppressor)
- {
- ec->supp_test1 += (ec->tx_history[ec->curr_pos] - ec->tx_history[(ec->curr_pos - 7) & ec->tap_mask]);
- ec->supp_test2 += (ec->tx_history[(ec->curr_pos - 24) & ec->tap_mask] - ec->tx_history[(ec->curr_pos - 31) & ec->tap_mask]);
- if (ec->supp_test1 > 42 && ec->supp_test2 > 42)
- supp_change = 25;
- else
- supp_change = 50;
- supp = supp_change + k1*ec->supp1 + k2*ec->supp2;
- ec->supp2 = ec->supp1;
- ec->supp1 = supp;
- clean_rx *= (1 - supp);
- }
-#endif
-
- if (ec->use_nlp && ec->rx_power < 32)
- clean_rx = 0;
-
- /* Roll around the rolling buffer */
- ec->curr_pos = (ec->curr_pos + 1) & ec->tap_mask;
-
- return clean_rx;
}
/*- End of function --------------------------------------------------------*/
-#endif
-static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
+static int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
{
/* Reset hang counter to avoid adjustments after
initial forced training */
@@ -447,5 +306,38 @@ static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short va
return 0;
}
-/*- End of file ------------------------------------------------------------*/
-#endif
+static const struct dahdi_echocan me = {
+ .name = "SEC2",
+ .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)) {
+ module_printk(KERN_ERR, "could not register with DAHDI core\n");
+
+ return -EPERM;
+ }
+
+ module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
+
+ return 0;
+}
+
+static void __exit mod_exit(void)
+{
+ dahdi_unregister_echocan(&me);
+}
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+
+MODULE_DESCRIPTION("DAHDI 'SEC2' Echo Canceler");
+MODULE_AUTHOR("Steve Underwood <steveu@coppice.org>");
+MODULE_LICENSE("GPL");
+
+module_init(mod_init);
+module_exit(mod_exit);
diff --git a/drivers/dahdi/dahdi_transcode.c b/drivers/dahdi/dahdi_transcode.c
index df11dce..31352ef 100644
--- a/drivers/dahdi/dahdi_transcode.c
+++ b/drivers/dahdi/dahdi_transcode.c
@@ -441,7 +441,7 @@ static struct dahdi_chardev transcode_chardev = {
.minor = 250,
};
-int zttranscode_init(void)
+int dahdi_transcode_init(void)
{
int res;
@@ -460,7 +460,7 @@ int zttranscode_init(void)
return 0;
}
-void zttranscode_cleanup(void)
+void dahdi_transcode_cleanup(void)
{
dahdi_unregister_chardev(&transcode_chardev);
@@ -473,9 +473,7 @@ module_param(debug, int, S_IRUGO | S_IWUSR);
MODULE_DESCRIPTION("DAHDI Transcoder Support");
MODULE_AUTHOR("Mark Spencer <markster@digium.com>");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
-module_init(zttranscode_init);
-module_exit(zttranscode_cleanup);
+module_init(dahdi_transcode_init);
+module_exit(dahdi_transcode_cleanup);
diff --git a/drivers/dahdi/datamods/syncppp.c b/drivers/dahdi/datamods/syncppp.c
index 5ca283a..2b63a01 100644
--- a/drivers/dahdi/datamods/syncppp.c
+++ b/drivers/dahdi/datamods/syncppp.c
@@ -1481,5 +1481,4 @@ static void __exit sync_ppp_cleanup(void)
module_init(sync_ppp_init);
module_exit(sync_ppp_cleanup);
module_param(debug, int, 0);
-MODULE_LICENSE("GPL");
-
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/dahdi/fir.h b/drivers/dahdi/fir.h
index 1722285..ee8cffe 100644
--- a/drivers/dahdi/fir.h
+++ b/drivers/dahdi/fir.h
@@ -51,7 +51,7 @@ static inline void fir16_create (fir16_state_t *fir,
fir->taps = taps;
fir->curr_pos = taps - 1;
fir->coeffs = coeffs;
- fir->history = MALLOC (taps*sizeof (int16_t));
+ fir->history = kmalloc(taps*sizeof (int16_t), GFP_KERNEL);
if (fir->history)
memset (fir->history, '\0', taps*sizeof (int16_t));
}
@@ -59,7 +59,7 @@ static inline void fir16_create (fir16_state_t *fir,
static inline void fir16_free (fir16_state_t *fir)
{
- FREE (fir->history);
+ kfree(fir->history);
}
/*- End of function --------------------------------------------------------*/
@@ -92,7 +92,7 @@ static inline void fir32_create (fir32_state_t *fir,
fir->taps = taps;
fir->curr_pos = taps - 1;
fir->coeffs = coeffs;
- fir->history = MALLOC (taps*sizeof (int16_t));
+ fir->history = kmalloc(taps*sizeof (int16_t), GFP_KERNEL);
if (fir->history)
memset (fir->history, '\0', taps*sizeof (int16_t));
}
@@ -100,7 +100,7 @@ static inline void fir32_create (fir32_state_t *fir,
static inline void fir32_free (fir32_state_t *fir)
{
- FREE (fir->history);
+ kfree(fir->history);
}
/*- End of function --------------------------------------------------------*/
diff --git a/drivers/dahdi/hpec/hpec_dahdi.h b/drivers/dahdi/hpec/dahdi_echocan_hpec.c
index bb54e8e..5da8c8c 100644
--- a/drivers/dahdi/hpec/hpec_dahdi.h
+++ b/drivers/dahdi/hpec/dahdi_echocan_hpec.c
@@ -1,14 +1,13 @@
/*
* DAHDI Telephony Interface to Digium High-Performance Echo Canceller
*
- * Copyright (C) 2006 Digium, Inc.
+ * Copyright (C) 2006-2008 Digium, Inc.
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -20,10 +19,19 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#if !defined(_HPEC_DAHDI_H)
-#define _HPEC_DAHDI_H
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/moduleparam.h>
-#define DAHDI_EC_ARRAY_UPDATE
+#include <dahdi/kernel.h>
+
+static int debug;
+
+#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)
#include "hpec_user.h"
#include "hpec.h"
@@ -59,28 +67,12 @@ static void memfree(void *ptr)
kfree(ptr);
}
-static void echo_can_init(void)
-{
- printk("DAHDI Echo Canceller: Digium High-Performance Echo Canceller\n");
- hpec_init(logger, debug, DAHDI_CHUNKSIZE, memalloc, memfree);
-}
-
-static void echo_can_identify(char *buf, size_t len)
-{
- dahdi_copy_string(buf, "HPEC", len);
-}
-
-static void echo_can_shutdown(void)
-{
- hpec_shutdown();
-}
-
-static inline void echo_can_free(struct echo_can_state *ec)
+static void echo_can_free(struct echo_can_state *ec)
{
hpec_channel_free(ec);
}
-static inline void echo_can_array_update(struct echo_can_state *ec, short *iref, short *isig)
+static void echo_can_array_update(struct echo_can_state *ec, short *iref, short *isig)
{
hpec_channel_update(ec, iref, isig);
}
@@ -143,4 +135,46 @@ static int hpec_license_ioctl(unsigned int cmd, unsigned long data)
}
}
-#endif /* !defined(_HPEC_DAHDI_H) */
+static const struct dahdi_echocan me = {
+ .name = "HPEC",
+ .owner = THIS_MODULE,
+ .echo_can_create = echo_can_create,
+ .echo_can_free = echo_can_free,
+ .echo_can_array_update = echo_can_array_update,
+ .echo_can_traintap = echo_can_traintap,
+};
+
+static int __init mod_init(void)
+{
+ if (dahdi_register_echocan(&me)) {
+ module_printk(KERN_ERR, "could not register with DAHDI core\n");
+
+ return -EPERM;
+ }
+
+ module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
+
+ hpec_init(logger, debug, DAHDI_CHUNKSIZE, memalloc, memfree);
+
+ dahdi_set_hpec_ioctl(hpec_license_ioctl);
+
+ return 0;
+}
+
+static void __exit mod_exit(void)
+{
+ dahdi_unregister_echocan(&me);
+
+ dahdi_set_hpec_ioctl(NULL);
+
+ hpec_shutdown();
+}
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+
+MODULE_DESCRIPTION("DAHDI High Performance Echo Canceller");
+MODULE_AUTHOR("Kevin P. Fleming <kpfleming@digium.com>");
+MODULE_LICENSE("Digium Commercial");
+
+module_init(mod_init);
+module_exit(mod_exit);
diff --git a/drivers/dahdi/jpah.h b/drivers/dahdi/jpah.h
deleted file mode 100644
index 72b4d00..0000000
--- a/drivers/dahdi/jpah.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * ECHO_CAN_JP1
- *
- * by Jason Parker
- *
- * Based upon mg2ec.h - sort of.
- * This "echo can" will completely hose your audio.
- * Don't use it unless you're absolutely sure you know what you're doing.
- *
- * Copyright (C) 2007, Digium, Inc.
- *
- * This program is free software and may be used and
- * distributed according to the terms of the GNU
- * General Public License, incorporated herein by
- * reference.
- *
- */
-
-#ifndef _JP_ECHO_H
-#define _JP_ECHO_H
-
-#ifdef __KERNEL__
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#define MALLOC(a) kmalloc((a), GFP_KERNEL)
-#define FREE(a) kfree(a)
-#else
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <string.h>
-#define MALLOC(a) malloc(a)
-#define FREE(a) free(a)
-#endif
-
-/* Echo canceller definition */
-struct echo_can_state {
- /* an arbitrary ID for this echo can - this really should be settable from the calling channel... */
- int id;
-
- /* absolute time - aka. sample number index - essentially the number of samples since this can was init'ed */
- int i_d;
-};
-
-static void echo_can_init(void)
-{
- printk("DAHDI Audio Hoser: JP1\n");
-}
-
-static void echo_can_identify(char *buf, size_t len)
-{
- dahdi_copy_string(buf, "JP1", len);
-}
-
-static void echo_can_shutdown(void)
-{
-}
-
-static inline void init_cc(struct echo_can_state *ec)
-{
- void *ptr = ec;
- unsigned long tmp;
- /* Double-word align past end of state */
- ptr += sizeof(struct echo_can_state);
- tmp = (unsigned long)ptr;
- tmp += 3;
- tmp &= ~3L;
- ptr = (void *)tmp;
-}
-
-static inline void echo_can_free(struct echo_can_state *ec)
-{
- FREE(ec);
-}
-
-static inline short echo_can_update(struct echo_can_state *ec, short iref, short isig)
-{
- static int blah = 0;
-
- if (blah < 2) {
- blah++;
- return 0;
- } else {
- blah = (blah + 1) % 3;
- return isig;
- }
-}
-
-static inline struct echo_can_state *echo_can_create(int len, int adaption_mode)
-{
- struct echo_can_state *ec;
- ec = (struct echo_can_state *)MALLOC(sizeof(struct echo_can_state) + 4); /* align */
- if (ec) {
- memset(ec, 0, sizeof(struct echo_can_state) + 4); /* align */
- init_cc(ec);
- }
- return ec;
-}
-
-static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
-{
- return 0;
-}
-#endif
diff --git a/drivers/dahdi/kb1ec_const.h b/drivers/dahdi/kb1ec_const.h
deleted file mode 100644
index 0849b14..0000000
--- a/drivers/dahdi/kb1ec_const.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- Important constants for tuning kb1 echo can
- */
-#ifndef _MEC2_CONST_H
-#define _MEC2_CONST_H
-
-
-/* Convergence (aka. adaptation) speed -- higher means slower */
-#define DEFAULT_BETA1_I 2048
-
-/* Constants for various power computations */
-#define DEFAULT_SIGMA_LY_I 7
-#define DEFAULT_SIGMA_LU_I 7
-#define DEFAULT_ALPHA_ST_I 5 /* near-end speech detection sensitivity factor */
-#define DEFAULT_ALPHA_YT_I 5
-
-#define DEFAULT_CUTOFF_I 128
-
-/* Define the near-end speech hangover counter: if near-end speech
- * is declared, hcntr is set equal to hangt (see pg. 432)
- */
-#define DEFAULT_HANGT 600 /* in samples, so 600 samples = 75ms */
-
-/* define the residual error suppression threshold */
-#define DEFAULT_SUPPR_I 16 /* 16 = -24db */
-
-/* This is the minimum reference signal power estimate level
- * that will result in filter adaptation.
- * If this is too low then background noise will cause the filter
- * coefficients to constantly be updated.
- */
-#define MIN_UPDATE_THRESH_I 4096
-
-/* The number of samples used to update coefficients using the
- * the block update method (M). It should be related back to the
- * length of the echo can.
- * ie. it only updates coefficients when (sample number MOD default_m) = 0
- *
- * Getting this wrong may cause an oops. Consider yourself warned!
- */
-#define DEFAULT_M 16 /* every 16th sample */
-
-/* If AGGRESSIVE supression is enabled, then we start cancelling residual
- * echos again even while there is potentially the very end of a near-side
- * signal present.
- * This defines how many samples of DEFAULT_HANGT can remain before we
- * kick back in
- */
-#define AGGRESSIVE_HCNTR 160 /* in samples, so 160 samples = 20ms */
-
-
-/***************************************************************/
-/* The following knobs are not implemented in the current code */
-
-/* we need a dynamic level of suppression varying with the ratio of the
- power of the echo to the power of the reference signal this is
- done so that we have a smoother background.
- we have a higher suppression when the power ratio is closer to
- suppr_ceil and reduces logarithmically as we approach suppr_floor.
- */
-#define SUPPR_FLOOR -64
-#define SUPPR_CEIL -24
-
-/* in a second departure, we calculate the residual error suppression
- * as a percentage of the reference signal energy level. The threshold
- * is defined in terms of dB below the reference signal.
- */
-#define RES_SUPR_FACTOR -20
-
-
-#endif /* _MEC2_CONST_H */
-
diff --git a/drivers/dahdi/mg2ec_const.h b/drivers/dahdi/mg2ec_const.h
deleted file mode 100644
index 08fd897..0000000
--- a/drivers/dahdi/mg2ec_const.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- Important constants for tuning mg2 echo can
- */
-#ifndef _MG2_CONST_H
-#define _MG2_CONST_H
-
-
-/* Convergence (aka. adaptation) speed -- higher means slower */
-#define DEFAULT_BETA1_I 2048
-
-/* Constants for various power computations */
-#define DEFAULT_SIGMA_LY_I 7
-#define DEFAULT_SIGMA_LU_I 7
-#define DEFAULT_ALPHA_ST_I 5 /* near-end speech detection sensitivity factor */
-#define DEFAULT_ALPHA_YT_I 5
-
-#define DEFAULT_CUTOFF_I 128
-
-/* Define the near-end speech hangover counter: if near-end speech
- * is declared, hcntr is set equal to hangt (see pg. 432)
- */
-#define DEFAULT_HANGT 600 /* in samples, so 600 samples = 75ms */
-
-/* define the residual error suppression threshold */
-#define DEFAULT_SUPPR_I 16 /* 16 = -24db */
-
-/* This is the minimum reference signal power estimate level
- * that will result in filter adaptation.
- * If this is too low then background noise will cause the filter
- * coefficients to constantly be updated.
- */
-#define MIN_UPDATE_THRESH_I 2048
-
-/* The number of samples used to update coefficients using the
- * the block update method (M). It should be related back to the
- * length of the echo can.
- * ie. it only updates coefficients when (sample number MOD default_m) = 0
- *
- * Getting this wrong may cause an oops. Consider yourself warned!
- */
-#define DEFAULT_M 16 /* every 16th sample */
-
-/* If AGGRESSIVE supression is enabled, then we start cancelling residual
- * echos again even while there is potentially the very end of a near-side
- * signal present.
- * This defines how many samples of DEFAULT_HANGT can remain before we
- * kick back in
- */
-#define AGGRESSIVE_HCNTR 160 /* in samples, so 160 samples = 20ms */
-
-/* Treat sample as error if it has a different sign as the
- * input signal and is this number larger in ABS() as
- * the input-signal */
-#define MAX_SIGN_ERROR 3000
-
-/* Number of coefficients really used for calculating the
- * simulated echo. The value specifies how many of the
- * biggest coefficients are used for calculating rs.
- * This helps on long echo-tails by artificially limiting
- * the number of coefficients for the calculation and
- * preventing overflows.
- * Comment this to deactivate the code */
-#define USED_COEFFS 64
-
-/* Backup coefficients every this number of samples */
-#define BACKUP 256
-
-/***************************************************************/
-/* The following knobs are not implemented in the current code */
-
-/* we need a dynamic level of suppression varying with the ratio of the
- power of the echo to the power of the reference signal this is
- done so that we have a smoother background.
- we have a higher suppression when the power ratio is closer to
- suppr_ceil and reduces logarithmically as we approach suppr_floor.
- */
-#define SUPPR_FLOOR -64
-#define SUPPR_CEIL -24
-
-/* in a second departure, we calculate the residual error suppression
- * as a percentage of the reference signal energy level. The threshold
- * is defined in terms of dB below the reference signal.
- */
-#define RES_SUPR_FACTOR -20
-
-
-#endif /* _MG2_CONST_H */
-
diff --git a/drivers/dahdi/pciradio.c b/drivers/dahdi/pciradio.c
index 1f90af3..30d49d1 100644
--- a/drivers/dahdi/pciradio.c
+++ b/drivers/dahdi/pciradio.c
@@ -1888,10 +1888,7 @@ module_param(debug, int, 0600);
MODULE_DESCRIPTION("DAHDI Telephony PCI Radio Card Driver");
MODULE_AUTHOR("Jim Dixon <jim@lambdatel.com>");
-
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
module_init(pciradio_init);
module_exit(pciradio_cleanup);
diff --git a/drivers/dahdi/tor2.c b/drivers/dahdi/tor2.c
index 6fab600..2f51403 100644
--- a/drivers/dahdi/tor2.c
+++ b/drivers/dahdi/tor2.c
@@ -1483,9 +1483,7 @@ static int tor2_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long d
MODULE_AUTHOR("Mark Spencer");
MODULE_DESCRIPTION("Tormenta 2 PCI Quad T1 or E1 DAHDI Driver");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
module_param(debug, int, 0600);
module_param(loopback, int, 0600);
diff --git a/drivers/dahdi/wcfxo.c b/drivers/dahdi/wcfxo.c
index c641aa6..f369225 100644
--- a/drivers/dahdi/wcfxo.c
+++ b/drivers/dahdi/wcfxo.c
@@ -1061,9 +1061,7 @@ module_param(opermode, int, 0444);
MODULE_DESCRIPTION("Wildcard X100P DAHDI Driver");
MODULE_AUTHOR("Mark Spencer <markster@digium.com>");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
module_init(wcfxo_init);
module_exit(wcfxo_cleanup);
diff --git a/drivers/dahdi/wct1xxp.c b/drivers/dahdi/wct1xxp.c
index 0814e85..54377bf 100644
--- a/drivers/dahdi/wct1xxp.c
+++ b/drivers/dahdi/wct1xxp.c
@@ -1407,9 +1407,7 @@ module_param(debug, int, 0600);
MODULE_DESCRIPTION("Wildcard T100P/E100P DAHDI Driver");
MODULE_AUTHOR("Mark Spencer <markster@digium.com>");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
module_init(t1xxp_init);
module_exit(t1xxp_cleanup);
diff --git a/drivers/dahdi/wct4xxp/base.c b/drivers/dahdi/wct4xxp/base.c
index 8e38a01..66d1433 100644
--- a/drivers/dahdi/wct4xxp/base.c
+++ b/drivers/dahdi/wct4xxp/base.c
@@ -3799,12 +3799,9 @@ static void __exit t4_cleanup(void)
MODULE_AUTHOR("Mark Spencer");
MODULE_DESCRIPTION("Unified TE4XXP-TE2XXP PCI Driver");
-#if defined(MODULE_ALIAS)
MODULE_ALIAS("wct2xxp");
-#endif
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
+
module_param(pedanticpci, int, 0600);
module_param(debug, int, 0600);
module_param(loopback, int, 0600);
diff --git a/drivers/dahdi/wctc4xxp/base.c b/drivers/dahdi/wctc4xxp/base.c
index b0705bf..635c797 100644
--- a/drivers/dahdi/wctc4xxp/base.c
+++ b/drivers/dahdi/wctc4xxp/base.c
@@ -2013,11 +2013,10 @@ module_param(debug_des_cnt, int, S_IRUGO | S_IWUSR);
module_param(debug_notimeout, int, S_IRUGO | S_IWUSR);
module_param(force_alert, int, S_IRUGO | S_IWUSR);
module_param(mode, charp, S_IRUGO | S_IWUSR);
+
MODULE_DESCRIPTION("Wildcard TC400P+TC400M Driver");
MODULE_AUTHOR("John Sloan <jsloan@digium.com>");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
module_init(ztdte_init);
module_exit(ztdte_cleanup);
diff --git a/drivers/dahdi/wctdm.c b/drivers/dahdi/wctdm.c
index a086223..a50aeff 100644
--- a/drivers/dahdi/wctdm.c
+++ b/drivers/dahdi/wctdm.c
@@ -2498,12 +2498,8 @@ module_param(fxsrxgain, int, 0600);
MODULE_DESCRIPTION("Wildcard TDM400P DAHDI Driver");
MODULE_AUTHOR("Mark Spencer <markster@digium.com>");
-#if defined(MODULE_ALIAS)
MODULE_ALIAS("wcfxs");
-#endif
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
module_init(wctdm_init);
module_exit(wctdm_cleanup);
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index d5bbb7e..1e45884 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -4009,12 +4009,8 @@ module_param(vpmnlpmaxsupp, int, 0600);
MODULE_DESCRIPTION("Wildcard TDM2400P/TDM800P DAHDI Driver");
MODULE_AUTHOR("Mark Spencer <markster@digium.com>");
-#if defined(MODULE_ALIAS)
MODULE_ALIAS("wctdm8xxp");
-#endif
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
module_init(wctdm_init);
module_exit(wctdm_cleanup);
diff --git a/drivers/dahdi/wcte11xp.c b/drivers/dahdi/wcte11xp.c
index 824e8e1..f454bc4 100644
--- a/drivers/dahdi/wcte11xp.c
+++ b/drivers/dahdi/wcte11xp.c
@@ -1611,9 +1611,7 @@ module_param(j1mode, int, 0600);
MODULE_DESCRIPTION("Wildcard TE110P DAHDI Driver");
MODULE_AUTHOR("Mark Spencer <markster@digium.com>");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
module_init(t1xxp_init);
module_exit(t1xxp_cleanup);
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c
index e98cc35..422b704 100644
--- a/drivers/dahdi/wcte12xp/base.c
+++ b/drivers/dahdi/wcte12xp/base.c
@@ -1725,9 +1725,7 @@ module_param(vpmdtmfsupport, int, S_IRUGO | S_IWUSR);
module_param(vpmtsisupport, int, S_IRUGO | S_IWUSR);
#endif
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
+MODULE_LICENSE("GPL v2");
module_init(te12xp_init);
module_exit(te12xp_cleanup);
diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h
index be1a1a3..fccd10f 100644
--- a/include/dahdi/kernel.h
+++ b/include/dahdi/kernel.h
@@ -1,7 +1,7 @@
/*
* DAHDI Telephony Interface
*
- * Written by Mark Spencer <markster@linux-suppot.net>
+ * Written by Mark Spencer <markster@linux-support.net>
* Based on previous works, designs, and architectures conceived and
* written by Jim Dixon <jim@lambdatel.com>.
*
@@ -252,13 +252,13 @@ int sync; /* what level of sync source we are */
typedef struct dahdi_chanconfig
{
int chan; /* Channel we're applying this to (0 to use name) */
-char name[40]; /* Name of channel to use */
+char name[40]; /* Name of channel to use */
int sigtype; /* Signal type */
-int deflaw; /* Default law (DAHDI_LAW_DEFAULT, DAHDI_LAW_MULAW, or DAHDI_LAW_ALAW */
+int deflaw; /* Default law (DAHDI_LAW_DEFAULT, DAHDI_LAW_MULAW, or DAHDI_LAW_ALAW) */
int master; /* Master channel if sigtype is DAHDI_SLAVE */
int idlebits; /* Idle bits (if this is a CAS channel) or
channel to monitor (if this is DACS channel) */
-char netdev_name[16]; /*name for the hdlc network device*/
+char netdev_name[16];/* name for the hdlc network device*/
} DAHDI_CHANCONFIG;
typedef struct dahdi_sfconfig
@@ -328,11 +328,16 @@ struct dahdi_versioninfo {
char echo_canceller[80];
};
-struct dahdi_hwgain{
+struct dahdi_hwgain {
__s32 newgain; /* desired gain in dB but x10. -3.5dB would be -35 */
__u32 tx:1; /* 0=rx; 1=tx */
};
+struct dahdi_attach_echocan {
+ int chan; /* Channel we're applying this to */
+ char echocan[16]; /* Name of echo canceler to attach to this channel
+ (leave empty to have no echocan attached */
+};
/* ioctl definitions */
#define DAHDI_CODE 0xDA
@@ -644,6 +649,13 @@ struct dahdi_hwgain{
*/
#define DAHDI_LOOPBACK _IOW(DAHDI_CODE, 58, int)
+/*
+ Attach the desired echo canceler module (or none) to a channel in an
+ audio-supporting mode, so that when the channel needs an echo canceler
+ that module will be used to supply one.
+ */
+#define DAHDI_ATTACH_ECHOCAN _IOW(DAHDI_CODE, 59, struct dahdi_attach_echocan)
+
/*
* 60-80 are reserved for private drivers
@@ -870,6 +882,21 @@ struct dahdi_echocanparams {
struct dahdi_echocanparam params[0];
};
+/* Echo cancellation */
+struct echo_can_state;
+
+struct dahdi_echocan {
+ const char *name;
+ struct module *owner;
+ int (*echo_can_create)(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p, struct echo_can_state **ec);
+ void (*echo_can_free)(struct echo_can_state *ec);
+ void (*echo_can_array_update)(struct echo_can_state *ec, short *iref, short *isig);
+ int (*echo_can_traintap)(struct echo_can_state *ec, int pos, short val);
+};
+
+int dahdi_register_echocan(const struct dahdi_echocan *ec);
+void dahdi_unregister_echocan(const struct dahdi_echocan *ec);
+
struct dahdi_tone_def_header {
int count; /* How many samples follow */
int zone; /* Which zone we are loading */
@@ -1169,20 +1196,6 @@ struct dahdi_hdlc {
};
#endif
-/* Echo cancellation */
-struct echo_can_state;
-#if 0
-/* echo can API consists of these functions */
-void echo_can_init(void);
-void echo_chan_shutdown(void);
-void echo_can_identify(char *buf, size_t len);
-int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p, struct echo_can_state **ec);
-void echo_can_free(struct echo_can_state *ec);
-short echo_can_update(struct echo_can_state *ec, short iref, short isig);
-void echo_can_array_update(struct echo_can_state *ec, short *iref, short *isig);
-int echo_can_traintap(struct echo_can_state *ec, int pos, short val);
-#endif
-
/* Conference queue stucture */
struct confq {
u_char buffer[DAHDI_CHUNKSIZE * DAHDI_CB_SIZE];
@@ -1347,7 +1360,14 @@ struct dahdi_chan {
/* Is echo cancellation enabled or disabled */
int echocancel;
- struct echo_can_state *ec;
+ /* The echo canceler module that should be used to create an
+ instance when this channel needs one */
+ const struct dahdi_echocan *ec_factory;
+ /* The echo canceler module that owns the instance currently
+ on this channel, if one is present */
+ const struct dahdi_echocan *ec_current;
+ /* The private state data of the echo canceler instance in use */
+ struct echo_can_state *ec_state;
echo_can_disable_detector_state_t txecdis;
echo_can_disable_detector_state_t rxecdis;
@@ -1757,6 +1777,9 @@ extern u_char __dahdi_lin2a[16384];
/* Used by dynamic DAHDI -- don't use directly */
void dahdi_set_dynamic_ioctl(int (*func)(unsigned int cmd, unsigned long data));
+/* Used by DAHDI HPEC module -- don't use directly */
+void dahdi_set_hpec_ioctl(int (*func)(unsigned int cmd, unsigned long data));
+
/* Used privately by DAHDI. Avoid touching directly */
struct dahdi_tone {
int fac1;