diff options
author | mattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-05-31 18:16:18 +0000 |
---|---|---|
committer | mattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-05-31 18:16:18 +0000 |
commit | 52f4d906cbe39a90bb9254492705dc4ace45f58f (patch) | |
tree | 642763cb3520db8896c6345d2189cb5b3afc3d67 /wct4xxp.c | |
parent | cb603ecd4c11c62eac1bbf1d73ef425dc3dcef30 (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.c | 84 |
1 files changed, 47 insertions, 37 deletions
@@ -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; |