[zaptel-commits] trunk r1100 - /trunk/wct4xxp.c

zaptel-commits at lists.digium.com zaptel-commits at lists.digium.com
Wed May 31 11:16:18 MST 2006


Author: mattf
Date: Wed May 31 13:16:18 2006
New Revision: 1100

URL: http://svn.digium.com/view/zaptel?rev=1100&view=rev
Log:
Fix so that HardHDLC works if ztcfg is ran twice.  Thanks PCadach!

Modified:
    trunk/wct4xxp.c

Modified: trunk/wct4xxp.c
URL: http://svn.digium.com/view/zaptel/trunk/wct4xxp.c?rev=1100&r1=1099&r2=1100&view=diff
==============================================================================
--- trunk/wct4xxp.c (original)
+++ trunk/wct4xxp.c Wed May 31 13:16:18 2006
@@ -388,6 +388,13 @@
 
 #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)
 {
@@ -666,6 +673,8 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	}
 	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 @@
 	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 @@
 		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 @@
 
 	/* 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 @@
 		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 @@
 	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 @@
 		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 @@
 	__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 @@
 		}
 		/* 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 @@
 	}
 
 	/* HDLC controller checks - receive side */
-	if (!wc->tspans[span]->sigchan)
+	if (!ts->sigchan)
 		return;
 
 	if (isr0 & FRMR_ISR0_RME) {
@@ -3022,6 +3031,7 @@
 	__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;



More information about the zaptel-commits mailing list