[zaptel-commits] kpfleming: branch mogorman/zaptel-1.2-transcoder r2023 - in /team/mogorman/za...

zaptel-commits at lists.digium.com zaptel-commits at lists.digium.com
Tue Jan 30 11:29:00 MST 2007


Author: kpfleming
Date: Tue Jan 30 12:28:59 2007
New Revision: 2023

URL: http://svn.digium.com/view/zaptel?view=rev&rev=2023
Log:
rename ZT_TCOP_RESET to ZT_TCOP_ALLOCATE (so it will match ZT_TCOP_RELEASE)
use a linked-list of dynamically-sized cmdq entries instead of an array
use specific-sized types for the transcoder-related ioctl structures (and don't make pointless typedefs)
various other cleanups

Modified:
    team/mogorman/zaptel-1.2-transcoder/wctc4xxp/Makefile
    team/mogorman/zaptel-1.2-transcoder/wctc4xxp/base.c
    team/mogorman/zaptel-1.2-transcoder/wctc4xxp/codec_test.c
    team/mogorman/zaptel-1.2-transcoder/zaptel.h
    team/mogorman/zaptel-1.2-transcoder/ztmonitor.c
    team/mogorman/zaptel-1.2-transcoder/zttool.c
    team/mogorman/zaptel-1.2-transcoder/zttranscode.c

Modified: team/mogorman/zaptel-1.2-transcoder/wctc4xxp/Makefile
URL: http://svn.digium.com/view/zaptel/team/mogorman/zaptel-1.2-transcoder/wctc4xxp/Makefile?view=diff&rev=2023&r1=2022&r2=2023
==============================================================================
--- team/mogorman/zaptel-1.2-transcoder/wctc4xxp/Makefile (original)
+++ team/mogorman/zaptel-1.2-transcoder/wctc4xxp/Makefile Tue Jan 30 12:28:59 2007
@@ -5,3 +5,6 @@
 endif
 
 tests: codec_test
+
+codec_test: codec_test.c ../zaptel.h
+	$(CC) -o $@ -c $< $(CFLAGS)

Modified: team/mogorman/zaptel-1.2-transcoder/wctc4xxp/base.c
URL: http://svn.digium.com/view/zaptel/team/mogorman/zaptel-1.2-transcoder/wctc4xxp/base.c?view=diff&rev=2023&r1=2022&r2=2023
==============================================================================
--- team/mogorman/zaptel-1.2-transcoder/wctc4xxp/base.c (original)
+++ team/mogorman/zaptel-1.2-transcoder/wctc4xxp/base.c Tue Jan 30 12:28:59 2007
@@ -41,6 +41,7 @@
 #include <linux/workqueue.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/list.h>
 
 #ifdef STANDALONE_ZAPATA
 #include "zaptel.h"
@@ -83,11 +84,6 @@
 #define G729_BYTES 20
 #define G723_BYTES 20
 
-#define ACK_SPACE 20
-
-#define MAX_COMMANDS (NUM_CHANNELS + ACK_SPACE)
-#define MAX_RCV_COMMANDS 16
-
 /* 274 for 30ms ulaw, 194 for 20ms ulaw */
 #define OTHER_CMD_LEN 300
 
@@ -112,173 +108,125 @@
 #define RCV_OTHER         99
 
 /* TDM Commands */
-#define CMD_MSG_TDM_SELECT_BUS_MODE_LEN 30
 #define CMD_MSG_TDM_SELECT_BUS_MODE(s) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x01, 0x00,0x06,0x17,0x04, 0xFF,0xFF, \
 	0x04,0x00 }
-#define CMD_MSG_TDM_ENABLE_BUS_LEN 30
 #define CMD_MSG_TDM_ENABLE_BUS(s) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x02, 0x00,0x06,0x05,0x04, 0xFF,0xFF, \
 	0x04,0x00 }
-#define CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN 34
 #define CMD_MSG_SUPVSR_SETUP_TDM_PARMS(s,p1,p2,p3) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x10, p1, 0x00,0x06,0x07,0x04, 0xFF,0xFF, \
 	p2,0x83, 0x00,0x0C, 0x00,0x00, p3,0x00 }
-#define CMD_MSG_TDM_OPT_LEN 30
 #define CMD_MSG_TDM_OPT(s) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x35,0x04, 0xFF,0xFF, \
 	0x00,0x00 }
-#define CMD_MSG_DEVICE_SET_COUNTRY_CODE_LEN 30
 #define CMD_MSG_DEVICE_SET_COUNTRY_CODE(s) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x1B,0x04, 0xFF,0xFF, \
 	0x00,0x00 }
 
 /* CPU Commands */
-#define CMD_MSG_SET_ARM_CLK_LEN 32
 #define CMD_MSG_SET_ARM_CLK(s) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0C, 0x00, 0x00,0x06,0x11,0x04, 0x00,0x00, \
 	0x2C,0x01, 0x00,0x00 }
