[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