From d9c6c401a232b45b454316700aad63cf5d9f539a Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Thu, 12 Nov 2009 20:02:24 +0000 Subject: Merged revisions 7309,7348,7565-7571 via svnmerge from https://origsvn.digium.com/svn/dahdi/linux/trunk ........ r7309 | mattf | 2009-10-02 11:31:58 -0500 (Fri, 02 Oct 2009) | 1 line Implement API update to do per-channel companding selection for VPMADT032 ........ r7348 | mattf | 2009-10-07 16:26:08 -0500 (Wed, 07 Oct 2009) | 1 line Fix a logic error in the companding check. Duh.... ........ r7565 | sruffell | 2009-11-12 13:22:06 -0600 (Thu, 12 Nov 2009) | 7 lines voicebus: Fix race when enabling/disabling hardware echocan. This closes a race condition where it was possible for the driver to believe it has enabled the VPMADT032 when in fact, it really has not. This fixes a regression introduced in dahdi-linux 2.2.0. (issue #15724) ........ r7566 | sruffell | 2009-11-12 13:22:06 -0600 (Thu, 12 Nov 2009) | 1 line wctdm24xxp, wcte12xp: We no longer have any DTMF events to check for. ........ r7567 | sruffell | 2009-11-12 13:22:07 -0600 (Thu, 12 Nov 2009) | 1 line voicebus: Remove unused curtone from 'struct vpmadt032' ........ r7568 | sruffell | 2009-11-12 13:22:07 -0600 (Thu, 12 Nov 2009) | 1 line voicebus: Remove redundant MAX_CHANNELS_FROM_SPAN ........ r7569 | sruffell | 2009-11-12 13:22:08 -0600 (Thu, 12 Nov 2009) | 3 lines voicebus: Use dev_xxx macro when printing vpm messages. We also do not need the unused context member of the vpmadt032 structure. ........ r7570 | sruffell | 2009-11-12 13:22:08 -0600 (Thu, 12 Nov 2009) | 4 lines wcte12xp: Change serial port configuration setting for hw echocan. The wcte12xp, like the wctdm24xpp, should have the PcmOutPortA set to SerialPortNull. ........ r7571 | sruffell | 2009-11-12 13:56:49 -0600 (Thu, 12 Nov 2009) | 1 line kernel.h: Define 'list_replace' for kernels < 2.6.18 ........ git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.2@7572 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/adt_lec.c | 4 +- drivers/dahdi/adt_lec.h | 6 + drivers/dahdi/voicebus/GpakCust.c | 294 +++++++++++++++++++++++++------------- drivers/dahdi/voicebus/GpakCust.h | 11 +- drivers/dahdi/wctdm24xxp/base.c | 35 ++--- drivers/dahdi/wcte12xp/base.c | 18 +-- include/dahdi/kernel.h | 10 ++ 7 files changed, 239 insertions(+), 139 deletions(-) diff --git a/drivers/dahdi/adt_lec.c b/drivers/dahdi/adt_lec.c index 02c1322..18de6c0 100644 --- a/drivers/dahdi/adt_lec.c +++ b/drivers/dahdi/adt_lec.c @@ -29,8 +29,10 @@ static inline void adt_lec_init_defaults(struct adt_lec_params *params, __u32 tap_length) { - memset(params, 0, sizeof(*params)); params->tap_length = tap_length; + params->nlp_type = 0; + params->nlp_max_suppress = 0; + params->nlp_threshold = 0; } static int adt_lec_parse_params(struct adt_lec_params *params, diff --git a/drivers/dahdi/adt_lec.h b/drivers/dahdi/adt_lec.h index b2f7896..678fb30 100644 --- a/drivers/dahdi/adt_lec.h +++ b/drivers/dahdi/adt_lec.h @@ -32,11 +32,17 @@ enum adt_lec_nlp_type { ADT_LEC_SUPPRESS, }; +enum adt_companding { + ADT_COMP_ULAW = 0, + ADT_COMP_ALAW, +}; + struct adt_lec_params { __u32 tap_length; enum adt_lec_nlp_type nlp_type; __u32 nlp_threshold; __u32 nlp_max_suppress; + enum adt_companding companding; }; #endif /* _ADT_LEC_H */ diff --git a/drivers/dahdi/voicebus/GpakCust.c b/drivers/dahdi/voicebus/GpakCust.c index 00fe603..ec23336 100644 --- a/drivers/dahdi/voicebus/GpakCust.c +++ b/drivers/dahdi/voicebus/GpakCust.c @@ -53,6 +53,9 @@ static rwlock_t ifacelock; static struct vpmadt032 *ifaces[MAX_DSP_CORES]; +#define vpm_info(vpm, format, arg...) \ + dev_info(&voicebus_get_pci_dev(vpm->vb)->dev , format , ## arg) + static inline struct vpmadt032 *find_iface(const unsigned short dspid) { struct vpmadt032 *ret; @@ -212,29 +215,42 @@ static int vpmadt032_setreg(struct vpmadt032 *vpm, unsigned int addr, u16 data) return res; } -static int vpmadt032_enable_ec(struct vpmadt032 *vpm, int channel) +struct change_order { + struct list_head node; + unsigned int channel; + struct adt_lec_params params; +}; + +static struct change_order *alloc_change_order(void) +{ + return kzalloc(sizeof(struct change_order), GFP_KERNEL); +} + +static void free_change_order(struct change_order *order) +{ + kfree(order); +} + +static int vpmadt032_enable_ec(struct vpmadt032 *vpm, int channel, + enum adt_companding companding) { int res; GPAK_AlgControlStat_t pstatus; GpakAlgCtrl_t control; - if (vpm->span) { - control = (DAHDI_LAW_ALAW == vpm->span->deflaw) ? - EnableALawSwCompanding : - EnableMuLawSwCompanding; - } else { - control = EnableMuLawSwCompanding; - } + control = (ADT_COMP_ALAW == companding) ? EnableALawSwCompanding : + EnableMuLawSwCompanding; + if (vpm->options.debug & DEBUG_ECHOCAN) { const char *law; law = (control == EnableMuLawSwCompanding) ? "MuLaw" : "ALaw"; - printk(KERN_DEBUG "Enabling ecan on channel: %d (%s)\n", - channel, law); + vpm_info(vpm, "Enabling ecan on channel: %d (%s)\n", + channel, law); } res = gpakAlgControl(vpm->dspid, channel, control, &pstatus); if (res) { - printk(KERN_WARNING "Unable to set SW Companding on " \ - "channel %d (reason %d)\n", channel, res); + vpm_info(vpm, "Unable to set SW Companding on " + "channel %d (reason %d)\n", channel, res); } res = gpakAlgControl(vpm->dspid, channel, EnableEcanA, &pstatus); return res; @@ -246,18 +262,98 @@ static int vpmadt032_disable_ec(struct vpmadt032 *vpm, int channel) GPAK_AlgControlStat_t pstatus; if (vpm->options.debug & DEBUG_ECHOCAN) - printk(KERN_DEBUG "Disabling ecan on channel: %d\n", channel); + vpm_info(vpm, "Disabling ecan on channel: %d\n", channel); res = gpakAlgControl(vpm->dspid, channel, BypassSwCompanding, &pstatus); if (res) { - printk(KERN_WARNING "Unable to disable sw companding on " \ - "echo cancellation channel %d (reason %d)\n", - channel, res); + vpm_info(vpm, "Unable to disable sw companding on " + "echo cancellation channel %d (reason %d)\n", + channel, res); } res = gpakAlgControl(vpm->dspid, channel, BypassEcanA, &pstatus); return res; } +static struct change_order *get_next_order(struct vpmadt032 *vpm) +{ + struct change_order *order; + + spin_lock(&vpm->change_list_lock); + if (!list_empty(&vpm->change_list)) { + order = list_entry(vpm->change_list.next, + struct change_order, node); + list_del(&order->node); + } else { + order = NULL; + } + spin_unlock(&vpm->change_list_lock); + + return order; +} + +static int nlp_settings_changed(const struct adt_lec_params *a, + const struct adt_lec_params *b) +{ + return ((a->nlp_type != b->nlp_type) || + (a->nlp_threshold != b->nlp_threshold) || + (a->nlp_max_suppress != b->nlp_max_suppress)); +} + +static int echocan_on(const struct adt_lec_params *new, + const struct adt_lec_params *old) +{ + return ((new->tap_length != old->tap_length) && + (new->tap_length > 0)); +} + +static int echocan_off(const struct adt_lec_params *new, + const struct adt_lec_params *old) +{ + return ((new->tap_length != old->tap_length) && + (0 == new->tap_length)); +} + +static void update_channel_config(struct vpmadt032 *vpm, unsigned int channel, + struct adt_lec_params *desired) +{ + int res; + GPAK_AlgControlStat_t pstatus; + GPAK_ChannelConfigStat_t cstatus; + GPAK_TearDownChanStat_t tstatus; + GpakChannelConfig_t chanconfig; + + if (vpm->options.debug & DEBUG_ECHOCAN) { + vpm_info(vpm, "Reconfiguring chan %d for nlp %d, " + "nlp_thresh %d, and max_supp %d\n", channel + 1, + desired->nlp_type, desired->nlp_threshold, + desired->nlp_max_suppress); + } + + vpm->setchanconfig_from_state(vpm, channel, &chanconfig); + + res = gpakTearDownChannel(vpm->dspid, channel, &tstatus); + if (res) + return; + + res = gpakConfigureChannel(vpm->dspid, channel, tdmToTdm, + &chanconfig, &cstatus); + if (res) + return; + + if (!desired->tap_length) { + res = gpakAlgControl(vpm->dspid, channel, + BypassSwCompanding, &pstatus); + if (res) { + vpm_info(vpm, "Unable to disable sw companding on " + "echo cancellation channel %d (reason %d)\n", + channel, res); + } + gpakAlgControl(vpm->dspid, channel, BypassEcanA, &pstatus); + } + + return; +} + /** * vpmadt032_bh - Changes the echocan parameters on the vpmadt032 module. * @@ -275,97 +371,80 @@ static void vpmadt032_bh(struct work_struct *data) { struct vpmadt032 *vpm = container_of(data, struct vpmadt032, work); #endif - struct adt_lec_params *curstate, *desiredstate; - int channel; - - /* Sweep through all the echo can channels on the VPMADT032 module, - * looking for ones where the desired state does not match the current - * state. - */ - for (channel = 0; channel < vpm->span->channels; channel++) { - GPAK_AlgControlStat_t pstatus; - int res = 1; - curstate = &vpm->curecstate[channel]; - desiredstate = &vpm->desiredecstate[channel]; - - if ((desiredstate->nlp_type != curstate->nlp_type) || - (desiredstate->nlp_threshold != curstate->nlp_threshold) || - (desiredstate->nlp_max_suppress != curstate->nlp_max_suppress)) { - - GPAK_ChannelConfigStat_t cstatus; - GPAK_TearDownChanStat_t tstatus; - GpakChannelConfig_t chanconfig; - - if (vpm->options.debug & DEBUG_ECHOCAN) - printk(KERN_DEBUG "Reconfiguring chan %d for nlp %d, nlp_thresh %d, and max_supp %d\n", channel + 1, vpm->desiredecstate[channel].nlp_type, - desiredstate->nlp_threshold, desiredstate->nlp_max_suppress); - - vpm->setchanconfig_from_state(vpm, channel, &chanconfig); - - res = gpakTearDownChannel(vpm->dspid, channel, &tstatus); - if (res) - goto vpm_bh_out; - - res = gpakConfigureChannel(vpm->dspid, channel, tdmToTdm, &chanconfig, &cstatus); - if (res) - goto vpm_bh_out; - - if (!desiredstate->tap_length) { - res = gpakAlgControl(vpm->dspid, channel, BypassSwCompanding, &pstatus); - if (res) - printk("Unable to disable sw companding on echo cancellation channel %d (reason %d)\n", channel, res); - res = gpakAlgControl(vpm->dspid, channel, BypassEcanA, &pstatus); - } + struct change_order *order; - } else if (desiredstate->tap_length != curstate->tap_length) { - if (desiredstate->tap_length) - res = vpmadt032_enable_ec(vpm, channel); - else - res = vpmadt032_disable_ec(vpm, channel); - } -vpm_bh_out: - if (!res) - *curstate = *desiredstate; + while ((order = get_next_order(vpm))) { + + struct adt_lec_params *old; + struct adt_lec_params *new; + unsigned int channel; + + channel = order->channel; + BUG_ON(channel >= ARRAY_SIZE(vpm->curecstate)); + old = &vpm->curecstate[channel]; + new = &order->params; + + if (nlp_settings_changed(new, old)) + update_channel_config(vpm, channel, new); + else if (echocan_on(new, old)) + vpmadt032_enable_ec(vpm, channel, new->companding); + else if (echocan_off(new, old)) + vpmadt032_disable_ec(vpm, channel); + + *old = order->params; + free_change_order(order); } - return; } + #include "adt_lec.c" -static void vpmadt032_check_and_schedule_update(struct vpmadt032 *vpm, int channo) -{ - int update; - /* Only update the parameters if the new state of the echo canceller - * is different than the current state. */ - update = memcmp(&vpm->curecstate[channo], - &vpm->desiredecstate[channo], - sizeof(vpm->curecstate[channo])); - if (update && test_bit(VPM150M_ACTIVE, &vpm->control)) { - /* Since updating the parameters can take a bit of time while - * the driver sends messages to the VPMADT032 and waits for - * their responses, we'll push the work of updating the - * parameters to a work queue so the caller can continue to - * proceed with setting up the call. - */ - queue_work(vpm->wq, &vpm->work); +static void vpmadt032_check_and_schedule_update(struct vpmadt032 *vpm, + struct change_order *order) +{ + struct change_order *cur; + struct change_order *n; + + INIT_LIST_HEAD(&order->node); + spin_lock(&vpm->change_list_lock); + list_for_each_entry_safe(cur, n, &vpm->change_list, node) { + if (cur->channel == order->channel) { + list_replace(&cur->node, &order->node); + free_change_order(cur); + break; + } } + if (list_empty(&order->node)) + list_add_tail(&order->node, &vpm->change_list); + spin_unlock(&vpm->change_list_lock); + + queue_work(vpm->wq, &vpm->work); } int vpmadt032_echocan_create(struct vpmadt032 *vpm, int channo, struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p) { unsigned int ret; + struct change_order *order = alloc_change_order(); + if (!order) + return -ENOMEM; - ret = adt_lec_parse_params(&vpm->desiredecstate[channo], ecp, p); - if (ret) + memcpy(&order->params, &vpm->curecstate[channo], sizeof(order->params)); + ret = adt_lec_parse_params(&order->params, ecp, p); + if (ret) { + free_change_order(order); return ret; + } - if (vpm->options.debug & DEBUG_ECHOCAN) - printk(KERN_DEBUG "echocan: Channel is %d length %d\n", channo, ecp->tap_length); + if (vpm->options.debug & DEBUG_ECHOCAN) { + vpm_info(vpm, "Channel is %d length %d\n", + channo, ecp->tap_length); + } /* The driver cannot control the number of taps on the VPMADT032 * module. Instead, it uses tap_length to enable or disable the echo * cancellation. */ - vpm->desiredecstate[channo].tap_length = (ecp->tap_length) ? 1 : 0; + order->params.tap_length = (ecp->tap_length) ? 1 : 0; + order->channel = channo; - vpmadt032_check_and_schedule_update(vpm, channo); + vpmadt032_check_and_schedule_update(vpm, order); return 0; } EXPORT_SYMBOL(vpmadt032_echocan_create); @@ -373,15 +452,22 @@ EXPORT_SYMBOL(vpmadt032_echocan_create); void vpmadt032_echocan_free(struct vpmadt032 *vpm, int channo, struct dahdi_echocan_state *ec) { - adt_lec_init_defaults(&vpm->desiredecstate[channo], 0); - vpm->desiredecstate[channo].nlp_type = vpm->options.vpmnlptype; - vpm->desiredecstate[channo].nlp_threshold = vpm->options.vpmnlpthresh; - vpm->desiredecstate[channo].nlp_max_suppress = vpm->options.vpmnlpmaxsupp; + struct change_order *order; + order = alloc_change_order(); + WARN_ON(!order); + if (!order) + return; + + adt_lec_init_defaults(&order->params, 0); + order->params.nlp_type = vpm->options.vpmnlptype; + order->params.nlp_threshold = vpm->options.vpmnlpthresh; + order->params.nlp_max_suppress = vpm->options.vpmnlpmaxsupp; + order->channel = channo; if (vpm->options.debug & DEBUG_ECHOCAN) - printk(KERN_DEBUG "echocan: Channel is %d length 0\n", channo); + vpm_info(vpm, "Channel is %d length 0\n", channo); - vpmadt032_check_and_schedule_update(vpm, channo); + vpmadt032_check_and_schedule_update(vpm, order); } EXPORT_SYMBOL(vpmadt032_echocan_free); @@ -413,6 +499,8 @@ vpmadt032_alloc(struct vpmadt032_options *options, const char *board_name) /* Init our vpmadt032 struct */ memcpy(&vpm->options, options, sizeof(*options)); spin_lock_init(&vpm->list_lock); + spin_lock_init(&vpm->change_list_lock); + INIT_LIST_HEAD(&vpm->change_list); INIT_LIST_HEAD(&vpm->free_cmds); INIT_LIST_HEAD(&vpm->pending_cmds); INIT_LIST_HEAD(&vpm->active_cmds); @@ -446,8 +534,6 @@ vpmadt032_alloc(struct vpmadt032_options *options, const char *board_name) kfree(vpm); printk(KERN_NOTICE "Unable to initialize another vpmadt032 modules\n"); vpm = NULL; - } else if (vpm->options.debug & DEBUG_ECHOCAN) { - printk(KERN_DEBUG "Setting VPMADT032 DSP ID to %d\n", vpm->dspid); } return vpm; @@ -464,6 +550,9 @@ vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb) BUG_ON(!vpm->setchanconfig_from_state); BUG_ON(!vpm->wq); + BUG_ON(!vb); + + vpm->vb = vb; might_sleep(); @@ -583,6 +672,7 @@ void vpmadt032_free(struct vpmadt032 *vpm) { unsigned long flags; struct vpmadt032_cmd *cmd; + struct change_order *order; LIST_HEAD(local_list); BUG_ON(!vpm); @@ -603,6 +693,16 @@ void vpmadt032_free(struct vpmadt032 *vpm) kfree(cmd); } + spin_lock(&vpm->change_list_lock); + list_splice(&vpm->change_list, &local_list); + spin_unlock(&vpm->change_list_lock); + + while (!list_empty(&local_list)) { + order = list_entry(local_list.next, struct change_order, node); + list_del(&order->node); + kfree(order); + } + BUG_ON(ifaces[vpm->dspid] != vpm); write_lock(&ifacelock); ifaces[vpm->dspid] = NULL; diff --git a/drivers/dahdi/voicebus/GpakCust.h b/drivers/dahdi/voicebus/GpakCust.h index 0546bfb..3a493e1 100644 --- a/drivers/dahdi/voicebus/GpakCust.h +++ b/drivers/dahdi/voicebus/GpakCust.h @@ -105,10 +105,8 @@ struct vpmadt032_options { struct GpakChannelConfig; -#define MAX_CHANNELS_PER_SPAN 32 struct vpmadt032 { - void *context; - const struct dahdi_span *span; + struct voicebus *vb; struct work_struct work; struct workqueue_struct *wq; int dspid; @@ -116,8 +114,10 @@ struct vpmadt032 { unsigned long control; unsigned char curpage; unsigned short version; - struct adt_lec_params curecstate[MAX_CHANNELS_PER_SPAN]; - struct adt_lec_params desiredecstate[MAX_CHANNELS_PER_SPAN]; + enum adt_companding companding; + struct adt_lec_params curecstate[MAX_CHANNELS]; + spinlock_t change_list_lock; + struct list_head change_list; spinlock_t list_lock; /* Commands that are ready to be used. */ struct list_head free_cmds; @@ -125,7 +125,6 @@ struct vpmadt032 { struct list_head pending_cmds; /* Commands that are currently in progress by the VPM module */ struct list_head active_cmds; - unsigned char curtone[MAX_CHANNELS_PER_SPAN]; struct vpmadt032_options options; void (*setchanconfig_from_state)(struct vpmadt032 *vpm, int channel, struct GpakChannelConfig *chanconfig); /* This must be last */ diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c index 1386e5f..70aa969 100644 --- a/drivers/dahdi/wctdm24xxp/base.c +++ b/drivers/dahdi/wctdm24xxp/base.c @@ -312,18 +312,8 @@ void setchanconfig_from_state(struct vpmadt032 *vpm, int channel, GpakChannelCon chanconfig->MuteToneB = Disabled; chanconfig->FaxCngDetB = Disabled; - switch (vpm->span->deflaw) { - case DAHDI_LAW_MULAW: - chanconfig->SoftwareCompand = cmpPCMU; - break; - case DAHDI_LAW_ALAW: - chanconfig->SoftwareCompand = cmpPCMA; - break; - default: - chanconfig->SoftwareCompand = cmpPCMU; - break; - } - + chanconfig->SoftwareCompand = (ADT_COMP_ALAW == vpm->companding) ? + cmpPCMA : cmpPCMU; chanconfig->FrameRate = rate2ms; p = &chanconfig->EcanParametersA; @@ -338,7 +328,7 @@ void setchanconfig_from_state(struct vpmadt032 *vpm, int channel, GpakChannelCon sizeof(chanconfig->EcanParametersB)); } -static int config_vpmadt032(struct vpmadt032 *vpm) +static int config_vpmadt032(struct vpmadt032 *vpm, struct wctdm *wc) { int res, i; GpakPortConfig_t portconfig = {0}; @@ -427,12 +417,12 @@ static int config_vpmadt032(struct vpmadt032 *vpm) return -1; } - for (i = 0; i < vpm->span->channels; ++i) { + for (i = 0; i < vpm->options.channels; ++i) { vpm->curecstate[i].tap_length = 0; vpm->curecstate[i].nlp_type = vpm->options.vpmnlptype; vpm->curecstate[i].nlp_threshold = vpm->options.vpmnlpthresh; vpm->curecstate[i].nlp_max_suppress = vpm->options.vpmnlpmaxsupp; - memcpy(&vpm->desiredecstate[i], &vpm->curecstate[i], sizeof(vpm->curecstate[i])); + vpm->curecstate[i].companding = (wc->span.deflaw == DAHDI_LAW_MULAW) ? ADT_COMP_ULAW : ADT_COMP_ALAW; /* set_vpmadt032_chanconfig_from_state(&vpm->curecstate[i], &vpm->options, i, &chanconfig); !!! */ vpm->setchanconfig_from_state(vpm, i, &chanconfig); @@ -449,6 +439,11 @@ static int config_vpmadt032(struct vpmadt032 *vpm) printk(KERN_NOTICE "Unable to disable echo can on channel %d (reason %d:%d)\n", i + 1, res, algstatus); return -1; } + + if ((res = gpakAlgControl(vpm->dspid, i, BypassSwCompanding, &algstatus))) { + printk(KERN_NOTICE "Unable to disable echo can on channel %d (reason %d:%d)\n", i + 1, res, algstatus); + return -1; + } } if ((res = gpakPingDsp(vpm->dspid, &vpm->version))) { @@ -567,11 +562,6 @@ static inline void cmd_dequeue_vpmadt032(struct wctdm *wc, u8 *writechunk, int w for (x = 24; x < 28; x++) { writechunk[CMD_BYTE(x, 0, 0)] |= leds; } - - /* Now let's figure out if we need to check for DTMF */ - if (test_bit(VPM150M_ACTIVE, &vpmadt032->control) && !whichframe && !(wc->intcount % 100)) { - schedule_work(&vpmadt032->work); - } } static inline void cmd_dequeue(struct wctdm *wc, unsigned char *writechunk, int card, int pos) @@ -3677,8 +3667,7 @@ retry: return -ENOMEM; wc->vpmadt032->setchanconfig_from_state = setchanconfig_from_state; - wc->vpmadt032->context = wc; - wc->vpmadt032->span = &wc->span; + wc->vpmadt032->options.channels = wc->span.channels; get_default_portconfig(&portconfig); res = vpmadt032_init(wc->vpmadt032, wc->vb); if (res) { @@ -3689,7 +3678,7 @@ retry: /* Now we need to configure the VPMADT032 module for this * particular board. */ - res = config_vpmadt032(wc->vpmadt032); + res = config_vpmadt032(wc->vpmadt032, wc); if (res) { vpmadt032_free(wc->vpmadt032); wc->vpmadt032 = NULL; diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c index c4856ca..ae9c975 100644 --- a/drivers/dahdi/wcte12xp/base.c +++ b/drivers/dahdi/wcte12xp/base.c @@ -260,7 +260,7 @@ inline void cmd_decipher_vpmadt032(struct t1 *wc, unsigned char *readchunk) } } -static int config_vpmadt032(struct vpmadt032 *vpm) +static int config_vpmadt032(struct vpmadt032 *vpm, struct t1 *wc) { int res, channel; GpakPortConfig_t portconfig = {0}; @@ -349,12 +349,12 @@ static int config_vpmadt032(struct vpmadt032 *vpm) return -1; } - for (channel = 0; channel < MAX_CHANNELS_PER_SPAN; ++channel) { + for (channel = 0; channel < ARRAY_SIZE(vpm->curecstate); ++channel) { vpm->curecstate[channel].tap_length = 0; vpm->curecstate[channel].nlp_type = vpm->options.vpmnlptype; vpm->curecstate[channel].nlp_threshold = vpm->options.vpmnlpthresh; vpm->curecstate[channel].nlp_max_suppress = vpm->options.vpmnlpmaxsupp; - memcpy(&vpm->desiredecstate[channel], &vpm->curecstate[channel], sizeof(vpm->curecstate[channel])); + vpm->curecstate[channel].companding = (wc->spantype == TYPE_T1) ? ADT_COMP_ULAW : ADT_COMP_ALAW; vpm->setchanconfig_from_state(vpm, channel, &chanconfig); if ((res = gpakConfigureChannel(vpm->dspid, channel, tdmToTdm, &chanconfig, &cstatus))) { @@ -528,11 +528,6 @@ static void cmd_dequeue_vpmadt032(struct t1 *wc, unsigned char *writechunk, int } #endif - /* Now let's figure out if we need to check for DTMF */ - /* polling */ - if (test_bit(VPM150M_ACTIVE, &vpm->control) && !whichframe && !(atomic_read(&wc->txints) % 100)) - schedule_work(&vpm->work); - #if 0 /* This may be needed sometime in the future to troubleshoot ADT related issues. */ if (test_bit(VPM150M_ACTIVE, &vpm->control) && !whichframe && !(atomic_read(&wc->txints) % 10000)) @@ -1313,7 +1308,7 @@ static void setchanconfig_from_state(struct vpmadt032 *vpm, int channel, GpakCha chanconfig->PcmInPortA = 3; chanconfig->PcmInSlotA = (channel + 1) * 2; - chanconfig->PcmOutPortA = 2; + chanconfig->PcmOutPortA = SerialPortNull; chanconfig->PcmOutSlotA = (channel + 1) * 2; chanconfig->PcmInPortB = 2; chanconfig->PcmInSlotB = (channel + 1) * 2; @@ -1388,14 +1383,13 @@ static int t1_hardware_post_init(struct t1 *wc) options.vpmnlptype = vpmnlptype; options.vpmnlpthresh = vpmnlpthresh; options.vpmnlpmaxsupp = vpmnlpmaxsupp; + options.channels = (wc->spantype == TYPE_T1) ? 24 : 32; wc->vpmadt032 = vpmadt032_alloc(&options, wc->name); if (!wc->vpmadt032) return -ENOMEM; - wc->vpmadt032->context = wc; wc->vpmadt032->setchanconfig_from_state = setchanconfig_from_state; - wc->vpmadt032->span = &wc->span; res = vpmadt032_init(wc->vpmadt032, wc->vb); if (res) { @@ -1404,7 +1398,7 @@ static int t1_hardware_post_init(struct t1 *wc) return -EIO; } - config_vpmadt032(wc->vpmadt032); + config_vpmadt032(wc->vpmadt032, wc); set_span_devicetype(wc); module_printk("VPM present and operational (Firmware version %x)\n", wc->vpmadt032->version); diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h index 6058779..c07b45a 100644 --- a/include/dahdi/kernel.h +++ b/include/dahdi/kernel.h @@ -1172,6 +1172,16 @@ static inline short dahdi_txtone_nextsample(struct dahdi_chan *ss) #define kzalloc(a, b) kcalloc(1, a, b) #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +static inline void list_replace(struct list_head *old, struct list_head *new) +{ + new->next = old->next; + new->next->prev = new; + new->prev = old->prev; + new->prev->next = new; +} +#endif + #ifndef DMA_BIT_MASK #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) #endif -- cgit v1.2.3