-#define CMD_MSG_SET_SPU_CLK_LEN 32
 #define CMD_MSG_SET_SPU_CLK(s) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0C, 0x00, 0x00,0x06,0x12,0x04, 0x00,0x00, \
 	0x2C,0x01, 0x00,0x00 }
-#define CMD_MSG_SPU_FEATURES_CONTROL_LEN 30
 #define CMD_MSG_SPU_FEATURES_CONTROL(s,p1) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x13,0x00, 0xFF,0xFF, \
 	p1,0x00 }
-#define CMD_MSG_DEVICE_STATUS_CONFIG_LEN 30
 #define CMD_MSG_DEVICE_STATUS_CONFIG(s) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x0F,0x04, 0xFF,0xFF, \
 	0x05,0x00 }
 
 /* General IP/RTP Commands */
-#define CMD_MSG_SET_ETH_HEADER_LEN 44
 #define CMD_MSG_SET_ETH_HEADER(s) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x18, 0x00, 0x00,0x06,0x00,0x01, 0xFF,0xFF, \
 	0x01,0x00, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55, 0x08,0x00 }
-#define CMD_MSG_IP_SERVICE_CONFIG_LEN 30
 #define CMD_MSG_IP_SERVICE_CONFIG(s) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x02,0x03, 0xFF,0xFF, \
 	0x00,0x02 }
-#define CMD_MSG_ARP_SERVICE_CONFIG_LEN 30
 #define CMD_MSG_ARP_SERVICE_CONFIG(s) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x05,0x01, 0xFF,0xFF, \
 	0x01,0x00 }
-#define CMD_MSG_ICMP_SERVICE_CONFIG_LEN 30
 #define CMD_MSG_ICMP_SERVICE_CONFIG(s) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x04,0x03, 0xFF,0xFF, \
 	0x01,0xFF }
-#define CMD_MSG_IP_OPTIONS_LEN 30
 #define CMD_MSG_IP_OPTIONS(s) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x06,0x03, 0xFF,0xFF, \
 	0x02,0x00 }
 
 /* Supervisor channel commands */
-#define CMD_MSG_CREATE_CHANNEL_LEN 32
 #define CMD_MSG_CREATE_CHANNEL(s,t) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0C, 0x00, 0x00,0x06,0x10,0x00, 0x00,0x00, \
 	0x02,0x00, (t&0x00FF), ((t&0xFF00) >> 8) }
-#define CMD_MSG_TRANS_CONNECT_LEN 38
 #define CMD_MSG_TRANS_CONNECT(s,e,c1,c2,f1,f2) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x12, 0x00, 0x00,0x06,0x22,0x93, 0x00,0x00, \
 	e,0x00, (c1&0x00FF),((c1&0xFF00)>>8), f1,0x00, (c2&0x00FF),((c2&0xFF00)>>8), f2,0x00 }
-#define CMD_MSG_DESTROY_CHANNEL_LEN 32
 #define CMD_MSG_DESTROY_CHANNEL(s,t) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x11,0x00, 0x00,0x00, \
 	(t&0x00FF),((t&0xFF00)>>8), 0x00, 0x00 }
 
 /* Individual channel config commands */
-#define CMD_MSG_SET_IP_HDR_CHANNEL_LEN 58
 #define CMD_MSG_SET_IP_HDR_CHANNEL(s,c,t2,t1) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, ((c&0xFF00) >> 8),(c&0x00FF), 0x26, 0x00, 0x00,0x02,0x00,0x90, 0x00,0x00, \
 	0x00,0x00, 0x45,0x00, 0x00,0x00, 0x00,0x00, 0x40,0x00, 0x80,0x11, 0x00,0x00, \
 	0xC0,0xA8,0x09,0x03, 0xC0,0xA8,0x09,0x03, \
 	((t2&0xFF00)>>8)+0x50,(t2&0x00FF), ((t1&0xFF00)>>8)+0x50,(t1&0x00FF), 0x00,0x00, 0x00,0x00 }
-#define CMD_MSG_VOIP_VCEOPT_LEN 40
 #define CMD_MSG_VOIP_VCEOPT(s,c,l,w) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x12, 0x00, 0x00,0x02,0x01,0x80, 0x00,0x00, \
 	0x21,l, 0x00,0x1C, 0x04,0x00, 0x00,0x00, w,0x00, 0x80,0x11 }
-#define CMD_MSG_VOIP_VOPENA_LEN 44
 #define CMD_MSG_VOIP_VOPENA(s,c,f) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x16, 0x00, 0x00,0x02,0x00,0x80, 0x00,0x00, \
 	0x01,0x00, 0x80,f, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x12,0x34, 0x56,0x78, 0x00,0x00 }
-#define CMD_MSG_VOIP_VOPENA_CLOSE_LEN 32
 #define CMD_MSG_VOIP_VOPENA_CLOSE(s,c) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x0A, 0x00, 0x00,0x02,0x00,0x80, 0x00,0x00, \
 	0x00,0x00, 0x00,0x00 }
