summaryrefslogtreecommitdiff
path: root/wct4xxp.c
diff options
context:
space:
mode:
authormattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-05-31 18:16:18 +0000
committermattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-05-31 18:16:18 +0000
commit52f4d906cbe39a90bb9254492705dc4ace45f58f (patch)
tree642763cb3520db8896c6345d2189cb5b3afc3d67 /wct4xxp.c
parentcb603ecd4c11c62eac1bbf1d73ef425dc3dcef30 (diff)
Fix so that HardHDLC works if ztcfg is ran twice. Thanks PCadach!
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1100 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wct4xxp.c')
-rw-r--r--wct4xxp.c84
1 files changed, 47 insertions, 37 deletions
diff --git a/wct4xxp.c b/wct4xxp.c
index fd2b05e..31de0ca 100644
--- a/wct4xxp.c
+++ b/wct4xxp.c
@@ -389,6 +389,13 @@ static struct t4 *cards[MAX_T4_CARDS];
#define MAX_TDM_CHAN 32
#define MAX_DTMF_DET 16
+#define HDLC_IMR0_MASK (FRMR_IMR0_RME | FRMR_IMR0_RPF)
+#if 0
+#define HDLC_IMR1_MASK (FRMR_IMR1_ALLS | FRMR_IMR1_XDU | FRMR_IMR1_XPR)
+#else
+#define HDLC_IMR1_MASK (FRMR_IMR1_XDU | FRMR_IMR1_XPR)
+#endif
+
static inline unsigned int __t4_pci_in(struct t4 *wc, const unsigned int addr)
{
unsigned int res = le32_to_cpu(wc->membase[addr]);
@@ -666,6 +673,8 @@ static void __hdlc_stop(struct t4 *wc, unsigned int span)
unsigned char imr0, imr1, mode;
int i = 0;
+ if (debug & DEBUG_FRAMER) printk("Stopping HDLC controller on span %d\n", span+1);
+
/* Clear receive and transmit timeslots */
for (i = 0; i < 4; i++) {
__t4_framer_out(wc, span, FRMR_RTR_BASE + i, 0x00);
@@ -676,20 +685,16 @@ static void __hdlc_stop(struct t4 *wc, unsigned int span)
imr1 = __t4_framer_in(wc, span, FRMR_IMR1);
/* Disable HDLC interrupts */
- imr0 |= FRMR_IMR0_RME | FRMR_IMR0_RPF;
+ imr0 |= HDLC_IMR0_MASK;
__t4_framer_out(wc, span, FRMR_IMR0, imr0);
-#if 0
- imr1 |= FRMR_IMR1_ALLS | FRMR_IMR1_XDU | FRMR_IMR1_XPR;
-#endif
- imr1 |= FRMR_IMR1_XDU | FRMR_IMR1_XPR;
+ imr1 |= HDLC_IMR1_MASK;
__t4_framer_out(wc, span, FRMR_IMR1, imr1);
mode = __t4_framer_in(wc, span, FRMR_MODE);
mode &= ~FRMR_MODE_HRAC;
__t4_framer_out(wc, span, FRMR_MODE, mode);
- t->sigchan = NULL;
t->sigactive = 0;
}
@@ -724,7 +729,7 @@ static int __hdlc_start(struct t4 *wc, unsigned int span, struct zt_chan *chan,
unsigned char imr0, imr1;
int offset = chan->chanpos;
- if (debug & DEBUG_FRAMER) printk("Initializing signalling controller for channel %d span %d\n", chan->chanpos, chan->span->offset);
+ if (debug & DEBUG_FRAMER) printk("Starting HDLC controller for channel %d span %d\n", offset, span+1);
if (mode != FRMR_MODE_NO_ADDR_CMP)
return -1;
@@ -749,13 +754,10 @@ static int __hdlc_start(struct t4 *wc, unsigned int span, struct zt_chan *chan,
imr1 = __t4_framer_in(wc, span, FRMR_IMR1);
/* Enable our interrupts again */
- imr0 &= ~(FRMR_IMR0_RME | FRMR_IMR0_RPF);
+ imr0 &= ~HDLC_IMR0_MASK;
__t4_framer_out(wc, span, FRMR_IMR0, imr0);
-#if 0
- imr1 &= ~(FRMR_IMR1_ALLS | FRMR_IMR1_XDU | FRMR_IMR1_XPR);
-#endif
- imr1 &= ~(FRMR_IMR1_XDU | FRMR_IMR1_XPR);
+ imr1 &= ~HDLC_IMR1_MASK;
__t4_framer_out(wc, span, FRMR_IMR1, imr1);
/* Reset the signaling controller */
@@ -801,12 +803,12 @@ static void __set_clear(struct t4 *wc, int span)
}
if (ts->notclear != oldnotclear) {
unsigned char reg;
- reg = __t4_framer_in(wc, span, 0x14);
+ reg = __t4_framer_in(wc, span, FRMR_IMR0);
if (ts->notclear)
reg &= ~0x08;
else
reg |= 0x08;
- __t4_framer_out(wc, span, 0x14, reg);
+ __t4_framer_out(wc, span, FRMR_IMR0, reg);
}
}
@@ -996,7 +998,12 @@ static void t4_hdlc_hard_xmit(struct zt_chan *chan)
unsigned long flags;
spin_lock_irqsave(&wc->reglock, flags);
- if (debug & DEBUG_FRAMER) printk("t4_hdlc_hard_xmit, sigactive=%d\n", ts->sigactive);
+ if (!ts->sigchan) {
+ printk("t4_hdlc_hard_xmit: Invalid (NULL) signalling channel\n");
+ spin_unlock_irqrestore(&wc->reglock, flags);
+ return;
+ }
+ if (debug & DEBUG_FRAMER) printk("t4_hdlc_hard_xmit on channel %s (sigchan %s), sigactive=%d\n", chan->name, ts->sigchan->name, ts->sigactive);
if ((ts->sigchan == chan) && !ts->sigactive)
__t4_hdlc_xmit_fifo(wc, span, ts);
spin_unlock_irqrestore(&wc->reglock, flags);
@@ -1127,6 +1134,8 @@ static int t4_shutdown(struct zt_span *span)
return -1;
}
+ if (debug & DEBUG_MAIN) printk("Shutting down span %d (%s)\n", span->spanno, span->name);
+
spin_lock_irqsave(&wc->reglock, flags);
wasrunning = span->flags & ZT_FLAG_RUNNING;
@@ -1136,7 +1145,7 @@ static int t4_shutdown(struct zt_span *span)
/* Stop HDLC controller if runned */
if (ts->sigchan)
- __hdlc_stop(wc, ts->sigchan->span->offset);
+ __hdlc_stop(wc, span->offset);
__t4_set_led(wc, span->offset, WC_OFF);
if (((wc->numspans == 4) &&
@@ -1190,15 +1199,7 @@ static int t4_spanconfig(struct zt_span *span, struct zt_lineconfig *lc)
wc->tspans[lc->sync - 1]->psync = span->offset + 1;
}
wc->checktiming = 1;
- /* HDLC controller part */
- if (ts->sigchan) {
- unsigned long flags;
- spin_lock_irqsave(&wc->reglock, flags);
- __hdlc_stop(wc, ts->sigchan->span->offset);
- spin_unlock_irqrestore(&wc->reglock, flags);
- }
-
/* If we're already running, then go ahead and apply the changes */
if (span->flags & ZT_FLAG_RUNNING)
return t4_startup(span);
@@ -1226,18 +1227,25 @@ static int t4_chanconfig(struct zt_chan *chan, int sigtype)
if (alreadyrunning)
__set_clear(wc, chan->span->offset);
- if ((sigtype == ZT_SIG_HARDHDLC) && (ts->sigchan != chan)) {
+ /* (re)configure signalling channel */
+ if ((sigtype == ZT_SIG_HARDHDLC) || (ts->sigchan == chan)) {
+ if (debug & DEBUG_FRAMER)
+ printk("%sonfiguring hardware HDLC on %s\n", ((sigtype == ZT_SIG_HARDHDLC) ? "C" : "Unc"), chan->name);
if (alreadyrunning) {
if (ts->sigchan)
__hdlc_stop(wc, ts->sigchan->span->offset);
- if (__hdlc_start(wc, chan->span->offset, chan, ts->sigmode)) {
- printk("Error initializing signalling controller\n");
- spin_unlock_irqrestore(&wc->reglock, flags);
- return -1;
+ if (sigtype == ZT_SIG_HARDHDLC) {
+ if (__hdlc_start(wc, chan->span->offset, chan, ts->sigmode)) {
+ printk("Error initializing signalling controller\n");
+ spin_unlock_irqrestore(&wc->reglock, flags);
+ return -1;
+ }
}
+ else
+ ts->sigchan = NULL;
}
else {
- ts->sigchan = chan;
+ ts->sigchan = (sigtype == ZT_SIG_HARDHDLC) ? chan : NULL;
ts->sigactive = 0;
}
}
@@ -1613,8 +1621,9 @@ static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlev
break;
}
- __t4_framer_out(wc, unit, 0x14, 0xff); /* IMR0: We care about CAS changes, etc */
- __t4_framer_out(wc, unit, 0x15, 0xff); /* IMR1: We care about nothing */
+ /* Don't mask framer interrupts if hardware HDLC is in use */
+ __t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0)); /* IMR0: We care about CAS changes, etc */
+ __t4_framer_out(wc, unit, FRMR_IMR1, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0)); /* IMR1: We care about nothing */
__t4_framer_out(wc, unit, 0x16, 0x00); /* IMR2: We care about all the alarm stuff! */
if (debugslips) {
__t4_framer_out(wc, unit, 0x17, 0xf4); /* IMR3: We care about AIS and friends */
@@ -1701,8 +1710,9 @@ static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig)
__t4_framer_out(wc, unit, 0x27, 0x02); /* XPM1 */
__t4_framer_out(wc, unit, 0x28, 0x00); /* XPM2 */
- __t4_framer_out(wc, unit, 0x14, 0xff); /* IMR0: We care about CRC errors, CAS changes, etc */
- __t4_framer_out(wc, unit, 0x15, 0x3f); /* IMR1: We care about loopup / loopdown */
+ /* Don't mask framer interrupts if hardware HDLC is in use */
+ __t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0)); /* IMR0: We care about CRC errors, CAS changes, etc */
+ __t4_framer_out(wc, unit, FRMR_IMR1, 0x3f & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0)); /* IMR1: We care about loopup / loopdown */
__t4_framer_out(wc, unit, 0x16, 0x00); /* IMR2: We care about all the alarm stuff! */
if (debugslips) {
__t4_framer_out(wc, unit, 0x17, 0xc4 | imr3extra); /* IMR3: We care about AIS and friends */
@@ -1785,8 +1795,7 @@ static int t4_startup(struct zt_span *span)
}
/* Startup HDLC controller too */
if (ts->sigchan) {
- printk("Starting HDLC controller for channel %d span %d\n", ts->sigchan->channo, ts->sigchan->span->offset);
- if (__hdlc_start(wc, ts->sigchan->span->offset, ts->sigchan, ts->sigmode)) {
+ if (__hdlc_start(wc, span->offset, ts->sigchan, ts->sigmode)) {
printk("Error initializing signalling controller\n");
/* XXX Should de-initialize span XXX */
spin_unlock_irqrestore(&wc->reglock, flags);
@@ -2372,7 +2381,7 @@ static inline void __t4_framer_interrupt(struct t4 *wc, int span)
}
/* HDLC controller checks - receive side */
- if (!wc->tspans[span]->sigchan)
+ if (!ts->sigchan)
return;
if (isr0 & FRMR_ISR0_RME) {
@@ -3022,6 +3031,7 @@ static void t4_tsi_unassign(struct t4 *wc, int tospan, int tochan)
__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
spin_unlock_irqrestore(&wc->reglock, flags);
}
+
static int t4_hardware_init_1(struct t4 *wc, int gen2)
{
unsigned int version;