summaryrefslogtreecommitdiff
path: root/zaptel-base.c
diff options
context:
space:
mode:
Diffstat (limited to 'zaptel-base.c')
-rw-r--r--zaptel-base.c166
1 files changed, 62 insertions, 104 deletions
diff --git a/zaptel-base.c b/zaptel-base.c
index b90eb42..309b813 100644
--- a/zaptel-base.c
+++ b/zaptel-base.c
@@ -419,12 +419,18 @@ static struct zt_zone *tone_zones[ZT_TONE_ZONE_MAX];
#include "sec.h"
#elif defined(ECHO_CAN_STEVE2)
#include "sec-2.h"
+#elif defined(ECHO_CAN_MARK)
+#include "mec.h"
+#elif defined(ECHO_CAN_MARK2)
+#include "mec2.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"
+#else
+#include "mec3.h"
#endif
static inline void rotate_sums(void)
@@ -4302,95 +4308,6 @@ static void do_ppp_calls(unsigned long data)
}
#endif
-#define MAX_ECHOCANPARAMS 8
-
-static int ioctl_echocancel(struct zt_chan *chan, struct zt_echocanparams *ecp, void *data)
-{
- struct echo_can_state *ec = NULL, *tec;
- struct zt_echocanparam params[MAX_ECHOCANPARAMS];
- int ret;
- unsigned long flags;
-
- if (ecp->param_count > MAX_ECHOCANPARAMS)
- return -E2BIG;
-
- if (ecp->tap_length == 0) {
- /* disable mode, don't need to inspect params */
- spin_lock_irqsave(&chan->lock, flags);
- tec = chan->ec;
- chan->echocancel = 0;
- chan->ec = NULL;
- chan->echostate = ECHO_STATE_IDLE;
- chan->echolastupdate = 0;
- chan->echotimer = 0;
- spin_unlock_irqrestore(&chan->lock, flags);
- if (chan->span && chan->span->echocan)
- chan->span->echocan(chan, 0);
- if (tec)
- echo_can_free(tec);
-
- return 0;
- }
-
- /* if parameters were supplied and this channel's span provides an echocan,
- but not one that takes params, then we must punt here and return an error */
- if (ecp->param_count && chan->span && chan->span->echocan &&
- !chan->span->echocan_with_params)
- return -EINVAL;
-
- /* enable mode, need the params */
-
- if (copy_from_user(params, (struct zt_echocanparam *) data, sizeof(params[0]) * ecp->param_count))
- return -EFAULT;
-
- spin_lock_irqsave(&chan->lock, flags);
- tec = chan->ec;
- chan->ec = NULL;
- spin_unlock_irqrestore(&chan->lock, flags);
-
- ret = -ENOTTY;
-
- /* attempt to use the span's echo canceler; fall back to built-in
- if it fails (but not if an error occurs) */
- if (chan->span && chan->span->echocan_with_params)
- ret = chan->span->echocan_with_params(chan, ecp, params);
-
- if (ret == -ENOTTY) {
- switch (ecp->tap_length) {
- case 32:
- case 64:
- case 128:
- case 256:
- case 512:
- case 1024:
- break;
- default:
- ecp->tap_length = deftaps;
- }
-
- if ((ret = echo_can_create(ecp, params, &ec))) {
- if (tec)
- echo_can_free(tec);
- return ret;
- }
-
- spin_lock_irqsave(&chan->lock, flags);
- chan->echocancel = ecp->tap_length;
- chan->ec = ec;
- chan->echostate = ECHO_STATE_IDLE;
- chan->echolastupdate = 0;
- chan->echotimer = 0;
- echo_can_disable_detector_init(&chan->txecdis);
- echo_can_disable_detector_init(&chan->rxecdis);
- spin_unlock_irqrestore(&chan->lock, flags);
- }
-
- if (tec)
- echo_can_free(tec);
-
- return 0;
-}
-
static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit)
{
struct zt_chan *chan = chans[unit];
@@ -4400,7 +4317,6 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm
int oldconf;
void *rxgain=NULL;
struct echo_can_state *ec, *tec;
- struct zt_echocanparams ecp;
if (!chan)
return -ENOSYS;
@@ -4565,20 +4481,62 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm
case ZT_ECHOCANCEL:
if (!(chan->flags & ZT_FLAG_AUDIO))
return -EINVAL;
- if (copy_from_user(&ecp, (struct zt_echocanparams *) data, sizeof(ecp)))
- return -EFAULT;
- data += sizeof(ecp);
- if ((ret = ioctl_echocancel(chan, &ecp, (void *) data)))
- return ret;
- break;
- case ZT_ECHOCANCEL_V1:
- if (!(chan->flags & ZT_FLAG_AUDIO))
- return -EINVAL;
- get_user(j, (int *) data);
- ecp.tap_length = j;
- ecp.param_count = 0;
- if ((ret = ioctl_echocancel(chan, &ecp, (void *) data)))
- return ret;
+ get_user(j, (int *)data);
+ if (j) {
+ spin_lock_irqsave(&chan->lock, flags);
+ /* If we had an old echo can, zap it now */
+ tec = chan->ec;
+ chan->ec = NULL;
+ /* Attempt hardware native echo can */
+ spin_unlock_irqrestore(&chan->lock, flags);
+
+ if (chan->span && chan->span->echocan)
+ ret = chan->span->echocan(chan, j);
+ else
+ ret = -ENOTTY;
+
+ if (ret) {
+ /* Use built-in echo can */
+ if ((j == 32) ||
+ (j == 64) ||
+ (j == 128) ||
+ (j == 256) ||
+ (j == 512) ||
+ (j == 1024)) {
+ /* Okay */
+ } else {
+ j = deftaps;
+ }
+ ec = echo_can_create(j, 0);
+ if (!ec)
+ return -ENOMEM;
+ spin_lock_irqsave(&chan->lock, flags);
+ chan->echocancel = j;
+ chan->ec = ec;
+ chan->echostate = ECHO_STATE_IDLE;
+ chan->echolastupdate = 0;
+ chan->echotimer = 0;
+ echo_can_disable_detector_init(&chan->txecdis);
+ echo_can_disable_detector_init(&chan->rxecdis);
+ spin_unlock_irqrestore(&chan->lock, flags);
+ }
+ if (tec)
+ echo_can_free(tec);
+ } else {
+ spin_lock_irqsave(&chan->lock, flags);
+ tec = chan->ec;
+ chan->echocancel = 0;
+ chan->ec = NULL;
+ chan->echostate = ECHO_STATE_IDLE;
+ chan->echolastupdate = 0;
+ chan->echotimer = 0;
+ spin_unlock_irqrestore(&chan->lock, flags);
+ /* Attempt hardware native echo can */
+ if (chan->span && chan->span->echocan)
+ chan->span->echocan(chan, 0);
+ if (tec)
+ echo_can_free(tec);
+ }
break;
case ZT_ECHOTRAIN:
get_user(j, (int *)data); /* get pre-training time from user */