-#define CMD_MSG_VOIP_INDCTRL_LEN 32
 #define CMD_MSG_VOIP_INDCTRL(s,c) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x0A, 0x00, 0x00,0x02,0x84,0x80, 0x00,0x00, \
 	0x07,0x00, 0x00,0x00 }
 
 /* CPU ACK command */ 
-#define CMD_MSG_ACK_LEN 20
 #define CMD_MSG_ACK(s,c) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
 	0x00,0x01, s, 0xE0, (c&0x00FF), ((c>>8)&0x00FF) }
 
 /* Wrapper for RTP packets */
-#define CMD_MSG_IP_UDP_RTP_LEN 54
 #define CMD_MSG_IP_UDP_RTP(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20) { \
 	0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x08,0x00, \
 	0x45,0x00, p1,p2, 0x00,p3, 0x40,0x00, 0x80,0x11, p4,p5, \
 	0xC0,0xA8,0x09,0x03, 0xC0,0xA8,0x09,0x03, p6,p7, p8,p9, p10,p11, p12,p13, \
 	0x80,p14, p15,p16, p17,p18,p19,p20, 0x12,0x34,0x56,0x78}
 
-
-#define send_cmd(wc, command, length, hex) \
-	({ \
-		int ret = 0; \
-		do { \
-	 		if (ret == 2) { \
-				wc->ztsnd_rtx++; \
-	 			if (hex == 0x0010) \
-					wc->ztsnd_0010_rtx++; \
-			} \
-			down(&wc->cmdqsem); \
-	 		wc->last_command_sent = hex; \
-			if ((((wc->cmdq_wndx + 1) % MAX_COMMANDS) == wc->cmdq_rndx)) {\
-				debug_printk(1, "cmdq is full\n"); \
-			} else { \
-				u8 fifo[OTHER_CMD_LEN] = command; \
-				wc->cmdq[wc->cmdq_wndx].cmdlen = length; \
-				memcpy(wc->cmdq[wc->cmdq_wndx].cmd, fifo, length); \
-				wc->cmdq_wndx = (wc->cmdq_wndx + 1) % MAX_COMMANDS; \
-			} \
-			__transmit_demand(wc); \
-			up(&wc->cmdqsem); \
-			ret = waitfor_csmencaps(wc, RCV_CSMENCAPS, 0); \
-			if (ret == 1) \
-				return 1; \
-		} while (ret == 2); \
-	})
-
-
 struct cmdq {
-	u32 cmdlen;
-	u8 cmd[MAX_COMMAND_LEN];
+	struct list_head list;
+	size_t cmdspace;
+	size_t cmdlen;
+	u8 cmd[0];
 };
