From b05391fe2b5ae43144d789f91e8c3d1989cefd78 Mon Sep 17 00:00:00 2001 From: markster Date: Mon, 4 Mar 2002 15:45:10 +0000 Subject: Version 0.1.6 from FTP git-svn-id: http://svn.digium.com/svn/zaptel/trunk@62 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- tor2.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 26 deletions(-) (limited to 'tor2.c') diff --git a/tor2.c b/tor2.c index 902a785..de55c00 100755 --- a/tor2.c +++ b/tor2.c @@ -42,6 +42,16 @@ #include "tor2-hw.h" #include "tor2fw.h" +/* + * Tasklets provide better system interactive response at the cost of the + * possibility of losing a frame of data at very infrequent intervals. If + * you are more concerned with the performance of your machine, enable the + * tasklets. If you are strict about absolutely no drops, then do not enable + * tasklets. + */ + +#define ENABLE_TASKLETS + #define MAX_SPANS 16 #define FLAG_STARTED (1 << 0) @@ -69,6 +79,7 @@ struct tor2 { int num; /* Which card we are */ int syncsrc; /* active sync source */ int syncs[4]; /* sync sources */ + int psyncs[4]; /* span-relative sync sources */ int alarmtimer[4]; /* Alarm timer */ char *type; /* Type of tormenta 2 card */ int irq; /* IRQ used by device */ @@ -92,20 +103,25 @@ struct tor2 { int spansstarted; /* number of spans started */ spinlock_t lock; /* lock context */ unsigned char leds; /* copy of LED register */ +#ifdef ENABLE_TASKLETS int taskletrun; int taskletsched; int taskletpending; int taskletexec; int txerrors; struct tasklet_struct tor2_tlet; +#endif int cardtype; /* card type, T1 or E1 */ unsigned int *datxlt; /* pointer to datxlt structure */ + unsigned int passno; /* number of interrupt passes */ }; #define t1out(tor,span,reg,val) tor->mem8[((span - 1) * 0x100) + reg] = val #define t1in(tor,span,reg) tor->mem8[((span - 1) * 0x100) + reg] +#ifdef ENABLE_TASKLETS static void tor2_tasklet(unsigned long data); +#endif #define GPIOC (PLX_LOC_GPIOC >> 1) /* word-oriented address for PLX GPIOC reg. (32 bit reg.) */ #define INTCSR (0x4c >> 1) /* word-oriented address for PLX INTCSR reg. */ @@ -174,10 +190,17 @@ static int tor2_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) span->syncsrc = p->tor->syncsrc; /* remove this span number from the current sync sources, if there */ - for(i = 0; i < 3; i++) if (p->tor->syncs[i] == span->spanno) p->tor->syncs[i] = 0; + for(i = 0; i < 3; i++) { + if (p->tor->syncs[i] == span->spanno) { + p->tor->syncs[i] = 0; + p->tor->psyncs[i] = 0; + } + } /* if a sync src, put it in proper place */ - if (lc->sync) p->tor->syncs[lc->sync - 1] = span->spanno; - + if (lc->sync) { + p->tor->syncs[lc->sync - 1] = span->spanno; + p->tor->psyncs[lc->sync - 1] = p->span + 1; + } /* If we're already running, then go ahead and apply the changes */ if (span->flags & ZT_FLAG_RUNNING) return tor2_startup(span); @@ -274,6 +297,7 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id if (!tor) return -ENOMEM; memset(tor,0,sizeof(struct tor2)); + spin_lock_init(&tor->lock); for(x = 0; x < 4; x++) { tor->chans[x] = kmalloc(sizeof(struct zt_chan) * 31,GFP_KERNEL); if (!tor->chans[x]) @@ -431,7 +455,9 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id goto err_out_release_all; } tor->plx[INTCSR] = PLX_INTENA; /* enable PLX interrupt */ +#ifdef ENABLE_TASKLETS tasklet_init(&tor->tor2_tlet, tor2_tasklet, (unsigned long)tor); +#endif return 0; err_out_release_all: @@ -880,6 +906,7 @@ static int tor2_maint(struct zt_span *span, int cmd) return 0; } +#ifdef ENABLE_TASKLETS static void tor2_tasklet(unsigned long data) { struct tor2 *tor = (struct tor2 *)data; @@ -898,12 +925,12 @@ static void tor2_tasklet(unsigned long data) } tor->taskletpending = 0; } +#endif static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) { - static unsigned int passno = 0; - int n, i, j, k, x; - static unsigned long rxword,txword; + int n, i, j, k, syncsrc; + unsigned long rxword,txword; unsigned char c, rxc; unsigned char abits, bbits; struct tor2 *tor = (struct tor2 *) dev_id; @@ -922,7 +949,7 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) tor->mem8[CTLREG] = OUTBIT | INTENA | INTACK; #if 0 - if (!passno) + if (!tor->passno) printk("Interrupt handler\n"); #endif @@ -957,28 +984,30 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) tor->spans[3].chans[n].readchunk[i] = rxword & 0xff; } } - i = passno & 63; + + i = tor->passno & 63; /* if an E1 card, do rx signalling for it */ if ((i < 3) && (tor->cardtype == TYPE_E1)) { /* if an E1 card */ - for(j = (i * 3); j < (i * 3) + 5; j++) + for(j = (i * 5); j < (i * 5) + 5; j++) { - for(k = 1,x = j; k <= 4; k++,x += tor->spans[0].channels) { + for(k = 1; k <= 4; k++) { c = t1in(tor,k,0x31 + j); rxc = c & 15; - if (rxc != tor->spans[k - 1].chans[x + 15].rxsig) { + if (rxc != tor->spans[k - 1].chans[j + 15].rxsig) { /* Check for changes in received bits */ - if (!(tor->spans[k - 1].chans[x + 15].sig & ZT_SIG_CLEAR)) - zt_rbsbits(&tor->spans[k - 1].chans[x + 15], rxc); + if (!(tor->spans[k - 1].chans[j + 15].sig & ZT_SIG_CLEAR)) + zt_rbsbits(&tor->spans[k - 1].chans[j + 15], rxc); } rxc = c >> 4; - if (rxc != tor->spans[k - 1].chans[x].rxsig) { + if (rxc != tor->spans[k - 1].chans[j].rxsig) { /* Check for changes in received bits */ - if (!(tor->spans[k - 1].chans[x].sig & ZT_SIG_CLEAR)) - zt_rbsbits(&tor->spans[k - 1].chans[x], rxc); + if (!(tor->spans[k - 1].chans[j].sig & ZT_SIG_CLEAR)) + zt_rbsbits(&tor->spans[k - 1].chans[j], rxc); } } } } + /* if a T1, do the signalling */ if ((i < 12) && (tor->cardtype == TYPE_T1)) { k = (i / 3); /* get span */ @@ -1015,7 +1044,7 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) } } - i = passno & 63; + i = tor->passno & 63; if ((i >= 50) && (i <= 53)) { j = 0; /* clear this alarm status */ @@ -1113,7 +1142,7 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) tor->mem8[LEDREG] = tor->leds; zt_alarm_notify(&tor->spans[i]); } - if (!(passno % 1000)) /* even second boundary */ + if (!(tor->passno % 1000)) /* even second boundary */ { /* do all spans */ for(i = 1; i <= 4; i++) @@ -1128,25 +1157,38 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) } /* re-evaluate active sync src */ tor->syncsrc = 0; + syncsrc = 0; /* if primary sync specified, see if we can use it */ - if (tor->syncs[0]) + if (tor->psyncs[0]) { /* if no alarms, use it */ - if (!(tor->spans[tor->syncs[0] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | - ZT_ALARM_LOOPBACK))) tor->syncsrc = tor->syncs[0]; + 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->syncs[i])) { + if ((!tor->syncsrc) && (tor->psyncs[i])) { /* if no alarms, use it */ - if (!(tor->spans[tor->syncs[i] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | - ZT_ALARM_LOOPBACK))) tor->syncsrc = tor->syncs[i]; + 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 = tor->syncsrc; + for(i = 0; i < 4; i++) tor->spans[i].syncsrc = syncsrc; + + /* actually set the sync register */ + tor->mem8[SYNCREG] = tor->syncsrc; + + tor->passno++; +#ifdef ENABLE_TASKLETS if (!tor->taskletpending) { tor->taskletpending = 1; tor->taskletsched++; @@ -1154,8 +1196,17 @@ static void tor2_intr(int irq, void *dev_id, struct pt_regs *regs) } else { tor->txerrors++; } +#else + for (i=0;i<4;i++) { + if (tor->spans[i].flags & ZT_FLAG_RUNNING) + zt_receive(&tor->spans[i]); + } + for (i=0;i<4;i++) { + if (tor->spans[i].flags & ZT_FLAG_RUNNING) + zt_transmit(&tor->spans[i]); + } +#endif - passno++; if (tor->cardtype == TYPE_E1) /* clear OUTBIT and enable interrupts */ tor->mem8[CTLREG] = INTENA | E1DIV; @@ -1176,6 +1227,9 @@ static int tor2_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data MODULE_AUTHOR("Mark Spencer"); MODULE_DESCRIPTION("Tormenta 2 PCI Driver"); +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif MODULE_PARM(debug, "i"); MODULE_PARM(loopback, "i"); -- cgit v1.2.3