[svn-commits] kpfleming: branch mogorman/zaptel-1.2-transcoder
r2023 - in /team/mogorman/za...
svn-commits at lists.digium.com
svn-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 svn-commits
mailing list