+
+#define MAX_PACKET_SIZE 1500
+#define MAX_TOTAL_CMDQ 40
 
 struct wcdte {
 	struct pci_dev *dev;
@@ -297,9 +245,9 @@
 	
 	struct semaphore chansem;
 	struct semaphore cmdqsem;
-	struct cmdq cmdq[MAX_COMMANDS];
-	unsigned int cmdq_wndx;
-	unsigned int cmdq_rndx;
+	struct list_head pending_cmdq;
+	struct list_head free_cmdq;
+	u32 total_cmdq;		/* total of all cmdq entries, both pending and free */
 
 	unsigned int last_command_sent;
 	unsigned int last_rcommand;
@@ -365,6 +313,104 @@
 
 static int create_channel(struct wcdte *wc, int simple, int complicated, int part1_id, int part2_id, unsigned int *dte_chan1, unsigned int *dte_chan2);
 static int destroy_channel(struct wcdte *wc, unsigned int chan1, unsigned int chan2);
+
+static struct cmdq *get_free_cmdq(struct wcdte *wc, size_t size_needed)
+{
+	struct cmdq *winner = NULL;
+	struct cmdq *candidate = NULL;
+	size_t candidate_size = MAX_PACKET_SIZE;
+	struct cmdq *smallest_seen = NULL;
+	size_t smallest_seen_size = MAX_PACKET_SIZE;
+	struct cmdq *entry;
+
+	if (size_needed > MAX_PACKET_SIZE)
+		return NULL;
+
+	list_for_each_entry(entry, &wc->free_cmdq, list) {
+		if (entry->cmdspace == size_needed) {
+			winner = entry;
+			break;
+		} else if ((entry->cmdspace > size_needed) &&
+			   (entry->cmdspace < candidate_size)) {
+			candidate = entry;
+			candidate_size = entry->cmdspace;
+		} else if (entry->cmdspace < smallest_seen_size) {
+			smallest_seen = entry;
+			smallest_seen_size = entry->cmdspace;
+		}
+	}
+
+	/* at this point, we either have a winner, a candidate,
+	   a potentially freeable too-small entry, or nothing...
+	   deal with the results
+	*/
+
+	if (winner) {
+		list_del_init(&winner->list);
+		return winner;
+	} else if (candidate) {
+		list_del_init(&candidate->list);
+		return candidate;
+	} else if (wc->total_cmdq < MAX_TOTAL_CMDQ) {
+		/* we can make a new entry */
+		if ((winner = kmalloc(sizeof(*winner) + size_needed, GFP_KERNEL))) {
+			debug_printk(1, "created a '%zd' byte cmdq entry\n", size_needed);
+			winner->cmdspace = size_needed;
+			INIT_LIST_HEAD(&winner->list);
+		}
+		return winner;
+	} else if (smallest_seen) {
+		/* we can't allocate new entries, but we have a
+		   too-small entry we can free and replace */
+		list_del(&smallest_seen->list);
+		kfree(smallest_seen);
+		if ((winner = kmalloc(sizeof(*winner) + size_needed, GFP_KERNEL))) {
+			debug_printk(1, "replaced a '%zd' byte cmdq entry with a '%zd' byte one\n", smallest_seen_size, size_needed);
+			winner->cmdspace = size_needed;
+			INIT_LIST_HEAD(&winner->list);
+		}
+		return winner;
+	} else {
+		/* we failed */
+		debug_printk(1, "no cmdq entries available\n");
+		return NULL;
+	}
+}
+
+static int queue_cmd(struct wcdte *wc, u8 *data, size_t length)
+{
+	struct cmdq *cmdq = get_free_cmdq(wc, length);
+
+	if (!cmdq)
+		return -1;
+
+	cmdq->cmdlen = length;
+	memcpy(cmdq->cmd, data, length);
+	list_add_tail(&wc->pending_cmdq, &cmdq->list);
+
+	return 0;
+}
+
+#define send_cmd(wc, command, length, hex) \
+	({ \
+		int ret = 0; \
+		u8 fifo[] = command; \
+		do { \
+	 		if (ret == 2) { \
+				wc->ztsnd_rtx++; \
+	 			if (hex == 0x0010) \
+					wc->ztsnd_0010_rtx++; \
+			} \
+			down(&wc->cmdqsem); \
+			queue_cmd(wc, fifo, sizeof(fifo)); \
+	 		wc->last_command_sent = hex; \
+			__transmit_demand(wc); \
+			up(&wc->cmdqsem); \
+			ret = waitfor_csmencaps(wc, RCV_CSMENCAPS, 0); \
+			if (ret == 1) \
+				return 1; \
+		} while (ret == 2); \
+	})
 
 static void dte_init_state(struct dte_state *state_ptr, int encoder, unsigned int channel, struct wcdte *wc)
 {
@@ -445,11 +491,11 @@
 	setctl(wc, 0x0008, 0x00000000);
 }
 
-static inline void __transmit_one(struct wcdte *wc, u8 *data, u32 length)
+static inline void __transmit_one(struct wcdte *wc, u8 *data, size_t length)
 {
 	u32 o2 = wc->tdbl * 4;
 	volatile u8 *writechunk = (volatile u8 *) wc->writechunk + (wc->tdbl * SFRAME_SIZE);
-	u32 xmt_length;
+	size_t xmt_length;
 
 	/* Yes... this is a busy loop, that is not interruptible. However, it is
 	   highly unlikely (and testing proves) that the wait for a descriptor
@@ -457,7 +503,7 @@
 	*/
 	do {} while ((le32_to_cpu(wc->descripchunk[o2]) & 0x80000000));
 
-	xmt_length = max(length, 64U);
+	xmt_length = max(length, (size_t) 64);
 
 	wc->descripchunk[o2 + 1] = cpu_to_le32((le32_to_cpu(wc->descripchunk[o2 + 1]) & 0xFBFFF800) | xmt_length);
 				
@@ -480,20 +526,18 @@
 	reg = getctl(wc, 0x0028) & 0x00700000;
 	
 	/* Nothing to transmit */
-	if (wc->cmdq_rndx == wc->cmdq_wndx)
+	if (list_empty(&wc->pending_cmdq))
 		return 1;
 
-	cmdq = &wc->cmdq[wc->cmdq_rndx];
-
-	/* Nothing to transmit */
-	if (!cmdq->cmdlen)
-		return 1;
+	/* pop the first entry off the list */
+	cmdq = list_entry(wc->pending_cmdq.next, struct cmdq, list);
+	list_del(&cmdq->list);
 
 	__transmit_one(wc, cmdq->cmd, cmdq->cmdlen);
 
 	if (debug_packets) {
 		debug_printk(1, "TX: ");
-		for (i = 0; i < min(debug_packets, cmdq->cmdlen); i++)
+		for (i = 0; i < min((size_t) debug_packets, cmdq->cmdlen); i++)
 			printk("%02X ", cmdq->cmd[i]);
 		printk("\n");
 	}
@@ -502,14 +546,14 @@
 	    (cmdq->cmd[12] == 0x88) &&
 	    (cmdq->cmd[13] == 0x9B)) {
 		debug_printk(1, "TX: ");
-		for (i = 0; i < min(debug_cmd_packets, cmdq->cmdlen); i++)
+		for (i = 0; i < min((size_t) debug_cmd_packets, cmdq->cmdlen); i++)
 			printk("%02X ", cmdq->cmd[i]);
 		printk("\n");
 	}
 
 	cmdq->cmdlen = 0;
 
-	wc->cmdq_rndx = (wc->cmdq_rndx + 1) % MAX_COMMANDS;
+	list_add_tail(&wc->free_cmdq, &cmdq->list);
 
 	return 0;
 }
