From 1ab5fa38aab79228f241525048c48425274d1287 Mon Sep 17 00:00:00 2001 From: markster Date: Mon, 16 Dec 2002 19:15:20 +0000 Subject: Version 0.4.0 from FTP git-svn-id: http://svn.digium.com/svn/zaptel/trunk@138 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- tor2.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 131 insertions(+), 34 deletions(-) (limited to 'tor2.c') diff --git a/tor2.c b/tor2.c index 4eb0847..8b3e64e 100755 --- a/tor2.c +++ b/tor2.c @@ -85,6 +85,8 @@ struct tor2 { int irq; /* IRQ used by device */ int order; /* Order */ int flags; /* Device flags */ + int syncpos[4]; /* span-relative sync sources */ + int master; /* Are we master */ unsigned long plx_region; /* phy addr of PCI9030 registers */ unsigned long plx_len; /* length of PLX window */ volatile unsigned short *plx; /* Virtual representation of local space */ @@ -142,6 +144,8 @@ static void tor2_tasklet(unsigned long data); #define E1DIV 0x10 #define INTACK (0x80 + ((loopback & 3) << 5)) #define INTACTIVE 2 +#define MASTER (1 << 3) + /* un-define this if you dont want NON-REV A hardware support */ /* #define NONREVA 1 */ @@ -150,6 +154,7 @@ static void tor2_tasklet(unsigned long data); #define SYNC2 2 #define SYNC3 3 #define SYNC4 4 +#define SYNCEXTERN 5 #define LEDRED 2 #define LEDGREEN 1 @@ -165,6 +170,7 @@ struct tor2 *cards[MAX_TOR_CARDS]; static int debug; static int loopback; static int highestorder; +static int timingcable; static void set_clear(struct tor2 *tor); static int tor2_startup(struct zt_span *span); @@ -204,6 +210,7 @@ static int tor2_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) p->tor->psyncs[i] = 0; } } + p->tor->syncpos[p->span] = lc->sync; /* if a sync src, put it in proper place */ if (lc->sync) { p->tor->syncs[lc->sync - 1] = span->spanno; @@ -770,12 +777,17 @@ static int tor2_startup(struct zt_span *span) memset(p->tor->ec_chunk2[p->span][i], ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE); } + /* Force re-evaluation fo timing source */ + if (timingcable) + p->tor->syncsrc = -1; + if (p->tor->cardtype == TYPE_E1) { /* if this is an E1 card */ unsigned char tcr1,ccr1; if (!alreadyrunning) { p->tor->mem8[SYNCREG] = SYNCSELF; p->tor->mem8[CTLREG] = E1DIV; p->tor->mem8[LEDREG] = 0; + /* Force re-evaluation of sync src */ /* Zero out all registers */ for (i = 0; i < 192; i++) t1out(p->tor,tspan, i, 0); @@ -1030,6 +1042,87 @@ static void tor2_tasklet(unsigned long data) } #endif +static int syncsrc = 0; +static int syncnum = 0 /* -1 */; +static int syncspan = 0; +static spinlock_t synclock = SPIN_LOCK_UNLOCKED; + +static int tor2_findsync(struct tor2 *tor) +{ + int i; + int x; + long flags; + int p; + int nonzero; + int newsyncsrc = 0; /* Zaptel span number */ + int newsyncnum = 0; /* tor2 card number */ + int newsyncspan = 0; /* span on given tor2 card */ + spin_lock_irqsave(&synclock, flags); +#if 1 + if (!tor->num) { + /* If we're the first card, go through all the motions, up to 8 levels + of sync source */ + p = 1; + while(p < 8) { + nonzero = 0; + for (x=0;cards[x];x++) { + for (i=0;i<4;i++) { + if (cards[x]->syncpos[i]) { + nonzero = 1; + if ((cards[x]->syncpos[i] == p) && + !(cards[x]->spans[i].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | ZT_ALARM_LOOPBACK)) && + (cards[x]->spans[i].flags & ZT_FLAG_RUNNING)) { + /* This makes a good sync source */ + newsyncsrc = cards[x]->spans[i].spanno; + newsyncnum = x; + newsyncspan = i + 1; + /* Jump out */ + goto found; + } + } + } + } + if (nonzero) + p++; + else + break; + } +found: + if ((syncnum != newsyncnum) || (syncsrc != newsyncsrc) || (newsyncspan != syncspan)) { + syncnum = newsyncnum; + syncsrc = newsyncsrc; + syncspan = newsyncspan; + if (debug) printk("New syncnum: %d, syncsrc: %d, syncspan: %d\n", syncnum, syncsrc, syncspan); + } + } +#endif + /* update sync src info */ + if (tor->syncsrc != syncsrc) { + tor->syncsrc = syncsrc; + /* Update sync sources */ + for(i = 0; i < 4; i++) { + tor->spans[i].syncsrc = tor->syncsrc; + } + if (syncnum == tor->num) { +#if 1 + /* actually set the sync register */ + tor->mem8[SYNCREG] = syncspan; +#endif + if (debug) printk("Card %d, using sync span %d, master\n", tor->num, syncspan); + tor->master = MASTER; + } else { +#if 1 + /* time from the timing cable */ + tor->mem8[SYNCREG] = SYNCEXTERN; +#endif + tor->master = 0; + if (debug) printk("Card %d, using Timing Bus, NOT master\n", tor->num); + } + } + spin_unlock_irqrestore(&synclock, flags); + return 0; +} + static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) { int n, i, j, k, syncsrc; @@ -1047,10 +1140,10 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) if (tor->cardtype == TYPE_E1) /* set outbit, interrupt enable, and ack interrupt */ - tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK | E1DIV; + tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK | E1DIV | tor->master; else /* set outbit, interrupt enable, and ack interrupt */ - tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK; + tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK | tor->master; #if 0 if (!tor->passno) @@ -1089,7 +1182,7 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) } } - i = tor->passno & 63; + i = tor->passno & 15; /* if an E1 card, do rx signalling for it */ if ((i < 3) && (tor->cardtype == TYPE_E1)) { /* if an E1 card */ for(j = (i * 5); j < (i * 5) + 5; j++) @@ -1148,11 +1241,11 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) } } - i = tor->passno & 63; - if ((i >= 50) && (i <= 53)) + i = tor->passno & 15; + if ((i >= 10) && (i <= 13)) { j = 0; /* clear this alarm status */ - i -= 50; + i -= 10; if (tor->cardtype == TYPE_T1) { c = t1in(tor,i + 1,0x31); /* get RIR2 */ tor->spans[i].rxlevel = c >> 6; /* get rx level */ @@ -1259,36 +1352,39 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) tor->spans[i - 1].bpvcount += t1in(tor,i,0x24) + (t1in(tor,i,0x23) << 8); } } - /* re-evaluate active sync src */ - tor->syncsrc = 0; - syncsrc = 0; - /* if primary sync specified, see if we can use it */ - if (tor->psyncs[0]) - { - /* if no alarms, use it */ - if (!(tor->spans[tor->psyncs[0] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | - ZT_ALARM_LOOPBACK))) { - tor->syncsrc = tor->psyncs[0]; - syncsrc = tor->syncs[0]; - } - } - /* if any others specified, see if we can use them */ - for(i = 1; i < 4; i++) { - /* if we dont have one yet, and there is one specified at this level, see if we can use it */ - if ((!tor->syncsrc) && (tor->psyncs[i])) { + if (!timingcable) { + /* re-evaluate active sync src (no cable version) */ + tor->syncsrc = 0; + syncsrc = 0; + /* if primary sync specified, see if we can use it */ + if (tor->psyncs[0]) + { /* if no alarms, use it */ - if (!(tor->spans[tor->psyncs[i] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | + if (!(tor->spans[tor->psyncs[0] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | ZT_ALARM_LOOPBACK))) { - tor->syncsrc = tor->psyncs[i]; - syncsrc = tor->syncs[i]; + tor->syncsrc = tor->psyncs[0]; + syncsrc = tor->syncs[0]; } + } + /* if any others specified, see if we can use them */ + for(i = 1; i < 4; i++) { + /* if we dont have one yet, and there is one specified at this level, see if we can use it */ + if ((!tor->syncsrc) && (tor->psyncs[i])) { + /* if no alarms, use it */ + if (!(tor->spans[tor->psyncs[i] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | + ZT_ALARM_LOOPBACK))) { + tor->syncsrc = tor->psyncs[i]; + syncsrc = tor->syncs[i]; + } + } } - } - /* update sync src info */ - for(i = 0; i < 4; i++) tor->spans[i].syncsrc = syncsrc; + /* update sync src info */ + for(i = 0; i < 4; i++) tor->spans[i].syncsrc = syncsrc; - /* actually set the sync register */ - tor->mem8[SYNCREG] = tor->syncsrc; + /* actually set the sync register */ + tor->mem8[SYNCREG] = tor->syncsrc; + } else /* Timing cable version */ + tor2_findsync(tor); tor->passno++; @@ -1303,13 +1399,13 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) #else tor2_run(tor); #endif - + /* We are not the timing bus master */ if (tor->cardtype == TYPE_E1) /* clear OUTBIT and enable interrupts */ - tor->mem8[CTLREG] = INTENA | E1DIV; + tor->mem8[CTLREG] = INTENA | E1DIV | tor->master; else /* clear OUTBIT and enable interrupts */ - tor->mem8[CTLREG] = INTENA; + tor->mem8[CTLREG] = INTENA | tor->master; } @@ -1329,6 +1425,7 @@ MODULE_LICENSE("GPL"); #endif MODULE_PARM(debug, "i"); MODULE_PARM(loopback, "i"); +MODULE_PARM(timingcable, "i"); MODULE_DEVICE_TABLE(pci, tor2_pci_ids); -- cgit v1.2.3