[Asterisk-cvs] zaptel raddiag.tar.gz, NONE, 1.1 pciradio.rbt, 1.3,
1.4 pciradio_vhdl.tar.gz, 1.1, 1.2 pciradio.c, 1.9, 1.10
jim at lists.digium.com
jim at lists.digium.com
Mon Jan 24 00:27:52 CST 2005
Update of /usr/cvsroot/zaptel
In directory mongoose.digium.com:/tmp/cvs-serv20540
Modified Files:
pciradio.rbt pciradio_vhdl.tar.gz pciradio.c
Added Files:
raddiag.tar.gz
Log Message:
Updated pciradio driver and VHDL to fix nasty bus access bug, and added
diagnostic (raddiag).
--- NEW FILE: raddiag.tar.gz ---
(This appears to be a binary file; contents omitted.)
Index: pciradio.rbt
===================================================================
RCS file: /usr/cvsroot/zaptel/pciradio.rbt,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- pciradio.rbt 22 Dec 2004 04:44:26 -0000 1.3
+++ pciradio.rbt 24 Jan 2005 06:30:14 -0000 1.4
@@ -3,7 +3,7 @@
Design name: pciradio_xilinx.ncd
Architecture: spartan2
Part: 2s30vq100
-Date: Mon Dec 20 20:30:21 2004
+Date: Sun Jan 23 19:05:08 2005
Bits: 336768
11111111111111111111111111111111
10101010100110010101010101100110
@@ -87,5462 +87,5462 @@
00000000000000000000010000000000
00000000000000000000000000000000
[...14538 lines suppressed...]
00000000000100001000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
+00000000000000000000000111001100
00000000000000000000000000000000
-00000000000000000000000000000000
-00000000000000000000000000000000
+00000000000000110011000000000000
00000000000000000000000000000000
00000000000000000000010000100000
00000000000000000000000000000000
@@ -10506,7 +10506,7 @@
00000000000000000000000000000000
00000000000000000000000000000000
00110000000000000000000000000001
-00000000000000001011100001100010
+00000000000000000001110101100111
00110000000000001000000000000001
00000000000000000000000000000011
00110000000000000100000000001001
Index: pciradio_vhdl.tar.gz
===================================================================
RCS file: /usr/cvsroot/zaptel/pciradio_vhdl.tar.gz,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
Binary files /tmp/cvsAxpePD and /tmp/cvsOhPVx7 differ
Index: pciradio.c
===================================================================
RCS file: /usr/cvsroot/zaptel/pciradio.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- pciradio.c 15 Jan 2005 22:59:18 -0000 1.9
+++ pciradio.c 24 Jan 2005 06:30:14 -0000 1.10
@@ -50,15 +50,14 @@
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include <asm/delay.h>
+
#ifdef STANDALONE_ZAPATA
#include "zaptel.h"
#else
#include <linux/zaptel.h>
#endif
-#ifdef LINUX26
-#include <linux/moduleparam.h>
-#endif
#define RAD_MAX_IFACES 128
@@ -132,7 +131,10 @@
unsigned char saudio_ctrl[NUM_CHANS];
unsigned char saudio_setup[NUM_CHANS];
unsigned char txcode[NUM_CHANS];
+ unsigned long lastcmd;
int myindex[NUM_CHANS];
+ unsigned long waittime;
+ unsigned char retstate;
} ;
@@ -150,7 +152,7 @@
spinlock_t rbilock;
unsigned char pasave;
unsigned char pfsave;
- unsigned long ioaddr;
+ volatile unsigned long ioaddr;
dma_addr_t readdma;
dma_addr_t writedma;
volatile int *writechunk; /* Double-word aligned write memory */
@@ -445,12 +447,12 @@
}
-static void __pciradio_setcreg(struct pciradio *rad, unsigned char reg, unsigned char val)
+void __pciradio_setcreg(struct pciradio *rad, unsigned char reg, unsigned char val)
{
outb(val, rad->ioaddr + RAD_REGBASE + ((reg & 0xf) << 2));
}
-static unsigned char __pciradio_getcreg(struct pciradio *rad, unsigned char reg)
+unsigned char __pciradio_getcreg(struct pciradio *rad, unsigned char reg)
{
return inb(rad->ioaddr + RAD_REGBASE + ((reg & 0xf) << 2));
}
@@ -496,36 +498,48 @@
void mx828_command_wait(struct pciradio *rad,int channel, unsigned char command, unsigned char *byte1, unsigned char *byte2)
{
-unsigned int flags;
DECLARE_WAIT_QUEUE_HEAD(mywait);
+unsigned int flags;
- for(;;)
+
+ spin_lock_irqsave(&rad->lock,flags);
+ while(rad->encdec.state)
{
- spin_lock_irqsave(&rad->lock,flags);
- if ((!(__pciradio_getcreg(rad,0xc) & 1)) &&
- (!(rad->encdec.state)))
- {
- mx828_command(rad,channel,command,byte1,byte2);
- spin_unlock_irqrestore(&rad->lock,flags);
- return;
- }
- spin_unlock_irqrestore(&rad->lock,flags);
- interruptible_sleep_on_timeout(&mywait,5);
+ spin_unlock_irqrestore(&rad->lock,flags);
+ interruptible_sleep_on_timeout(&mywait,2);
+ spin_lock_irqsave(&rad->lock,flags);
}
+ rad->encdec.lastcmd = jiffies + 1000;
+ spin_unlock_irqrestore(&rad->lock,flags);
+ while(__pciradio_getcreg(rad,0xc) & 1);
+ rad->encdec.lastcmd = jiffies + 1000;
+ spin_lock_irqsave(&rad->lock,flags);
+ rad->encdec.lastcmd = jiffies + 1000;
+ mx828_command(rad,channel,command,byte1,byte2);
+ spin_unlock_irqrestore(&rad->lock,flags);
+ rad->encdec.lastcmd = jiffies + 1000;
+ while(__pciradio_getcreg(rad,0xc) & 1);
+ rad->encdec.lastcmd = jiffies;
}
-
-static void _do_encdec(struct pciradio *rad, int n)
+static void _do_encdec(struct pciradio *rad)
{
-int i;
+int i,n;
unsigned char byte1,byte2;
/* return doing nothing if busy */
+ if ((rad->encdec.lastcmd + 2) > jiffies) return;
if (__pciradio_getcreg(rad,0xc) & 1) return;
+ n = 0;
switch(rad->encdec.state)
{
case 0:
- if (!rad->encdec.req[n]) return;
+ for(i = 0; i < rad->nchans; i++)
+ {
+ n = (unsigned)(i - rad->intcount) % rad->nchans;
+ if (rad->encdec.req[n]) break;
+ }
+ if (i >= rad->nchans) return;
rad->encdec.req[n] = 0;
rad->encdec.dcsrx[n] = 0;
rad->encdec.ctrx[n] = 0;
@@ -588,7 +602,7 @@
byte1 = cttable_tx[rad->encdec.txcode[rad->encdec.chan]].b1;
byte2 = cttable_tx[rad->encdec.txcode[rad->encdec.chan]].b2;
mx828_command(rad,rad->encdec.chan, MX828_TX_TONE, &byte1, &byte2 );
- }
+ }
rad->encdec.state = 5;
break;
case 5:
@@ -725,15 +739,15 @@
}
if (ints & 0x0f) {
+
rad->intcount++;
x = rad->intcount % rad->nchans;
/* freeze */
__pciradio_setcreg(rad,0,rad->mx828_addr | 4);
/* read SAUDIO_STATUS for the proper channel */
- byte1 = __pciradio_getcreg(rad,x);
+ byte1 = rad->saudio_status[x] = __pciradio_getcreg(rad,x);
/* thaw */
__pciradio_setcreg(rad,0,rad->mx828_addr);
- rad->saudio_status[x] = byte1;
/* get COR input */
byte2 = __pciradio_getcreg(rad,9);
/* get bit for this channel */
@@ -802,7 +816,7 @@
rad->encdec.req[x] = 1;
rad->last_code[x] = rad->present_code[x];
}
- _do_encdec(rad,x);
+ _do_encdec(rad);
for(x = 0; x < rad->nchans; x++)
{
unsigned char mask = 1 << x;
@@ -871,7 +885,7 @@
if (debug) printk("Chan %d lost rx\n",x + 1);
zt_qevent_lock(&rad->chans[x], ZT_EVENT_ONHOOK);
}
- rad->encdec.req[x] = 1;
+ rad->encdec.req[x] = 1;
}
rad->gotrx1[x] = rad->gotrx[x];
}
@@ -1025,7 +1039,9 @@
}
rad->corthresh[chan->chanpos - 1] = stack.p.data;
byte1 = 0xc0 | (rad->corthresh[chan->chanpos - 1] << 2);
+ spin_unlock_irqrestore(&rad->lock,flags);
mx828_command_wait(rad,chan->chanpos - 1, MX828_GEN_CTRL, &byte1, &byte2);
+ spin_lock_irqsave(&rad->lock,flags);
break;
case ZT_RADPAR_EXTRXTONE:
if (stack.p.data)
@@ -1044,7 +1060,7 @@
rad->rxclass[chan->chanpos - 1][i] = 0;
rad->txcode[chan->chanpos - 1][i] = 0;
}
- break;
+ spin_unlock_irqrestore(&rad->lock,flags);
for(i = 0; i < NUM_CODES; i++)
{
/* set to no encode/decode */
@@ -1055,6 +1071,8 @@
byte2 = 0;
mx828_command_wait(rad,chan->chanpos - 1, MX828_RX_TONE, &byte1, &byte2 );
}
+ spin_lock_irqsave(&rad->lock,flags);
+ break;
case ZT_RADPAR_RXTONE:
if (!stack.p.index) /* if RX DCS mode */
{
@@ -1083,7 +1101,9 @@
rad->rxcode[chan->chanpos - 1][stack.p.index] = mycode;
byte1 = cttable_rx[mycode].b1 | ((stack.p.index - 1) << 4);
byte2 = cttable_rx[mycode].b2;
+ spin_unlock_irqrestore(&rad->lock,flags);
mx828_command_wait(rad,chan->chanpos - 1, MX828_RX_TONE, &byte1, &byte2 );
+ spin_lock_irqsave(&rad->lock,flags);
/* zot out DCS one if there */
rad->rxcode[chan->chanpos - 1][0] = 0;
rad->encdec.req[chan->chanpos - 1] = 1;
@@ -1406,8 +1426,13 @@
printk("Did not get DONE signal. Short file maybe??\n");
return -1;
}
+ wait_just_a_bit(2);
+ /* get the thingy started */
+ outb(0,rad->ioaddr + RAD_REGBASE);
+ outb(0,rad->ioaddr + RAD_REGBASE);
printk("Xilinx Chip successfully loaded, configured and started!!\n");
+ wait_just_a_bit(HZ/4);
rad->pasave = 0;
__pciradio_setcreg(rad,0xa,rad->pasave);
@@ -1418,14 +1443,9 @@
rad->pfsave = 0;
__pciradio_setcreg(rad,0xf,rad->pfsave);
-
-
/* Back to normal, with automatic DMA wrap around */
outb(0x30 | 0x01, rad->ioaddr + RAD_CNTL);
- /* Make sure serial port and DMA are out of reset */
- outb(inb(rad->ioaddr + RAD_CNTL) & 0xf9, RAD_CNTL);
-
/* Configure serial port for MSB->LSB operation */
outb(0xc1, rad->ioaddr + RAD_SERCTL); /* DEBUG set double dlck to 0 SR */
@@ -1461,7 +1481,8 @@
mx828_command_wait(rad,x, MX828_GEN_CTRL, &byte1, &byte2);
rad->corthresh[x] = 2;
}
-
+ /* Wait 1/4 of a sec */
+ wait_just_a_bit(HZ/4);
return 0;
}
@@ -1477,17 +1498,17 @@
static void pciradio_restart_dma(struct pciradio *rad)
{
/* Reset Master and serial */
- outb(0x01, rad->ioaddr + RAD_CNTL);
+ outb(0x31, rad->ioaddr + RAD_CNTL);
outb(0x01, rad->ioaddr + RAD_OPER);
}
static void pciradio_start_dma(struct pciradio *rad)
{
/* Reset Master and serial */
- outb(0x0f, rad->ioaddr + RAD_CNTL);
+ outb(0x3f, rad->ioaddr + RAD_CNTL);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
- outb(0x01, rad->ioaddr + RAD_CNTL);
+ outb(0x31, rad->ioaddr + RAD_CNTL);
outb(0x01, rad->ioaddr + RAD_OPER);
}
@@ -1499,7 +1520,7 @@
static void pciradio_reset_serial(struct pciradio *rad)
{
/* Reset serial */
- outb(0x0f, rad->ioaddr + RAD_CNTL);
+ outb(0x3f, rad->ioaddr + RAD_CNTL);
}
static void pciradio_disable_interrupts(struct pciradio *rad)
@@ -1579,19 +1600,9 @@
/* Keep track of which device we are */
pci_set_drvdata(pdev, rad);
- if (request_irq(pdev->irq, pciradio_interrupt, SA_SHIRQ, "pciradio", rad)) {
- printk("pciradio: Unable to request IRQ %d\n", pdev->irq);
- if (rad->freeregion)
- release_region(rad->ioaddr, 0xff);
- pci_free_consistent(pdev, ZT_MAX_CHUNKSIZE * 2 * 2 * 2 * 4, (void *)rad->writechunk, rad->writedma);
- pci_set_drvdata(pdev, NULL);
- kfree(rad);
- return -EIO;
- }
-
-
if (pciradio_hardware_init(rad)) {
unsigned char x;
+
/* Set Reset Low */
x=inb(rad->ioaddr + RAD_CNTL);
outb((~0x1)&x, rad->ioaddr + RAD_CNTL);
@@ -1607,6 +1618,16 @@
}
+ if (request_irq(pdev->irq, pciradio_interrupt, SA_SHIRQ, "pciradio", rad)) {
+ printk("pciradio: Unable to request IRQ %d\n", pdev->irq);
+ if (rad->freeregion)
+ release_region(rad->ioaddr, 0xff);
+ pci_free_consistent(pdev, ZT_MAX_CHUNKSIZE * 2 * 2 * 2 * 4, (void *)rad->writechunk, rad->writedma);
+ pci_set_drvdata(pdev, NULL);
+ kfree(rad);
+ return -EIO;
+ }
+
/* Enable interrupts */
pciradio_enable_interrupts(rad);
/* Initialize Write/Buffers to all blank data */
@@ -1614,7 +1635,6 @@
/* Start DMA */
pciradio_start_dma(rad);
-
printk("Found a PCI Radio Card\n");
res = 0;
} else
@@ -1649,7 +1669,7 @@
free_irq(pdev->irq, rad);
/* Reset PCI chip and registers */
- outb(0x0e, rad->ioaddr + RAD_CNTL);
+ outb(0x3e, rad->ioaddr + RAD_CNTL);
/* Release span, possibly delayed */
if (!rad->usecount)
@@ -1694,11 +1714,7 @@
pci_unregister_driver(&pciradio_driver);
}
-#ifdef LINUX26
-module_param(debug, int, 0600);
-#else
MODULE_PARM(debug, "i");
-#endif
MODULE_DESCRIPTION("Zapate Telephony PCI Radio Card Zaptel Driver");
MODULE_AUTHOR("Jim Dixon <jim at lambdatel.com>");
#ifdef MODULE_LICENSE
More information about the svn-commits
mailing list