diff options
author | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2003-01-08 22:46:00 +0000 |
---|---|---|
committer | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2003-01-08 22:46:00 +0000 |
commit | 20d38c5728ce21efb81ec11e6b24e1ce7e093d36 (patch) | |
tree | 445c7de486e5ebebc601d6d427789166d29c16c4 /wct1xxp.c | |
parent | b6c65aa86205db3c13f8a020d10b8f5abcd0e71a (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-x | wct1xxp.c | 45 |
1 files changed, 39 insertions, 6 deletions
@@ -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); |