[zaptel-commits] mogorman: trunk r1540 - /trunk/ztcodec_dte.c

zaptel-commits at lists.digium.com zaptel-commits at lists.digium.com
Mon Oct 30 09:53:33 MST 2006


Author: mogorman
Date: Mon Oct 30 10:53:32 2006
New Revision: 1540

URL: http://svn.digium.com/view/zaptel?rev=1540&view=rev
Log:
Fixed REL4 stack overflow. - jsloan

Modified:
    trunk/ztcodec_dte.c

Modified: trunk/ztcodec_dte.c
URL: http://svn.digium.com/view/zaptel/trunk/ztcodec_dte.c?rev=1540&r1=1539&r2=1540&view=diff
==============================================================================
--- trunk/ztcodec_dte.c (original)
+++ trunk/ztcodec_dte.c Mon Oct 30 10:53:32 2006
@@ -36,6 +36,7 @@
 #include <linux/vmalloc.h>
 #include <linux/mman.h>
 #include <linux/delay.h>
+#include <asm/io.h>
 #ifdef CONFIG_DEVFS_FS
 #include <linux/devfs_fs_kernel.h>
 #endif
@@ -79,11 +80,16 @@
 #define ACK_SPACE 20
 
 #define MAX_COMMANDS (NUM_CHANNELS + ACK_SPACE)
-#define COMMAND_LEN 1500		/* 1432 for boot, 274 for 30msec ulaw, 194 for 20mec ulaw */
+
+/* 1432 for boot, 274 for 30msec ulaw, 194 for 20mec ulaw */
+#define BOOT_CMD_LEN 1500
+#define OTHER_CMD_LEN 300
+
+#define MAX_COMMAND_LEN BOOT_CMD_LEN	/* Must be the larger of BOOT_CMD_LEN or OTHER_CMD_LEN */
 
 #define ERING_SIZE (NUM_CHANNELS * 2)		/* Maximum ring size */
 
-#define SFRAME_SIZE COMMAND_LEN
+#define SFRAME_SIZE MAX_COMMAND_LEN
 
 #define PCI_WINDOW_SIZE ((2*  2 * ERING_SIZE * SFRAME_SIZE) + (2 * ERING_SIZE * 4))
 
@@ -191,7 +197,7 @@
 			if ( (((wc->cmdq_wndx + 1) % MAX_COMMANDS) == wc->cmdq_rndx) && debug ) \
 				printk("wcdte error: cmdq is full.\n"); \
 			else { \
-				unsigned char fifo[COMMAND_LEN] = command; \
+				unsigned char fifo[OTHER_CMD_LEN] = command; \
 				wc->cmdq[wc->cmdq_wndx].cmdlen = length; \
 				for (i = 0; i < length; i++) \
 					wc->cmdq[wc->cmdq_wndx].cmd[i] = fifo[i]; \
@@ -225,7 +231,7 @@
 
 struct cmdq {
 	unsigned int cmdlen;
-	unsigned int cmd[COMMAND_LEN];
+	unsigned int cmd[MAX_COMMAND_LEN];
 };
 
 
@@ -383,7 +389,7 @@
 
 	if (!tx)
 		o2 += ERING_SIZE * 4;
-	wc->descripchunk[o2] = 0x80000000;
+	wc->descripchunk[o2] = cpu_to_le32(0x80000000);
 
 	wcdte_setctl(wc, 0x0008, 0x00000000);
 }
@@ -427,13 +433,13 @@
 		
 	do
 	{
-	} while ((wc->descripchunk[o2] & 0x80000000));
+	} while ((le32_to_cpu(wc->descripchunk[o2]) & 0x80000000));
 
 	xmt_length = wc->cmdq[wc->cmdq_rndx].cmdlen;
 	if (xmt_length < 64)
 		xmt_length = 64;
 	
-	wc->descripchunk[o2+1] = (wc->descripchunk[o2+1] & 0xFBFFF800) | xmt_length;
+	wc->descripchunk[o2+1] = cpu_to_le32((le32_to_cpu(wc->descripchunk[o2+1]) & 0xFBFFF800) | xmt_length);
 				
 	for(i = 0; i < wc->cmdq[wc->cmdq_rndx].cmdlen; i++)
 		writechunk[i] = wc->cmdq[wc->cmdq_rndx].cmd[i];
@@ -442,7 +448,7 @@
 
 	wc->cmdq[wc->cmdq_rndx].cmdlen = 0;
 
-	wc->descripchunk[o2] = 0x80000000;
+	wc->descripchunk[o2] = cpu_to_le32(0x80000000);
 	__wcdte_setctl(wc, 0x0008, 0x00000000);			/* Transmit Poll Demand */
 	
 	wc->tdbl = (wc->tdbl + 1) % ERING_SIZE;
