summaryrefslogtreecommitdiff
path: root/wct1xxp.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-01-08 22:46:00 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-01-08 22:46:00 +0000
commit20d38c5728ce21efb81ec11e6b24e1ce7e093d36 (patch)
tree445c7de486e5ebebc601d6d427789166d29c16c4 /wct1xxp.c
parentb6c65aa86205db3c13f8a020d10b8f5abcd0e71a (diff)
Version 0.4.0 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@141 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wct1xxp.c')
-rwxr-xr-xwct1xxp.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/wct1xxp.c b/wct1xxp.c
index 1c6b4d4..2df2bde 100755
--- a/wct1xxp.c
+++ b/wct1xxp.c
@@ -151,6 +151,7 @@ struct t1xxp {
unsigned char ledtestreg;
unsigned char outbyte;
unsigned long ioaddr;
+ unsigned short canary;
/* T1 signalling */
unsigned char txsiga[3];
unsigned char txsigb[3];
@@ -160,10 +161,13 @@ struct t1xxp {
volatile unsigned char *readchunk; /* Double-word aligned read memory */
unsigned char ec_chunk1[31][ZT_CHUNKSIZE];
unsigned char ec_chunk2[31][ZT_CHUNKSIZE];
+ unsigned char tempo[32];
struct zt_span span; /* Span */
struct zt_chan chans[31]; /* Channels */
};
+#define CANARY 0xca1e
+
int debug = 0; /* doesnt do anything */
static struct t1xxp *cards[WC_MAX_CARDS];
@@ -292,7 +296,7 @@ static void t1xxp_enable_interrupts(struct t1xxp *wc)
/* Clear interrupts */
outb(0xff, wc->ioaddr + WC_INTSTAT);
/* Enable interrupts (we care about all of them) */
- outb(0x3f, wc->ioaddr + WC_MASK0);
+ outb(0x3c /* 0x3f */, wc->ioaddr + WC_MASK0);
/* No external interrupts */
outb(0x00, wc->ioaddr + WC_MASK1);
}
@@ -765,7 +769,10 @@ static int t1xxp_software_init(struct t1xxp *wc)
wc->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_B8ZS | ZT_CONFIG_D4 | ZT_CONFIG_ESF;
wc->span.ioctl = t1xxp_ioctl;
wc->span.pvt = wc;
- wc->span.deflaw = ZT_LAW_MULAW;
+ if (wc->ise1)
+ wc->span.deflaw = ZT_LAW_ALAW;
+ else
+ wc->span.deflaw = ZT_LAW_MULAW;
init_waitqueue_head(&wc->span.maintq);
for (x=0;x<wc->span.channels;x++) {
sprintf(wc->chans[x].name, "WCT1/%d/%d", wc->num, x + 1);
@@ -840,7 +847,8 @@ static void t1xxp_transmitprep(struct t1xxp *wc, int ints)
{
volatile unsigned char *txbuf;
int x,y;
- if (ints & 0x01) {
+ int pos;
+ if (ints & 0x04 /* 0x01 */) {
/* We just finished sending the first buffer, start filling it
now */
txbuf = wc->writechunk;
@@ -849,11 +857,16 @@ static void t1xxp_transmitprep(struct t1xxp *wc, int ints)
txbuf = wc->writechunk + 32 * ZT_CHUNKSIZE;
}
zt_transmit(&wc->span);
+ for (x=0;x<wc->offset;x++)
+ txbuf[x] = wc->tempo[x];
for (y=0;y<ZT_CHUNKSIZE;y++) {
for (x=0;x<wc->span.channels;x++) {
+ pos = y * 32 + wc->chanmap[x] + wc->offset;
/* Put channel number as outgoing data */
- txbuf[y * 32 + ((wc->chanmap[x] + wc->offset) & 0x1f)] =
- wc->chans[x].writechunk[y];
+ if (pos < 32 * ZT_CHUNKSIZE)
+ txbuf[pos] = wc->chans[x].writechunk[y];
+ else
+ wc->tempo[pos - 32 * ZT_CHUNKSIZE] = wc->chans[x].writechunk[y];
}
}
}
@@ -861,13 +874,26 @@ static void t1xxp_transmitprep(struct t1xxp *wc, int ints)
static void t1xxp_receiveprep(struct t1xxp *wc, int ints)
{
volatile unsigned char *rxbuf;
+ volatile unsigned int *canary;
int x;
int y;
+ unsigned int oldcan;
if (ints & 0x04) {
/* Just received first buffer */
rxbuf = wc->readchunk;
+ canary = (unsigned int *)(wc->readchunk + ZT_CHUNKSIZE * 64 - 4);
} else {
rxbuf = wc->readchunk + ZT_CHUNKSIZE * 32;
+ canary = (unsigned int *)(wc->readchunk + ZT_CHUNKSIZE * 32 - 4);
+ }
+ oldcan = *canary;
+ if (((oldcan & 0xffff0000) >> 16) != CANARY) {
+ /* Check top part */
+ if (debug) printk("Expecting top %04x, got %04x\n", CANARY, (oldcan & 0xffff0000) >> 16);
+ wc->span.irqmisses++;
+ } else if ((oldcan & 0xffff) != ((wc->canary - 1) & 0xffff)) {
+ if (debug) printk("Expecting bottom %d, got %d\n", wc->canary - 1, oldcan & 0xffff);
+ wc->span.irqmisses++;
}
for (y=0;y<ZT_CHUNKSIZE;y++) {
for (x=0;x<wc->span.channels;x++) {
@@ -906,6 +932,9 @@ static void t1xxp_receiveprep(struct t1xxp *wc, int ints)
}
}
}
+ /* Store the next canary */
+ canary = (unsigned int *)(rxbuf + ZT_CHUNKSIZE * 32 - 4);
+ *canary = (wc->canary++) | (CANARY << 16);
for (x=0;x<wc->span.channels;x++) {
zt_ec_chunk(&wc->chans[x], wc->chans[x].readchunk,
wc->ec_chunk2[x]);
@@ -1116,7 +1145,7 @@ static void t1xxp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
__t1xxp_do_counters(wc);
/* Do some things that we don't have to do very often */
- x = wc->intcount & 63;
+ x = wc->intcount & 15 /* 63 */;
switch(x) {
case 0:
case 1:
@@ -1204,6 +1233,7 @@ static int __devinit t1xxp_init_one(struct pci_dev *pdev, const struct pci_devic
{
int res;
struct t1xxp *wc;
+ unsigned int *canary;
if (pci_enable_device(pdev)) {
res = -EIO;
@@ -1233,6 +1263,9 @@ static int __devinit t1xxp_init_one(struct pci_dev *pdev, const struct pci_devic
/* Initialize Write/Buffers to all blank data */
memset((void *)wc->writechunk,0x00,ZT_MAX_CHUNKSIZE * 2 * 2 * 32);
+ /* Initialize canary */
+ canary = (unsigned int *)(wc->readchunk + ZT_CHUNKSIZE * 64 - 4);
+ *canary = (CANARY << 16) | (0xffff);
/* Enable bus mastering */
pci_set_master(pdev);