@@ -534,37 +578,36 @@
 	unsigned char *chars;
 	unsigned int inbytes = 0;
 	unsigned int timestamp_inc = 0;
-	int i = 0;
 	int res = 0;
 	u32 ipchksum;
 
-	switch(op) {
-	case ZT_TCOP_RESET:
+	switch (op) {
+	case ZT_TCOP_ALLOCATE:
+		if (ztc->chan_built)
+			break;
 		down(&wc->chansem);
-		if (!ztc->chan_built) {
-			if (st->encoder)
-				create_channel(wc, zapfmt_to_dtefmt(zth->srcfmt), zapfmt_to_dtefmt(zth->dstfmt),
-					       st->timeslot_in_num, st->timeslot_out_num, &(st->chan_in_num),
-					       &(st->chan_out_num));
-			else
-				create_channel(wc, zapfmt_to_dtefmt(zth->dstfmt), zapfmt_to_dtefmt(zth->srcfmt),
-					       st->timeslot_out_num, st->timeslot_in_num, &(st->chan_out_num),
-					       &(st->chan_in_num));
-			/* Mark this channel as built */
-			ztc->chan_built = 1;
-			ztc->built_fmts = zth->dstfmt | zth->srcfmt;
-
-			/* Mark the channel complement (other half of encoder/decoder pair) as built */
-			if (st->encoder)
-				compl_ztc = &(wc->udecode->channels[st->timeslot_in_num >> 1]);
-			else
-				compl_ztc = &(wc->uencode->channels[st->timeslot_in_num >> 1]);
-			compl_ztc->chan_built = 1;
-			compl_ztc->built_fmts = zth->dstfmt | zth->srcfmt;
-			compl_st = compl_ztc->pvt;
-			compl_st->chan_in_num = st->chan_out_num;
-			compl_st->chan_out_num = st->chan_in_num;
-		}
+		if (st->encoder)
+			create_channel(wc, zapfmt_to_dtefmt(zth->srcfmt), zapfmt_to_dtefmt(zth->dstfmt),
+				       st->timeslot_in_num, st->timeslot_out_num, &(st->chan_in_num),
+				       &(st->chan_out_num));
+		else
+			create_channel(wc, zapfmt_to_dtefmt(zth->dstfmt), zapfmt_to_dtefmt(zth->srcfmt),
+				       st->timeslot_out_num, st->timeslot_in_num, &(st->chan_out_num),
+				       &(st->chan_in_num));
+		/* Mark this channel as built */
+		ztc->chan_built = 1;
+		ztc->built_fmts = zth->dstfmt | zth->srcfmt;
+		
+		/* Mark the channel complement (other half of encoder/decoder pair) as built */
+		if (st->encoder)
+			compl_ztc = &(wc->udecode->channels[st->timeslot_in_num >> 1]);
+		else
+			compl_ztc = &(wc->uencode->channels[st->timeslot_in_num >> 1]);
+		compl_ztc->chan_built = 1;
+		compl_ztc->built_fmts = zth->dstfmt | zth->srcfmt;
+		compl_st = compl_ztc->pvt;
+		compl_st->chan_in_num = st->chan_out_num;
+		compl_st->chan_out_num = st->chan_in_num;
 		up(&wc->chansem);
 		break;
 	case ZT_TCOP_RELEASE:
@@ -604,6 +647,8 @@
 		      (zth->dstfmt == ZT_FORMAT_G723_1  && zth->srclen >= G723_SAMPLES))) ||
 		    ((zth->srcfmt == ZT_FORMAT_G729A) && (zth->srclen >= G729_BYTES)) ||
 		    ((zth->srcfmt == ZT_FORMAT_G723_1) && (zth->srclen >= G723_BYTES))) {
+			struct cmdq *cmdq;
+
 			do {
 				chars = (u8 *)(zth->srcdata + zth->srcoffset);
 				
@@ -626,7 +671,7 @@
 				zth->srclen -= inbytes;
 			
 				{
-					u8 fifo[OTHER_CMD_LEN] = CMD_MSG_IP_UDP_RTP(
+					u8 fifo[] = CMD_MSG_IP_UDP_RTP(
 						((inbytes+40) >> 8)                 & 0xFF,
 						(inbytes+40)                       & 0xFF,
 						st->seqno                         & 0xFF,
@@ -660,26 +705,22 @@
 					st->seqno += 1;
 					st->timestamp += timestamp_inc;
 
-					for (i = 0; i < inbytes; i++)
-						fifo[i+CMD_MSG_IP_UDP_RTP_LEN]= chars[i];
-
 					down(&wc->cmdqsem);
+
+					if (!(cmdq = get_free_cmdq(wc, sizeof(fifo) + inbytes))) {
+						up(&wc->cmdqsem);
+						res = -EIO;
+						break;
+					}
 		
-					if (((wc->cmdq_wndx + 1) % MAX_COMMANDS) == wc->cmdq_rndx) {
-						debug_printk(1, "cmdq is full\n");
-					} else {
-						wc->cmdq[wc->cmdq_wndx].cmdlen = CMD_MSG_IP_UDP_RTP_LEN + inbytes;
-						for (i = 0; i < CMD_MSG_IP_UDP_RTP_LEN+inbytes; i++)
-							wc->cmdq[wc->cmdq_wndx].cmd[i] = fifo[i];
-						wc->cmdq_wndx = (wc->cmdq_wndx + 1) % MAX_COMMANDS;
-					}
-					
+					memcpy(cmdq->cmd, fifo, sizeof(fifo));
+					memcpy(cmdq->cmd + sizeof(fifo), chars, inbytes);
+					list_add_tail(&wc->pending_cmdq, &cmdq->list);
 					__transmit_demand(wc);
 					up(&wc->cmdqsem);
+					st->packets_sent++;
+					zth->srcoffset += inbytes;
 				}
-				st->packets_sent++;
-
-				zth->srcoffset += inbytes;
 			} while ((((zth->srcfmt == ZT_FORMAT_ULAW) || (zth->srcfmt == ZT_FORMAT_ALAW)) &&
 				  ((zth->dstfmt == ZT_FORMAT_G729A  && zth->srclen >= G729_SAMPLES) ||
 				   (zth->dstfmt == ZT_FORMAT_G723_1  && zth->srclen >= G723_SAMPLES))) ||
@@ -687,9 +728,9 @@
 				 ((zth->srcfmt == ZT_FORMAT_G723_1) && (zth->srclen >= G723_BYTES)));
 		} else {
 			zt_transcoder_alert(ztc);
+			res = -EINVAL;
 		}
 
-		res = 0;
 		break;
 	}
 
@@ -733,26 +774,18 @@
 			rcommand = readchunk[24] | (readchunk[25] << 8);
 			rchannel = readchunk[18] | (readchunk[19] << 8);
 			rseq = readchunk[16];
+			{
+				u8 fifo[] = CMD_MSG_ACK(rseq++, rchannel);
 			
-			down(&wc->cmdqsem);
-			if ((((wc->cmdq_wndx + 1) % MAX_COMMANDS) == wc->cmdq_rndx)) {
-				debug_printk(1, "cmdq is full\n");
-			} else {
-				u8 fifo[OTHER_CMD_LEN] = CMD_MSG_ACK(rseq++, rchannel);
-
-				wc->cmdq[wc->cmdq_wndx].cmdlen = CMD_MSG_ACK_LEN;
-				for (i = 0; i < wc->cmdq[wc->cmdq_wndx].cmdlen; i++)
-					wc->cmdq[wc->cmdq_wndx].cmd[i] = fifo[i];
-				wc->cmdq_wndx = (wc->cmdq_wndx + 1) % MAX_COMMANDS;
+				down(&wc->cmdqsem);
+				queue_cmd(wc, fifo, sizeof(fifo));
+				__transmit_demand(wc);
+				wc->rcvflags = RCV_CSMENCAPS;
+				wc->last_rcommand = rcommand;
+				wc->last_rparm2 = readchunk[30] | (readchunk[31] << 8);
+				wake_up_interruptible(&wc->regq);
+				up(&wc->cmdqsem);
 			}
-				
-			__transmit_demand(wc);
-		
-			wc->rcvflags = RCV_CSMENCAPS;
-			wc->last_rcommand = rcommand;
-			wc->last_rparm2 = readchunk[30] | (readchunk[31] << 8);
-			wake_up_interruptible(&wc->regq);
-			up(&wc->cmdqsem);
 		} else {
 			wc->rcvflags = RCV_CSMENCAPS_ACK;
 			wake_up_interruptible(&wc->regq);
@@ -1334,8 +1367,8 @@
 	if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL)))
 		return -ENOMEM;
 
