summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;