summaryrefslogtreecommitdiff
path: root/wctc4xxp
diff options
context:
space:
mode:
authorkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-02-06 21:57:38 +0000
committerkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-02-06 21:57:38 +0000
commitb730255a7b8f572a2d6d905c128c7a86b75eca2e (patch)
treeb7f85ebc7a1c02da998e190fdc590f4e961e4abe /wctc4xxp
parent7c83bf68acb1c9515cd044de00d86f03953a8958 (diff)
revert transcoder driver to last version that passed PQ testing... improved version will come back once testing has been completed and bugs are found/fixed
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@2092 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wctc4xxp')
-rw-r--r--wctc4xxp/base.c1896
1 files changed, 997 insertions, 899 deletions
diff --git a/wctc4xxp/base.c b/wctc4xxp/base.c
index f42c577..46fac4d 100644
--- a/wctc4xxp/base.c
+++ b/wctc4xxp/base.c
@@ -1,10 +1,9 @@
/*
- * Wildcard TC400B Interface Driver for Zapata Telephony interface
+ * Wildcard TC400B Driver
*
* Written by John Sloan <jsloan@digium.com>
- * and Kevin P. Fleming <kpfleming@digium.com>
*
- * Copyright (C) 2006-2007, Digium, Inc.
+ * Copyright (C) 2006, Digium, Inc.
*
* All rights reserved.
*
@@ -24,6 +23,7 @@
*
*/
+
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
@@ -34,6 +34,7 @@
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
+#include <linux/vmalloc.h>
#include <linux/mman.h>
#include <linux/delay.h>
#include <asm/io.h>
@@ -42,30 +43,30 @@
#include <linux/workqueue.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
-#include <linux/list.h>
-
+#ifdef CONFIG_DEVFS_FS
+#include <linux/devfs_fs_kernel.h>
+#endif
#ifdef STANDALONE_ZAPATA
#include "zaptel.h"
#else
#include <linux/zaptel.h>
#endif
-#if defined(HOTPLUG_FIRMWARE)
-static const char *tc400m_firmware = "tc400m-firmware.bin";
+#ifdef HOTPLUG_FIRMWARE
+static const char *dte_firmware = "tc400m-firmware.bin";
#else
extern u8 _binary_tc400m_firmware_bin_start[];
extern void _binary_tc400m_firmware_bin_size;
#endif
-static struct pci_driver driver;
-
-#define module_printk(fmt, args...) printk("%s: " fmt, driver.name, ## args)
-#define debug_printk(test, fmt, args...) if (debug && (test)) printk("%s (%s): " fmt, driver.name, __FUNCTION__, ## args)
/* #define USE_TEST_HW */
#define USE_TDM_CONFIG
-#define WC_MAX_IFACES 8
+#define WC_MAX_IFACES 128
+
+#define NUM_CARDS 24
+#define NUM_EC 4
/* NUM_CHANNELS must be checked if new firmware (dte_firm.h) is used */
#define NUM_CHANNELS 97
@@ -79,22 +80,30 @@ static struct pci_driver driver;
#define G729_LENGTH 20
#define G723_LENGTH 30
-#define G729_SAMPLES 160
-#define G723_SAMPLES 240
+#define G729_SAMPLES 160 /* g.729 */
+#define G723_SAMPLES 240 /* g.723 */
+
+#define G729_BYTES 20 /* g.729 */
+#define G723_BYTES 20 /* g.723 */
-#define G729_BYTES 20
-#define G723_BYTES 20
-/* 274 for 30ms ulaw, 194 for 20ms ulaw */
+
+#define ACK_SPACE 20
+
+#define MAX_COMMANDS (NUM_CHANNELS + ACK_SPACE)
+#define MAX_RCV_COMMANDS 16
+
+/* 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 OTHER_CMD_LEN
+#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 MAX_COMMAND_LEN
-#define PCI_WINDOW_SIZE ((2 * 2 * ERING_SIZE * SFRAME_SIZE) + (2 * ERING_SIZE * 4))
+#define PCI_WINDOW_SIZE ((2* 2 * ERING_SIZE * SFRAME_SIZE) + (2 * ERING_SIZE * 4))
#define MDIO_SHIFT_CLK 0x10000
#define MDIO_DATA_WRITE0 0x00000
@@ -108,130 +117,182 @@ static struct pci_driver driver;
#define RCV_CSMENCAPS_ACK 3
#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 zt_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("wcdte error: cmdq is full.\n"); \
+ else { \
+ unsigned char fifo[OTHER_CMD_LEN] = command; \
+ int i; \
+ wc->cmdq[wc->cmdq_wndx].cmdlen = length; \
+ for (i = 0; i < length; i++) \
+ wc->cmdq[wc->cmdq_wndx].cmd[i] = fifo[i]; \
+ wc->cmdq_wndx = (wc->cmdq_wndx + 1) % MAX_COMMANDS; \
+ } \
+ __transmit_demand(wc); \
+ up(&wc->cmdqsem); \
+ ret = wcdte_waitfor_csmencaps(wc, RCV_CSMENCAPS, 0); \
+ if (ret == 1) \
+ return(1); \
+ } while (ret == 2); \
+ })
+
+
struct cmdq {
- struct list_head list;
- size_t cmdspace;
- size_t cmdlen;
- u8 cmd[0];
+ unsigned int cmdlen;
+ unsigned int cmd[MAX_COMMAND_LEN];
};
-#define MAX_PACKET_SIZE 1500
-#define MAX_TOTAL_CMDQ 40
-
struct wcdte {
struct pci_dev *dev;
- const char *variety;
+ char *variety;
unsigned int intcount;
unsigned int rxints;
unsigned int txints;
@@ -240,15 +301,16 @@ struct wcdte {
int freeregion;
int rdbl;
int tdbl;
+ int cards;
spinlock_t reglock;
wait_queue_head_t regq;
int rcvflags;
struct semaphore chansem;
struct semaphore cmdqsem;
- struct list_head pending_cmdq;
- struct list_head free_cmdq;
- u32 total_cmdq; /* total of all cmdq entries, both pending and free */
+ struct cmdq cmdq[MAX_COMMANDS];
+ unsigned int cmdq_wndx;
+ unsigned int cmdq_rndx;
unsigned int last_command_sent;
unsigned int last_rcommand;
@@ -259,16 +321,16 @@ struct wcdte {
unsigned int ztsnd_rtx;
unsigned int ztsnd_0010_rtx;
- unsigned int numchannels;
+ unsigned char numchannels;
unsigned char complexname[40];
unsigned long iobase;
- dma_addr_t readdma;
- dma_addr_t writedma;
- dma_addr_t descripdma;
- volatile u8 *writechunk; /* write buffers */
- volatile u8 *readchunk; /* read buffers */
- volatile u32 *descripchunk; /* descriptors */
+ dma_addr_t readdma;
+ dma_addr_t writedma;
+ dma_addr_t descripdma;
+ volatile unsigned int *writechunk; /* Double-word aligned write memory */
+ volatile unsigned int *readchunk; /* Double-word aligned read memory */
+ volatile unsigned int *descripchunk; /* Descriptors */
int wqueints;
struct workqueue_struct *dte_wq;
@@ -278,27 +340,40 @@ struct wcdte {
struct zt_transcoder *udecode;
};
+static void dte_wque_run(struct wcdte *wc);
+
struct wcdte_desc {
- const char *name;
+ char *name;
int flags;
};
-static const struct wcdte_desc wcdte = { "Wildcard TC400P+TC400M", 0 };
+static struct wcdte_desc wcdte = { "Wildcard TC400P+TC400M", 0 };
static struct wcdte *ifaces[WC_MAX_IFACES];
+
+
+/*
+ * The following is the definition of the state structure
+ * used by the G.721/G.723 encoder and decoder to preserve their internal
+ * state between successive calls. The meanings of the majority
+ * of the state structure fields are explained in detail in the
+ * CCITT Recommendation G.721. The field names are essentially indentical
+ * to variable names in the bit level description of the coding algorithm
+ * included in this Recommendation.
+ */
struct dte_state {
- int encoder;
+ int encoder; /* If we're an encoder */
struct wcdte *wc;
unsigned int timestamp;
unsigned int seqno;
- unsigned int timeslot_in_num;
- unsigned int timeslot_out_num;
+ unsigned int timeslot_in_num; /* DTE chennel on which results we be received from */
+ unsigned int timeslot_out_num; /* DTE channel to send data to */
- unsigned int chan_in_num;
- unsigned int chan_out_num;
+ unsigned int chan_in_num; /* DTE chennel on which results we be received from */
+ unsigned int chan_out_num; /* DTE channel to send data to */
unsigned int packets_sent;
unsigned int packets_received;
@@ -307,17 +382,21 @@ struct dte_state {
unsigned int dte_seqno_rcv;
};
+
+static struct zt_transcoder *uencode;
+static struct zt_transcoder *udecode;
+static struct dte_state *encoders;
+static struct dte_state *decoders;
static int debug = 0;
-static char *mode[2] = { "g729", "g723" };
-static int mode_count = 2;
-u32 debug_packets = 0;
-u32 debug_cmd_packets = 0;
+static char *mode;
+int debug_packets = 0;
+
-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 int wcdte_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 wcdte_destroy_channel(struct wcdte *wc, unsigned int chan1, unsigned int chan2);
/* Sanity check values */
-static inline int sanitycheck(struct zt_transcode_header *zth, unsigned int outbytes)
+static inline int zt_tc_sanitycheck(struct zt_transcode_header *zth, unsigned int outbytes)
{
if (zth->dstoffset >= sizeof(zth->dstdata))
return 0;
@@ -336,136 +415,23 @@ static inline int sanitycheck(struct zt_transcode_header *zth, unsigned int outb
return 1;
}
-static void dump_cmdq(struct wcdte *wc)
-{
- struct cmdq *cmdq;
-
- debug_printk(1, "pending_cmdq: ");
- list_for_each_entry(cmdq, &wc->pending_cmdq, list)
- printk("%p(%zd) ", cmdq, cmdq->cmdspace);
- printk("\n");
-
- debug_printk(1, "free_cmdq: ");
- list_for_each_entry(cmdq, &wc->free_cmdq, list)
- printk("%p(%zd) ", cmdq, cmdq->cmdspace);
- printk("\n");
-}
-
-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;
-
- size_needed = ((size_needed / 16) + 1) * 16;
-
- 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 (debug)
- dump_cmdq(wc);
- if ((winner = kmalloc(sizeof(*winner) + size_needed, GFP_KERNEL))) {
- debug_printk(1, "created a '%zd' byte cmdq entry at '%p'\n", size_needed, winner);
- 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 */
- if (debug)
- dump_cmdq(wc);
- 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 at '%p' with a '%zd' byte one at '%p'\n", smallest_seen_size, smallest_seen, size_needed, winner);
- winner->cmdspace = size_needed;
- INIT_LIST_HEAD(&winner->list);
- }
- return winner;
- } else {
- /* we failed */
- module_printk("no cmdq entries available; limit of %d reached\n", MAX_TOTAL_CMDQ);
- 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(&cmdq->list, &wc->pending_cmdq);
-
- 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)
{
- memset(state_ptr, 0, sizeof(*state_ptr));
-
state_ptr->encoder = encoder;
state_ptr->wc = wc;
+ state_ptr->timestamp = 0;
+ state_ptr->seqno = 0;
+
+ state_ptr->packets_sent = 0;
+ state_ptr->packets_received = 0;
+ state_ptr->last_dte_seqno = 0;
+ state_ptr->dte_seqno_rcv = 0;
state_ptr->chan_in_num = 999;
state_ptr->chan_out_num = 999;
- if (encoder) {
+ if (encoder == 1)
+ {
state_ptr->timeslot_in_num = channel * 2;
state_ptr->timeslot_out_num = channel * 2 + 1;
} else {
@@ -474,141 +440,138 @@ static void dte_init_state(struct dte_state *state_ptr, int encoder, unsigned in
}
}
-static inline unsigned int zapfmt_to_dtefmt(unsigned int fmt)
+static unsigned int wcdte_zapfmt_to_dtefmt(unsigned int fmt)
{
- switch (fmt) {
- case ZT_FORMAT_G723_1:
- return DTE_FORMAT_G723_1;
- case ZT_FORMAT_ULAW:
- return DTE_FORMAT_ULAW;
- case ZT_FORMAT_ALAW:
- return DTE_FORMAT_ALAW;
- case ZT_FORMAT_G729A:
- return DTE_FORMAT_G729A;
- default:
- return DTE_FORMAT_UNDEF;
+ unsigned int pt;
+
+ switch(fmt)
+ {
+ case ZT_FORMAT_G723_1:
+ pt = DTE_FORMAT_G723_1;
+ break;
+ case ZT_FORMAT_ULAW:
+ pt = DTE_FORMAT_ULAW;
+ break;
+ case ZT_FORMAT_ALAW:
+ pt = DTE_FORMAT_ALAW;
+ break;
+ case ZT_FORMAT_G729A:
+ pt = DTE_FORMAT_G729A;
+ break;
+ default:
+ pt = DTE_FORMAT_UNDEF;
}
+
+ return(pt);
}
-static inline void __setctl(struct wcdte *wc, unsigned int addr, unsigned int val)
+static inline void __wcdte_setctl(struct wcdte *wc, unsigned int addr, unsigned int val)
{
outl(val, wc->iobase + addr);
}
-static inline unsigned int __getctl(struct wcdte *wc, unsigned int addr)
+static inline unsigned int __wcdte_getctl(struct wcdte *wc, unsigned int addr)
{
return inl(wc->iobase + addr);
}
-static inline void setctl(struct wcdte *wc, unsigned int addr, unsigned int val)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&wc->reglock, flags);
- __setctl(wc, addr, val);
- spin_unlock_irqrestore(&wc->reglock, flags);
-}
-
-static inline unsigned int getctl(struct wcdte *wc, unsigned int addr)
+static inline void wcdte_setctl(struct wcdte *wc, unsigned int addr, unsigned int val)
{
unsigned long flags;
- unsigned int val;
-
spin_lock_irqsave(&wc->reglock, flags);
- val = __getctl(wc, addr);
+ __wcdte_setctl(wc, addr, val);
spin_unlock_irqrestore(&wc->reglock, flags);
-
- return val;
}
-static inline void reinit_descriptor(struct wcdte *wc, int tx, int dbl, char *s)
+static inline void wcdte_reinit_descriptor(struct wcdte *wc, int tx, int dbl, char *s)
{
- unsigned int o2;
-
- o2 = dbl * 4;
+ int o2 = 0;
+ o2 += dbl * 4;
if (!tx)
o2 += ERING_SIZE * 4;
wc->descripchunk[o2] = cpu_to_le32(0x80000000);
- setctl(wc, 0x0008, 0x00000000);
+ wcdte_setctl(wc, 0x0008, 0x00000000);
}
-static inline void __transmit_one(struct wcdte *wc, u8 *data, size_t length)
+static inline unsigned int wcdte_getctl(struct wcdte *wc, unsigned int addr)
{
- u32 o2 = wc->tdbl * 4;
- volatile u8 *writechunk = (volatile u8 *) wc->writechunk + (wc->tdbl * SFRAME_SIZE);
- 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
- to become available will ever be long enough for this to be an issue.
- */
- do {} while ((le32_to_cpu(wc->descripchunk[o2]) & 0x80000000));
-
- xmt_length = max(length, (size_t) 64);
-
- wc->descripchunk[o2 + 1] = cpu_to_le32((le32_to_cpu(wc->descripchunk[o2 + 1]) & 0xFBFFF800) | xmt_length);
-
- memcpy((void *) writechunk, data, length);
- if (length < xmt_length)
- memset((void *) writechunk + length, 0, xmt_length - length);
-
- wc->descripchunk[o2] = cpu_to_le32(0x80000000);
- setctl(wc, 0x0008, 0x00000000); /* Transmit Poll Demand */
-
- wc->tdbl = (wc->tdbl + 1) % ERING_SIZE;
+ unsigned long flags;
+ unsigned int val;
+ spin_lock_irqsave(&wc->reglock, flags);
+ val = __wcdte_getctl(wc, addr);
+ spin_unlock_irqrestore(&wc->reglock, flags);
+ return val;
}
static inline int __transmit_demand(struct wcdte *wc)
{
- int i;
- unsigned int reg;
- struct cmdq *cmdq;
+ volatile unsigned char *writechunk;
+ int o2,i,j;
+ unsigned int reg, xmt_length;
- reg = getctl(wc, 0x0028) & 0x00700000;
+ reg = wcdte_getctl(wc, 0x0028) & 0x00700000;
+ /* Already transmiting, no need to demand another */
+ if (!((reg == 0) || (reg = 6)))
+ return(1);
+
/* Nothing to transmit */
- if (list_empty(&wc->pending_cmdq))
- return 1;
+ if (wc->cmdq_rndx == wc->cmdq_wndx)
+ return(1);
- /* pop the first entry off the list */
- cmdq = list_entry(wc->pending_cmdq.next, struct cmdq, list);
- list_del_init(&cmdq->list);
+ /* Nothing to transmit */
+ if (wc->cmdq[wc->cmdq_rndx].cmdlen == 0 )
+ return(1);
- debug_printk(1, "transmitting command at '%p' of '%zd' bytes\n", cmdq, cmdq->cmdlen);
+ writechunk = (volatile unsigned char *)(wc->writechunk);
- __transmit_one(wc, cmdq->cmd, cmdq->cmdlen);
+ writechunk += wc->tdbl * SFRAME_SIZE;
- if (debug_packets) {
- debug_printk(1, "TX: ");
- for (i = 0; i < min((size_t) debug_packets, cmdq->cmdlen); i++)
- printk("%02X ", cmdq->cmd[i]);
- printk("\n");
- }
+ o2 = wc->tdbl * 4;
+
+ do
+ {
+ } while ((le32_to_cpu(wc->descripchunk[o2]) & 0x80000000));
- if (debug_cmd_packets &&
- (cmdq->cmd[12] == 0x88) &&
- (cmdq->cmd[13] == 0x9B)) {
- debug_printk(1, "TX: ");
- for (i = 0; i < min((size_t) debug_cmd_packets, cmdq->cmdlen); i++)
- printk("%02X ", cmdq->cmd[i]);
+ xmt_length = wc->cmdq[wc->cmdq_rndx].cmdlen;
+ if (xmt_length < 64)
+ xmt_length = 64;
+
+ 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];
+ for (j = i; j < xmt_length; j++)
+ writechunk[j] = 0;
+
+ if (debug_packets && (writechunk[12] == 0x88) && (writechunk[13] == 0x9B))
+ {
+ printk("wcdte debug: TX: ");
+ for (i=0; i<debug_packets; i++)
+ printk("%02X ", writechunk[i]);
printk("\n");
}
- list_add_tail(&cmdq->list, &wc->free_cmdq);
+ wc->cmdq[wc->cmdq_rndx].cmdlen = 0;
- return 0;
+ wc->descripchunk[o2] = cpu_to_le32(0x80000000);
+ wcdte_setctl(wc, 0x0008, 0x00000000); /* Transmit Poll Demand */
+
+ wc->tdbl = (wc->tdbl + 1) % ERING_SIZE;
+
+ wc->cmdq_rndx = (wc->cmdq_rndx + 1) % MAX_COMMANDS;
+
+ return(0);
}
static inline int transmit_demand(struct wcdte *wc)
{
int val;
-
down(&wc->cmdqsem);
val = __transmit_demand(wc);
up(&wc->cmdqsem);
-
return val;
}
@@ -621,61 +584,63 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op)
unsigned char *chars;
unsigned int inbytes = 0;
unsigned int timestamp_inc = 0;
+ int i = 0;
int res = 0;
- u32 ipchksum;
-
- switch (op) {
+ unsigned int ipchksum, ndx;
+ switch(op) {
case ZT_TCOP_ALLOCATE:
- if (ztc->flags.chan_built)
- break;
down(&wc->chansem);
- 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->flags.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->flags.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 (ztc->chan_built == 0)
+ {
+ if (st->encoder == 1)
+ wcdte_create_channel(wc, wcdte_zapfmt_to_dtefmt(zth->srcfmt), wcdte_zapfmt_to_dtefmt(zth->dstfmt),
+ st->timeslot_in_num, st->timeslot_out_num, &(st->chan_in_num), &(st->chan_out_num));
+ else
+ wcdte_create_channel(wc, wcdte_zapfmt_to_dtefmt(zth->dstfmt), wcdte_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 */
+ ndx = st->timeslot_in_num/2;
+ if (st->encoder == 1)
+ compl_ztc = &(wc->udecode->channels[ndx]);
+ else
+ compl_ztc = &(wc->uencode->channels[ndx]);
+ 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:
down(&wc->chansem);
+ ndx = st->timeslot_in_num/2;
- if (st->encoder)
- compl_ztc = &(wc->udecode->channels[st->timeslot_in_num >> 1]);
+ if (st->encoder == 1)
+ compl_ztc = &(wc->udecode->channels[ndx]);
else
- compl_ztc = &(wc->uencode->channels[st->timeslot_in_num >> 1]);
+ compl_ztc = &(wc->uencode->channels[ndx]);
/* If the channel complement (other half of the encoder/decoder pair) is not being used... */
- if (!compl_ztc->flags.busy) {
- if (st->encoder)
- destroy_channel(wc, st->chan_in_num, st->chan_out_num);
+ if ((compl_ztc->flags & ZT_TC_FLAG_BUSY) == 0)
+ {
+ if (st->encoder == 1)
+ wcdte_destroy_channel(wc, st->chan_in_num, st->chan_out_num);
else
- destroy_channel(wc, st->chan_out_num, st->chan_in_num);
+ wcdte_destroy_channel(wc, st->chan_out_num, st->chan_in_num);
/* Mark this channel as not built */
- ztc->flags.chan_built = 0;
+ ztc->chan_built = 0;
ztc->built_fmts = 0;
st->chan_in_num = 999;
st->chan_out_num = 999;
/* Mark the channel complement as not built */
- compl_ztc->flags.chan_built = 0;
+ compl_ztc->chan_built = 0;
compl_ztc->built_fmts = 0;
compl_st = compl_ztc->pvt;
compl_st->chan_in_num = 999;
@@ -685,66 +650,61 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op)
up(&wc->chansem);
break;
case ZT_TCOP_TRANSCODE:
- if ((((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))) ||
- ((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);
-
- switch (zth->srcfmt) {
- case ZT_FORMAT_ULAW:
- case ZT_FORMAT_ALAW:
- switch (zth->dstfmt) {
- case ZT_FORMAT_G729A:
- inbytes = G729_SAMPLES;
- timestamp_inc = G729_SAMPLES;
- break;
- case ZT_FORMAT_G723_1:
- inbytes = G723_SAMPLES;
- timestamp_inc = G723_SAMPLES;
- break;
+ if ( (((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)) )
+ || ((zth->srcfmt == ZT_FORMAT_G729A) && (zth->srclen >= G729_BYTES))
+ || ((zth->srcfmt == ZT_FORMAT_G723_1) && (zth->srclen >= G723_BYTES)) )
+ {
+ do
+ {
+ chars = (unsigned char *)(zth->srcdata + zth->srcoffset);
+
+ if ((zth->srcfmt == ZT_FORMAT_ULAW) || (zth->srcfmt == ZT_FORMAT_ALAW))
+ {
+ if (zth->dstfmt == ZT_FORMAT_G729A) {
+ inbytes = G729_SAMPLES;
+ timestamp_inc = G729_SAMPLES;
+ } else if (zth->dstfmt == ZT_FORMAT_G723_1) {
+ inbytes = G723_SAMPLES;
+ timestamp_inc = G723_SAMPLES;
}
- break;
- case ZT_FORMAT_G729A:
+
+ } else if (zth->srcfmt == ZT_FORMAT_G729A)
+ {
inbytes = G729_BYTES;
timestamp_inc = G729_SAMPLES;
- break;
- case ZT_FORMAT_G723_1:
+ } else if (zth->srcfmt == ZT_FORMAT_G723_1)
+ {
inbytes = G723_BYTES;
timestamp_inc = G723_SAMPLES;
- break;
}
zth->srclen -= inbytes;
-
+
{
- u8 fifo[] = CMD_MSG_IP_UDP_RTP(
- ((inbytes+40) >> 8) & 0xFF,
- (inbytes+40) & 0xFF,
- st->seqno & 0xFF,
- 0x00,
- 0x00,
+ unsigned char fifo[OTHER_CMD_LEN] = CMD_MSG_IP_UDP_RTP(
+ ((inbytes+40) >> 8) & 0xFF,
+ (inbytes+40) & 0xFF,
+ st->seqno & 0xFF,
+ 0x00,
+ 0x00,
(((st->timeslot_out_num) >> 8)+0x50) & 0xFF,
- (st->timeslot_out_num) & 0xFF,
+ (st->timeslot_out_num) & 0xFF,
(((st->timeslot_in_num) >> 8)+0x50) & 0xFF,
- (st->timeslot_in_num) & 0xFF,
- ((inbytes+20) >> 8) & 0xFF,
- (inbytes+20) & 0xFF,
- 0x00,
- 0x00,
- zapfmt_to_dtefmt(zth->srcfmt),
- ((st->seqno) >> 8) & 0xFF,
- (st->seqno) & 0xFF,
- ((st->timestamp) >> 24) & 0xFF,
- ((st->timestamp) >> 16) & 0xFF,
- ((st->timestamp) >> 8) & 0xFF,
- (st->timestamp) & 0xFF);
-
- ipchksum = 0x9869 + (fifo[16] << 8) + fifo[17] + (fifo[18] << 8) + fifo[19];
+ (st->timeslot_in_num) & 0xFF,
+ ((inbytes+20) >> 8) & 0xFF,
+ (inbytes+20) & 0xFF,
+ 0x00,
+ 0x00,
+ wcdte_zapfmt_to_dtefmt(zth->srcfmt),
+ ((st->seqno) >> 8) & 0xFF,
+ (st->seqno) & 0xFF,
+ ((st->timestamp) >> 24) & 0xFF,
+ ((st->timestamp) >> 16) & 0xFF,
+ ((st->timestamp) >> 8) & 0xFF,
+ (st->timestamp) & 0xFF);
+
+ ipchksum = 0x9869 + (fifo[16] << 8) + fifo[17]
+ + (fifo[18] << 8) + fifo[19];
while (ipchksum >> 16)
ipchksum = (ipchksum & 0xFFFF) + (ipchksum >> 16);
ipchksum = (~ipchksum) & 0xFFFF;
@@ -755,198 +715,273 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op)
st->seqno += 1;
st->timestamp += timestamp_inc;
- down(&wc->cmdqsem);
+ for (i = 0; i < inbytes; i++)
+ fifo[i+CMD_MSG_IP_UDP_RTP_LEN]= chars[i];
- if (!(cmdq = get_free_cmdq(wc, sizeof(fifo) + inbytes))) {
- up(&wc->cmdqsem);
- res = -EIO;
- break;
- }
+ down(&wc->cmdqsem);
- memcpy(cmdq->cmd, fifo, sizeof(fifo));
- memcpy(cmdq->cmd + sizeof(fifo), chars, inbytes);
- cmdq->cmdlen = sizeof(fifo) + inbytes;
- list_add_tail(&cmdq->list, &wc->pending_cmdq);
+ if ( (((wc->cmdq_wndx + 1) % MAX_COMMANDS) == wc->cmdq_rndx) && debug )
+ printk("wcdte error: 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;
+ }
+
__transmit_demand(wc);
up(&wc->cmdqsem);
- 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))) ||
- ((zth->srcfmt == ZT_FORMAT_G729A) && (zth->srclen >= G729_BYTES)) ||
- ((zth->srcfmt == ZT_FORMAT_G723_1) && (zth->srclen >= G723_BYTES)));
+ 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)) )
+ || ((zth->srcfmt == ZT_FORMAT_G729A) && (zth->srclen >= G729_BYTES))
+ || ((zth->srcfmt == ZT_FORMAT_G723_1) && (zth->srclen >= G723_BYTES)) );
+
} else {
zt_transcoder_alert(ztc);
- res = -EINVAL;
}
+ res = 0;
break;
}
-
return res;
}
-static void stop_dma(struct wcdte *wc);
+static void wcdte_stop_dma(struct wcdte *wc);
-static inline void receiveprep(struct wcdte *wc, int dbl)
+static inline void wcdte_receiveprep(struct wcdte *wc, int dbl)
{
- volatile u8 *readchunk = wc->readchunk + (dbl * SFRAME_SIZE);
+ volatile unsigned char *readchunk;
struct zt_transcoder_channel *ztc = NULL;
struct zt_transcode_header *zth = NULL;
struct dte_state *st = NULL;
- int o2, i;
+ int o2,i;
unsigned char rseq, rcodec;
unsigned int rcommand, rchannel, rlen, rtp_rseq, rtp_eseq;
- u8 *chars = NULL;
+ unsigned char *chars = NULL;
unsigned int ztc_ndx;
+ readchunk = (volatile unsigned char *)wc->readchunk;
+ readchunk += dbl * SFRAME_SIZE;
+
o2 = dbl * 4;
o2 += ERING_SIZE * 4;
- if (debug_packets) {
- debug_printk(1, "RX: ");
- for (i = 0; i < debug_packets; i++)
- printk("%02X ", readchunk[i]);
- printk("\n");
- }
-
- if ((readchunk[12] == 0x88) && (readchunk[13] == 0x9B)) {
- /* Control in packet */
- if (debug_cmd_packets) {
- debug_printk(1, "RX: ");
- for (i = 0; i < debug_cmd_packets; i++)
+ /* Control in packet */
+ if ((readchunk[12] == 0x88) && (readchunk[13] == 0x9B))
+ {
+ if (debug_packets)
+ {
+ printk("wcdte debug: RX: ");
+ for (i=0; i<debug_packets; i++)
printk("%02X ", readchunk[i]);
printk("\n");
}
/* See if message must be ACK'd */
- if ((readchunk[17] & 0xC0) == 0) {
+ if ((readchunk[17] & 0xC0) == 0)
+ {
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);
- 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);
+ down(&wc->cmdqsem);
+ if ( (((wc->cmdq_wndx + 1) % MAX_COMMANDS) == wc->cmdq_rndx) && debug )
+ printk("wcdte error: cmdq is full (rndx = %d, wndx = %d).\n", wc->cmdq_rndx, wc->cmdq_wndx);
+ else
+ {
+ unsigned char 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;
}
- } else {
+
+ __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);
}
- } else if ((readchunk[12] == 0x08) && (readchunk[13] == 0x00) &&
- (readchunk[50] == 0x12) && (readchunk[51] == 0x34) &&
- (readchunk[52] = 0x56) && (readchunk[53] == 0x78)) {
- /* IP/UDP in packet */
+ }
+
+ /* IP/UDP in packet */
+ else if ((readchunk[12] == 0x08) && (readchunk[13] == 0x00)
+ && (readchunk[50] == 0x12) && (readchunk[51] == 0x34) && (readchunk[52] = 0x56) && (readchunk[53] == 0x78))
+ {
rchannel = (readchunk[37] | (readchunk[36] << 8)) - 0x5000;
rlen = (readchunk[39] | (readchunk[38] << 8)) - 20;
rtp_rseq = (readchunk[45] | (readchunk[44] << 8));
rcodec = readchunk[43];
- ztc_ndx = rchannel >> 1;
+ ztc_ndx = rchannel/2;
- if (ztc_ndx >= wc->numchannels) {
- debug_printk(1, "Invalid channel number received (ztc_ndx = %d) (numchannels = %d)\n", ztc_ndx, wc->numchannels);
+ if (ztc_ndx >= wc->numchannels)
+ {
+ if (debug)
+ printk("wcdte error: Invalid channel number received (ztc_ndx = %d) (numchannels = %d)\n", ztc_ndx, wc->numchannels);
rcodec = DTE_FORMAT_UNDEF;
}
- switch (rcodec) {
- case 0x00: /* ulaw */
- case 0x08: /* alaw */
+ if ((rcodec == 0x00) || (rcodec == 0x08)) /* ulaw or alaw (decoders) */
+ {
ztc = &(wc->udecode->channels[ztc_ndx]);
- break;
- case 0x04: /* g.723.1 */
- case 0x12: /* g.729 */
- ztc = &(wc->uencode->channels[ztc_ndx]);
- break;
- }
+ zth = ztc->tch;
+ st = ztc->pvt;
- zth = ztc->tch;
- st = ztc->pvt;
+ if (zth == NULL)
+ {
+ if (debug)
+ printk("wcdte error: Tried to put DTE data into a freed zth header!\n");
+ rcodec = DTE_FORMAT_UNDEF;
+ } else {
+ chars = (unsigned char *)(zth->dstdata + zth->dstoffset + zth->dstlen);
+ st->packets_received++;
+ }
+
+ }
- if (!zth) {
- debug_printk(1, "Tried to put data into a freed zth header\n");
- rcodec = DTE_FORMAT_UNDEF;
- } else {
- chars = (u8 *)(zth->dstdata + zth->dstoffset + zth->dstlen);
- st->packets_received++;
+ if ((rcodec == 0x04) || (rcodec == 0x12)) /* g.723 or g.729 (encoders) */
+ {
+ ztc = &(wc->uencode->channels[ztc_ndx]);
+ zth = ztc->tch;
+ st = ztc->pvt;
+
+ if (zth == NULL)
+ {
+ if (debug)
+ printk("wcdte error: Tried to put DTE data into a freed zth header!\n");
+ rcodec = DTE_FORMAT_UNDEF;
+ } else {
+ chars = (unsigned char *)(zth->dstdata + zth->dstoffset + zth->dstlen);
+ st->packets_received++;
+ }
+
}
- if (st->dte_seqno_rcv == 0) {
+ if (st->dte_seqno_rcv == 0)
+ {
st->dte_seqno_rcv = 1;
st->last_dte_seqno = rtp_rseq;
} else {
rtp_eseq = (st->last_dte_seqno + 1) & 0xFFFF;
- debug_printk(rtp_rseq != rtp_eseq, "Bad seqno from module [%d][%d][%d]\n", rchannel, rtp_rseq, st->last_dte_seqno);
+ if ( (rtp_rseq != rtp_eseq) && debug )
+ printk("wcdte error: Bad seqno from DTE! [%d][%d][%d]\n", rchannel, rtp_rseq, st->last_dte_seqno);
+
st->last_dte_seqno = rtp_rseq;
}
- switch (rcodec) {
- case 0x00: /* ulaw */
- case 0x08: /* alaw */
- if (sanitycheck(zth, rlen) &&
- ((zth->srcfmt == ZT_FORMAT_G729A && rlen == G729_SAMPLES) ||
- (zth->srcfmt == ZT_FORMAT_G723_1 && rlen == G723_SAMPLES))) {
- memcpy(chars, (void *) readchunk + 54, rlen);
+ if (rcodec == 0x00) /* ulaw */
+ {
+ if (zt_tc_sanitycheck(zth, rlen) && ((zth->srcfmt == ZT_FORMAT_G729A && rlen == G729_SAMPLES) || (zth->srcfmt == ZT_FORMAT_G723_1 && rlen == G723_SAMPLES))) {
+ for (i = 0; i < rlen; i++)
+ chars[i] = readchunk[i+54];
+
zth->dstlen += rlen;
zth->dstsamples = zth->dstlen;
+
} else {
ztc->errorstatus = -EOVERFLOW;
}
zt_transcoder_alert(ztc);
- break;
- case 0x04: /* g.723.1 */
- if (sanitycheck(zth, rlen) && (rlen == G723_BYTES)) {
- memcpy(chars, (void *) readchunk + 54, rlen);
+ }
+ else if (rcodec == 0x08) /* alaw */
+ {
+ if (zt_tc_sanitycheck(zth, rlen) && ((zth->srcfmt == ZT_FORMAT_G729A && rlen == G729_SAMPLES) || (zth->srcfmt == ZT_FORMAT_G723_1 && rlen == G723_SAMPLES))) {
+
+ for (i = 0; i < rlen; i++)
+ chars[i] = readchunk[i+54];
+
+ zth->dstlen += rlen;
+ zth->dstsamples = zth->dstlen;
+
+ } else {
+ ztc->errorstatus = -EOVERFLOW;
+ }
+ zt_transcoder_alert(ztc);
+ }
+ else if (rcodec == 0x04) /* g.723.1 */
+ {
+ if (zt_tc_sanitycheck(zth, rlen) && (rlen == G723_BYTES))
+ {
+ for (i = 0; i < rlen; i++)
+ chars[i] = readchunk[i+54];
+
zth->dstlen += rlen;
zth->dstsamples = zth->dstlen * 12;
+
} else {
ztc->errorstatus = -EOVERFLOW;
}
- if ((zth->dstsamples % G723_SAMPLES) == 0)
+
+ if (!(zth->dstsamples % G723_SAMPLES))
+ {
zt_transcoder_alert(ztc);
- break;
- case 0x12: /* g.729 */
- if (sanitycheck(zth, rlen) && (rlen == G729_BYTES)) {
- memcpy(chars, (void *) readchunk + 54, rlen);
+ }
+ }
+ else if (rcodec == 0x12) /* g.729a */
+ {
+ if (zt_tc_sanitycheck(zth, rlen) && (rlen == G729_BYTES))
+ {
+ for (i = 0; i < rlen; i++)
+ chars[i] = readchunk[i+54];
+
zth->dstlen += rlen;
zth->dstsamples = zth->dstlen * 8;
+
} else {
ztc->errorstatus = -EOVERFLOW;
}
- if ((zth->dstsamples % G729_SAMPLES) == 0)
+ if (!(zth->dstsamples % G729_SAMPLES))
+ {
zt_transcoder_alert(ztc);
+ }
}
}
}
-static int check_descriptor(struct wcdte *wc)
+
+
+
+
+/* static inline int wcdte_check_descriptor(struct wcdte *wc) */
+static int wcdte_check_descriptor(struct wcdte *wc)
{
- int o2 = (ERING_SIZE * 4) + (wc->rdbl * 4);
+ int o2 = 0;
+
+ o2 += ERING_SIZE * 4;
+ o2 += wc->rdbl * 4;
if (!(le32_to_cpu(wc->descripchunk[o2]) & 0x80000000)) {
wc->rxints++;
- receiveprep(wc, wc->rdbl);
- reinit_descriptor(wc, 0, wc->rdbl, "rxchk");
+ wcdte_receiveprep(wc, wc->rdbl);
+ wcdte_reinit_descriptor(wc, 0, wc->rdbl, "rxchk");
wc->rdbl = (wc->rdbl + 1) % ERING_SIZE;
return 1;
}
-
return 0;
}
-static void init_descriptors(struct wcdte *wc)
+static void wcdte_init_descriptors(struct wcdte *wc)
{
- volatile u32 *descrip;
+ volatile unsigned int *descrip;
dma_addr_t descripdma;
dma_addr_t writedma;
dma_addr_t readdma;
@@ -957,23 +992,23 @@ static void init_descriptors(struct wcdte *wc)
writedma = wc->writedma;
readdma = wc->readdma;
- for (x = 0; x < ERING_SIZE; x++) {
+ for (x=0;x<ERING_SIZE;x++) {
if (x < ERING_SIZE - 1)
descripdma += 16;
else
descripdma = wc->descripdma;
/* Transmit descriptor */
- 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);
+ 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] = 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));
+ 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;
@@ -986,27 +1021,31 @@ static void dte_wque_run(struct wcdte *wc)
if (wc->wqueints & 0x00000040) {
/* Loop descriptors is available */
- do {} while ((res = check_descriptor(wc)));
+ do {
+ res = wcdte_check_descriptor(wc);
+ } while(res);
}
/* Handle TX interrupts */
- if (wc->wqueints & 0x00000001) {
+ if (wc->wqueints & 0x00000001)
+ {
wc->txints++;
transmit_demand(wc);
wc->intcount++;
}
}
-ZAP_IRQ_HANDLER(interrupt_handler)
+ZAP_IRQ_HANDLER(wcdte_interrupt)
{
struct wcdte *wc = dev_id;
unsigned int ints;
- if (!(ints = getctl(wc, 0x0028)))
- return IRQ_NONE;
-
- setctl(wc, 0x0028, ints);
+ /* Read and clear interrupts */
+ ints = wcdte_getctl(wc, 0x0028);
+ wcdte_setctl(wc, 0x0028, ints);
+ if (!ints)
+ return IRQ_NONE;
ints &= wc->intmask;
if (ints & 0x00000041) {
@@ -1014,122 +1053,147 @@ ZAP_IRQ_HANDLER(interrupt_handler)
queue_work(wc->dte_wq, &wc->dte_work);
}
- if (!debug)
- return IRQ_RETVAL(1);
+ if ((ints & 0x00008000) && debug)
+ printk("wcdte: Abnormal 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");
- debug_printk(ints & 0x00008000, "Abnormal Interrupt\n");
- debug_printk(ints & 0x00002000, "Fatal Bus Error\n");
- debug_printk(ints & 0x00000100, "Receive Stopped\n");
- debug_printk(ints & 0x00000080, "Receive Desciptor Unavailable\n");
- debug_printk(ints & 0x00000020, "Transmit Under-flow\n");
- debug_printk(ints & 0x00000008, "Jabber Timer Time-out\n");
- debug_printk(ints & 0x00000004, "Transmit Descriptor Unavailable\n");
- debug_printk(ints & 0x00000002, "Transmit Processor Stopped\n");
+ if ((ints & 0x00000004) && debug)
+ printk("wcdte: Transmit Descriptor Unavailable INT\n");
+
+ if ((ints & 0x00000002) && debug)
+ printk("wcdte: Transmit Processor Stopped INT\n");
return IRQ_RETVAL(1);
+
}
-
-static int hardware_init(struct wcdte *wc)
+static int wcdte_hardware_init(struct wcdte *wc)
{
/* Hardware stuff */
unsigned int reg;
unsigned long newjiffies;
/* Initialize descriptors */
- init_descriptors(wc);
+ wcdte_init_descriptors(wc);
/* Enable I/O Access */
pci_read_config_dword(wc->dev, 0x0004, &reg);
reg |= 0x00000007;
pci_write_config_dword(wc->dev, 0x0004, reg);
- setctl(wc, 0x0000, 0xFFF88001);
+ wcdte_setctl(wc, 0x0000, 0xFFF88001);
newjiffies = jiffies + HZ/10;
- while (((reg = getctl(wc, 0x0000)) & 0x00000001) && (newjiffies > jiffies));
+ while(((reg = wcdte_getctl(wc,0x0000)) & 0x00000001) && (newjiffies > jiffies));
+
/* Configure watchdogs, access, etc */
- setctl(wc, 0x0030, 0x00280048);
- setctl(wc, 0x0078, 0x00000013 /* | (1 << 28) */);
+ wcdte_setctl(wc, 0x0030, 0x00280048);
+ wcdte_setctl(wc, 0x0078, 0x00000013 /* | (1 << 28) */);
- reg = getctl(wc, 0x00fc);
- setctl(wc, 0x00fc, (reg & ~0x7) | 0x7);
+ reg = wcdte_getctl(wc, 0x00fc);
+ wcdte_setctl(wc, 0x00fc, (reg & ~0x7) | 0x7);
- reg = getctl(wc, 0x00fc);
+ reg = wcdte_getctl(wc, 0x00fc);
return 0;
}
-static inline void setintmask(struct wcdte *wc, unsigned int intmask)
+static void wcdte_setintmask(struct wcdte *wc, unsigned int intmask)
{
wc->intmask = intmask;
- setctl(wc, 0x0038, intmask);
+ wcdte_setctl(wc, 0x0038, intmask);
}
-static inline void enable_interrupts(struct wcdte *wc)
+static void wcdte_enable_interrupts(struct wcdte *wc)
{
- setintmask(wc, !debug ? 0x00010041 : 0x0001A1EB);
+ /* Enable interrupts */
+ if (!debug)
+ wcdte_setintmask(wc, 0x00010041);
+ else
+ wcdte_setintmask(wc, 0x0001A1EB);
}
-static void start_dma(struct wcdte *wc)
+static void wcdte_start_dma(struct wcdte *wc)
{
unsigned int reg;
-
wmb();
- setctl(wc, 0x0020, wc->descripdma);
- setctl(wc, 0x0018, wc->descripdma + (16 * ERING_SIZE));
+ wcdte_setctl(wc, 0x0020, wc->descripdma);
+ wcdte_setctl(wc, 0x0018, wc->descripdma + (16 * ERING_SIZE));
/* Start receiver/transmitter */
- reg = getctl(wc, 0x0030);
- setctl(wc, 0x0030, reg | 0x00002002); /* Start XMT and RCD */
- setctl(wc, 0x0010, 0x00000000); /* Receive Poll Demand */
- reg = getctl(wc, 0x0028);
- setctl(wc, 0x0028, reg);
-}
+ reg = wcdte_getctl(wc, 0x0030);
+ wcdte_setctl(wc, 0x0030, reg | 0x00002002); /* Start XMT and RCD */
+ wcdte_setctl(wc, 0x0010, 0x00000000); /* Receive Poll Demand */
+ reg = wcdte_getctl(wc, 0x0028);
+ wcdte_setctl(wc, 0x0028, reg);
-static void disable_interrupts(struct wcdte *wc)
-{
- setintmask(wc, 0x00000000);
- setctl(wc, 0x0084, 0x00000000);
}
-static void stop_dma(struct wcdte *wc)
+static void wcdte_stop_dma(struct wcdte *wc)
{
+ /* Disable interrupts and reset */
unsigned int reg;
-
- disable_interrupts(wc);
- setctl(wc, 0x0048, 0x00000000);
+ /* Disable interrupts */
+ wcdte_setintmask(wc, 0x00000000);
+ wcdte_setctl(wc, 0x0084, 0x00000000);
+ wcdte_setctl(wc, 0x0048, 0x00000000);
/* Reset the part to be on the safe side */
- reg = getctl(wc, 0x0000);
+ reg = wcdte_getctl(wc, 0x0000);
reg |= 0x00000001;
- setctl(wc, 0x0000, reg);
+ wcdte_setctl(wc, 0x0000, reg);
+}
+
+static void wcdte_disable_interrupts(struct wcdte *wc)
+{
+ /* Disable interrupts */
+ wcdte_setintmask(wc, 0x00000000);
+ wcdte_setctl(wc, 0x0084, 0x00000000);
}
-static int waitfor_csmencaps(struct wcdte *wc, unsigned int mask, int use_mask)
+static int wcdte_waitfor_csmencaps(struct wcdte *wc, unsigned int mask, int use_mask)
{
int ret;
- ret = wait_event_interruptible_timeout(wc->regq,
- use_mask ? (wc->rcvflags == mask) : (wc->last_rcommand == wc->last_command_sent),
- wc->timeout);
+
+ if (use_mask)
+ ret = wait_event_interruptible_timeout(wc->regq, (wc->rcvflags == mask), wc->timeout);
+ else
+ ret = wait_event_interruptible_timeout(wc->regq, (wc->last_rcommand == wc->last_command_sent), wc->timeout);
wc->rcvflags = 0;
wc->last_rcommand = 0;
wc->last_command_sent = 0;
- if (ret < 0) {
- debug_printk(1, "Wait interrupted, need to stop boot (ret = %d)\n", ret);
- return 1;
+ if (ret < 0)
+ {
+ if (debug)
+ printk("wcdte error: Wait interrupted, need to stop boot (ret = %d)\n", ret);
+ return(1);
}
-
- if (!ret) {
- debug_printk(1, "Waitfor CSMENCAPS response timed out (ret = %d)\n", ret);
- return 2;
+ if (ret == 0)
+ {
+ if (debug)
+ printk("wcdte error: Waitfor CSMENCAPS response timed out (ret = %d)\n", ret);
+ return(2);
}
-
- return 0;
+ return(0);
}
-static int read_phy(struct wcdte *wc, int location)
+
+static int wcdte_read_phy(struct wcdte *wc, int location)
{
int i;
long mdio_addr = 0x0048;
@@ -1138,35 +1202,34 @@ static int read_phy(struct wcdte *wc, int location)
/* Establish sync by sending at least 32 logic ones. */
for (i = 32; i >= 0; i--) {
- setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1);
- getctl(wc, mdio_addr);
- setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK);
- getctl(wc, mdio_addr);
+ wcdte_setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1);
+ wcdte_getctl(wc, mdio_addr);
+ wcdte_setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK);
+ wcdte_getctl(wc, mdio_addr);
}
/* Shift the read command bits out. */
for (i = 17; i >= 0; i--) {
int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
- setctl(wc, mdio_addr, MDIO_ENB | dataval);
- getctl(wc, mdio_addr);
- setctl(wc, mdio_addr, MDIO_ENB | dataval | MDIO_SHIFT_CLK);
- getctl(wc, mdio_addr);
+ wcdte_setctl(wc, mdio_addr, MDIO_ENB | dataval);
+ wcdte_getctl(wc, mdio_addr);
+ wcdte_setctl(wc, mdio_addr, MDIO_ENB | dataval | MDIO_SHIFT_CLK);
+ wcdte_getctl(wc, mdio_addr);
}
/* Read the two transition, 16 data, and wire-idle bits. */
for (i = 19; i > 0; i--) {
- setctl(wc, mdio_addr, MDIO_ENB_IN);
- getctl(wc, mdio_addr);
- retval = (retval << 1) | ((getctl(wc, mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
- setctl(wc, mdio_addr, MDIO_ENB_IN | MDIO_SHIFT_CLK);
- getctl(wc, mdio_addr);
+ wcdte_setctl(wc, mdio_addr, MDIO_ENB_IN);
+ wcdte_getctl(wc, mdio_addr);
+ retval = (retval << 1) | ((wcdte_getctl(wc, mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
+ wcdte_setctl(wc, mdio_addr, MDIO_ENB_IN | MDIO_SHIFT_CLK);
+ wcdte_getctl(wc, mdio_addr);
}
- retval = (retval >> 1) & 0xffff;
-
+ retval = (retval>>1) & 0xffff;
return retval;
}
-void write_phy(struct wcdte *wc, int location, int value)
+void wcdte_write_phy(struct wcdte *wc, int location, int value)
{
int i;
int cmd = (0x5002 << 16) | (1 << 23) | (location<<18) | value;
@@ -1174,124 +1237,150 @@ void write_phy(struct wcdte *wc, int location, int value)
/* Establish sync by sending 32 logic ones. */
for (i = 32; i >= 0; i--) {
- setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1);
- getctl(wc, mdio_addr);
- setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK);
- getctl(wc, mdio_addr);
+ wcdte_setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1);
+ wcdte_getctl(wc, mdio_addr);
+ wcdte_setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK);
+ wcdte_getctl(wc, mdio_addr);
}
/* Shift the command bits out. */
for (i = 31; i >= 0; i--) {
int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
- setctl(wc, mdio_addr, MDIO_ENB | dataval);
- getctl(wc, mdio_addr);
- setctl(wc, mdio_addr, MDIO_ENB | dataval | MDIO_SHIFT_CLK);
- getctl(wc, mdio_addr);
+ wcdte_setctl(wc, mdio_addr, MDIO_ENB | dataval);
+ wcdte_getctl(wc, mdio_addr);
+ wcdte_setctl(wc, mdio_addr, MDIO_ENB | dataval | MDIO_SHIFT_CLK);
+ wcdte_getctl(wc, mdio_addr);
}
/* Clear out extra bits. */
for (i = 2; i > 0; i--) {
- setctl(wc, mdio_addr, MDIO_ENB_IN);
- getctl(wc, mdio_addr);
- setctl(wc, mdio_addr, MDIO_ENB_IN | MDIO_SHIFT_CLK);
- getctl(wc, mdio_addr);
+ wcdte_setctl(wc, mdio_addr, MDIO_ENB_IN);
+ wcdte_getctl(wc, mdio_addr);
+ wcdte_setctl(wc, mdio_addr, MDIO_ENB_IN | MDIO_SHIFT_CLK);
+ wcdte_getctl(wc, mdio_addr);
}
return;
}
-static int boot_processor(struct wcdte *wc, const struct firmware *firmware)
+static int wcdte_boot_processor(struct wcdte *wc, const struct firmware *firmware)
{
- int byteloc, last_byteloc, length, delay_count;
+ int i, j, byteloc, last_byteloc, length, delay_count;
unsigned int reg, ret;
-#if !defined(USE_TEST_HW)
+#ifndef USE_TEST_HW
/* Turn off auto negotiation */
- write_phy(wc, 0, 0x2100);
-
- debug_printk(1, "PHY register 0 = %X", read_phy(wc, 0));
+ wcdte_write_phy(wc, 0, 0x2100);
+ if (debug)
+ printk("wcdte: PHY register 0 = %X", wcdte_read_phy(wc, 0));
/* Set reset */
- setctl(wc, 0x00A0, 0x04000000);
+ wcdte_setctl(wc, 0x00A0, 0x04000000);
- /* Wait 1000ms to ensure processor reset */
+ /* Wait 1000msec to ensure processor reset */
mdelay(1000);
/* Clear reset */
- setctl(wc, 0x00A0, 0x04080000);
-
- /* Wait for Ethernet link */
- for (delay_count = 0;
- ((getctl(wc, 0x00fc) & 0xE0000000) != 0xE0000000) && delay_count < 100;
- mdelay(100), delay_count++);
+ wcdte_setctl(wc, 0x00A0, 0x04080000);
+
+ /* Waitfor ethernet link */
+ delay_count = 0;
+ do
+ {
+ reg = wcdte_getctl(wc, 0x00fc);
+ mdelay(100);
+ delay_count++;
+
+ if (delay_count >= 100)
+ {
+ printk("wcdte error: Failed to link to DTE processor!\n");
+ return(1);
+ }
+ } while ((reg & 0xE0000000) != 0xE0000000);
- if (delay_count == 100) {
- module_printk("Failed to link to DTE processor!\n");
- return 1;
- }
/* Turn off booted LED */
- setctl(wc, 0x00A0, 0x04084000);
-#endif /* !defined(USE_TEST_HW) */
+ wcdte_setctl(wc, 0x00A0, 0x04084000);
- if (debug) {
- reg = getctl(wc, 0x00fc);
- debug_printk(1, "LINK STATUS: reg(0xfc) = %X\n", reg);
- }
+
+#endif
- for (ret = 0, last_byteloc = byteloc = 17; byteloc < (firmware->size - 20); last_byteloc = byteloc) {
- length = (firmware->data[byteloc] << 8) | firmware->data[byteloc + 1];
+ reg = wcdte_getctl(wc, 0x00fc);
+ if (debug)
+ printk("wcdte: LINK STATUS: reg(0xfc) = %X\n", reg);
+
+ reg = wcdte_getctl(wc, 0x00A0);
+
+ byteloc = 17;
+ j = 0;
+ do
+ {
+ last_byteloc = byteloc;
+
+ length = (firmware->data[byteloc] << 8) |firmware->data[byteloc+1];
byteloc += 2;
- __transmit_one(wc, firmware->data + byteloc, length);
- byteloc += length;
- ret = waitfor_csmencaps(wc, RCV_CSMENCAPS_ACK, 1);
+
+ down(&wc->cmdqsem);
+ if ( (((wc->cmdq_wndx + 1) % MAX_COMMANDS) == wc->cmdq_rndx) && debug )
+ printk("wcdte error: cmdq is full.\n");
+ else
+ {
+ wc->cmdq[wc->cmdq_wndx].cmdlen = length;
+ for (i = 0; i < length; i++)
+ wc->cmdq[wc->cmdq_wndx].cmd[i] = firmware->data[byteloc++];
+ wc->cmdq_wndx = (wc->cmdq_wndx + 1) % MAX_COMMANDS;
+ }
+
+ __transmit_demand(wc);
+ up(&wc->cmdqsem);
+
+ ret = wcdte_waitfor_csmencaps(wc, RCV_CSMENCAPS_ACK, 1);
if (ret == 1)
- return 1;
- else if (ret == 2) /* Retransmit if processor times out */
+ return(1);
+ else if (ret == 2) /* Retransmit if dte processor times out */
byteloc = last_byteloc;
- }
+ j++;
+ } while (byteloc < firmware->size-20);
wc->timeout = 10 * HZ;
- if (waitfor_csmencaps(wc, RCV_CSMENCAPS, 1))
- return 1;
+ if (wcdte_waitfor_csmencaps(wc, RCV_CSMENCAPS, 1))
+ return(1);
/* Turn on booted LED */
- setctl(wc, 0x00A0, 0x04080000);
-
- debug_printk(1, "Successfully booted DTE processor.\n");
+ wcdte_setctl(wc, 0x00A0, 0x04080000);
+ if(debug)
+ printk("wcdte: Successfully booted DTE processor.\n");
- return 0;
+ return(0);
}
-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 wcdte_create_channel(struct wcdte *wc, int simple, int complicated, int part1_id, int part2_id, unsigned int *dte_chan1, unsigned int *dte_chan2)
{
int length = 0;
unsigned char chan1, chan2;
-
- if (complicated == DTE_FORMAT_G729A)
+ if(complicated == DTE_FORMAT_G729A)
length = G729_LENGTH;
else if (complicated == DTE_FORMAT_G723_1)
length = G723_LENGTH;
/* Create complex channel */
- send_cmd(wc, CMD_MSG_CREATE_CHANNEL(wc->seq_num++, part1_id), CMD_MSG_CREATE_CHANNEL_LEN, 0x0010);
+ zt_send_cmd(wc, CMD_MSG_CREATE_CHANNEL(wc->seq_num++, part1_id), CMD_MSG_CREATE_CHANNEL_LEN, 0x0010);
chan1 = wc->last_rparm2;
/* Create simple channel */
- send_cmd(wc, CMD_MSG_CREATE_CHANNEL(wc->seq_num++, part2_id), CMD_MSG_CREATE_CHANNEL_LEN, 0x0010);
+ zt_send_cmd(wc, CMD_MSG_CREATE_CHANNEL(wc->seq_num++, part2_id), CMD_MSG_CREATE_CHANNEL_LEN, 0x0010);
chan2 = wc->last_rparm2;
/* Configure complex channel */
- send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(wc->seq_num++, chan1, part2_id, part1_id), CMD_MSG_SET_IP_HDR_CHANNEL_LEN, 0x9000);
- send_cmd(wc, CMD_MSG_VOIP_VCEOPT(wc->seq_num++, chan1, length, 0), CMD_MSG_VOIP_VCEOPT_LEN, 0x8001);
+ zt_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(wc->seq_num++, chan1, part2_id, part1_id), CMD_MSG_SET_IP_HDR_CHANNEL_LEN, 0x9000);
+ zt_send_cmd(wc, CMD_MSG_VOIP_VCEOPT(wc->seq_num++, chan1, length, 0), CMD_MSG_VOIP_VCEOPT_LEN, 0x8001);
/* Configure simple channel */
- send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(wc->seq_num++, chan2, part1_id, part2_id), CMD_MSG_SET_IP_HDR_CHANNEL_LEN, 0x9000);
- send_cmd(wc, CMD_MSG_VOIP_VCEOPT(wc->seq_num++, chan2, length, 0), CMD_MSG_VOIP_VCEOPT_LEN, 0x8001);
+ zt_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(wc->seq_num++, chan2, part1_id, part2_id), CMD_MSG_SET_IP_HDR_CHANNEL_LEN, 0x9000);
+ zt_send_cmd(wc, CMD_MSG_VOIP_VCEOPT(wc->seq_num++, chan2, length, 0), CMD_MSG_VOIP_VCEOPT_LEN, 0x8001);
- send_cmd(wc, CMD_MSG_TRANS_CONNECT(wc->seq_num++, 1, chan1, chan2, complicated, simple), CMD_MSG_TRANS_CONNECT_LEN, 0x9322);
- send_cmd(wc, CMD_MSG_VOIP_INDCTRL(wc->seq_num++, chan1), CMD_MSG_VOIP_INDCTRL_LEN, 0x8084);
- send_cmd(wc, CMD_MSG_VOIP_INDCTRL(wc->seq_num++, chan2), CMD_MSG_VOIP_INDCTRL_LEN, 0x8084);
- send_cmd(wc, CMD_MSG_VOIP_VOPENA(wc->seq_num++, chan1, complicated), CMD_MSG_VOIP_VOPENA_LEN, 0x8000);
- send_cmd(wc, CMD_MSG_VOIP_VOPENA(wc->seq_num++, chan2, simple), CMD_MSG_VOIP_VOPENA_LEN, 0x8000);
+ zt_send_cmd(wc, CMD_MSG_TRANS_CONNECT(wc->seq_num++, 1, chan1, chan2, complicated, simple), CMD_MSG_TRANS_CONNECT_LEN, 0x9322);
+ zt_send_cmd(wc, CMD_MSG_VOIP_INDCTRL(wc->seq_num++, chan1), CMD_MSG_VOIP_INDCTRL_LEN, 0x8084);
+ zt_send_cmd(wc, CMD_MSG_VOIP_INDCTRL(wc->seq_num++, chan2), CMD_MSG_VOIP_INDCTRL_LEN, 0x8084);
+ zt_send_cmd(wc, CMD_MSG_VOIP_VOPENA(wc->seq_num++, chan1, complicated), CMD_MSG_VOIP_VOPENA_LEN, 0x8000);
+ zt_send_cmd(wc, CMD_MSG_VOIP_VOPENA(wc->seq_num++, chan2, simple), CMD_MSG_VOIP_VOPENA_LEN, 0x8000);
*dte_chan1 = chan1;
*dte_chan2 = chan2;
@@ -1299,407 +1388,416 @@ static int create_channel(struct wcdte *wc, int simple, int complicated, int par
return 1;
}
-static int destroy_channel(struct wcdte *wc, unsigned int chan1, unsigned int chan2)
+static int wcdte_destroy_channel(struct wcdte *wc, unsigned int chan1, unsigned int chan2)
{
+
/* Turn off both channels */
- send_cmd(wc, CMD_MSG_VOIP_VOPENA_CLOSE(wc->seq_num++, chan1), CMD_MSG_VOIP_VOPENA_CLOSE_LEN, 0x8000);
- send_cmd(wc, CMD_MSG_VOIP_VOPENA_CLOSE(wc->seq_num++, chan2), CMD_MSG_VOIP_VOPENA_CLOSE_LEN, 0x8000);
+ zt_send_cmd(wc, CMD_MSG_VOIP_VOPENA_CLOSE(wc->seq_num++, chan1), CMD_MSG_VOIP_VOPENA_CLOSE_LEN, 0x8000);
+ zt_send_cmd(wc, CMD_MSG_VOIP_VOPENA_CLOSE(wc->seq_num++, chan2), CMD_MSG_VOIP_VOPENA_CLOSE_LEN, 0x8000);
/* Disconnect the channels */
- send_cmd(wc, CMD_MSG_TRANS_CONNECT(wc->seq_num++, 0, chan1, chan2, 0, 0), CMD_MSG_TRANS_CONNECT_LEN, 0x9322);
+ zt_send_cmd(wc, CMD_MSG_TRANS_CONNECT(wc->seq_num++, 0, chan1, chan2, 0, 0), CMD_MSG_TRANS_CONNECT_LEN, 0x9322);
/* Remove the channels */
- send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan1), CMD_MSG_DESTROY_CHANNEL_LEN, 0x0011);
- send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan2), CMD_MSG_DESTROY_CHANNEL_LEN, 0x0011);
+ zt_send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan1), CMD_MSG_DESTROY_CHANNEL_LEN, 0x0011);
+ zt_send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan2), CMD_MSG_DESTROY_CHANNEL_LEN, 0x0011);
return 1;
}
-static int setup_channels(struct wcdte *wc)
+static int wcdte_setup_channels(struct wcdte *wc)
{
#ifndef USE_TEST_HW
- send_cmd(wc, CMD_MSG_SET_ARM_CLK(wc->seq_num++), CMD_MSG_SET_ARM_CLK_LEN, 0x0411);
- send_cmd(wc, CMD_MSG_SET_SPU_CLK(wc->seq_num++), CMD_MSG_SET_SPU_CLK_LEN, 0x0412);
+ zt_send_cmd(wc, CMD_MSG_SET_ARM_CLK(wc->seq_num++), CMD_MSG_SET_ARM_CLK_LEN, 0x0411);
+ zt_send_cmd(wc, CMD_MSG_SET_SPU_CLK(wc->seq_num++), CMD_MSG_SET_SPU_CLK_LEN, 0x0412);
#endif
#ifdef USE_TDM_CONFIG
- send_cmd(wc, CMD_MSG_TDM_SELECT_BUS_MODE(wc->seq_num++), CMD_MSG_TDM_SELECT_BUS_MODE_LEN, 0x0417);
- send_cmd(wc, CMD_MSG_TDM_ENABLE_BUS(wc->seq_num++), CMD_MSG_TDM_ENABLE_BUS_LEN, 0x0405);
- send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x03, 0x20, 0x00), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
- send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x04, 0x80, 0x04), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
- send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x05, 0x20, 0x08), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
- send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x06, 0x80, 0x0C), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
+ zt_send_cmd(wc, CMD_MSG_TDM_SELECT_BUS_MODE(wc->seq_num++), CMD_MSG_TDM_SELECT_BUS_MODE_LEN, 0x0417);
+ zt_send_cmd(wc, CMD_MSG_TDM_ENABLE_BUS(wc->seq_num++), CMD_MSG_TDM_ENABLE_BUS_LEN, 0x0405);
+ zt_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x03, 0x20, 0x00), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
+ zt_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x04, 0x80, 0x04), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
+ zt_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x05, 0x20, 0x08), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
+ zt_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x06, 0x80, 0x0C), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
#endif
- send_cmd(wc, CMD_MSG_SET_ETH_HEADER(wc->seq_num++), CMD_MSG_SET_ETH_HEADER_LEN, 0x0100);
- send_cmd(wc, CMD_MSG_IP_SERVICE_CONFIG(wc->seq_num++), CMD_MSG_IP_SERVICE_CONFIG_LEN, 0x0302);
- send_cmd(wc, CMD_MSG_ARP_SERVICE_CONFIG(wc->seq_num++), CMD_MSG_ARP_SERVICE_CONFIG_LEN, 0x0105);
- send_cmd(wc, CMD_MSG_ICMP_SERVICE_CONFIG(wc->seq_num++), CMD_MSG_ICMP_SERVICE_CONFIG_LEN, 0x0304);
+ zt_send_cmd(wc, CMD_MSG_SET_ETH_HEADER(wc->seq_num++), CMD_MSG_SET_ETH_HEADER_LEN, 0x0100);
+ zt_send_cmd(wc, CMD_MSG_IP_SERVICE_CONFIG(wc->seq_num++), CMD_MSG_IP_SERVICE_CONFIG_LEN, 0x0302);
+ zt_send_cmd(wc, CMD_MSG_ARP_SERVICE_CONFIG(wc->seq_num++), CMD_MSG_ARP_SERVICE_CONFIG_LEN, 0x0105);
+ zt_send_cmd(wc, CMD_MSG_ICMP_SERVICE_CONFIG(wc->seq_num++), CMD_MSG_ICMP_SERVICE_CONFIG_LEN, 0x0304);
#ifdef USE_TDM_CONFIG
- send_cmd(wc, CMD_MSG_DEVICE_SET_COUNTRY_CODE(wc->seq_num++), CMD_MSG_DEVICE_SET_COUNTRY_CODE_LEN, 0x041B);
+ zt_send_cmd(wc, CMD_MSG_DEVICE_SET_COUNTRY_CODE(wc->seq_num++), CMD_MSG_DEVICE_SET_COUNTRY_CODE_LEN, 0x041B);
#endif
- send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL(wc->seq_num++, 0x02), CMD_MSG_SPU_FEATURES_CONTROL_LEN, 0x0013);
- send_cmd(wc, CMD_MSG_IP_OPTIONS(wc->seq_num++), CMD_MSG_IP_OPTIONS_LEN, 0x0306);
- send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL(wc->seq_num++, 0x04), CMD_MSG_SPU_FEATURES_CONTROL_LEN, 0x0013);
+ zt_send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL(wc->seq_num++, 0x02), CMD_MSG_SPU_FEATURES_CONTROL_LEN, 0x0013);
+ zt_send_cmd(wc, CMD_MSG_IP_OPTIONS(wc->seq_num++), CMD_MSG_IP_OPTIONS_LEN, 0x0306);
+ zt_send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL(wc->seq_num++, 0x04), CMD_MSG_SPU_FEATURES_CONTROL_LEN, 0x0013);
#ifdef USE_TDM_CONFIG
- send_cmd(wc, CMD_MSG_TDM_OPT(wc->seq_num++), CMD_MSG_TDM_OPT_LEN, 0x0435);
+ zt_send_cmd(wc, CMD_MSG_TDM_OPT(wc->seq_num++), CMD_MSG_TDM_OPT_LEN, 0x0435);
#endif
- wc->timeout = HZ/100 + 1;
+ wc->timeout = HZ/100 + 1; /* 10msec */
- return 0;
+ return(0);
}
-static int __devinit init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- int res = 0, reg;
+ int res, reg;
struct wcdte *wc;
- struct wcdte_desc *d = (struct wcdte_desc *) ent->driver_data;
+ struct wcdte_desc *d = (struct wcdte_desc *)ent->driver_data;
int x;
- unsigned int g729_numchannels, g723_numchannels;
- u8 firmware_ver;
- unsigned int complexfmts = 0;
- struct firmware embedded_firmware;
+ static int initd_ifaces=0;
+ unsigned char g729_numchannels, g723_numchannels, min_numchannels, dte_firmware_ver;
+ unsigned int complexfmts;
+ struct firmware embedded_firmware = {
+#if !defined(HOTPLUG_FIRMWARE)
+ /* Yes... this is weird. objcopy gives us a symbol containing
+ the size of the firmware, not a pointer to a variable containing
+ the size. The only way we can get the value of the symbol
+ is to take its address, so we define it as a pointer and
+ then cast that value to the proper type.
+ */
+ .size = (size_t) &_binary_tc400m_firmware_bin_size,
+ .data = _binary_tc400m_firmware_bin_start,
+#endif
+ };
const struct firmware *firmware = &embedded_firmware;
- struct dte_state *encoders;
- struct dte_state *decoders;
- for (x = 0; x < (sizeof(ifaces) / sizeof(ifaces[0])); x++)
+ if (!initd_ifaces) {
+ memset((void *)ifaces,0,(sizeof(struct wcdte *))*WC_MAX_IFACES);
+ initd_ifaces=1;
+ }
+ for (x=0;x<WC_MAX_IFACES;x++)
if (!ifaces[x]) break;
-
- if (x == (sizeof(ifaces) / sizeof(ifaces[0]))) {
- module_printk("Too many interfaces\n");
+ if (x >= WC_MAX_IFACES) {
+ printk("wcdte: Too many interfaces\n");
return -EIO;
}
- if (pci_enable_device(pdev))
- return -EIO;
+ if (pci_enable_device(pdev)) {
+ res = -EIO;
+ } else {
- if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL)))
- return -ENOMEM;
-
- memset(wc, 0, sizeof(*wc));
- ifaces[x] = wc;
- spin_lock_init(&wc->reglock);
- sema_init(&wc->chansem, 1);
- sema_init(&wc->cmdqsem, 1);
- wc->iobase = pci_resource_start(pdev, 0);
- wc->dev = pdev;
- wc->pos = x;
- wc->variety = d->name;
-
- wc->seq_num = 6;
- wc->timeout = HZ;
+ wc = vmalloc(sizeof(struct wcdte));
+ if (wc) {
+ ifaces[x] = wc;
+ memset(wc, 0, sizeof(struct wcdte));
+ spin_lock_init(&wc->reglock);
+ sema_init(&wc->chansem, 1);
+ sema_init(&wc->cmdqsem, 1);
+ wc->cards = NUM_CARDS;
+ wc->iobase = pci_resource_start(pdev, 0);
+ wc->dev = pdev;
+ wc->pos = x;
+ wc->variety = d->name;
+
+ wc->tdbl = 0;
+ wc->rdbl = 0;
+ wc->rcvflags = 0;
+ wc->last_command_sent = 0;
+ wc->last_rcommand = 0;
+ wc->last_rparm2 = 0;
+ wc->cmdq_wndx = 0;
+ wc->cmdq_rndx = 0;
+ wc->seq_num = 6;
+ wc->timeout = 1 * HZ; /* 1 sec */
+ wc->ztsnd_rtx = 0;
+ wc->ztsnd_0010_rtx = 0;
+
+ /* Keep track of whether we need to free the region */
+ if (request_region(wc->iobase, 0xff, "wcdte"))
+ wc->freeregion = 1;
+
+ /* Allocate enought memory for all TX buffers, RX buffers, and descriptors */
+ wc->writechunk = (int *)pci_alloc_consistent(pdev, PCI_WINDOW_SIZE, &wc->writedma);
+ if (!wc->writechunk) {
+ printk("wcdte error: Unable to allocate DMA-able memory\n");
+ if (wc->freeregion)
+ release_region(wc->iobase, 0xff);
+ return -ENOMEM;
+ }
- 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"))
- wc->freeregion = 1;
-
- /* Allocate enough memory for all TX buffers, RX buffers, and descriptors */
- wc->writechunk = pci_alloc_consistent(pdev, PCI_WINDOW_SIZE, &wc->writedma);
- if (!wc->writechunk) {
- module_printk("Unable to allocate DMA-able memory\n");
- if (wc->freeregion)
- release_region(wc->iobase, 0xff);
-
- return -ENOMEM;
- }
-
- wc->readchunk = wc->writechunk + (SFRAME_SIZE * ERING_SIZE);
- wc->readdma = wc->writedma + (SFRAME_SIZE * ERING_SIZE);
-
- wc->descripchunk = (u32 *) (wc->readchunk + (SFRAME_SIZE * ERING_SIZE));
- wc->descripdma = wc->readdma + (SFRAME_SIZE * ERING_SIZE);
-
- init_waitqueue_head(&wc->regq);
-
- /* Initialize the work queue */
- wc->dte_wq = create_workqueue("wctc4xxp");
+ wc->readchunk = wc->writechunk + (SFRAME_SIZE * ERING_SIZE) / 4; /* in doublewords */
+ wc->readdma = wc->writedma + (SFRAME_SIZE * ERING_SIZE); /* in bytes */
+
+ wc->descripchunk = wc->readchunk + (SFRAME_SIZE * ERING_SIZE) / 4; /* in doublewords */
+ wc->descripdma = wc->readdma + (SFRAME_SIZE * ERING_SIZE); /* in bytes */
- INIT_WORK(&wc->dte_work, (void (*)(void *)) dte_wque_run, wc);
+ /* Initialize Write/Buffers to all blank data */
+ memset((void *)wc->writechunk,0x00, SFRAME_SIZE * 2);
+ memset((void *)wc->readchunk, 0x00, SFRAME_SIZE * 2);
+ init_waitqueue_head(&wc->regq);
+
+ /* Initialize the work queue */
+ wc->dte_wq = create_workqueue("tc400b");
+ INIT_WORK(&wc->dte_work, (void (*)(void *))dte_wque_run, wc);
#ifdef HOTPLUG_FIRMWARE
- if ((request_firmware(&firmware, tc400m_firmware, &wc->dev->dev) != 0) || !firmware) {
- module_printk("Firmware %s not available from userspace\n", tc400m_firmware);
- return -1;
- }
-#else
- embedded_firmware.data = _binary_tc400m_firmware_bin_start;
- /* Yes... this is weird. objcopy gives us a symbol containing
- the size of the firmware, not a pointer a variable containing
- the size. The only way we can get the value of the symbol
- is to take its address, so we do that and then cast that
- value to the proper type.
- */
- embedded_firmware.size = (size_t) &_binary_tc400m_firmware_bin_size;
+ if ((request_firmware(&firmware, dte_firmware, &wc->dev->dev) != 0) || !firmware) {
+ printk("TC400B: firmware %s not available from userspace\n", dte_firmware);
+ return -1;
+ }
#endif
+ dte_firmware_ver = firmware->data[0];
+ g729_numchannels = firmware->data[1];
+ g723_numchannels = firmware->data[2];
- firmware_ver = firmware->data[0];
- g729_numchannels = firmware->data[1];
- g723_numchannels = firmware->data[2];
-
- wc->numchannels = 2048; /* someday... */
+ if (g723_numchannels < g729_numchannels)
+ min_numchannels = g723_numchannels;
+ else
+ min_numchannels = g729_numchannels;
+
+ /* Setup Encoders nad Decoders */
+
+ if (!mode || strlen(mode) < 4)
+ {
+ sprintf(wc->complexname, "g.729a / g.723.1 5.3kbps");
+ complexfmts = ZT_FORMAT_G729A | ZT_FORMAT_G723_1;
+ wc->numchannels = min_numchannels;
+ }
+ else if (mode[3] == '9') /* "g729" */
+ {
+ sprintf(wc->complexname, "g.729a");
+ complexfmts = ZT_FORMAT_G729A;
+ wc->numchannels = g729_numchannels;
+ }
+ else if (mode[3] == '3') /* "g723" */
+ {
+ sprintf(wc->complexname, "g.723.1 5.3kbps");
+ complexfmts = ZT_FORMAT_G723_1;
+ wc->numchannels = g723_numchannels;
+ }
+ else
+ {
+ sprintf(wc->complexname, "g.729a / g.723.1 5.3kbps");
+ complexfmts = ZT_FORMAT_G729A | ZT_FORMAT_G723_1;
+ wc->numchannels = min_numchannels;
+ }
+
+ uencode = zt_transcoder_alloc(wc->numchannels);
+ udecode = zt_transcoder_alloc(wc->numchannels);
+ encoders = vmalloc(sizeof(struct dte_state) * wc->numchannels);
+ decoders = vmalloc(sizeof(struct dte_state) * wc->numchannels);
+ memset(encoders, 0, sizeof(struct dte_state) * wc->numchannels);
+ memset(decoders, 0, sizeof(struct dte_state) * wc->numchannels);
+ if (!uencode || !udecode || !encoders || !decoders) {
+ if (uencode)
+ zt_transcoder_free(uencode);
+ if (udecode)
+ zt_transcoder_free(udecode);
+ if (encoders)
+ vfree(encoders);
+ if (decoders)
+ vfree(decoders);
+ return -ENOMEM;
+ }
+ sprintf(udecode->name, "DTE Decoder");
+ sprintf(uencode->name, "DTE Encoder");
- for (x = 0; x < mode_count; x++) {
- if (!strcmp(mode[x], "g729") ||
- !strcmp(mode[x], "G729")) {
- if (!g729_numchannels) {
- module_printk("Format '%s' not supported by the firmware for this module; ignored.\n", mode[x]);
- continue;
+ udecode->srcfmts = uencode->dstfmts = complexfmts;
+ udecode->dstfmts = uencode->srcfmts = ZT_FORMAT_ULAW | ZT_FORMAT_ALAW;
+
+ udecode->operation = uencode->operation = dte_operation;
+
+ for (x=0;x<wc->numchannels;x++) {
+ dte_init_state(encoders + x, 1, x, wc);
+ encoders[x].encoder = 1;
+ decoders[x].encoder = 0;
+ dte_init_state(decoders + x, 0, x, wc);
+ uencode->channels[x].pvt = encoders + x;
+ udecode->channels[x].pvt = decoders + x;
}
- strcat(wc->complexname, "G.729A / ");
- complexfmts |= ZT_FORMAT_G729A;
- wc->numchannels = min(wc->numchannels, g729_numchannels);
- } else if (!strcmp(mode[x], "g723") ||
- !strcmp(mode[x], "G723")) {
- if (!g723_numchannels) {
- module_printk("Format '%s' not supported by the firmware for this module; ignored.\n", mode[x]);
- continue;
+
+ wc->uencode = uencode;
+ wc->udecode = udecode;
+
+ zt_transcoder_register(uencode);
+ zt_transcoder_register(udecode);
+
+ printk("Zaptel DTE (%s) Transcoder support LOADED (firm ver = %d)\n", wc->complexname, dte_firmware_ver);
+
+
+ /* Enable bus mastering */
+ pci_set_master(pdev);
+
+ /* Keep track of which device we are */
+ pci_set_drvdata(pdev, wc);
+
+ if (request_irq(pdev->irq, wcdte_interrupt, SA_SHIRQ, "tc400b", wc)) {
+ printk("wcdte error: Unable to request IRQ %d\n", pdev->irq);
+ if (wc->freeregion)
+ release_region(wc->iobase, 0xff);
+ pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
+ pci_set_drvdata(pdev, NULL);
+ vfree(wc);
+ return -EIO;
}
- strcat(wc->complexname, "G.723.1 5.3Kbps / ");
- complexfmts |= ZT_FORMAT_G723_1;
- wc->numchannels = min(wc->numchannels, g723_numchannels);
- } else {
- module_printk("Invalid transcoder format specified: %s\n", mode[x]);
- }
- }
- if (!complexfmts) {
- module_printk("No valid transcoder formats specified; module will not be enabled.\n");
- return -1;
- }
- wc->complexname[strlen(wc->complexname) - 3] = '\0';
-
- wc->uencode = zt_transcoder_alloc(wc->numchannels);
- wc->udecode = zt_transcoder_alloc(wc->numchannels);
- encoders = kmalloc(sizeof(*encoders) * wc->numchannels, GFP_KERNEL);
- decoders = kmalloc(sizeof(*decoders) * wc->numchannels, GFP_KERNEL);
- if (!wc->uencode || !wc->udecode || !encoders || !decoders) {
- if (wc->uencode)
- zt_transcoder_free(wc->uencode);
- if (wc->udecode)
- zt_transcoder_free(wc->udecode);
- if (encoders)
- kfree(encoders);
- if (decoders)
- kfree(decoders);
-
- return -ENOMEM;
- }
+ if (wcdte_hardware_init(wc)) {
+ /* Set Reset Low */
+ wcdte_stop_dma(wc);
+ /* Free Resources */
+ free_irq(pdev->irq, wc);
+ if (wc->freeregion)
+ release_region(wc->iobase, 0xff);
+ pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
+ pci_set_drvdata(pdev, NULL);
+ vfree(wc);
+ return -EIO;
- strcpy(wc->udecode->name, wc->variety);
- strcpy(wc->uencode->name, wc->variety);
-
- wc->udecode->srcfmts = wc->uencode->dstfmts = complexfmts;
- wc->udecode->dstfmts = wc->uencode->srcfmts = ZT_FORMAT_ULAW | ZT_FORMAT_ALAW;
-
- wc->udecode->operation = wc->uencode->operation = dte_operation;
-
- for (x = 0;x < wc->numchannels; x++) {
- dte_init_state(&encoders[x], 1, x, wc);
- dte_init_state(&decoders[x], 0, x, wc);
- wc->uencode->channels[x].pvt = &encoders[x];
- wc->udecode->channels[x].pvt = &decoders[x];
- }
-
- wc->uencode->owner = wc->udecode->owner = THIS_MODULE;
+ }
- zt_transcoder_register(wc->uencode);
- zt_transcoder_register(wc->udecode);
-
- /* Enable bus mastering */
- pci_set_master(pdev);
-
- /* Keep track of which device we are */
- pci_set_drvdata(pdev, wc);
-
- if (request_irq(pdev->irq, interrupt_handler, SA_SHIRQ, driver.name, wc)) {
- module_printk("Unable to request IRQ %d\n", pdev->irq);
- if (wc->freeregion)
- release_region(wc->iobase, 0xFF);
- pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *) wc->writechunk, wc->writedma);
- pci_set_drvdata(pdev, NULL);
- kfree(wc);
- /* TODO: what about all the encoders and decoders (do this earlier)? */
- return -EIO;
- }
-
- if (hardware_init(wc)) {
- /* Set Reset Low */
- stop_dma(wc);
- /* Free Resources */
- free_irq(pdev->irq, wc);
- if (wc->freeregion)
- release_region(wc->iobase, 0xff);
- pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *) wc->writechunk, wc->writedma);
- pci_set_drvdata(pdev, NULL);
- kfree(wc);
- return -EIO;
- }
-
- /* Enable interrupts */
- enable_interrupts(wc);
-
- /* Start DMA */
- start_dma(wc);
+ /* Enable interrupts */
+ wcdte_enable_interrupts(wc);
+
+ /* Start DMA */
+ wcdte_start_dma(wc);
+ if (wcdte_boot_processor(wc,firmware)) {
+ if (firmware != &embedded_firmware)
+ release_firmware(firmware);
+
+ /* Set Reset Low */
+ wcdte_stop_dma(wc);
+ /* Free Resources */
+ free_irq(pdev->irq, wc);
+ if (wc->freeregion)
+ release_region(wc->iobase, 0xff);
+ pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
+ pci_set_drvdata(pdev, NULL);
+ vfree(wc);
+ return -EIO;
+ }
- if (boot_processor(wc, firmware)) {
- /* Set Reset Low */
- stop_dma(wc);
- /* Free Resources */
- free_irq(pdev->irq, wc);
- if (wc->freeregion)
- release_region(wc->iobase, 0xff);
- pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *) wc->writechunk, wc->writedma);
- pci_set_drvdata(pdev, NULL);
- kfree(wc);
- return -EIO;
- }
-
- if (setup_channels(wc)) {
- /* Set Reset Low */
- stop_dma(wc);
- /* Free Resources */
- free_irq(pdev->irq, wc);
- if (wc->freeregion)
- release_region(wc->iobase, 0xff);
- pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *) wc->writechunk, wc->writedma);
- pci_set_drvdata(pdev, NULL);
- kfree(wc);
- return -EIO;
- }
-
- if (debug) {
- reg = getctl(wc, 0x00fc);
- debug_printk(1, "(post-boot) Reg fc is %08x\n", reg);
+ if (wcdte_setup_channels(wc))
+ {
+ /* Set Reset Low */
+ wcdte_stop_dma(wc);
+ /* Free Resources */
+ free_irq(pdev->irq, wc);
+ if (wc->freeregion)
+ release_region(wc->iobase, 0xff);
+ pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
+ pci_set_drvdata(pdev, NULL);
+ vfree(wc);
+ return -EIO;
+ }
+
+ reg = wcdte_getctl(wc, 0x00fc);
+ if (debug)
+ printk("wcdte debug: (post-boot) Reg fc is %08x\n", reg);
+
+ printk("Found and successfully installed a Wildcard TC: %s \n", wc->variety);
+ res = 0;
+ } else
+ res = -ENOMEM;
}
-
- module_printk("%s supporting '%s' with firmware version '%d'\n", wc->variety, wc->complexname, firmware_ver);
-
- res = 0;
-
return res;
}
-static void release(struct wcdte *wc)
+static void wcdte_release(struct wcdte *wc)
{
- struct cmdq *cmdq, *next;
-
if (wc->freeregion)
release_region(wc->iobase, 0xff);
- list_for_each_entry_safe(cmdq, next, &wc->pending_cmdq, list) {
- debug_printk(1, "freeing cmdq entry at '%p'\n", cmdq);
- list_del(&cmdq->list);
- kfree(cmdq);
- }
- list_for_each_entry_safe(cmdq, next, &wc->free_cmdq, list) {
- debug_printk(1, "freeing cmdq entry at '%p'\n", cmdq);
- list_del(&cmdq->list);
- kfree(cmdq);
- }
- kfree(wc);
+ vfree(wc);
}
-static void __devexit remove_one(struct pci_dev *pdev)
+static void __devexit wcdte_remove_one(struct pci_dev *pdev)
{
int i;
struct wcdte *wc = pci_get_drvdata(pdev);
struct zt_transcoder_channel *ztc_en, *ztc_de;
struct dte_state *st_en, *st_de;
- if (!wc)
- return;
-
- zt_transcoder_unregister(wc->udecode);
- zt_transcoder_unregister(wc->uencode);
-
- if (debug) {
- debug_printk(1, "wc->ztsnd_rtx = %d\n", wc->ztsnd_rtx);
- debug_printk(1, "wc->ztsnd_0010_rtx = %d\n", wc->ztsnd_0010_rtx);
-
- for (i = 0; i < wc->numchannels; i++) {
- ztc_en = &(wc->uencode->channels[i]);
- st_en = ztc_en->pvt;
-
- ztc_de = &(wc->udecode->channels[i]);
- st_de = ztc_de->pvt;
+ if (wc) {
+ if (debug)
+ {
+ printk("wcdte debug: wc->ztsnd_rtx = %d\n", wc->ztsnd_rtx);
+ printk("wcdte debug: wc->ztsnd_0010_rtx = %d\n", wc->ztsnd_0010_rtx);
+
+ for(i = 0; i < wc->numchannels; i++)
+ {
+ ztc_en = &(wc->uencode->channels[i]);
+ st_en = ztc_en->pvt;
- debug_printk(1, "en[%d] snt = %d, rcv = %d [%d]\n", i, st_en->packets_sent, st_en->packets_received, st_en->packets_sent - st_en->packets_received);
- debug_printk(1, "de[%d] snt = %d, rcv = %d [%d]\n", i, st_de->packets_sent, st_de->packets_received, st_de->packets_sent - st_de->packets_received);
+ ztc_de = &(wc->udecode->channels[i]);
+ st_de = ztc_de->pvt;
+
+ printk("wcdte debug: en[%d] snt = %d, rcv = %d [%d]\n", i, st_en->packets_sent, st_en->packets_received, st_en->packets_sent - st_en->packets_received);
+ printk("wcdte debug: de[%d] snt = %d, rcv = %d [%d]\n", i, st_de->packets_sent, st_de->packets_received, st_de->packets_sent - st_de->packets_received);
+ }
}
- }
-
- /* Stop any DMA */
- stop_dma(wc);
- /* In case hardware is still there */
- disable_interrupts(wc);
+ zt_transcoder_unregister(wc->udecode);
+ zt_transcoder_unregister(wc->uencode);
+ zt_transcoder_free(wc->uencode);
+ zt_transcoder_free(wc->udecode);
+ vfree(wc->uencode->channels[0].pvt);
+ vfree(wc->udecode->channels[0].pvt);
- /* Kill workqueue */
- destroy_workqueue(wc->dte_wq);
-
- /* Immediately free resources */
- pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *) wc->writechunk, wc->writedma);
- free_irq(pdev->irq, wc);
-
- kfree(wc->uencode->channels[0].pvt);
- kfree(wc->udecode->channels[0].pvt);
+ /* Stop any DMA */
+ wcdte_stop_dma(wc);
+
+ /* In case hardware is still there */
+ wcdte_disable_interrupts(wc);
- zt_transcoder_free(wc->uencode);
- zt_transcoder_free(wc->udecode);
+ /* Kill workqueue */
+ destroy_workqueue(wc->dte_wq);
+
+ /* Immediately free resources */
+ pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
+ free_irq(pdev->irq, wc);
- /* Release span, possibly delayed */
- release(wc);
+ /* Release span, possibly delayed */
+ wcdte_release(wc);
+ }
}
-static struct pci_device_id pci_tbl[] = {
+static struct pci_device_id wcdte_pci_tbl[] = {
#ifndef USE_TEST_HW
- { 0xd161, 0x3400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &wcdte }, /* digium board */
+ { 0xd161, 0x3400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &wcdte }, /* Digium board */
#else
{ 0x1317, 0x0985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &wcdte }, /* reference board */
#endif
{ 0 }
};
-MODULE_DEVICE_TABLE(pci, pci_tbl);
+MODULE_DEVICE_TABLE(pci, wcdte_pci_tbl);
-static struct pci_driver driver = {
+static struct pci_driver wcdte_driver = {
name: "wctc4xxp",
- probe: init_one,
- remove: __devexit_p(remove_one),
+ probe: wcdte_init_one,
+ remove: __devexit_p(wcdte_remove_one),
suspend: NULL,
resume: NULL,
- id_table: pci_tbl,
+ id_table: wcdte_pci_tbl,
};
-static int init(void)
+int ztdte_init(void)
{
- return pci_module_init(&driver) ? -ENODEV : 0;
+ int res;
+
+ res = pci_module_init(&wcdte_driver);
+ if (res)
+ return -ENODEV;
+ return 0;
}
-static void cleanup(void)
+void ztdte_cleanup(void)
{
- pci_unregister_driver(&driver);
+ pci_unregister_driver(&wcdte_driver);
}
module_param(debug, int, S_IRUGO | S_IWUSR);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
-module_param_array(mode, charp, &mode_count, S_IRUGO | S_IWUSR);
-#else
-module_param_array(mode, charp, mode_count, S_IRUGO | S_IWUSR);
-#endif
-module_param(debug_packets, uint, S_IRUGO | S_IWUSR);
-module_param(debug_cmd_packets, uint, S_IRUGO | S_IWUSR);
-MODULE_DESCRIPTION("Wildcard TC400P+TC400M Transcoder");
+module_param(mode, charp, S_IRUGO | S_IWUSR);
+MODULE_DESCRIPTION("Wildcard TC400P+TC400M Driver");
MODULE_AUTHOR("John Sloan <jsloan@digium.com>");
+#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
+#endif
-module_init(init);
-module_exit(cleanup);
+module_init(ztdte_init);
+module_exit(ztdte_cleanup);