+	memset(wc, 0, sizeof(*wc));
 	ifaces[x] = wc;
-	memset(wc, 0, sizeof(*wc));
 	spin_lock_init(&wc->reglock);
 	sema_init(&wc->chansem, 1);
 	sema_init(&wc->cmdqsem, 1);
@@ -1346,6 +1379,9 @@
 	
 	wc->seq_num = 6;
 	wc->timeout = HZ;
+
+	INIT_LIST_HEAD(&wc->pending_cmdq);
+	INIT_LIST_HEAD(&wc->free_cmdq);
 	
 	/* Keep track of whether we need to free the region */
 	if (request_region(wc->iobase, 0xff, "wctc4xxp")) 
@@ -1532,8 +1568,18 @@
 
 static void release(struct wcdte *wc)
 {
+	struct cmdq *cmdq;
+
 	if (wc->freeregion)
 		release_region(wc->iobase, 0xff);
+	while ((cmdq = list_entry(wc->pending_cmdq.next, struct cmdq, list))) {
+		list_del(&cmdq->list);
+		kfree(cmdq);
+	}
+	while ((cmdq = list_entry(wc->free_cmdq.next, struct cmdq, list))) {
+		list_del(&cmdq->list);
+		kfree(cmdq);
+	}
 	kfree(wc);
 }
 
