summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xMakefile59
-rwxr-xr-xwcfxo.c240
-rwxr-xr-xwcfxsusb.c12
3 files changed, 213 insertions, 98 deletions
diff --git a/Makefile b/Makefile
index 7502f18..fb592cb 100755
--- a/Makefile
+++ b/Makefile
@@ -15,14 +15,32 @@ DEFAULTZONE=0
KINCLUDES=$(shell if [ -d /usr/src/linux-2.4/include ]; then echo /usr/src/linux-2.4/include ; else echo /usr/src/linux/include ; fi)
CFLAGS+=-I. -O4 -g -Wall -DBUILDING_TONEZONE #-DTONEZONE_DRIVER
+CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
LCFLAGS=-fPIC $(CFLAGS) -DBUILDING_TONEZONE
KFLAGS+=-I/usr/src/linux-2.4/include -O6
KFLAGS+=-DMODULE -D__KERNEL__ -DEXPORT_SYMTAB -I/usr/src/linux/drivers/net \
-Wall -I. -Wstrict-prototypes -fomit-frame-pointer -I/usr/src/linux/drivers/net/wan -I /usr/src/linux/include -I/usr/src/linux/include/net
KFLAGS+=$(shell [ -f $(KINCLUDES)/linux/modversions.h ] && echo "-DMODVERSIONS -include $(KINCLUDES)/linux/modversions.h")
+KFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-msoft-float -fsigned-char"; fi)
#
# Features
#
+#
+# Define CONFIG_CALC_XLAW if you have a small number of channels and/or
+# a small level 2 cache, to optimize for few channels
+#
+#KFLAGS+=-DCONFIG_CALC_XLAW
+#
+# Define if you want MMX optimizations in zaptel
+#
+#KFLAGS+=-DCONFIG_ZAPTEL_MMX
+#
+# Pick your echo canceller: MARK, STEVE, or STEVE2 :)
+#
+KFLAGS+=-DECHO_CAN_STEVE
+#KFLAGS+=-DECHO_CAN_STEVE2
+#KFLAGS+=-DECHO_CAN_MARK
+#
# Uncomment -DCONFIG_ZAPATA_NET to enable SyncPPP, CiscoHDLC, and Frame Relay
# support.
#
@@ -30,7 +48,7 @@ KFLAGS+=$(shell [ -f $(KINCLUDES)/linux/modversions.h ] && echo "-DMODVERSIONS -
#
# Uncomment for Generic PPP support (i.e. ZapRAS)
#
-#KFLAGS+=-DCONFIG_ZAPATA_PPP
+KFLAGS+=-DCONFIG_ZAPATA_PPP
#
# ISA Defaults can be set here.
#
@@ -45,7 +63,7 @@ KFLAGS+=-DDEFAULT_TONE_ZONE=$(DEFAULTZONE)
KFLAGS+=-DSTANDALONE_ZAPATA
CFLAGS+=-DSTANDALONE_ZAPATA
-MODCONF=$(shell if [ -f /etc/modules.conf ]; then echo /etc/modules.conf; else echo /etc/conf.modules ; fi)
+MODCONF=$(shell if [ -d /etc/modutils ]; then echo "/etc/modutils/zaptel"; elif [ -f /etc/modules.conf ]; then echo /etc/modules.conf; else echo /etc/conf.modules ; fi)
TZOBJS=zonedata.lo tonezone.lo
LIBTONEZONE=libtonezone.so.1.0
@@ -57,7 +75,7 @@ ZTTOOL=$(shell if [ -f /usr/include/newt.h ]; then echo zttool; fi)
PRIMARY=torisa
#PRIMARY=wcfxo
-all: $(MODULES) ztcfg torisatool fxstest makefw $(ZTTOOL) sethdlc
+all: $(MODULES) ztcfg torisatool fxstest makefw ztmonitor ztspeed $(ZTTOOL)
devel: tor2ee
@@ -66,7 +84,7 @@ tests: patgen pattest
tor2.o: tor2.c tor2-hw.h tor.h tor2fw.h zaptel.h
gcc $(KFLAGS) -c tor2.c
-zaptel.o: zaptel.c zaptel.h digits.h
+zaptel.o: zaptel.c zaptel.h digits.h arith.h
gcc $(KFLAGS) -c zaptel.c
torisa.o: torisa.c zaptel.h torisa.h
@@ -120,9 +138,23 @@ zaptel.c: tones.h
zttool.o: zttool.c zaptel.h
+ztmonitor.o: ztmonitor.c zaptel.h
+
+ztspeed.o: ztspeed.c
+ $(CC) -c ztspeed.c
+
zttool: zttool.o
$(CC) -o zttool zttool.o -lnewt
+ztmonitor: ztmonitor.o
+ $(CC) -o ztmonitor ztmonitor.o
+
+ztcat: ztcat.o
+ $(CC) -o ztcat ztcat.o -ltonezone
+
+ztspeed: ztspeed.o
+ $(CC) -o ztspeed ztspeed.o
+
$(LIBTONEZONE): $(TZOBJS)
$(CC) -shared -Wl,-soname,libtonezone.so.1 -lm -o $@ $(TZOBJS)
/sbin/ldconfig -n .
@@ -150,7 +182,7 @@ devices:
install: all devices
install -m 755 ztcfg /sbin
- install -m 755 sethdlc /sbin
+ if [ -f sethdlc ]; then install -m 755 sethdlc /sbin ; fi
if [ -f zttool ]; then install -m 755 zttool /sbin; fi
mkdir -p /lib/modules/`uname -r`/misc
for x in $(MODULES); do \
@@ -193,9 +225,26 @@ install: all devices
if ! grep "post-install wct1xxp" $(MODCONF); then \
echo "post-install wct1xxp /sbin/ztcfg" >> $(MODCONF); \
fi
+ if [ -d /etc/modutils ]; then \
+ /sbin/update-modules ; \
+ fi
/sbin/depmod -a
[ -f /etc/zaptel.conf ] || install -m 644 zaptel.conf.sample /etc/zaptel.conf
+config:
+ if [ -d /etc/rc.d/init.d ]; then \
+ install -m 755 zaptel.init /etc/rc.d/init.d/zaptel; \
+ chkconfig --add zaptel; \
+ elif [ -d /etc/init.d ]; then \
+ install -m 755 zaptel.init /etc/init.d/zaptel; \
+ fi
+ if [ ! -f /etc/sysconfig/zaptel ]; then \
+ install -m 644 zaptel.sysconfig /etc/sysconfig/zaptel; \
+ fi
+ if [ -d /etc/sysconfig/network-scripts ]; then \
+ install -m 755 ifup-hdlc /etc/sysconfig/network-scripts/ifup-hdlc; \
+ fi
+
clean:
rm -f torisatool makefw tor2fw.h
rm -f zttool
diff --git a/wcfxo.c b/wcfxo.c
index b878467..1b020fd 100755
--- a/wcfxo.c
+++ b/wcfxo.c
@@ -12,15 +12,15 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
@@ -37,9 +37,10 @@
#include <linux/zaptel.h>
#endif
-/* RING detection fiddling */
-#define RING_INC 10
-#define RING_MAX 50
+/* Uncomment to enable tasklet handling in the FXO driver. Not recommended
+ in general, but may improve interactive performance */
+
+/* #define ENABLE_TASKLETS */
#define WC_MAX_IFACES 128
@@ -67,7 +68,11 @@
#define FLAG_READ 2
#define RING_DEBOUNCE 64 /* Ringer Debounce (in ms) */
-#define BATT_DEBOUNCE 8 /* Battery debounce (in ms) */
+#define BATT_DEBOUNCE 80 /* Battery debounce (in ms) */
+
+#define MINPEGTIME 10 * 8 /* 30 ms peak to peak gets us no more than 100 Hz */
+#define PEGTIME 50 * 8 /* 50ms peak to peak gets us rings of 10 Hz or more */
+#define PEGCOUNT 5 /* 5 cycles of pegging means RING */
struct reg {
int flags;
@@ -90,11 +95,13 @@ struct wcfxo {
int flags;
int freeregion;
int ring;
+ int offhook;
int battery;
int wregcount;
int readpos;
int rreadpos;
- int ringdebounce;
+ unsigned int pegtimer;
+ int pegcount;
int battdebounce;
int nobatttimer;
int allread;
@@ -105,6 +112,7 @@ struct wcfxo {
/* Up to 6 register can be written at a time */
struct reg regs[ZT_CHUNKSIZE];
struct reg oldregs[ZT_CHUNKSIZE];
+ unsigned char lasttx[ZT_CHUNKSIZE];
/* Up to 32 registers of whatever we most recently read */
unsigned char readregs[32];
unsigned long ioaddr;
@@ -112,6 +120,15 @@ struct wcfxo {
dma_addr_t writedma;
volatile int *writechunk; /* Double-word aligned write memory */
volatile int *readchunk; /* Double-word aligned read memory */
+#ifdef ENABLE_TASKLETS
+ int taskletrun;
+ int taskletsched;
+ int taskletpending;
+ int taskletexec;
+ int txerrors;
+ int ints;
+ struct tasklet_struct wcfxo_tlet;
+#endif
};
#define FLAG_INVERTSER (1 << 0)
@@ -124,8 +141,9 @@ struct wcfxo_desc {
int flags;
};
+
static struct wcfxo_desc wcfxo = { "Wildcard Prototype", 0};
-static struct wcfxo_desc wcx100p = { "Wildcard X100P",
+static struct wcfxo_desc wcx100p = { "Wildcard X100P",
FLAG_INVERTSER | FLAG_USE_XTAL | FLAG_DOUBLE_CLOCK };
static struct wcfxo *ifaces[WC_MAX_IFACES];
@@ -142,23 +160,37 @@ static inline void wcfxo_transmitprep(struct wcfxo *wc, unsigned char ints)
int x;
int written=0;
unsigned short cmd;
- if (ints & 0x01)
+
+ /* if nothing to transmit, have to do the zt_transmit() anyway */
+ if (!(ints & 3)) {
+ /* Calculate Transmission */
+ zt_transmit(&wc->span);
+ return;
+ }
+
+ /* Remember what it was we just sent */
+ memcpy(wc->lasttx, wc->chan.writechunk, ZT_CHUNKSIZE);
+
+ if (ints & 0x01) {
/* Write is at interrupt address. Start writing from normal offset */
writechunk = wc->writechunk;
- else
+ } else {
writechunk = wc->writechunk + ZT_CHUNKSIZE * 2;
- /* Calculate Transmission */
+ }
+
zt_transmit(&wc->span);
for (x=0;x<ZT_CHUNKSIZE;x++) {
/* Send a sample, as a 32-bit word, and be sure to indicate that a command follows */
- if (wc->flags & FLAG_INVERTSER)
- writechunk[x << 1] =
- ~((unsigned short)(ZT_MULAW(wc->chan.writechunk[x]))| 0x1) << 16;
+ if (wc->flags & FLAG_INVERTSER)
+ writechunk[x << 1] = cpu_to_le32(
+ ~((unsigned short)(ZT_XLAW(wc->chan.writechunk[x], (&wc->chan)))| 0x1) << 16
+ );
else
- writechunk[x << 1] =
- ((unsigned short)(ZT_MULAW(wc->chan.writechunk[x]))| 0x1) << 16;
-
+ writechunk[x << 1] = cpu_to_le32(
+ ((unsigned short)(ZT_XLAW(wc->chan.writechunk[x], (&wc->chan)))| 0x1) << 16
+ );
+
/* We always have a command to follow our signal */
if (!wc->regs[x].flags) {
/* Fill in an empty register command with a read for a potentially useful register */
@@ -172,7 +204,7 @@ static inline void wcfxo_transmitprep(struct wcfxo *wc, unsigned char ints)
}
}
- /* Prepare the command to follow it */
+ /* Prepare the command to follow it */
switch(wc->regs[x].flags) {
case FLAG_READ:
cmd = (wc->regs[x].reg | 0x20) << 8;
@@ -189,9 +221,9 @@ static inline void wcfxo_transmitprep(struct wcfxo *wc, unsigned char ints)
}
/* Setup the write chunk */
if (wc->flags & FLAG_INVERTSER)
- writechunk[(x << 1) + 1] = ~(cmd << 16);
+ writechunk[(x << 1) + 1] = cpu_to_le32(~(cmd << 16));
else
- writechunk[(x << 1) + 1] = cmd << 16;
+ writechunk[(x << 1) + 1] = cpu_to_le32(cmd << 16);
}
if (written)
wc->readpos = 0;
@@ -211,24 +243,29 @@ static inline void wcfxo_receiveprep(struct wcfxo *wc, unsigned char ints)
int x;
int realreg;
int realval;
- if (ints & 0x08)
+ int sample;
+ static int peg = 0;
+ if (ints & 0x04)
/* Read is at interrupt address. Valid data is available at normal offset */
readchunk = wc->readchunk;
else
readchunk = wc->readchunk + ZT_CHUNKSIZE * 2;
+
+ /* Keep track of how quickly our peg alternates */
+ wc->pegtimer+=ZT_CHUNKSIZE;
for (x=0;x<ZT_CHUNKSIZE;x++) {
-
+
/* We always have a command to follow our signal. */
if (wc->oldregs[x].flags == FLAG_READ && !wc->ignoreread) {
- realreg = wecareregs[(wc->regs[x].index + wc->regoffset) %
- (sizeof(wecareregs) / sizeof(wecareregs[0]))];
- realval = (readchunk[(x << 1) +wc->alt] >> 16) & 0xff;
+ realreg = wecareregs[(wc->regs[x].index + wc->regoffset) %
+ (sizeof(wecareregs) / sizeof(wecareregs[0]))];
+ realval = (le32_to_cpu(readchunk[(x << 1) +wc->alt]) >> 16) & 0xff;
if ((realval == 0x89) && (realreg != 0x9)) {
/* Some sort of slippage, correct for it */
while(realreg != 0x9) {
/* Find register 9 */
- realreg = wecareregs[(wc->regs[x].index + ++wc->regoffset) %
- (sizeof(wecareregs) / sizeof(wecareregs[0]))];
+ realreg = wecareregs[(wc->regs[x].index + ++wc->regoffset) %
+ (sizeof(wecareregs) / sizeof(wecareregs[0]))];
wc->regoffset = wc->regoffset % (sizeof(wecareregs) / sizeof(wecareregs[0]));
}
if (debug)
@@ -237,13 +274,67 @@ static inline void wcfxo_receiveprep(struct wcfxo *wc, unsigned char ints)
/* Receive into the proper register */
wc->readregs[realreg] = realval;
}
- wc->chan.readchunk[x] = ZT_LIN2MU(((short)(readchunk[(x << 1) + (1 - wc->alt)] >> 16)));
+ /* Look for pegging to indicate ringing */
+ sample = (short)(le32_to_cpu(readchunk[(x << 1) + (1 - wc->alt)]) >> 16);
+ if ((sample > 32000) && (peg != 1)) {
+ if ((wc->pegtimer < PEGTIME) && (wc->pegtimer > MINPEGTIME))
+ wc->pegcount++;
+ wc->pegtimer = 0;
+ peg = 1;
+ } else if ((sample < -32000) && (peg != -1)) {
+ if ((wc->pegtimer < PEGTIME) && (wc->pegtimer > MINPEGTIME))
+ wc->pegcount++;
+ wc->pegtimer = 0;
+ peg = -1;
+ }
+ wc->chan.readchunk[x] = ZT_LIN2X((sample), (&wc->chan));
+ }
+ if (wc->pegtimer > PEGTIME) {
+ /* Reset pegcount if our timer expires */
+ wc->pegcount = 0;
+ }
+ if (!wc->offhook) {
+ if (!wc->ring && (wc->pegcount > PEGCOUNT)) {
+ /* It's ringing */
+ if (debug)
+ printk("RING!\n");
+ zt_hooksig(&wc->chan, ZT_RXSIG_RING);
+ wc->ring = 1;
+ }
+ if (wc->ring && !wc->pegcount) {
+ /* No more ring */
+ if (debug)
+ printk("NO RING!\n");
+ zt_hooksig(&wc->chan, ZT_RXSIG_OFFHOOK);
+ wc->ring = 0;
+ }
}
if (wc->ignoreread)
wc->ignoreread--;
+
+ /* Do the echo cancellation... We are echo cancelling against
+ what we sent two chunks ago*/
+ zt_ec_chunk(&wc->chan, wc->chan.readchunk, wc->lasttx);
+
+ /* Receive the result */
zt_receive(&wc->span);
}
+#ifdef ENABLE_TASKLETS
+static void wcfxo_tasklet(unsigned long data)
+{
+ struct wcfxo *wc = (struct wcfxo *)data;
+ wc->taskletrun++;
+ /* Run tasklet */
+ if (wc->taskletpending) {
+ wc->taskletexec++;
+ wcfxo_receiveprep(wc, wc->ints);
+ wcfxo_transmitprep(wc, wc->ints);
+ }
+ wc->taskletpending = 0;
+}
+#endif
+
static void wcfxo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct wcfxo *wc = dev_id;
@@ -261,65 +352,33 @@ static void wcfxo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (!ints)
return;
- if (ints & 0x0f) {
+ if (ints & 0x0c) { /* if there is a rx interrupt pending */
+#ifdef ENABLE_TASKLETS
+ wc->ints = ints;
+ if (!wc->taskletpending) {
+ wc->taskletpending = 1;
+ wc->taskletsched++;
+ tasklet_hi_schedule(&wc->wcfxo_tlet);
+ } else
+ wc->txerrors++;
+#else
wcfxo_receiveprep(wc, ints);
+ /* transmitprep looks to see if there is anything to transmit
+ and returns by itself if there is nothing */
wcfxo_transmitprep(wc, ints);
+#endif
}
-
+
if (ints & 0x10) {
printk("PCI Master abort\n");
return;
}
-
+
if (ints & 0x20) {
printk("PCI Target abort\n");
return;
}
-
if (1 /* !(wc->report % 0xf) */) {
- /* Check RING from register and debounce. This is actually
- fairly challenging to do, because the ring behavior
- seems to differ from one system to another. */
- b = wc->readregs[0x5] & 0x60;
-#ifdef DEBUG_RING
- if (b != oldb) {
- printk("RING Change from %02x to %02x after %d (ringdebounce = %d)\n", oldb, b, oldcnt, wc->ringdebounce);
- oldb = b;
- oldcnt = 0;
- } else
- oldcnt++;
-#endif
- if (!b) {
- /* No ring -- subtract one from our counter. We need
- a whole bunch of no-rings in a row before we consider
- the real ring actually over */
- if (wc->ringdebounce > 0)
- wc->ringdebounce -= 1;
- if (wc->ring && !wc->ringdebounce) {
-#ifndef DEBUG_RING
- if (debug)
-#endif
- printk("NO RING!\n");
- zt_hooksig(&wc->chan, ZT_RXSIG_OFFHOOK);
- wc->ring = 0;
- }
- } else {
- /* Ring detected... Increment our counter by a bunch */
- wc->ringdebounce += RING_INC;
- /* Max out at RING_MAX. */
- if (wc->ringdebounce > RING_MAX)
- wc->ringdebounce = RING_MAX;
- if (!wc->ring && (wc->ringdebounce >= RING_MAX)) {
- /* Trigger the ring */
-#ifndef DEBUG_RING
- if (debug)
-#endif
- printk("RING!\n");
- zt_hooksig(&wc->chan, ZT_RXSIG_RING);
- wc->ring = 1;
- }
- }
-
/* Check for BATTERY from register and debounce for 8 ms */
b = wc->readregs[0xc] & 0xf;
if (!b) {
@@ -327,7 +386,7 @@ static void wcfxo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if 0
if (wc->battery)
printk("Battery loss: %d (%d debounce)\n", b, wc->battdebounce);
-#endif
+#endif
if (wc->battery && !wc->battdebounce) {
if (debug)
printk("NO BATTERY!\n");
@@ -359,7 +418,7 @@ static void wcfxo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* It's something else... */
wc->battdebounce = BATT_DEBOUNCE;
}
-
+
if (wc->battdebounce)
wc->battdebounce--;
}
@@ -396,7 +455,7 @@ static int wcfxo_close(struct zt_chan *chan)
wc->usecount--;
MOD_DEC_USE_COUNT;
/* If we're dead, release us now */
- if (!wc->usecount && wc->dead)
+ if (!wc->usecount && wc->dead)
wcfxo_release(wc);
return 0;
}
@@ -412,17 +471,19 @@ static int wcfxo_hooksig(struct zt_chan *chan, zt_txsig_t txsig)
be done in two steps because of a hardware bug. */
reg = wc->readregs[0x5] & ~0x08;
wcfxo_setreg(wc, 0x5, reg);
-
+
reg = reg | 0x1;
wcfxo_setreg(wc, 0x5, reg);
+ wc->offhook = 1;
break;
case ZT_TXSIG_ONHOOK:
/* Put on hook and enable on hook line monitor */
reg = wc->readregs[0x5] & 0xfe;
wcfxo_setreg(wc, 0x5, reg);
-
+
reg = reg | 0x08;
wcfxo_setreg(wc, 0x5, reg);
+ wc->offhook = 0;
break;
default:
printk("wcfxo: Can't set tx state to %d\n", txsig);
@@ -447,6 +508,9 @@ static int wcfxo_initialize(struct wcfxo *wc)
wc->span.close = wcfxo_close;
wc->span.flags = ZT_FLAG_RBS;
wc->span.deflaw = ZT_LAW_MULAW;
+#ifdef ENABLE_TASKLETS
+ tasklet_init(&wc->wcfxo_tlet, wcfxo_tasklet, (unsigned long)wc);
+#endif
init_waitqueue_head(&wc->span.maintq);
wc->span.pvt = wc;
@@ -473,13 +537,13 @@ static int wcfxo_hardware_init(struct wcfxo *wc)
}
/* Set all to outputs except AUX 4, which is an input */
outb(0xef, wc->ioaddr + WC_AUXC);
-
+
/* Back to normal, with automatic DMA wrap around */
outb(0x01, wc->ioaddr + WC_CNTL);
-
+
/* Make sure serial port and DMA are out of reset */
outb(inb(wc->ioaddr + WC_CNTL) & 0xf9, WC_CNTL);
-
+
/* Configure serial port for MSB->LSB operation */
if (wc->flags & FLAG_DOUBLE_CLOCK)
outb(0xc1, wc->ioaddr + WC_SERCTL);
@@ -549,7 +613,7 @@ static int wcfxo_init_daa(struct wcfxo *wc)
/* Let the reset go */
set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout(1 + (ZT_CHUNKSIZE * HZ) / 800);
/* We have a clock at 18.432 Mhz, so N1=1, M1=2, CGM=0 */
wcfxo_setreg(wc, 0x7, 0x0); /* This value is N1 - 1 */
@@ -559,7 +623,7 @@ static int wcfxo_init_daa(struct wcfxo *wc)
/* Wait until the PLL's are locked. Time is between 100 uSec and 1 mSec */
set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout(1 + HZ/1000 + (ZT_CHUNKSIZE * HZ) / 800);
/* No additional ration is applied to the PLL and faster lock times
* are possible */
@@ -576,10 +640,10 @@ static int wcfxo_init_daa(struct wcfxo *wc)
/* Wait a couple of jiffies for our writes to finish */
set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout(1 + (ZT_CHUNKSIZE * HZ) / 800);
/* Didn't get it right. Register 9 is still garbage */
- if (wc->readregs[0x9] != 0x89)
+ if (wc->readregs[0x9] != 0x89)
return -1;
#if 0
{ int x;
diff --git a/wcfxsusb.c b/wcfxsusb.c
index 1857f72..7b0f615 100755
--- a/wcfxsusb.c
+++ b/wcfxsusb.c
@@ -527,7 +527,7 @@ static int wcusb_async_write(struct wc_usb_pvt *p, unsigned char index, unsigned
__u16 ind = index;
memset(urb, 0, sizeof(urb_t));
-
+
p->dr.requesttype = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
p->dr.request = REQUEST_NORMAL;
p->dr.value = 0;
@@ -948,9 +948,9 @@ static void wcusb_do_io(struct wc_usb_pvt *p, struct urb *out, struct urb *in)
switch (p->sample) {
case STREAM_NORMAL:
for (x = 0; x < ZT_CHUNKSIZE; x++) {
- p->chan.readchunk[x] = ZT_LIN2MU(ichunk[x]);
+ p->chan.readchunk[x] = ZT_LIN2MU(le16_to_cpu(ichunk[x]));
}
-
+
break;
case STREAM_DTMF:
for (x = 0; x < ZT_CHUNKSIZE; x++) {
@@ -960,12 +960,14 @@ static void wcusb_do_io(struct wc_usb_pvt *p, struct urb *out, struct urb *in)
}
/* Work with Zaptel now */
+ /* XXX Might be able to optimize this some XXX */
+ zt_ec_chunk(&p->chan, p->chan.readchunk, p->chan.writechunk);
zt_receive(&p->span);
zt_transmit(&p->span);
/* Fill in transmission info */
for (x = 0; x < ZT_CHUNKSIZE; x++) {
- ochunk[x] = ZT_MULAW(p->chan.writechunk[x]);
+ ochunk[x] = ZT_MULAW(cpu_to_le16(p->chan.writechunk[x]));
}
/* Transmit the pending outgoing urb */
@@ -1147,7 +1149,7 @@ static int InitPrivate(struct wc_usb_pvt *p)
p->datawrite[x].urb.iso_frame_desc[0].offset = 0;
p->datawrite[x].urb.transfer_buffer = p->writechunk + ZT_CHUNKSIZE * x;
p->datawrite[x].urb.transfer_buffer_length = ZT_CHUNKSIZE * 2;
-
+
}