summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-06-17 12:38:20 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-06-17 12:38:20 +0000
commit9b3e78c5c997fe9363c473f1161ff9c554dcfe69 (patch)
tree859a756e6e219c8ce1fcf2c3181da512eeac6cd3
parentb5755da0d40e72fad44756bc009fcf688c3380cc (diff)
* Echo canceller not disablerd
* card_fxo.c: Fixed an unreleased spinlock * utils/Makefile: No more C++ flags * utils/Makefile: An install target * fpga_load: usb1 support * genzaptelconf: Support for more cards (Any Sangoma A20x testers?) * xpp_fxloder: The new USB ID, even for manual loads... * xpp_zap.c: Print module fetures in a better format at load time. git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1114 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rw-r--r--xpp/Makefile2
-rw-r--r--xpp/card_fxo.c1
-rw-r--r--xpp/utils/Makefile27
-rw-r--r--xpp/utils/fpga_load.c124
-rwxr-xr-xxpp/utils/genzaptelconf27
-rw-r--r--xpp/utils/xpp_fxloader2
-rw-r--r--xpp/xpp_zap.c45
7 files changed, 198 insertions, 30 deletions
diff --git a/xpp/Makefile b/xpp/Makefile
index ec7ecbe..1355cc6 100644
--- a/xpp/Makefile
+++ b/xpp/Makefile
@@ -1,4 +1,4 @@
-EXTRA_CFLAGS = -I$(SUBDIRS) -DDEBUG # -DHARD_CODED_INIT # -DOLD_CARD # -DWITH_RBS
+EXTRA_CFLAGS = -I$(SUBDIRS) -DDEBUG -DWITH_ECHO_SUPPRESSION # -DHARD_CODED_INIT # -DOLD_CARD # -DWITH_RBS
obj-m = xpp.o xpd_fxs.o xpd_fxo.o xpp_usb.o
xpp-y += xbus-core.o xpp_zap.o xproto.o card_global.o
diff --git a/xpp/card_fxo.c b/xpp/card_fxo.c
index 15e71e1..bd3e141 100644
--- a/xpp/card_fxo.c
+++ b/xpp/card_fxo.c
@@ -413,6 +413,7 @@ static int FXO_card_tick(xbus_t *xbus, xpd_t *xpd)
for_each_enabled_line(xpd, i) {
spin_lock_irqsave(&xpd->lock, flags);
do_led(xpd, i, LED_GREEN, LED_OFF);
+ spin_unlock_irqrestore(&xpd->lock, flags);
mdelay(20);
}
}
diff --git a/xpp/utils/Makefile b/xpp/utils/Makefile
index 021647c..562c738 100644
--- a/xpp/utils/Makefile
+++ b/xpp/utils/Makefile
@@ -1,15 +1,15 @@
-TEST_CPP = 1
-PEDANTIC = -ansi -pedantic
+PEDANTIC = -ansi -pedantic -std=c99
CC = gcc
RANLIB = ranlib
+INSTALL = install
-ifeq (1,${TEST_CPP})
-CXXFLAGS = $(CFLAGS)
-EXTRA_CFLAGS = -x c++
-EXTRA_LIBS = -lstdc++
-LDLIBS += $(EXTRA_LIBS)
-endif
+BINDIR = /sbin
+DATADIR = /usr/share/zaptel
+MANDIR = /usr/share/man/man8
+HOTPLUG_USB_DIR = /etc/hotplug/usb
+
+DATA_FILES = ../init_data_*.cmd ../initialize_registers
CFLAGS = -g -Wall $(EXTRA_CFLAGS)
@@ -17,6 +17,17 @@ TARGETS = libhexfile.a fpga_load test_parse
all: $(TARGETS)
+install: all
+ $(INSTALL) -d $(BINDIR)
+ $(INSTALL) genzaptelconf fpga_load $(BINDIR)/
+ $(INSTALL) -d $(DATADIR)
+ $(INSTALL) $(DATA_FILES) $(DATADIR)/
+ $(INSTALL) -d $(MANDIR)
+ $(INSTALL) fpga_load.8 $(MANDIR)/
+ $(INSTALL) -d $(HOTPLUG_USB_DIR)
+ $(INSTALL) xpp_fxloader xpp_fxloader.usermap $(HOTPLUG_USB_DIR)/
+
+
libhexfile.a: hexfile.o
$(AR) cru $@ $^
$(RANLIB) $@
diff --git a/xpp/utils/fpga_load.c b/xpp/utils/fpga_load.c
index cf20226..098b980 100644
--- a/xpp/utils/fpga_load.c
+++ b/xpp/utils/fpga_load.c
@@ -8,8 +8,6 @@
#include <usb.h>
#include "hexfile.h"
-#define XORCOM_INTERNAL
-
static const char rcsid[] = "$Id$";
#define ERR(fmt, arg...) fprintf(stderr, "%s: ERROR: " fmt, progname, ## arg)
@@ -359,6 +357,49 @@ int send_hexline(struct usb_dev_handle *handle, struct hexline *hexline, int seq
return 0;
}
+//. returns > 0 - ok, the number of lines sent
+//. returns < 0 - error number
+int send_splited_hexline(struct usb_dev_handle *handle, struct hexline *hexline, int seq, uint8_t maxwidth)
+{
+ struct hexline *extraline;
+ int linessent = 0;
+ int allocsize;
+ int extra_offset = 0;
+ unsigned int this_line = 0;
+ uint8_t bytesleft = 0;
+
+ if(!hexline) {
+ ERR("Bad record %d type = %d\n", seq, hexline->d.content.header.tt);
+ return -EINVAL;
+ }
+ bytesleft = hexline->d.content.header.ll;
+ // split the line into several lines
+ while (bytesleft > 0) {
+ int status;
+ this_line = (bytesleft >= maxwidth) ? maxwidth : bytesleft;
+ allocsize = sizeof(struct hexline) + this_line + 1;
+ // generate the new line
+ if((extraline = (struct hexline *)malloc(allocsize)) == NULL) {
+ ERR("Not enough memory for spliting the lines\n" );
+ return -EINVAL;
+ }
+ memset( extraline, 0, allocsize );
+ extraline->d.content.header.ll = this_line;
+ extraline->d.content.header.offset = hexline->d.content.header.offset + extra_offset;
+ extraline->d.content.header.tt = hexline->d.content.header.tt;
+ memcpy( extraline->d.content.tt_data.data, hexline->d.content.tt_data.data+extra_offset, this_line);
+ status = send_hexline( handle, extraline, seq+linessent );
+ // cleanups
+ free(extraline);
+ extra_offset += this_line;
+ bytesleft -= this_line;
+ if (status)
+ return status;
+ linessent++;
+ }
+ return linessent;
+}
+
int my_usb_device(struct usb_device *dev, usb_dev_handle *handle)
{
struct usb_device_descriptor *dev_desc;
@@ -460,6 +501,7 @@ int fpga_load(struct usb_dev_handle *handle, const struct hexdata *hexdata)
assert(handle != NULL);
if(verbose >= LOG_INFO)
INFO("Start...\n");
+
for(i = 0; i < hexdata->maxlines; i++) {
struct hexline *hexline = hexdata->lines[i];
@@ -484,6 +526,47 @@ int fpga_load(struct usb_dev_handle *handle, const struct hexdata *hexdata)
return 1;
}
+int fpga_load_usb1(struct usb_dev_handle *handle, const struct hexdata *hexdata)
+{
+ unsigned int i,j=0;
+ int ret;
+ int finished = 0;
+
+ assert(handle != NULL);
+ if(verbose >= LOG_INFO)
+ INFO("Start...\n");
+
+ // i - is the line number
+ // j - is the sequence number, on USB 2, i=j, but on
+ // USB 1 send_splited_hexline may increase the sequence
+ // number, as it needs
+ for(i = 0; i < hexdata->maxlines; i++) {
+ struct hexline *hexline = hexdata->lines[i];
+
+
+ if(!hexline)
+ break;
+ if(finished) {
+ ERR("Extra data after End Of Data Record (line %d)\n", i);
+ return 0;
+ }
+ if(hexline->d.content.header.tt == TT_EOF) {
+ INFO("End of data\n");
+ finished = 1;
+ continue;
+ }
+
+ if((ret = send_splited_hexline(handle, hexline, j, 60)) < 0) {
+ perror("Failed sending hexline (splitting did not help)");
+ return 0;
+ }
+ j += ret;
+ }
+ if(verbose >= LOG_INFO)
+ INFO("Finished...\n");
+ return 1;
+}
+
#include <getopt.h>
void usage()
@@ -494,6 +577,7 @@ void usage()
fprintf(stderr, "\t\t[-d] # Get device version from eeprom\n");
fprintf(stderr, "\t\t[-I <hexfile>] # Input from <hexfile>\n");
fprintf(stderr, "\t\t[-g] # Get eeprom from device\n");
+ fprintf(stderr, "\t\t[-C srC byte] # Set Address sourCe (default: C0)\n");
fprintf(stderr, "\t\t[-V vendorid] # Set Vendor id on device\n");
fprintf(stderr, "\t\t[-P productid] # Set Product id on device\n");
fprintf(stderr, "\t\t[-R release] # Set Release. 2 dot separated decimals\n");
@@ -511,6 +595,15 @@ static void parse_report_func(int level, const char *msg, ...)
va_end(ap);
}
+int hasUSB2( struct usb_device *dev )
+{
+ if (dev->config->interface->altsetting->endpoint->wMaxPacketSize != 512)
+ return 0;
+ else
+ return 1;
+}
+
+// usb_interface_descriptor->usb_endpoint_descriptor.wMaxPacketSize
int main(int argc, char *argv[])
{
@@ -526,11 +619,13 @@ int main(int argc, char *argv[])
#ifdef XORCOM_INTERNAL
int opt_write_eeprom = 0;
char *vendor = NULL;
+ char *source = NULL;
+ int is_source_given = 0;
char *product = NULL;
char *release = NULL;
char *serial = NULL;
uint8_t serial_buf[SERIAL_SIZE];
- const char options[] = "b:dD:ghI:vV:P:R:S:";
+ const char options[] = "b:C:dD:ghI:vV:P:R:S:";
#else
const char options[] = "b:dD:ghI:v";
#endif
@@ -567,6 +662,10 @@ int main(int argc, char *argv[])
case 'V':
vendor = optarg;
break;
+ case 'C':
+ source = optarg;
+ is_source_given = 1;
+ break;
case 'P':
product = optarg;
break;
@@ -648,8 +747,18 @@ int main(int argc, char *argv[])
ret = -ENODEV;
goto dev_err;
}
+
if(hexdata) {
- if(!fpga_load(handle, hexdata)) {
+ int status;
+
+ if (hasUSB2(dev))
+ status = fpga_load(handle, hexdata);
+ else {
+ INFO("Warning: working on a low end USB1 backend\n");
+ status = fpga_load_usb1(handle, hexdata);
+ }
+
+ if(!status) {
ERR("FPGA loading failed\n");
ret = -ENODEV;
goto dev_err;
@@ -661,7 +770,7 @@ int main(int argc, char *argv[])
}
}
#ifdef XORCOM_INTERNAL
- if(vendor || product || release || serial)
+ if(vendor || product || release || serial || source )
opt_read_eeprom = opt_write_eeprom = 1;
#endif
if(opt_read_eeprom) {
@@ -678,7 +787,10 @@ int main(int argc, char *argv[])
#ifdef XORCOM_INTERNAL
if(opt_write_eeprom) {
// FF: address source is from device. C0: from eeprom
- eeprom_buf.source = 0xC0;
+ if (is_source_given)
+ eeprom_buf.source = strtoul(source, NULL, 0);
+ else
+ eeprom_buf.source = 0xC0;
if(vendor)
eeprom_buf.vendor = strtoul(vendor, NULL, 0);
if(product)
diff --git a/xpp/utils/genzaptelconf b/xpp/utils/genzaptelconf
index 7bcc20e..fe5c9e4 100755
--- a/xpp/utils/genzaptelconf
+++ b/xpp/utils/genzaptelconf
@@ -31,6 +31,11 @@
# TODO: either ditch them or convert to perl
# Don't override variables here. Override them in /etc/default/zaptel
#
+# 0.5.3:
+# * Experimental support for Sangoman analog cards (A20x)
+# * fixed timeout for Astribank load
+# 0.5.2:
+# * Now it should detect most PRI cards and even wcusb
# 0.5.1:
# * Initial support for ztgsm (Junghanns's PCI GSM card)
# * Wait for the xpp module to register if just loaded
@@ -51,7 +56,7 @@
# * hence we can reduce the list of modules
# /etc/default/zaptel may override the following variables
-VERSION=0.5.1
+VERSION=0.5.3
VERSION_FULL="$VERSION $Id$"
lc_country=us
base_exten=6000
@@ -87,7 +92,7 @@ tmp_dir=
# A list of all modules:
# - the list of modules which will be probed (in this order) if -d is used
# - The module that will be deleted from /etc/modules , if -d -M is used
-ALL_MODULES="zaphfc qozap ztgsm wctdm wctdm24xxp wcfxo wcfxs pciradio tor2 torisa wct1xxp wct4xxp wcte11xp wcusb xpp_usb"
+ALL_MODULES="zaphfc qozap ztgsm wctdm wctdm24xxp wcfxo wcfxs pciradio tor2 torisa wct1xxp wct4xxp wcte11xp wanpipe wcusb xpp_usb"
# read default configuration from /etc/default/zaptel
if [ -r $ZAPTEL_BOOT ]; then . $ZAPTEL_BOOT; fi
@@ -469,16 +474,21 @@ wait_for_xpp() {
if [ -d /proc/xpp ] && \
[ "`cat /sys/module/xpp/parameters/zap_autoreg`" = 'Y' ]
then
+ out_on_timeout=0
# wait for the XPDs to register:
- for i in `seq 10`; do
+ for i in `seq 30`; do
sleep 1
if ! grep -q 0 /proc/xpp/*/*/zt_registration 2>/dev/null
then
# There are either no XPDs or all of them are
# registered. Nothing to do
+ out_on_timeout=1
break
fi
done
+ if [ "$out_on_timeout" != 0 ]
+ then echo >&2 "Warning: time out waiting for xpp init."
+ fi
fi
}
@@ -633,7 +643,7 @@ EOF
# in case this is a real channel.
chan_num=`echo $line |awk '{print $1}'`
case "$line" in
- *WCTDM/*)
+ *WCTDM/*|*/WRTDM/*)
# this can be either FXS or FXO
maybe_fxs=0
maybe_fxo=0
@@ -643,6 +653,8 @@ EOF
then
# An installed module won't accept both FXS and FXO signalling types:
# this is an empty slot.
+ # TODO: I believe that the Sangoma A20x will reject both and thus
+ # print nothing here.
echo "$rem_char channel $chan_num, WCTDM, no module."
continue
fi
@@ -654,6 +666,9 @@ EOF
print_pattern $chan_num fxs $mode || \
echo "$rem_char channel $chan_num, WCFXO, inactive."
;;
+ *WCUSB/*)
+ print_pattern $chan_num fxo $mode
+ ;;
*XPP_FXO/*)
print_pattern $chan_num fxs $mode
;;
@@ -666,7 +681,7 @@ EOF
*XPP_IN/*)
print_pattern -a input $chan_num fxo $mode
;;
- *ZTHFC*/*|*ztqoz*/*|*ztgsm/*|*WCT1/*) # should also be used for other PRI channels
+ *ZTHFC*/*|*ztqoz*/*|*ztgsm/*|*TE4/*|*TE2/*|*WCT1/*|*Tor2/*|*TorISA/*) # should also be used for other PRI channels
if [ "`cat $tmp_dir/span_begin`" = "-1" ]
then
echo $chan_num >$tmp_dir/span_begin
@@ -687,7 +702,7 @@ EOF
# what switch type? Any meaning to it?
echo 'gsm' >$tmp_dir/span_signalling
;;
- *WCT1/*)
+ *TE4/*|*TE2/*|*WCT1/*|*Tor2/*|*TorISA/*)
echo 'esf' >$tmp_dir/span_framing
echo 'b8zs' >$tmp_dir/span_coding
echo 'national' >$tmp_dir/span_switchtype
diff --git a/xpp/utils/xpp_fxloader b/xpp/utils/xpp_fxloader
index 6cde8f9..ef9f966 100644
--- a/xpp/utils/xpp_fxloader
+++ b/xpp/utils/xpp_fxloader
@@ -126,7 +126,7 @@ load_fpga() {
if [ "$1" = 'xppdetect' ]; then
load_fw 04b4 8613 USB_8613.hex
load_fw e4e4 1130 USB_1130.hex
- for dev in `find_dev e4e4 2311`; do
+ for dev in `find_dev e4e4 1131`; do
load_fpga $dev
done
exit $?
diff --git a/xpp/xpp_zap.c b/xpp/xpp_zap.c
index 52b2846..9a9ab0a 100644
--- a/xpp/xpp_zap.c
+++ b/xpp/xpp_zap.c
@@ -896,6 +896,30 @@ void fill_beep(u_char *buf, int duration)
memcpy(buf, &beep[(which*8) % ARRAY_SIZE(beep)], ZT_CHUNKSIZE);
}
+#ifdef XPP_EC_CHUNK
+/*
+ * Taken from zaptel.c
+ */
+static inline void xpp_ec_chunk(struct zt_chan *chan, unsigned char *rxchunk, const unsigned char *txchunk)
+{
+ short rxlin;
+ int x;
+ unsigned long flags;
+
+ /* Perform echo cancellation on a chunk if necessary */
+ if (!chan->ec)
+ return;
+ spin_lock_irqsave(&chan->lock, flags);
+ for (x=0;x<ZT_CHUNKSIZE;x++) {
+ rxlin = ZT_XLAW(rxchunk[x], chan);
+ rxlin = echo_can_update(chan->ec, ZT_XLAW(txchunk[x], chan), rxlin);
+ rxchunk[x] = ZT_LIN2X((int)rxlin, chan);
+ }
+ spin_unlock_irqrestore(&chan->lock, flags);
+}
+#endif
+
+
static void xpp_receiveprep(xpd_t *xpd)
{
volatile u_char *readchunk;
@@ -924,10 +948,14 @@ static void xpp_receiveprep(xpd_t *xpd)
readchunk += ZT_CHUNKSIZE;
}
-#if 0
+#if WITH_ECHO_SUPPRESSION
/* FIXME: need to Echo cancel double buffered data */
for (i = 0;i < xpd->span.channels; i++) {
+#ifdef XPP_EC_CHUNK
+ xpp_ec_chunk(&chans[i], chans[i].readchunk, xpd->ec_chunk2[i]);
+#else
zt_ec_chunk(&chans[i], chans[i].readchunk, xpd->ec_chunk2[i]);
+#endif
memcpy(xpd->ec_chunk2[i], xpd->ec_chunk1[i], ZT_CHUNKSIZE);
memcpy(xpd->ec_chunk1[i], chans[i].writechunk, ZT_CHUNKSIZE);
}
@@ -1517,18 +1545,19 @@ int __init xpp_zap_init(void)
INFO("%s revision %s\n", THIS_MODULE->name, ZAPTEL_VERSION);
#ifdef WITH_RBS
- INFO("%s (RBS signalling)\n", THIS_MODULE->name);
+ INFO("FEATURE: %s (RBS signalling)\n", THIS_MODULE->name);
#else
- INFO("%s (NO RBS signalling)\n", THIS_MODULE->name);
+ INFO("FEATURE: %s (NO RBS signalling)\n", THIS_MODULE->name);
#endif
-#ifdef HARD_CODED_INIT
-#ifdef OLD_CARD
- INFO("%s (HARD_CODED_INIT: OLD_CARD)\n", THIS_MODULE->name);
+#if WITH_ECHO_SUPPRESSION
+ INFO("FEATURE: %s (with ECHO_SUPPRESSION)\n", THIS_MODULE->name);
#else
- INFO("%s (HARD_CODED_INIT: NEW_CARD)\n", THIS_MODULE->name);
+ INFO("FEATURE: %s (without ECHO_SUPPRESSION)\n", THIS_MODULE->name);
#endif
+#ifdef XPP_EC_CHUNK
+ INFO("FEATURE: %s (with XPP_EC_CHUNK)\n", THIS_MODULE->name);
#else
- INFO("%s (DYNAMIC INIT REGISTERS)\n", THIS_MODULE->name);
+ INFO("FEATURE: %s (without XPP_EC_CHUNK)\n", THIS_MODULE->name);
#endif
#ifdef CONFIG_PROC_FS