@@ -1621,8 +1667,8 @@
 
 module_param(debug, int, 0600);
 module_param(mode, charp, 0600);
-module_param(debug_packets, int, 0600);
-module_param(debug_cmd_packets, int, 0600);
+module_param(debug_packets, uint, 0600);
+module_param(debug_cmd_packets, uint, 0600);
 MODULE_DESCRIPTION("Wildcard TC400P+TC400M Transcoder");
 MODULE_AUTHOR("John Sloan <jsloan at digium.com>");
 MODULE_LICENSE("GPL");

Modified: team/mogorman/zaptel-1.2-transcoder/wctc4xxp/codec_test.c
URL: http://svn.digium.com/view/zaptel/team/mogorman/zaptel-1.2-transcoder/wctc4xxp/codec_test.c?view=diff&rev=2023&r1=2022&r2=2023
==============================================================================
--- team/mogorman/zaptel-1.2-transcoder/wctc4xxp/codec_test.c (original)
+++ team/mogorman/zaptel-1.2-transcoder/wctc4xxp/codec_test.c Tue Jan 30 12:28:59 2007
@@ -35,6 +35,7 @@
 #include <errno.h>
 #include <sys/mman.h>
 #include <unistd.h>
+#include <linux/types.h>
 #ifdef STANDALONE_ZAPATA
 #include "../zaptel.h"
 #else
