From 91a60ef0e3c9c4485e5df84131ae91ba365a7079 Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Tue, 6 Apr 2010 19:05:27 +0000 Subject: wcte12xp: Reprogram the VPM only when neccessary. Only program the VPM in spanconfig if it either is not setup, or if it fails a ping test. Also, if the channel config fails (but ping would otherwise work), force a reset / reconfiguration if the VPM module. DAHDI-573. git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@8478 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/wcte12xp/base.c | 171 +++++++++++++++++++++++++----------------- 1 file changed, 103 insertions(+), 68 deletions(-) diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c index 81eade0..837188e 100644 --- a/drivers/dahdi/wcte12xp/base.c +++ b/drivers/dahdi/wcte12xp/base.c @@ -1379,61 +1379,91 @@ setchanconfig_from_state(struct vpmadt032 *vpm, int channel, sizeof(chanconfig->EcanParametersB)); } -static int -t1xxp_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc) +#ifdef VPM_SUPPORT +static int check_and_load_vpm(struct t1 *wc) { - struct vpmadt032_options options; - struct t1 *wc = span->pvt; int res; + struct vpmadt032_options options; -#ifdef VPM_SUPPORT - if (!fatal_signal_pending(current) && vpmsupport) { - struct vpmadt032 *vpm; - memset(&options, 0, sizeof(options)); - options.debug = debug; - options.vpmnlptype = vpmnlptype; - options.vpmnlpthresh = vpmnlpthresh; - options.vpmnlpmaxsupp = vpmnlpmaxsupp; - options.channels = (wc->spantype == TYPE_T1) ? 24 : 32; - - wc->vpm_check = jiffies + HZ*600; - wc->vpmadt032 = vpmadt032_alloc(&options, wc->name); - if (!wc->vpmadt032) - return -ENOMEM; + if (!vpmsupport) { + t1_info(wc, "VPM Support Disabled\n"); + vpmadt032_free(wc->vpmadt032); + wc->vpmadt032 = NULL; + return 0; + } - vpm = wc->vpmadt032; - vpm->setchanconfig_from_state = setchanconfig_from_state; + /* The firmware may already be loaded. */ + if (wc->vpmadt032) { + u16 version; + res = gpakPingDsp(wc->vpmadt032->dspid, &version); + if (!res) + return 0; + } - res = vpmadt032_init(vpm, &wc->vb); - if (-ENODEV == res) { - wc->vpm_check = jiffies + HZ*600; - vpmadt032_free(vpm); - wc->vpmadt032 = NULL; - } else if (res) { - wc->vpm_check = jiffies + HZ/2; - } else { - set_span_devicetype(wc); - if (config_vpmadt032(vpm, wc)) { - wc->vpm_check = jiffies + HZ/2; - } else { - /* turn on vpm (RX audio from vpm module) */ - set_bit(4, &wc->ctlreg); - wc->vpm_check = jiffies + HZ*5; - if (vpmtsisupport) { - debug_printk(wc, 1, - "enabling VPM TSI pin\n"); - /* turn on vpm timeslot - * interchange pin */ - set_bit(0, &wc->ctlreg); - } - } - } - } else { - t1_info(wc, "VPM Support Disabled\n"); + memset(&options, 0, sizeof(options)); + options.debug = debug; + options.vpmnlptype = vpmnlptype; + options.vpmnlpthresh = vpmnlpthresh; + options.vpmnlpmaxsupp = vpmnlpmaxsupp; + options.channels = (TYPE_T1 == wc->spantype) ? 24 : 32; + + /* We do not want to check that the VPM is alive until after we're + * done setting it up here, an hour should cover it... */ + wc->vpm_check = jiffies + HZ*3600; + + wc->vpmadt032 = vpmadt032_alloc(&options, wc->name); + if (!wc->vpmadt032) + return -ENOMEM; + + wc->vpmadt032->setchanconfig_from_state = setchanconfig_from_state; + + res = vpmadt032_init(wc->vpmadt032, &wc->vb); + if (-ENODEV == res) { + /* There does not appear to be a VPMADT032 installed. */ + vpmadt032_free(wc->vpmadt032); wc->vpmadt032 = NULL; + clear_bit(4, &wc->ctlreg); + return res; + + } else if (res) { + /* There was some problem during initialization, but it passed + * the address test, let's try again in a bit. */ + wc->vpm_check = jiffies + HZ/2; + return -EAGAIN; } + + if (config_vpmadt032(wc->vpmadt032, wc)) { + clear_bit(4, &wc->ctlreg); + wc->vpm_check = jiffies + HZ/2; + return -EAGAIN; + } + + /* turn on vpm (RX audio from vpm module) */ + set_bit(4, &wc->ctlreg); + wc->vpm_check = jiffies + HZ*5; + if (vpmtsisupport) { + debug_printk(wc, 1, "enabling VPM TSI pin\n"); + /* turn on vpm timeslot interchange pin */ + set_bit(0, &wc->ctlreg); + } + + return 0; +} +#else +static inline int check_and_load_vpm(const struct t1 *wc) +{ + return 0; +} #endif +static int +t1xxp_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc) +{ + struct t1 *wc = span->pvt; + + check_and_load_vpm(wc); + set_span_devicetype(wc); + /* Do we want to SYNC on receive or not */ if (lc->sync) { set_bit(7, &wc->ctlreg); @@ -1941,32 +1971,39 @@ static void vpm_check_func(struct work_struct *work) int res; u16 version; - res = gpakPingDsp(wc->vpmadt032->dspid, &version); - if (!res) { - set_bit(4, &wc->ctlreg); - return; - } + if (test_bit(4, &wc->ctlreg)) { + res = gpakPingDsp(wc->vpmadt032->dspid, &version); + if (!res) { + set_bit(4, &wc->ctlreg); + wc->vpm_check = jiffies + HZ*5; + return; + } - clear_bit(4, &wc->ctlreg); + clear_bit(4, &wc->ctlreg); + t1_info(wc, "VPMADT032 is non-responsive. Resetting.\n"); + } - t1_info(wc, "VPMADT032 is non-responsive. Resetting.\n"); res = vpmadt032_reset(wc->vpmadt032); - if (!res) { - res = config_vpmadt032(wc->vpmadt032, wc); - if (res) { - queue_work(wc->vpmadt032->wq, &wc->vpm_check_work); - return; - } - /* Looks like the reset went ok so we can put the VPM module - * back in the TDM path. */ - set_bit(4, &wc->ctlreg); - t1_info(wc, "VPMADT032 is reenabled.\n"); - } else { - t1_info(wc, "Failed VPMADT032 reset. " - "VPMADT032 is disabled.\n"); + if (res) { + t1_info(wc, "Failed VPMADT032 reset. VPMADT032 is disabled.\n"); + wc->vpm_check = jiffies + HZ*5; + return; + } + + res = config_vpmadt032(wc->vpmadt032, wc); + if (res) { + /* We failed the configuration, let's try again. */ + t1_info(wc, "Failed to configure the ports. Retrying.\n"); + queue_work(wc->vpmadt032->wq, &wc->vpm_check_work); + return; } + /* Looks like the reset went ok so we can put the VPM module back in + * the TDM path. */ + set_bit(4, &wc->ctlreg); + t1_info(wc, "VPMADT032 is reenabled.\n"); + wc->vpm_check = jiffies + HZ*5; return; } @@ -1985,8 +2022,6 @@ static void te12xp_timer(unsigned long data) if (time_after(wc->vpm_check, jiffies)) return; - /* We'll check the VPM module again in 5 seconds. */ - wc->vpm_check = jiffies + 5*HZ; queue_work(wc->vpmadt032->wq, &wc->vpm_check_work); return; } -- cgit v1.2.3