summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2010-04-06 19:05:27 +0000
committerShaun Ruffell <sruffell@digium.com>2010-04-06 19:05:27 +0000
commit91a60ef0e3c9c4485e5df84131ae91ba365a7079 (patch)
tree7ca8fa9e1f1114cc90ff1e223bbb08245f7ff8b0
parent35e23f0e6348c906b33d6bc3f9698b62eb36c30c (diff)
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
-rw-r--r--drivers/dahdi/wcte12xp/base.c171
1 files 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;
}