@@ -129,7 +130,7 @@
 static int open_transcoder(struct tcpvt *ztp, int dest, int source)
 {
 	int fd;
-	unsigned int x = ZT_TCOP_RESET;
+	unsigned int x = ZT_TCOP_ALLOCATE;
 	struct zt_transcode_header *hdr;
 	int flags;
 

Modified: team/mogorman/zaptel-1.2-transcoder/zaptel.h
URL: http://svn.digium.com/view/zaptel/team/mogorman/zaptel-1.2-transcoder/zaptel.h?view=diff&rev=2023&r1=2022&r2=2023
==============================================================================
--- team/mogorman/zaptel-1.2-transcoder/zaptel.h (original)
+++ team/mogorman/zaptel-1.2-transcoder/zaptel.h Tue Jan 30 12:28:59 2007
@@ -703,19 +703,19 @@
 #define ZT_TRANSCODE_MAGIC 0x74a9c0de
 
 /* Operations */
-#define ZT_TCOP_RESET		1			/* Reset the channel state / codec selection */
+#define ZT_TCOP_ALLOCATE	1			/* Allocate DTE channel */
 #define ZT_TCOP_TRANSCODE	2			/* Begin transcoding a block */
 #define ZT_TCOP_GETINFO		3			/* Get information (use zt_transcode_info) */
 #define ZT_TCOP_RELEASE         4                       /* Release DTE channel */
 #define ZT_TCOP_TEST            5                       /* test DTE device */
-typedef struct zt_transcode_info {
-	unsigned int op;
-	unsigned int tcnum;
-	char name[80];
-	int numchannels;
-	unsigned int srcfmts;
-	unsigned int dstfmts;
-} ZT_TRANSCODE_INFO;
+struct zt_transcode_info {
+	__u32 op;
+	__u32 tcnum;
+	__u8 name[80];
+	__u32 numchannels;
+	__u32 srcfmts;
+	__u32 dstfmts;
+};
 
 #define ZT_TCCONF_USETS		(1 << 0)		/* Use/update timestamp field */
 #define ZT_TCCONF_USESEQ	(1 << 1)		/* Use/update seqno field */
@@ -729,27 +729,27 @@
 #define ZT_TRANSCODE_DSTOFFSET	(((ZT_TRANSCODE_BUFSIZ) / 2) + ZT_TRANSCODE_HDRLEN)
 #define ZT_TRANSCODE_SRCOFFSET	(((ZT_TRANSCODE_BUFSIZ) / 2) + ZT_TRANSCODE_HDRLEN)
 
-typedef struct zt_transcode_header {
-	unsigned int srcfmt;		/* See formats.h -- use TCOP_RESET when you change */
-	unsigned int srcoffset; 	/* In bytes -- written by user */
-	unsigned int srclen;		/* In bytes -- written by user */
-	unsigned int srctimestamp;	/* In samples -- written by user (only used if ZT_TCCONF_USETS is set) */
-	unsigned int srcseqno;		/* In units -- written by user (only used if ZT_TCCONF_USESEQ is set) */
-
-	unsigned int dstfmt;		/* See formats.h -- use TCOP_RESET when you change */
-	unsigned int dstoffset;  	/* In bytes -- written by user */
-	unsigned int dsttimestamp;	/* In samples -- read by user */
-	unsigned int dstseqno;		/* In units -- read by user (only used if ZT_TCCONF_USESEQ is set) */
-	unsigned int dstlen;  		/* In bytes -- read by user */
-	unsigned int dstsamples;	/* In timestamp units -- read by user */
-
-	unsigned int magic;		/* Magic value -- ZT_TRANSCODE_MAGIC, read by user */
-	unsigned int config;		/* Read/write by user */
-	unsigned int status;		/* Read/write by user */
-	unsigned char userhdr[ZT_TRANSCODE_HDRLEN - (sizeof(unsigned int) * 14)];	/* Storage for user parameters */
-	unsigned char srcdata[ZT_TRANSCODE_BUFSIZ / 2];	/* Storage of source data */
-	unsigned char dstdata[ZT_TRANSCODE_BUFSIZ / 2];	/* Storage of destination data */
-} ZT_TRANSCODE_HEADER;
+struct zt_transcode_header {
+	__u32 srcfmt;		/* See formats.h -- use TCOP_RESET when you change */
+	__u32 srcoffset; 	/* In bytes -- written by user */
+	__u32 srclen;		/* In bytes -- written by user */
+	__u32 srctimestamp;	/* In samples -- written by user (only used if ZT_TCCONF_USETS is set) */
+	__u32 srcseqno;		/* In units -- written by user (only used if ZT_TCCONF_USESEQ is set) */
+
+	__u32 dstfmt;		/* See formats.h -- use TCOP_RESET when you change */
+	__u32 dstoffset;  	/* In bytes -- written by user */
+	__u32 dsttimestamp;	/* In samples -- read by user */
+	__u32 dstseqno;		/* In units -- read by user (only used if ZT_TCCONF_USESEQ is set) */
+	__u32 dstlen;  		/* In bytes -- read by user */
+	__u32 dstsamples;	/* In timestamp units -- read by user */
+
+	__u32 magic;		/* Magic value -- ZT_TRANSCODE_MAGIC, read by user */
+	__u32 config;		/* Read/write by user */
+	__u32 status;		/* Read/write by user */
+	__u8 userhdr[ZT_TRANSCODE_HDRLEN - (sizeof(__u32) * 14)];	/* Storage for user parameters */
+	__u8 srcdata[ZT_TRANSCODE_BUFSIZ / 2];	/* Storage of source data */
+	__u8 dstdata[ZT_TRANSCODE_BUFSIZ / 2];	/* Storage of destination data */
+};
 
 struct zt_ring_cadence {
 	int ringcadence [ZT_MAX_CADENCE];

Modified: team/mogorman/zaptel-1.2-transcoder/ztmonitor.c
URL: http://svn.digium.com/view/zaptel/team/mogorman/zaptel-1.2-transcoder/ztmonitor.c?view=diff&rev=2023&r1=2022&r2=2023
==============================================================================
--- team/mogorman/zaptel-1.2-transcoder/ztmonitor.c (original)
+++ team/mogorman/zaptel-1.2-transcoder/ztmonitor.c Tue Jan 30 12:28:59 2007
@@ -38,6 +38,7 @@
 #include <sys/time.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <linux/types.h>
 #ifdef STANDALONE_ZAPATA
 #include "zaptel.h"
 #include "tonezone.h"

Modified: team/mogorman/zaptel-1.2-transcoder/zttool.c
URL: http://svn.digium.com/view/zaptel/team/mogorman/zaptel-1.2-transcoder/zttool.c?view=diff&rev=2023&r1=2022&r2=2023
==============================================================================
--- team/mogorman/zaptel-1.2-transcoder/zttool.c (original)
+++ team/mogorman/zaptel-1.2-transcoder/zttool.c Tue Jan 30 12:28:59 2007
@@ -38,6 +38,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <newt.h>
+#include <linux/types.h>
 #ifdef STANDALONE_ZAPATA
 #include "zaptel.h"
 #include "tonezone.h"

Modified: team/mogorman/zaptel-1.2-transcoder/zttranscode.c
URL: http://svn.digium.com/view/zaptel/team/mogorman/zaptel-1.2-transcoder/zttranscode.c?view=diff&rev=2023&r1=2022&r2=2023
==============================================================================
--- team/mogorman/zaptel-1.2-transcoder/zttranscode.c (original)
+++ team/mogorman/zaptel-1.2-transcoder/zttranscode.c Tue Jan 30 12:28:59 2007
@@ -279,7 +279,7 @@
 
 	/* Actually reset the transcoder channel */
 	if ((*ztc)->parent && ((*ztc)->parent->operation))
-		return (*ztc)->parent->operation((*ztc), ZT_TCOP_RESET);
+		return (*ztc)->parent->operation((*ztc), ZT_TCOP_ALLOCATE);
 
 	return -EINVAL;
 }
@@ -339,7 +339,7 @@
 	case ZT_TCOP_GETINFO:
 		ret = zt_tc_getinfo(data);
 		break;
-	case ZT_TCOP_RESET:
+	case ZT_TCOP_ALLOCATE:
 		/* Reset transcoder, possibly changing who we point to */
 		ret = do_reset(&ztc);
 		file->private_data = ztc;



More information about the zaptel-commits mailing list