diff options
Diffstat (limited to 'zaptel-base.c')
-rw-r--r-- | zaptel-base.c | 166 |
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 */ |