[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