@@ -507,8 +513,7 @@
 				zth->srclen -= inbytes;
 
 				{
-					/* Make fifo[] size based on packet size define */
-					unsigned char fifo[COMMAND_LEN] = CMD_MSG_IP_UDP_RTP(
+					unsigned char fifo[OTHER_CMD_LEN] = CMD_MSG_IP_UDP_RTP(
 						 ((inbytes+40) >> 8)              & 0xFF,
 						  (inbytes+40)                    & 0xFF,
 						   st->seqno                      & 0xFF,
@@ -622,7 +627,7 @@
 				printk("wcdte error: cmdq is full (rndx = %d, wndx = %d).\n", wc->cmdq_rndx, wc->cmdq_wndx);
 			else
 			{
-				unsigned char fifo[COMMAND_LEN] = CMD_MSG_ACK((rseq++)&0x0F, rchannel&0x00FF, (rchannel>>8)&0x00FF);
+				unsigned char fifo[OTHER_CMD_LEN] = CMD_MSG_ACK((rseq++)&0x0F, rchannel&0x00FF, (rchannel>>8)&0x00FF);
 
 				wc->cmdq[wc->cmdq_wndx].cmdlen = CMD_MSG_ACK_LEN;
 				for (i = 0; i < wc->cmdq[wc->cmdq_wndx].cmdlen; i++)
@@ -799,7 +804,7 @@
 	o2 += ERING_SIZE * 4;
 	o2 += wc->rdbl * 4;
 
-	if (!(wc->descripchunk[o2] & 0x80000000)) {
+	if (!(le32_to_cpu(wc->descripchunk[o2]) & 0x80000000)) {
 		wc->rxints++;
 		wcdte_receiveprep(wc, wc->rdbl);
 		wcdte_reinit_descriptor(wc, 0, wc->rdbl, "rxchk");
@@ -830,16 +835,16 @@
 			descripdma = wc->descripdma;
 
 		/* Transmit descriptor */
-		descrip[0 ] = 0x00000000;
-		descrip[1 ] = 0xe5800000 | (SFRAME_SIZE);
-		descrip[2 ] = writedma + x*SFRAME_SIZE;
-		descrip[3 ] = descripdma;
+		descrip[0 ] = cpu_to_le32(0x00000000);
+		descrip[1 ] = cpu_to_le32(0xe5800000 | (SFRAME_SIZE));
+		descrip[2 ] = cpu_to_le32(writedma + x*SFRAME_SIZE);
+		descrip[3 ] = cpu_to_le32(descripdma);
 
 		/* Receive descriptor */
-		descrip[0 + ERING_SIZE * 4] = 0x80000000;
-		descrip[1 + ERING_SIZE * 4] = 0x01000000 | (SFRAME_SIZE);
-		descrip[2 + ERING_SIZE * 4] = readdma + x*SFRAME_SIZE;
-		descrip[3 + ERING_SIZE * 4] = descripdma + ERING_SIZE * 16;
+		descrip[0 + ERING_SIZE * 4] = cpu_to_le32(0x80000000);
+		descrip[1 + ERING_SIZE * 4] = cpu_to_le32(0x01000000 | (SFRAME_SIZE));
+		descrip[2 + ERING_SIZE * 4] = cpu_to_le32(readdma + x*SFRAME_SIZE);
+		descrip[3 + ERING_SIZE * 4] = cpu_to_le32(descripdma + ERING_SIZE * 16);
 	
 		/* Advance descriptor */
 		descrip += 4;
@@ -884,6 +889,30 @@
 		wc->intcount++;
 	}
 
+	if ((ints & 0x00008000) && debug)
+		printk("wcdte: Abormal Interrupt: ");
+
+	if ((ints & 0x00002000) && debug)
+		printk("wcdte: Fatal Bus Error INT\n");
+
+	if ((ints & 0x00000100) && debug)
+		printk("wcdte: Receive Stopped INT\n");
+
+	if ((ints & 0x00000080) && debug)
+		printk("wcdte: Receive Desciptor Unavailable INT\n");
+
+	if ((ints & 0x00000020) && debug)
+		printk("wcdte: Transmit Under-flow INT\n");
+
+	if ((ints & 0x00000008) && debug)
+		printk("wcdte: Jabber Timer Time-out INT\n");
+
+	if ((ints & 0x00000004) && debug)
+		printk("wcdte: Transmit Descriptor Unavailable INT\n");
+
+	if ((ints & 0x00000002) && debug)
+		printk("wcdte: Transmit Processor Stopped INT\n");
+
 #ifdef LINUX26
 	return IRQ_RETVAL(1);
 #endif		
@@ -931,8 +960,11 @@
 
 static void wcdte_enable_interrupts(struct wcdte *wc)
 {
-	/* Enable interrupts */ 
-	wcdte_setintmask(wc, 0x00010041);
+	/* Enable interrupts */
+	if (!debug)
+		wcdte_setintmask(wc, 0x00010041);
+	else
+		wcdte_setintmask(wc, 0x0001A1EB);
 }
 
 
@@ -977,7 +1009,16 @@
 {
 	int ret;
 
+#ifdef LINUX26
 	ret = wait_event_interruptible_timeout(wc->regq, wc->rcvflags != 0, (1*HZ));
+#else
+	/* Since timeout versions of wait_event... don't exist, */ 
+	/* make a success ret look like ir didn't timeout */
+	/* It may be good to look for a 2.4 compatible timeout mechanism */
+	ret = wait_event_interruptible(wc->regq, wc->rcvflags != 0);
+	if (ret == 0)
+		ret = 1;
+#endif
 
 	if (ret < 0)
 	{



More information about the zaptel-commits mailing list