summaryrefslogtreecommitdiff
path: root/tor2.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2002-03-04 15:45:10 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2002-03-04 15:45:10 +0000
commitb05391fe2b5ae43144d789f91e8c3d1989cefd78 (patch)
treea363f99382f8a0b548e14667da704e2752af4760 /tor2.c
parent1f48e488a3f0f7fe606e847ceb353812f8e503ad (diff)
Version 0.1.6 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@62 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'tor2.c')
-rwxr-xr-xtor2.c106
1 files changed, 80 insertions, 26 deletions
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");