[Pkg-voip-commits] r2024 - in zaptel/trunk/debian: . patches
Tzafrir Cohen
tzafrir-guest at costa.debian.org
Sat Jul 8 01:56:15 UTC 2006
Author: tzafrir-guest
Date: 2006-07-08 01:56:10 +0000 (Sat, 08 Jul 2006)
New Revision: 2024
Modified:
zaptel/trunk/debian/changelog
zaptel/trunk/debian/patches/xpp_xorcom_debian.dpatch
Log:
* xpp revision r1588 (branches/RELEASE-1.1.0). Changes vs. 1473:
- Generate ZT_EVENT_REMOVED in the right place: hinting asterisk to
disconnect
- Add support for fxotune ioctls
- Remove old cmd2inc et al.
Modified: zaptel/trunk/debian/changelog
===================================================================
--- zaptel/trunk/debian/changelog 2006-07-07 06:24:41 UTC (rev 2023)
+++ zaptel/trunk/debian/changelog 2006-07-08 01:56:10 UTC (rev 2024)
@@ -11,12 +11,16 @@
* Removing some unneeded dirs from zaptel-source
* debian/patches/Makefile_kbuild: a small part of the original one.
Fixes building on Sarge
- * xpp revision r1473 (branches/RELEASE-1.1.0):
+ * xpp revision r1588 (branches/RELEASE-1.1.0)
- With EC
- FXS caller ID working
- Improved FXO
- Back to RBS
- genzaptelconf is now in zaptel
+ - Generate ZT_EVENT_REMOVED in the right place: hinting asterisk to
+ disconnect
+ - Add support for fxotune ioctls
+ - Remove old cmd2inc et al.
* xpp/utils/Makefile has a decent install target
* debian/rules: Use CURDIR
* debian/modulestest: Building modules for -3 kernels
Modified: zaptel/trunk/debian/patches/xpp_xorcom_debian.dpatch
===================================================================
--- zaptel/trunk/debian/patches/xpp_xorcom_debian.dpatch 2006-07-07 06:24:41 UTC (rev 2023)
+++ zaptel/trunk/debian/patches/xpp_xorcom_debian.dpatch 2006-07-08 01:56:10 UTC (rev 2024)
@@ -2,16 +2,18 @@
## xpp_xorcom_debian.dpatch by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
##
## DP: Up-to-date zaptel drivers for the Xorcom Astribank and friends.
-## DP: Revision r1473 (branches/RELEASE-1.1.0)
+## DP: Revision r1588 (branches/RELEASE-1.1.0)
## DP: This version omites the .version file and the firmware files.
+## DP: This patch has been merged into trunk and branch 1.2 and is expected
+## DP: to be included in zaptel 1.2.7
@DPATCH@
-diff -uNr -x .svn -x debian zaptel-1.2.6/.version zaptel-xpp-8WuH7d_dist/.version
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/card_fxo.c zaptel-xpp-8WuH7d_dist/xpp/card_fxo.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/.version zaptel-xpp-oaIQ8i_dist/.version
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/card_fxo.c zaptel-xpp-oaIQ8i_dist/xpp/card_fxo.c
--- zaptel-1.2.6/xpp/card_fxo.c 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/card_fxo.c 2006-06-22 11:31:28.427315000 +0300
-@@ -0,0 +1,926 @@
++++ zaptel-xpp-oaIQ8i_dist/xpp/card_fxo.c 2006-07-05 16:28:42.355959000 +0300
+@@ -0,0 +1,946 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * Copyright (C) 2004-2006, Xorcom
@@ -45,10 +47,19 @@
+#include "card_fxo.h"
+#include "zap_debug.h"
+
-+static const char rcsid[] = "$Id: card_fxo.c 1431 2006-06-22 08:31:28Z oron $";
++static const char rcsid[] = "$Id: card_fxo.c 1584 2006-07-05 13:28:42Z tzafrir $";
+
+DEF_PARM(int, print_dbg, 0, "Print DBG statements"); /* must be before zap_debug.h */
++DEF_PARM(uint, poll_battery_interval, 100, "Poll battery interval in milliseconds");
++DEF_PARM(bool, report_battery, 0, "Report battery status to zaptel");
+
++/* Signaling is opposite (fxs signalling for fxo card) */
++#if 1
++#define FXO_DEFAULT_SIGCAP (ZT_SIG_FXSKS | ZT_SIG_FXSLS)
++#else
++#define FXO_DEFAULT_SIGCAP (ZT_SIG_SF)
++#endif
++
+enum fxo_leds {
+ LED_GREEN,
+};
@@ -58,40 +69,20 @@
+
+/*---------------- FXO Protocol Commands ----------------------------------*/
+
-+/* 0x0F */ DECLARE_CMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on);
-+/* 0x0F */ DECLARE_CMD(FXO, CHAN_CID, int pos);
-+/* 0x0F */ DECLARE_CMD(FXO, RING, int pos, bool on);
-+/* 0x0F */ DECLARE_CMD(FXO, SETHOOK, int pos, bool offhook);
-+/* 0x0F */ DECLARE_CMD(FXO, RELAY_OUT, byte which, bool on);
-+/* 0x0F */ DECLARE_CMD(FXO, DAA_INIT);
-+/* 0x0F */ DECLARE_CMD(FXO, DAA_QUERY, int pos, byte reg_num);
++static /* 0x0F */ DECLARE_CMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on);
++static /* 0x0F */ DECLARE_CMD(FXO, CHAN_CID, int pos);
++static /* 0x0F */ DECLARE_CMD(FXO, RING, int pos, bool on);
++static /* 0x0F */ DECLARE_CMD(FXO, SETHOOK, int pos, bool offhook);
++static /* 0x0F */ DECLARE_CMD(FXO, RELAY_OUT, byte which, bool on);
++static /* 0x0F */ DECLARE_CMD(FXO, DAA_QUERY, int pos, byte reg_num);
+
+static bool fxo_packet_is_valid(xpacket_t *pack);
+static void fxo_packet_dump(xpacket_t *pack);
+static int proc_fxo_info_read(char *page, char **start, off_t off, int count, int *eof, void *data);
+static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data);
+static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
++static int process_slic_cmdline(xpd_t *xpd, char *cmdline);
+
-+#define S_(s,l,...) \
-+ { \
-+ .lines = s, \
-+ { \
-+ .len = l, \
-+ .data = { __VA_ARGS__ }, \
-+ } \
-+ }
-+struct slic_init_data {
-+ xpp_line_t lines;
-+ slic_data_t slic_data;
-+} slic_init_data[] = {
-+#ifdef OLD_CARD
-+#include "init_data_4_19.inc"
-+#else
-+#include "init_data_4_20.inc"
-+#endif
-+};
-+#undef S_
-+
+#define PROC_DAA_FNAME "slics"
+#define PROC_FXO_INFO_FNAME "fxo_info"
+
@@ -140,7 +131,7 @@
+ BIT_CLR(priv->ledstate[which], pos);
+ }
+ }
-+ if(!(lines & xpd->enabled_chans)) // Ignore disabled channels
++ if(!lines) // Nothing to do
+ goto out;
+ DBG("%s/%s: LED: lines=0x%04X which=%d -- %s\n", xbus->busname, xpd->xpdname, lines, which, (on) ? "on" : "off");
+ XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
@@ -165,7 +156,7 @@
+ spin_lock_irqsave(&xpd->lock, flags);
+ priv = xpd->priv;
+ timer_count = xpd->timer_count;
-+ for_each_enabled_line(xpd, i) {
++ for_each_line(xpd, i) {
+ if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i))
+ continue;
+ if(IS_BLINKING(priv,i,color)) {
@@ -186,10 +177,16 @@
+
+static void do_sethook(xpd_t *xpd, int pos, bool offhook)
+{
-+ unsigned long flags;
++ unsigned long flags;
++ struct FXO_priv_data *priv;
+
+ BUG_ON(!xpd);
+ BUG_ON(xpd->direction == TO_PHONE); // We can SETHOOK state only on PSTN
++ priv = xpd->priv;
++ BUG_ON(!priv);
++ if(!IS_SET(priv->battery, pos)) {
++ DBG("%s/%s/%d: WARNING: called while battery is off\n", xpd->xbus->busname, xpd->xpdname, pos);
++ }
+ spin_lock_irqsave(&xpd->lock, flags);
+ xpd->ringing[pos] = 0; // No more rings
+ CALL_XMETHOD(SETHOOK, xpd->xbus, xpd, pos, offhook);
@@ -242,6 +239,7 @@
+{
+ struct FXO_priv_data *priv;
+ int ret = 0;
++ int i;
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
@@ -251,41 +249,34 @@
+ if(!priv->fxo_info) {
+ ERR("Failed to create proc '%s' for %s/%s\n", PROC_FXO_INFO_FNAME, xbus->busname, xpd->xpdname);
+ ret = -ENOENT;
-+ goto out;
++ goto err;
+ }
++ priv->fxo_info->owner = THIS_MODULE;
+ DBG("Creating DAAs file for %s/%s\n", xbus->busname, xpd->xpdname);
+ priv->xpd_slic = create_proc_entry(PROC_DAA_FNAME, 0644, xpd->proc_xpd_dir);
+ if(!priv->xpd_slic) {
+ ERR("Failed to create proc file for DAAs of %s/%s\n", xbus->busname, xpd->xpdname);
-+ goto out;
++ ret = -ENOENT;
++ goto err;
+ }
++ priv->xpd_slic->owner = THIS_MODULE;
+ priv->xpd_slic->write_proc = proc_xpd_slic_write;
+ priv->xpd_slic->read_proc = proc_xpd_slic_read;
+ priv->xpd_slic->data = xpd;
+#endif
-+#ifdef HARD_CODED_INIT
-+ CALL_PROTO(FXO, DAA_INIT, xbus, xpd);
-+#else
+ ret = run_initialize_registers(xpd);
+ if(ret < 0)
-+ goto out;
-+#endif
-+ if(xpd->direction == TO_PSTN) {
-+ int i;
-+
-+ // Hanghup all lines
-+ for_each_enabled_line(xpd, i) {
-+ init_waitqueue_head(&xpd->txstateq[i]);
-+ do_sethook(xpd, i, 0);
-+ }
++ goto err;
++ // Hanghup all lines
++ for_each_line(xpd, i) {
++ init_waitqueue_head(&xpd->txstateq[i]);
++ do_sethook(xpd, i, 0);
+ }
-+out:
-+ if(ret < 0) {
-+ clean_proc(xbus, xpd);
-+ ERR("%s/%s: Failed initializing registers (%d)\n", xbus->busname, xpd->xpdname, ret);
-+ } else {
-+ DBG("done: %s/%s\n", xbus->busname, xpd->xpdname);
-+ }
++ DBG("done: %s/%s\n", xbus->busname, xpd->xpdname);
++ return 0;
++err:
++ clean_proc(xbus, xpd);
++ ERR("%s/%s: Failed initializing registers (%d)\n", xbus->busname, xpd->xpdname, ret);
+ return ret;
+}
+
@@ -300,11 +291,43 @@
+ return 0;
+}
+
-+static int FXO_card_zaptel_registration(xpd_t *xpd, bool on)
++static int FXO_card_zaptel_preregistration(xpd_t *xpd, bool on)
+{
+ xbus_t *xbus;
+ struct FXO_priv_data *priv;
++ int i;
+ unsigned long flags;
++
++ BUG_ON(!xpd);
++ xbus = xpd->xbus;
++ BUG_ON(!xbus);
++ priv = xpd->priv;
++ BUG_ON(!priv);
++ DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on);
++ snprintf(xpd->span.desc, MAX_SPANDESC, "Xorcom XPD #%d/%d: FXO", xbus->num, xpd->id);
++ for_each_line(xpd, i) {
++ struct zt_chan *cur_chan = &xpd->chans[i];
++
++ DBG("setting FXO channel %d\n", i);
++ snprintf(cur_chan->name, MAX_CHANNAME, "XPP_FXO/%d/%d/%d", xbus->num, xpd->id, i);
++ cur_chan->chanpos = i + 1;
++ cur_chan->pvt = xpd;
++ cur_chan->sigcap = FXO_DEFAULT_SIGCAP;
++ }
++ spin_lock_irqsave(&xpd->lock, flags);
++ do_led(xpd, ALL_LINES, LED_GREEN, LED_OFF);
++ spin_unlock_irqrestore(&xpd->lock, flags);
++ for_each_line(xpd, i) {
++ do_led(xpd, i, LED_GREEN, LED_ON);
++ mdelay(50);
++ }
++ return 0;
++}
++
++static int FXO_card_zaptel_postregistration(xpd_t *xpd, bool on)
++{
++ xbus_t *xbus;
++ struct FXO_priv_data *priv;
+ int i;
+
+ BUG_ON(!xpd);
@@ -313,29 +336,9 @@
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on);
-+ if(on) {
-+ for_each_line(xpd, i) {
-+ spin_lock_irqsave(&xpd->lock, flags);
-+ do_led(xpd, i, LED_GREEN, LED_ON);
-+ spin_unlock_irqrestore(&xpd->lock, flags);
-+ mdelay(50);
-+ }
-+ for_each_line(xpd, i) {
-+ spin_lock_irqsave(&xpd->lock, flags);
-+ do_led(xpd, i, LED_GREEN, LED_OFF);
-+ spin_unlock_irqrestore(&xpd->lock, flags);
-+ mdelay(50);
-+ }
-+ } else {
-+ for_each_line(xpd, i) {
-+ spin_lock_irqsave(&xpd->lock, flags);
-+ do_led(xpd, i, LED_GREEN, LED_ON);
-+ spin_unlock_irqrestore(&xpd->lock, flags);
-+ mdelay(100);
-+ spin_lock_irqsave(&xpd->lock, flags);
-+ do_led(xpd, i, LED_GREEN, LED_OFF);
-+ spin_unlock_irqrestore(&xpd->lock, flags);
-+ }
++ for_each_line(xpd, i) {
++ do_led(xpd, i, LED_GREEN, LED_OFF);
++ mdelay(50);
+ }
+ return 0;
+}
@@ -343,6 +346,10 @@
+#ifdef WITH_RBS
+int FXO_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
+{
++ struct FXO_priv_data *priv;
++
++ priv = xpd->priv;
++ BUG_ON(!priv);
+ DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, pos, txsig2str(txsig));
+ BUG_ON(xpd->direction != TO_PSTN);
+ /* XXX Enable hooksig for FXO XXX */
@@ -365,13 +372,12 @@
+#else
+int FXO_card_sethook(xbus_t *xbus, xpd_t *xpd, int pos, int hookstate)
+{
-+ int ret = 0;
++ int ret = 0;
++ struct FXO_priv_data *priv;
+
+ DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, pos, hookstate2str(hookstate));
+ switch(hookstate) {
-+ /* On-hook, off-hook: The PBX is playing a phone on an FXO line.
-+ * Can be ignored for an FXS line
-+ */
++ /* On-hook, off-hook: The PBX is playing a phone on an FXO line. */
+ case ZT_ONHOOK:
+ do_sethook(xpd, pos, 0);
+ break;
@@ -390,7 +396,7 @@
+ WARN("No code yet\n");
+ break;
+ case ZT_RING:
-+ DBG("%s/%s/%d: (ringing[%d]=%d)\n", xbus->busname, xpd->xpdname, pos, pos, xpd->ringing[pos]);
++ DBG("%s/%s/%d: ZT_RING: %d\n", xbus->busname, xpd->xpdname, pos, xpd->ringing[pos]);
+ break;
+ case ZT_RINGOFF:
+ WARN("No code yet\n");
@@ -404,7 +410,7 @@
+{
+ int i;
+
-+ for_each_enabled_line(xpd, i) {
++ for_each_line(xpd, i) {
+ CALL_PROTO(FXO, DAA_QUERY, xbus, xpd, i, DAA_VBAT_REGISTER);
+ }
+}
@@ -412,23 +418,75 @@
+
+static int FXO_card_tick(xbus_t *xbus, xpd_t *xpd)
+{
-+ static int rate_limit = 0;
++ static unsigned rate_limit = 0;
+ struct FXO_priv_data *priv;
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ rate_limit++;
-+ if((rate_limit % 100) == 0) {
++ if(poll_battery_interval != 0 && (rate_limit % poll_battery_interval) == 0) {
+ poll_battery(xbus, xpd);
+ }
+ handle_fxo_leds(xpd);
+ return 0;
+}
+
++/* FIXME: based on data from from wctdm.h */
++#include <wctdm.h>
++static const int echotune_reg[] = {30,45,46,47,58,49,50,51,52};
++union echotune {
++ /* "coeff 0" is acim */
++ unsigned char coeff[sizeof(echotune_reg)];
++ struct wctdm_echo_coefs wctdm_struct;
++};
++
++static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long arg)
++{
++ union echotune echoregs;
++ int i,ret;
++
++ BUG_ON(!xpd);
++ DBG("cmd: 0x%x, expecting: 0x%x, pos=%d.\n", cmd, WCTDM_SET_ECHOTUNE, pos);
++ switch (cmd) {
++ case WCTDM_SET_ECHOTUNE:
++ DBG("-- Setting echo registers: \n");
++ /* first off: check if this span is fxs. If not: -EINVALID */
++ if (copy_from_user(&echoregs.wctdm_struct,
++ (struct wctdm_echo_coefs*)arg, sizeof(echoregs.wctdm_struct)))
++ return -EFAULT;
++
++ /* Set the ACIM register */
++ /* quick and dirty registers writing: */
++ for (i=0; i<sizeof(echotune_reg); i++) {
++ char buf[22];
++ xpp_line_t lines = BIT(pos);
++ sprintf(buf, "%02X %02X %02X %02X WD %2X %2X",
++ (lines & 0xFF),
++ ((lines >> 8) & 0xFF),
++ ((lines >> 16) & 0xFF),
++ ((lines >> 24) & 0xFF),
++ echotune_reg[i],echoregs.coeff[i]
++ );
++ /* FIXME: code duplicated from proc_xpd_register_write */
++ ret = process_slic_cmdline(xpd, buf);
++ if(ret < 0)
++ return ret;
++ mdelay(1);
++ }
++
++ DBG("-- Set echo registers successfully\n");
++
++ break;
++ default:
++ return -ENOTTY;
++ }
++ return 0;
++}
++
+/*---------------- FXO: HOST COMMANDS -------------------------------------*/
+
-+/* 0x0F */ HOSTCMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on)
++static /* 0x0F */ HOSTCMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on)
+{
+ unsigned long flags;
+ int ret = 0;
@@ -436,19 +494,18 @@
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
-+ lines &= xpd->enabled_chans; // Ignore disabled channels
+ if(!lines) {
+ return 0;
+ }
+ DBG("Channel Activation: 0x%4X %s\n", lines, (on) ? "on" : "off");
+ if(on) {
-+ for_each_enabled_line(xpd, i) {
++ for_each_line(xpd, i) {
+ spin_lock_irqsave(&xpd->lock, flags);
+ do_led(xpd, i, LED_GREEN, LED_ON);
+ spin_unlock_irqrestore(&xpd->lock, flags);
+ mdelay(20);
+ }
-+ for_each_enabled_line(xpd, i) {
++ for_each_line(xpd, i) {
+ spin_lock_irqsave(&xpd->lock, flags);
+ do_led(xpd, i, LED_GREEN, LED_OFF);
+ spin_unlock_irqrestore(&xpd->lock, flags);
@@ -458,14 +515,13 @@
+ return ret;
+}
+
-+/* 0x0F */ HOSTCMD(FXO, CHAN_CID, int pos)
++static /* 0x0F */ HOSTCMD(FXO, CHAN_CID, int pos)
+{
+ int ret = 0;
+ xpp_line_t lines = BIT(pos);
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
-+ lines &= xpd->enabled_chans; // Ignore disabled channels
+ if(!lines) {
+ return 0;
+ }
@@ -474,17 +530,16 @@
+}
+
+
-+/* 0x0F */ HOSTCMD(FXO, RING, int pos, bool on)
++static /* 0x0F */ HOSTCMD(FXO, RING, int pos, bool on)
+{
+ int ret = 0;
+ xpacket_t *pack;
+ slic_cmd_t *sc;
-+ xpp_line_t mask = (1 << pos);
++ xpp_line_t mask = BIT(pos);
+ int len;
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
-+ mask &= xpd->enabled_chans; // Ignore disabled channels
+ if(!mask) {
+ return 0;
+ }
@@ -498,7 +553,7 @@
+ return ret;
+}
+
-+/* 0x0F */ HOSTCMD(FXO, SETHOOK, int pos, bool offhook)
++static /* 0x0F */ HOSTCMD(FXO, SETHOOK, int pos, bool offhook)
+{
+ int ret = 0;
+ xpacket_t *pack;
@@ -509,58 +564,28 @@
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
-+ value = (offhook) ? 0x01 : 0x00;
++ value = (offhook) ? 0x09 : 0x08;
+ // value |= BIT(3); /* Bit 3 is for CID */
+ DBG("%s/%s/%d: SETHOOK: value=0x%02X %s\n", xbus->busname, xpd->xpdname, pos, value, (offhook)?"OFFHOOK":"ONHOOK");
+ spin_lock_irqsave(&xpd->lock, flags);
-+ if(!IS_SET(xpd->enabled_chans, pos))
-+ goto out;
+ XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
+ sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd);
+ len = slic_cmd_direct_write(sc, BIT(pos), 0x05, value);
+ pack->datalen = len;
+ packet_send(xbus, pack);
+ do_led(xpd, pos, LED_GREEN, (offhook)?LED_ON:LED_OFF);
-+out:
+ spin_unlock_irqrestore(&xpd->lock, flags);
+ return ret;
+}
+
-+/* 0x0F */ HOSTCMD(FXO, RELAY_OUT, byte which, bool on)
++static /* 0x0F */ HOSTCMD(FXO, RELAY_OUT, byte which, bool on)
+{
+ return -ENOSYS;
+}
+
-+/* 0x0F */ HOSTCMD(FXO, DAA_INIT)
++static /* 0x0F */ HOSTCMD(FXO, DAA_QUERY, int pos, byte reg_num)
+{
+ int ret = 0;
-+ xpacket_t *pack;
-+ slic_data_t *slic;
-+ struct slic_init_data *source;
-+ int i;
-+
-+ BUG_ON(!xbus);
-+ BUG_ON(!xpd);
-+ DBG("INITIALIZING DAA\n");
-+ for(i = 0; i < ARRAY_SIZE(slic_init_data); i++) {
-+ source = &slic_init_data[i];
-+ XPACKET_NEW(pack, xbus, FXO, DAA_INIT, xpd->id);
-+ RPACKET_FIELD(pack, FXO, DAA_INIT, lines) = source->lines;
-+
-+ slic = &RPACKET_FIELD(pack, FXO, DAA_INIT, slic_data);
-+ slic->len = source->slic_data.len;
-+ memcpy(slic->data, source->slic_data.data, source->slic_data.len);
-+ pack->datalen = sizeof(xpp_line_t) + slic->len + 1;
-+// dump_packet("DAA", pack, print_dbg);
-+ packet_send(xbus, pack);
-+ mdelay(1); // FIXME: check with Dima
-+ }
-+ return ret;
-+}
-+
-+/* 0x0F */ HOSTCMD(FXO, DAA_QUERY, int pos, byte reg_num)
-+{
-+ int ret = 0;
+ xpacket_t *pack;
+ slic_cmd_t *sc;
+ int len;
@@ -627,22 +652,16 @@
+
+ if(abs(info->data_low) < BAT_THRESHOLD) {
+ priv->battery &= ~lines;
-+ // DBG("BATTERY OFF (%04X) = %d\n", lines, info->data_low);
++ // DBG("%s/%s: BATTERY OFF (%04X) = %d\n", xpd->xbus->busname, xpd->xpdname, lines, info->data_low);
+ } else {
+ priv->battery |= lines;
-+ // DBG("BATTERY ON (%04X) = %d\n", lines, info->data_low);
++ // DBG("%s/%s: BATTERY ON (%04X) = %d\n", xpd->xbus->busname, xpd->xpdname, lines, info->data_low);
+ }
+ changed_lines = last_batt_on ^ priv->battery;
+ for_each_line(xpd, i) {
-+ if(!IS_SET(changed_lines, i) || IS_SET(xpd->hookstate, i))
-+ continue;
-+#if 0
-+ /* FIXME: We don't want to affect the whole span */
-+ if(IS_SET(priv->battery, i))
-+ update_xpd_status(xpd, ZT_ALARM_NONE);
-+ else
-+ update_xpd_status(xpd, ZT_ALARM_RED);
-+#endif
++ if(IS_SET(changed_lines, i)) {
++ update_line_status(xpd, i, IS_SET(priv->battery, i));
++ }
+ }
+ }
+#if 0
@@ -674,13 +693,15 @@
+ .card_new = FXO_card_new,
+ .card_init = FXO_card_init,
+ .card_remove = FXO_card_remove,
-+ .card_zaptel_registration = FXO_card_zaptel_registration,
++ .card_zaptel_preregistration = FXO_card_zaptel_preregistration,
++ .card_zaptel_postregistration = FXO_card_zaptel_postregistration,
+#ifdef WITH_RBS
+ .card_hooksig = FXO_card_hooksig,
+#else
+ .card_sethook = FXO_card_sethook,
+#endif
+ .card_tick = FXO_card_tick,
++ .card_ioctl = FXO_card_ioctl,
+
+ .RING = XPROTO_CALLER(FXO, RING),
+ .SETHOOK = XPROTO_CALLER(FXO, SETHOOK),
@@ -719,7 +740,8 @@
+ struct FXO_priv_data *priv;
+ int i;
+
-+ BUG_ON(!xpd);
++ if(!xpd)
++ return -ENODEV;
+ spin_lock_irqsave(&xpd->lock, flags);
+ priv = xpd->priv;
+ BUG_ON(!priv);
@@ -873,9 +895,8 @@
+ len = parse_slic_cmd(p, &sc, &priv->requested_reply);
+ if(len < 0)
+ return len;
-+ sc.lines &= xpd->enabled_chans; // Ignore disabled channels
+ if(!sc.lines) {
-+ NOTICE("%s: no enabled channels are marked. Skip.\n", __FUNCTION__);
++ NOTICE("%s: no channels are marked. Skip.\n", __FUNCTION__);
+ return 0;
+ }
+ dump_slic_cmd("WRITE_DAA", &sc);
@@ -895,7 +916,8 @@
+ int i;
+ int ret;
+
-+ BUG_ON(!xpd);
++ if(!xpd)
++ return -ENODEV;
+ for(i = 0; i < count; /* noop */) {
+ for(p = buf; p < buf + LINE_LEN; p++) { /* read a line */
+ if(i >= count)
@@ -938,10 +960,10 @@
+
+module_init(card_fxo_startup);
+module_exit(card_fxo_cleanup);
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/card_fxo.h zaptel-xpp-8WuH7d_dist/xpp/card_fxo.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/card_fxo.h zaptel-xpp-oaIQ8i_dist/xpp/card_fxo.h
--- zaptel-1.2.6/xpp/card_fxo.h 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/card_fxo.h 2006-03-30 12:42:46.619481000 +0200
-@@ -0,0 +1,65 @@
++++ zaptel-xpp-oaIQ8i_dist/xpp/card_fxo.h 2006-07-02 17:17:18.812352000 +0300
+@@ -0,0 +1,61 @@
+#ifndef CARD_FXO_H
+#define CARD_FXO_H
+/*
@@ -995,10 +1017,6 @@
+ xpp_line_t lines;
+ slic_reply_t info;
+ );
-+DEF_RPACKET_DATA(FXO, DAA_INIT,
-+ xpp_line_t lines;
-+ slic_data_t slic_data;
-+ );
+DEF_RPACKET_DATA(FXO, DAA_WRITE,
+ slic_cmd_t slic_cmd;
+ );
@@ -1007,9 +1025,9 @@
+#define BAT_THRESHOLD 3
+
+#endif /* CARD_FXO_H */
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/card_fxs.c zaptel-xpp-8WuH7d_dist/xpp/card_fxs.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/card_fxs.c zaptel-xpp-oaIQ8i_dist/xpp/card_fxs.c
--- zaptel-1.2.6/xpp/card_fxs.c 2006-04-03 10:08:13.000000000 +0300
-+++ zaptel-xpp-8WuH7d_dist/xpp/card_fxs.c 2006-06-27 19:12:14.132258000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/card_fxs.c 2006-07-04 10:42:50.607003000 +0300
@@ -1,6 +1,6 @@
/*
* Written by Oron Peled <oron at actcom.co.il>
@@ -1018,7 +1036,7 @@
*
* All rights reserved.
*
-@@ -23,13 +23,15 @@
+@@ -23,65 +23,232 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
@@ -1033,20 +1051,34 @@
-static const char rcsid[] = "$Id: card_fxs.c 995 2006-04-03 07:08:13Z tzafrir $";
-static const char revision[] = "$Revision: 995 $";
-+static const char rcsid[] = "$Id: card_fxs.c 1473 2006-06-27 16:12:14Z tzafrir $";
++static const char rcsid[] = "$Id: card_fxs.c 1564 2006-07-04 07:42:50Z oron $";
DEF_PARM(int, print_dbg, 0, "Print DBG statements"); /* must be before zap_debug.h */
++DEF_PARM(bool, poll_digital_inputs, 1, "Poll Digital Inputs"); /* must be before zap_debug.h */
++
++/* Signaling is opposite (fxo signalling for fxs card) */
++#if 1
++#define FXS_DEFAULT_SIGCAP (ZT_SIG_FXOKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS)
++#else
++#define FXS_DEFAULT_SIGCAP (ZT_SIG_SF | ZT_SIG_EM)
++#endif
-@@ -42,20 +44,41 @@
- #define MASK_DIGI_OUT (MASK_BITS(LINES_DIGI_OUT) << LINES_REGULAR)
- #define MASK_DIGI_INP (MASK_BITS(LINES_DIGI_INP) << (LINES_REGULAR + LINES_DIGI_OUT))
+ #define LINES_REGULAR 8
+ #define LINES_DIGI_OUT 2
+ #define LINES_DIGI_INP 4
+-#define MASK_BITS(b) ((1U << (b)) - 1)
++#define MASK_DIGI_OUT (BITMASK(LINES_DIGI_OUT) << LINES_REGULAR)
++#define MASK_DIGI_INP (BITMASK(LINES_DIGI_INP) << (LINES_REGULAR + LINES_DIGI_OUT))
++
+enum fxs_leds {
+ LED_GREEN,
+ LED_RED,
+ OUTPUT_RELAY,
+};
-+
+
+-#define MASK_DIGI_OUT (MASK_BITS(LINES_DIGI_OUT) << LINES_REGULAR)
+-#define MASK_DIGI_INP (MASK_BITS(LINES_DIGI_INP) << (LINES_REGULAR + LINES_DIGI_OUT))
+#define NUM_LEDS 2
+
+static int SLIC_DIRECT_REQUEST(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, byte reg, byte dL)
@@ -1062,7 +1094,7 @@
+ packet_send(xbus, pack);
+ return 0;
+}
-+
+
/*---------------- FXS Protocol Commands ----------------------------------*/
-/* 0x0F */ DECLARE_CMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on);
@@ -1079,7 +1111,6 @@
+static /* 0x0F */ DECLARE_CMD(FXS, RING, int pos, bool on);
+static /* 0x0F */ DECLARE_CMD(FXS, SETHOOK, int pos, bool offhook);
+static /* 0x0F */ DECLARE_CMD(FXS, RELAY_OUT, byte which, bool on);
-+static /* 0x0F */ DECLARE_CMD(FXS, SLIC_INIT);
+static /* 0x0F */ DECLARE_CMD(FXS, SLIC_QUERY, int pos, byte reg_num);
static bool fxs_packet_is_valid(xpacket_t *pack);
@@ -1088,19 +1119,22 @@
static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data);
static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
-@@ -71,17 +94,177 @@
- xpp_line_t lines;
- slic_data_t slic_data;
- } slic_init_data[] = {
+-#define S_(s,l,...) \
+- { \
+- .lines = s, \
+- { \
+- .len = l, \
+- .data = { __VA_ARGS__ }, \
+- } \
+- }
+-struct slic_init_data {
+- xpp_line_t lines;
+- slic_data_t slic_data;
+-} slic_init_data[] = {
-#include "slic_init.inc"
-+#ifdef OLD_CARD
-+#include "init_data_3_19.inc"
-+#else
-+#include "init_data_3_20.inc"
-+#endif
- };
- #undef S_
-
+-};
+-#undef S_
+-
#define PROC_SLIC_FNAME "slics"
+#define PROC_FXS_INFO_FNAME "fxs_info"
@@ -1126,7 +1160,6 @@
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
-+ lines &= xpd->enabled_chans; // Ignore disabled channels
+ if(!lines) {
+ return 0;
+ }
@@ -1147,8 +1180,8 @@
+}
+
+#define IS_BLINKING(priv,pos,color) ((priv)->blinking[color][pos] != 0)
-+#define DO_BLINK(priv,pos,color,val) ((priv)->blinking[color][pos] = (val))
-+#define DO_LED(priv,pos,color,val) ((val)?BIT_SET((priv)->ledcontrol[color],(pos)):BIT_CLR((priv)->ledcontrol[color],(pos)))
++#define MARK_BLINK(priv,pos,color,val) ((priv)->blinking[color][pos] = (val))
++#define MARK_LED(priv,pos,color,val) ((val)?BIT_SET((priv)->ledcontrol[color],(pos)):BIT_CLR((priv)->ledcontrol[color],(pos)))
+
+/*
+ * LED and RELAY control is done via SLIC register 0x06:
@@ -1210,7 +1243,7 @@
+ BIT_CLR(priv->ledstate[which], pos);
+ }
+ }
-+ if(!(lines & xpd->enabled_chans)) // Ignore disabled channels
++ if(!lines) // Nothing to do
+ goto out;
+ DBG("%s/%s: LED: lines=0x%04X which=%d -- %s\n", xbus->busname, xpd->xpdname, lines, which, (on) ? "on" : "off");
+ value = BIT(2) | BIT(3);
@@ -1237,11 +1270,11 @@
+ struct FXS_priv_data *priv;
+
+ BUG_ON(!xpd);
++ spin_lock_irqsave(&xpd->lock, flags);
+ priv = xpd->priv;
-+ spin_lock_irqsave(&xpd->lock, flags);
+ timer_count = xpd->timer_count;
+ for(color = 0; color < ARRAY_SIZE(colors); color++) {
-+ for_each_enabled_line(xpd, i) {
++ for_each_line(xpd, i) {
+ if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i))
+ continue;
+ if(IS_BLINKING(priv, i, color)) { // Blinking
@@ -1269,7 +1302,7 @@
/*---------------- FXS: Methods -------------------------------------------*/
static xpd_t *FXS_card_new(xbus_t *xbus, int xpd_num, const xproto_table_t *proto_table, byte revision)
-@@ -100,29 +283,83 @@
+@@ -100,29 +267,82 @@
xpd->digital_inputs = MASK_DIGI_INP;
}
xpd->direction = TO_PHONE;
@@ -1286,6 +1319,7 @@
+#ifdef CONFIG_PROC_FS
+ if(priv->xpd_slic) {
+ DBG("Removing xpd SLIC file %s/%s\n", xbus->busname, xpd->xpdname);
++ priv->xpd_slic->data = NULL;
+ remove_proc_entry(PROC_SLIC_FNAME, xpd->proc_xpd_dir);
+ }
+ if(priv->fxs_info) {
@@ -1309,28 +1343,26 @@
+ if(!priv->fxs_info) {
+ ERR("Failed to create proc '%s' for %s/%s\n", PROC_FXS_INFO_FNAME, xbus->busname, xpd->xpdname);
+ ret = -ENOENT;
-+ goto out;
++ goto err;
+ }
++ priv->fxs_info->owner = THIS_MODULE;
DBG("Creating SLICs file for %s/%s\n", xbus->busname, xpd->xpdname);
priv->xpd_slic = create_proc_entry(PROC_SLIC_FNAME, 0644, xpd->proc_xpd_dir);
if(!priv->xpd_slic) {
ERR("Failed to create proc file for SLICs of %s/%s\n", xbus->busname, xpd->xpdname);
+- goto out;
+ ret = -ENOENT;
- goto out;
++ goto err;
}
++ priv->xpd_slic->owner = THIS_MODULE;
priv->xpd_slic->write_proc = proc_xpd_slic_write;
priv->xpd_slic->read_proc = proc_xpd_slic_read;
priv->xpd_slic->data = xpd;
-out:
#endif
-- return 0;
-+#ifdef HARD_CODED_INIT
-+ CALL_PROTO(FXS, SLIC_INIT, xbus, xpd);
-+#else
+ ret = run_initialize_registers(xpd);
-+#endif
+ if(ret < 0)
-+ goto out;
++ goto err;
+ /*
+ * Setup ring timers
+ */
@@ -1345,18 +1377,18 @@
+ ret += SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x33, 0x3E); /* Inactive timer high byte */
+ ret += SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x22, 0x18); /* Ringing Oscilator Control */
+#endif
-+out:
-+ if(ret < 0) {
-+ clean_proc(xbus, xpd);
-+ ERR("%s/%s: Failed initializing registers (%d)\n", xbus->busname, xpd->xpdname, ret);
-+ } else {
-+ DBG("done: %s/%s\n", xbus->busname, xpd->xpdname);
-+ }
++ if(ret < 0)
++ goto err;
++ DBG("%s/%s: done\n", xbus->busname, xpd->xpdname);
+ return 0;
++err:
++ clean_proc(xbus, xpd);
++ ERR("%s/%s: Failed initializing registers (%d)\n", xbus->busname, xpd->xpdname, ret);
+ return ret;
}
static int FXS_card_remove(xbus_t *xbus, xpd_t *xpd)
-@@ -132,15 +369,200 @@
+@@ -132,15 +352,210 @@
BUG_ON(!xpd);
priv = xpd->priv;
DBG("%s/%s\n", xbus->busname, xpd->xpdname);
@@ -1368,42 +1400,62 @@
+ return 0;
+}
+
-+static int FXS_card_zaptel_registration(xpd_t *xpd, bool on)
++static int FXS_card_zaptel_preregistration(xpd_t *xpd, bool on)
+{
+ xbus_t *xbus;
+ struct FXS_priv_data *priv;
++ int i;
+ unsigned long flags;
-+ int i;
++ const enum fxs_leds color = (on) ? LED_GREEN : LED_RED;
+
+ BUG_ON(!xpd);
+ xbus = xpd->xbus;
++ BUG_ON(!xbus);
+ priv = xpd->priv;
++ BUG_ON(!priv);
++ DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on);
++ snprintf(xpd->span.desc, MAX_SPANDESC, "Xorcom XPD #%d/%d: FXS", xbus->num, xpd->id);
++ for_each_line(xpd, i) {
++ struct zt_chan *cur_chan = &xpd->chans[i];
++
++ DBG("setting FXS channel %d\n", i);
++ if(IS_SET(xpd->digital_outputs, i)) {
++ snprintf(cur_chan->name, MAX_CHANNAME, "XPP_OUT/%d/%d/%d", xbus->num, xpd->id, i);
++ } else if(IS_SET(xpd->digital_inputs, i)) {
++ snprintf(cur_chan->name, MAX_CHANNAME, "XPP_IN/%d/%d/%d", xbus->num, xpd->id, i);
++ } else {
++ snprintf(cur_chan->name, MAX_CHANNAME, "XPP_FXS/%d/%d/%d", xbus->num, xpd->id, i);
++ }
++ cur_chan->chanpos = i + 1;
++ cur_chan->pvt = xpd;
++ cur_chan->sigcap = FXS_DEFAULT_SIGCAP;
++ }
++ spin_lock_irqsave(&xpd->lock, flags);
++ do_led(xpd, ALL_LINES, color, LED_OFF);
++ spin_unlock_irqrestore(&xpd->lock, flags);
++ for_each_line(xpd, i) {
++ MARK_LED(priv, i, color, LED_ON);
++ mdelay(50);
++ }
++ return 0;
++}
++
++static int FXS_card_zaptel_postregistration(xpd_t *xpd, bool on)
++{
++ xbus_t *xbus;
++ struct FXS_priv_data *priv;
++ int i;
++ const enum fxs_leds color = (on) ? LED_GREEN : LED_RED;
++
++ BUG_ON(!xpd);
++ xbus = xpd->xbus;
+ BUG_ON(!xbus);
-+ DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on)?"on":"off");
-+ if(on) {
-+ spin_lock_irqsave(&xpd->lock, flags);
-+ do_led(xpd, ALL_LINES, LED_GREEN, LED_OFF);
-+ spin_unlock_irqrestore(&xpd->lock, flags);
-+ for_each_enabled_line(xpd, i) {
-+ DO_LED(priv,i,LED_GREEN,LED_ON);
-+ mdelay(50);
-+ }
-+ for_each_enabled_line(xpd, i) {
-+ DO_LED(priv,i,LED_GREEN,LED_OFF);
-+ mdelay(50);
-+ }
-+ } else {
-+ spin_lock_irqsave(&xpd->lock, flags);
-+ do_led(xpd, ALL_LINES, LED_RED, LED_OFF);
-+ spin_unlock_irqrestore(&xpd->lock, flags);
-+ for_each_enabled_line(xpd, i) {
-+ DO_LED(priv,i,LED_RED,LED_ON);
-+ mdelay(50);
-+ }
-+ for_each_enabled_line(xpd, i) {
-+ DO_LED(priv,i,LED_RED,LED_OFF);
-+ mdelay(50);
-+ }
++ priv = xpd->priv;
++ BUG_ON(!priv);
++ DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on);
++ for_each_line(xpd, i) {
++ MARK_LED(priv, i, color, LED_OFF);
++ mdelay(50);
}
-#endif
return 0;
@@ -1420,26 +1472,15 @@
+ DBG("Ignoring signal sent to digital input line\n");
+ return 0;
+ }
-+ if (IS_SET(xpd->digital_outputs, pos)) {
-+ DBG("This is an output channel.");
-+ switch(txsig) {
-+ case ZT_TXSIG_ONHOOK:
-+ DBG("%s/%s/%d: digital output OFF\n", xbus->busname, xpd->xpdname, pos);
-+ ret = CALL_XMETHOD(RELAY_OUT, xpd->xbus, xpd, pos-8, 0);
-+ return ret;
-+ case ZT_TXSIG_START:
-+ DBG("%s/%s/%d: digital output ON\n", xbus->busname, xpd->xpdname, pos);
-+ ret = CALL_XMETHOD(RELAY_OUT, xpd->xbus, xpd, pos-8, 1);
-+ return ret;
-+ default:
-+ DBG("Ignoring signal %s: unhandled for output channel.\n",
-+ txsig2str(txsig));
-+ }
-+ }
+ switch(txsig) {
+ case ZT_TXSIG_ONHOOK:
+ xpd->ringing[pos] = 0;
+ BIT_CLR(xpd->cid_on, pos);
++ if(IS_SET(xpd->digital_outputs, pos)) {
++ DBG("%s/%s/%d: digital output OFF\n", xbus->busname, xpd->xpdname, pos);
++ ret = CALL_XMETHOD(RELAY_OUT, xpd->xbus, xpd, pos-8, 0);
++ return ret;
++ }
+ ret = CALL_XMETHOD(RING, xbus, xpd, pos, 0); // RING off
+#if 0
+ switch(chan->sig) {
@@ -1475,9 +1516,10 @@
+ xpd->lasttxhook[pos] = FXS_LINE_RING;
+ xpd->ringing[pos] = 1;
+ BIT_CLR(xpd->cid_on, pos);
-+ if(IS_SET(xpd->digital_inputs, pos)) {
-+ NOTICE("%s: Trying to RING a digital input channel %d. Ignoring\n", __FUNCTION__, pos);
-+ return -EINVAL;
++ if(IS_SET(xpd->digital_outputs, pos)) {
++ DBG("%s/%s/%d: %s digital output ON\n", xbus->busname, xpd->xpdname, pos, txsig2str(txsig));
++ ret = CALL_XMETHOD(RELAY_OUT, xpd->xbus, xpd, pos-8, 1);
++ return ret;
+ }
+ ret = CALL_XMETHOD(RING, xbus, xpd, pos, 1); // RING on
+ break;
@@ -1562,20 +1604,34 @@
/*
* INPUT polling is done via SLIC register 0x06 (same as LEDS):
* 7 6 5 4 3 2 1 0
-@@ -164,22 +586,30 @@
+@@ -155,6 +570,7 @@
+ {
+ int i;
++ BUG_ON(xpd->id != 0); // Only unit #0 has digital inputs
+ for(i = 0; i < ARRAY_SIZE(input_channels); i++) {
+ int pos = input_channels[i];
+
+@@ -164,177 +580,129 @@
+
static int FXS_card_tick(xbus_t *xbus, xpd_t *xpd)
{
- static int rate_limit = 0;
+ static int rate_limit = 0;
+ struct FXS_priv_data *priv;
+- if((rate_limit++ % 1000) == 0) {
+- poll_inputs(xbus, xpd);
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ BUG_ON(!priv);
- if((rate_limit++ % 1000) == 0) {
- poll_inputs(xbus, xpd);
++#if POLL_DIGITAL_INPUTS
++ if(poll_digital_inputs && xpd->id == 0) {
++ if((rate_limit++ % 1000) == 0) {
++ poll_inputs(xbus, xpd);
++ }
}
++#endif
+ handle_fxs_leds(xpd);
return 0;
}
@@ -1595,7 +1651,8 @@
BUG_ON(!xbus);
BUG_ON(!xpd);
-@@ -188,49 +618,35 @@
+- lines &= xpd->enabled_chans; // Ignore disabled channels
+ if(!lines) {
return 0;
}
DBG("Channel Activation: 0x%4X %s\n", lines, (on) ? "on" : "off");
@@ -1659,7 +1716,7 @@
BUG_ON(!xbus);
BUG_ON(!xpd);
-@@ -238,103 +654,60 @@
+- lines &= xpd->enabled_chans; // Ignore disabled channels
if(!lines) {
return 0;
}
@@ -1684,14 +1741,15 @@
+ struct FXS_priv_data *priv;
xpacket_t *pack;
slic_cmd_t *sc;
- xpp_line_t mask = (1 << pos);
+- xpp_line_t mask = (1 << pos);
++ xpp_line_t mask = BIT(pos);
int len;
+ enum fxs_state value = (on) ? 0x04 : 0x01;
BUG_ON(!xbus);
BUG_ON(!xpd);
+- mask &= xpd->enabled_chans; // Ignore disabled channels
+ priv = xpd->priv;
- mask &= xpd->enabled_chans; // Ignore disabled channels
if(!mask) {
return 0;
}
@@ -1707,10 +1765,10 @@
packet_send(xbus, pack);
+ if(on) {
-+ DO_BLINK(priv,pos,LED_GREEN,LED_BLINK);
++ MARK_BLINK(priv,pos,LED_GREEN,LED_BLINK);
+ } else {
+ if(IS_BLINKING(priv, pos, LED_GREEN))
-+ DO_BLINK(priv,pos,LED_GREEN,0);
++ MARK_BLINK(priv,pos,LED_GREEN,0);
+ }
return ret;
}
@@ -1785,7 +1843,7 @@
{
int ret = 0;
xpacket_t *pack;
-@@ -351,9 +724,9 @@
+@@ -351,9 +719,9 @@
which = which % ARRAY_SIZE(relay_channels);
lines = BIT(relay_channels[which]);
value = BIT(2) | BIT(3);
@@ -1797,31 +1855,43 @@
XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
len = slic_cmd_direct_write(sc, lines, 0x06, value);
-@@ -364,7 +737,7 @@
+@@ -364,34 +732,7 @@
return ret;
}
-/* 0x0F */ HOSTCMD(FXS, SLIC_INIT)
-+static /* 0x0F */ HOSTCMD(FXS, SLIC_INIT)
- {
- int ret = 0;
- xpacket_t *pack;
-@@ -386,12 +759,12 @@
- pack->datalen = sizeof(xpp_line_t) + slic->len + 1;
- // dump_packet("SLIC", pack, print_dbg);
- packet_send(xbus, pack);
+-{
+- int ret = 0;
+- xpacket_t *pack;
+- slic_data_t *slic;
+- struct slic_init_data *source;
+- int i;
+-
+- BUG_ON(!xbus);
+- BUG_ON(!xpd);
+- DBG("INITIALIZING SLIC\n");
+- for(i = 0; i < ARRAY_SIZE(slic_init_data); i++) {
+- source = &slic_init_data[i];
+- XPACKET_NEW(pack, xbus, FXS, SLIC_INIT, xpd->id);
+- RPACKET_FIELD(pack, FXS, SLIC_INIT, lines) = source->lines;
+-
+- slic = &RPACKET_FIELD(pack, FXS, SLIC_INIT, slic_data);
+- slic->len = source->slic_data.len;
+- memcpy(slic->data, source->slic_data.data, source->slic_data.len);
+- pack->datalen = sizeof(xpp_line_t) + slic->len + 1;
+-// dump_packet("SLIC", pack, print_dbg);
+- packet_send(xbus, pack);
- mdelay(10); // FIXME: check with Dima
-+ mdelay(1); // FIXME: check with Dima
- }
- return ret;
- }
-
+- }
+- return ret;
+-}
+-
-/* 0x0F */ HOSTCMD(FXS, SLIC_QUERY, int pos, byte reg_num)
+static /* 0x0F */ HOSTCMD(FXS, SLIC_QUERY, int pos, byte reg_num)
{
int ret = 0;
xpacket_t *pack;
-@@ -400,7 +773,7 @@
+@@ -400,7 +741,7 @@
BUG_ON(!xbus);
BUG_ON(!xpd);
@@ -1830,7 +1900,7 @@
XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
len = slic_cmd_direct_read(sc, BIT(pos), reg_num);
-@@ -416,31 +789,45 @@
+@@ -416,31 +757,45 @@
HANDLER_DEF(FXS, SIG_CHANGED)
{
xpp_line_t sig_status = RPACKET_FIELD(pack, FXS, SIG_CHANGED, sig_status);
@@ -1852,7 +1922,7 @@
+ }
+#if 0
+ Is this needed?
-+ for_each_enabled_line(xpd, i) {
++ for_each_line(xpd, i) {
+ if(IS_SET(sig_toggles, i))
+ do_chan_power(xpd->xbus, xpd, BIT(i), 0); // Power down (prevent overheating!!!)
}
@@ -1862,30 +1932,31 @@
- } else { /* TO_PSTN - line ring changes */
- unsigned long flags;
- int i;
+-
+- DBG("%s (PSTN) sig_status=0x%04X\n", xpd->xpdname, sig_status);
+- spin_lock_irqsave(&xpd->lock, flags);
+- for(i = 0; i < xpd->channels; i++) {
+#endif
+ for_each_line(xpd, i) {
+ if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i))
+ continue;
+ if(IS_SET(sig_toggles, i)) {
+ struct zt_chan *chan = &xpd->span.chans[i];
-
-- DBG("%s (PSTN) sig_status=0x%04X\n", xpd->xpdname, sig_status);
-- spin_lock_irqsave(&xpd->lock, flags);
-- for(i = 0; i < xpd->channels; i++) {
++
+ xpd->ringing[i] = 0; // No more ringing...
-+ DO_BLINK(priv,i,LED_GREEN,0);
++ MARK_BLINK(priv,i,LED_GREEN,0);
if(IS_SET(sig_status, i)) {
- xpd->ringing[i] = RINGS_NUM*2;
- zt_hooksig(&xpd->chans[i], ZT_RXSIG_OFFHOOK);
+ DBG("OFFHOOK: channo=%d\n", chan->channo);
-+ DO_LED(priv,i,LED_GREEN,LED_ON);
++ MARK_LED(priv,i,LED_GREEN,LED_ON);
+ BIT_SET(xpd->hookstate, i);
+ zt_hooksig(chan, ZT_RXSIG_OFFHOOK);
} else {
- zt_hooksig(&xpd->chans[i], ZT_RXSIG_ONHOOK);
- xpd->ringing[i] = 0;
+ DBG("ONHOOK channo=%d\n", chan->channo);
-+ DO_LED(priv,i,LED_GREEN,LED_OFF);
++ MARK_LED(priv,i,LED_GREEN,LED_OFF);
+ BIT_CLR(xpd->hookstate, i);
+ zt_hooksig(chan, ZT_RXSIG_ONHOOK);
}
@@ -1894,7 +1965,7 @@
}
return 0;
}
-@@ -460,52 +847,75 @@
+@@ -460,52 +815,75 @@
spin_lock_irqsave(&xpd->lock, flags);
priv = xpd->priv;
BUG_ON(!priv);
@@ -1945,7 +2016,7 @@
return 0;
}
-
+-
xproto_table_t PROTO_TABLE(FXS) = {
+ .owner = THIS_MODULE,
.entries = {
@@ -1960,7 +2031,8 @@
.card_new = FXS_card_new,
.card_init = FXS_card_init,
.card_remove = FXS_card_remove,
-+ .card_zaptel_registration = FXS_card_zaptel_registration,
++ .card_zaptel_preregistration = FXS_card_zaptel_preregistration,
++ .card_zaptel_postregistration = FXS_card_zaptel_postregistration,
+#ifdef WITH_RBS
+ .card_hooksig = FXS_card_hooksig,
+#else
@@ -1977,7 +2049,7 @@
.CHAN_CID = XPROTO_CALLER(FXS, CHAN_CID),
.SYNC_SOURCE = XPROTO_CALLER(GLOBAL, SYNC_SOURCE),
-@@ -519,7 +929,7 @@
+@@ -519,7 +897,7 @@
{
const xproto_entry_t *xe;
@@ -1986,7 +2058,7 @@
xe = xproto_card_entry(&PROTO_TABLE(FXS), pack->content.opcode);
return xe != NULL;
}
-@@ -531,6 +941,56 @@
+@@ -531,6 +909,57 @@
/*------------------------- SLIC Handling --------------------------*/
@@ -1999,7 +2071,8 @@
+ int i;
+ int led;
+
-+ BUG_ON(!xpd);
++ if(!xpd)
++ return -ENODEV;
+ spin_lock_irqsave(&xpd->lock, flags);
+ priv = xpd->priv;
+ BUG_ON(!priv);
@@ -2043,7 +2116,7 @@
static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
int len = 0;
-@@ -570,7 +1030,7 @@
+@@ -570,7 +999,7 @@
* |
* SLIC #
*/
@@ -2052,7 +2125,7 @@
{
char op; /* [W]rite, [R]ead */
char reg_type; /* [D]irect, [I]ndirect */
-@@ -588,9 +1048,17 @@
+@@ -588,9 +1017,17 @@
if(reg_type == 'D' && ret == 7) {
// DBG("0x%X 0x%X 0x%X 0x%X %c %x\n", s1, s2, s3, s4, reg_type, reg_num);
ret = slic_cmd_direct_read(sc, lines, reg_num);
@@ -2070,7 +2143,7 @@
} else {
NOTICE("%s: Bad read input: ret=%d buf='%s' reg_type=%c\n", __FUNCTION__, ret, buf, reg_type);
goto err;
-@@ -619,14 +1087,16 @@
+@@ -619,14 +1056,16 @@
static int process_slic_cmdline(xpd_t *xpd, char *cmdline)
{
@@ -2092,7 +2165,7 @@
if((p = strchr(cmdline, '#')) != NULL) /* Truncate comments */
*p = '\0';
if((p = strchr(cmdline, ';')) != NULL) /* Truncate comments */
-@@ -635,7 +1105,7 @@
+@@ -635,12 +1074,11 @@
;
if(*p == '\0')
return 0;
@@ -2100,8 +2173,24 @@
+ len = parse_slic_cmd(p, &sc, &priv->requested_reply);
if(len < 0)
return len;
- sc.lines &= xpd->enabled_chans; // Ignore disabled channels
-@@ -677,6 +1147,7 @@
+- sc.lines &= xpd->enabled_chans; // Ignore disabled channels
+ if(!sc.lines) {
+- NOTICE("%s: no enabled channels are marked. Skip.\n", __FUNCTION__);
++ NOTICE("%s: no channels are marked. Skip.\n", __FUNCTION__);
+ return 0;
+ }
+ dump_slic_cmd("WRITE_SLIC", &sc);
+@@ -660,7 +1098,8 @@
+ int i;
+ int ret;
+
+- BUG_ON(!xpd);
++ if(!xpd)
++ return -ENODEV;
+ for(i = 0; i < count; /* noop */) {
+ for(p = buf; p < buf + LINE_LEN; p++) { /* read a line */
+ if(i >= count)
+@@ -677,6 +1116,7 @@
ret = process_slic_cmdline(xpd, buf);
if(ret < 0)
return ret;
@@ -2109,16 +2198,22 @@
}
return count;
}
-@@ -684,7 +1155,7 @@
+@@ -684,7 +1124,13 @@
int __init card_fxs_startup(void)
{
- INFO("%s revision %s\n", THIS_MODULE->name, revision);
+ INFO("%s revision %s\n", THIS_MODULE->name, ZAPTEL_VERSION);
++#ifdef POLL_DIGITAL_INPUTS
++ INFO("FEATURE: %s with DIGITAL INPUTS support (%s activated)\n",
++ THIS_MODULE->name, (poll_digital_inputs) ? "is" : "is not");
++#else
++ INFO("FEATURE: %s without DIGITAL INPUTS support\n", THIS_MODULE->name);
++#endif
xproto_register(&PROTO_TABLE(FXS));
return 0;
}
-@@ -697,7 +1168,8 @@
+@@ -697,7 +1143,8 @@
MODULE_DESCRIPTION("XPP FXS Card Driver");
MODULE_AUTHOR("Oron Peled <oron at actcom.co.il>");
MODULE_LICENSE("GPL");
@@ -2128,9 +2223,9 @@
module_init(card_fxs_startup);
module_exit(card_fxs_cleanup);
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/card_fxs.h zaptel-xpp-8WuH7d_dist/xpp/card_fxs.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/card_fxs.h zaptel-xpp-oaIQ8i_dist/xpp/card_fxs.h
--- zaptel-1.2.6/xpp/card_fxs.h 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/card_fxs.h 2006-03-30 12:42:46.619481000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/card_fxs.h 2006-07-02 17:17:18.812352000 +0300
@@ -2,7 +2,7 @@
#define CARD_FXS_H
/*
@@ -2165,9 +2260,20 @@
DEF_RPACKET_DATA(FXS, SIG_CHANGED,
byte type; /* unused -- we have it from DEV_DESC */
xpp_line_t sig_status; /* channels: lsb=1, msb=8 */
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/card_global.c zaptel-xpp-8WuH7d_dist/xpp/card_global.c
+@@ -34,10 +52,6 @@
+ xpp_line_t lines;
+ slic_reply_t info;
+ );
+-DEF_RPACKET_DATA(FXS, SLIC_INIT,
+- xpp_line_t lines;
+- slic_data_t slic_data;
+- );
+ DEF_RPACKET_DATA(FXS, SLIC_WRITE,
+ slic_cmd_t slic_cmd;
+ );
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/card_global.c zaptel-xpp-oaIQ8i_dist/xpp/card_global.c
--- zaptel-1.2.6/xpp/card_global.c 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/card_global.c 2006-03-30 12:42:46.619481000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/card_global.c 2006-07-03 14:04:21.414889000 +0300
@@ -1,6 +1,6 @@
/*
* Written by Oron Peled <oron at actcom.co.il>
@@ -2184,20 +2290,26 @@
#include <linux/module.h>
-static const char rcsid[] = "$Id: card_global.c 949 2006-02-15 02:24:18Z kpfleming $";
-+static const char rcsid[] = "$Id: card_global.c 733 2006-03-30 10:42:46Z oron $";
++static const char rcsid[] = "$Id: card_global.c 1549 2006-07-03 11:04:21Z oron $";
extern int print_dbg;
static bool pcm_valid(xpd_t *xpd, xpacket_t *pack);
-@@ -65,7 +66,7 @@
+@@ -61,13 +62,10 @@
+ byte *pcm;
+ byte *start_pcm;
+ int i;
+- extern ulong pcm_gen;
BUG_ON(!xbus);
BUG_ON(!xpd);
- lines &= xpd->enabled_chans;
-+ lines &= (xpd->enabled_chans | ~xpd->no_pcm);
- if(pcm_gen != 0)
- return 0;
+- if(pcm_gen != 0)
+- return 0;
++ lines &= ~xpd->no_pcm;
// if(lines == 0)
-@@ -81,7 +82,7 @@
+ // return 0;
+
+@@ -81,7 +79,7 @@
XPACKET_NEW(pack, xbus, GLOBAL, PCM_WRITE, xpd->id);
RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = lines;
start_pcm = pcm = RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, pcm);
@@ -2206,22 +2318,86 @@
if(IS_SET(lines, i)) {
memcpy(pcm, (byte *)buf, ZT_CHUNKSIZE);
pcm += ZT_CHUNKSIZE;
-@@ -177,7 +178,7 @@
+@@ -116,32 +114,44 @@
+
+ /*---------------- GLOBAL: Astribank Reply Handlers -----------------------*/
+
++HANDLER_DEF(GLOBAL, NULL_REPLY)
++{
++ DBG("got len=%d\n", pack->datalen);
++ return 0;
++}
++
+ HANDLER_DEF(GLOBAL, DEV_DESC)
+ {
+ byte rev = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, rev);
+ byte type = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, type);
+ xpp_line_t line_status = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, line_status);
+- int xpd_num = XPD_NUM(pack->content.addr);
++ xpd_addr_t xpd_addr = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, addr);
+ struct card_desc_struct *card_desc;
++ unsigned long flags;
+
+- DBG("xpd=%d type=%d rev=%d line_status=0x%04X\n",
+- xpd_num, type, rev, line_status);
++ BUG_ON(!xbus);
+ if((card_desc = kmalloc(sizeof(struct card_desc_struct), GFP_ATOMIC)) == NULL) {
+ ERR("%s: Card description allocation failed.\n", __FUNCTION__);
+ return -ENOMEM;
}
+ memset(card_desc, 0, sizeof(struct card_desc_struct));
+ card_desc->magic = CARD_DESC_MAGIC;
++ INIT_LIST_HEAD(&card_desc->card_list);
+ card_desc->xbus = xbus;
+ card_desc->type = type;
+ card_desc->rev = rev;
+- card_desc->xpd_num = xpd_num;
+- INIT_WORK(&card_desc->work, card_detected, card_desc);
+- DBG("Queueing xpp_worker for xpd %d\n", xpd_num);
+- if(!queue_work(xpp_worker, &card_desc->work)) {
+- ERR("Failed to queue card description work\n");
+- return -EINVAL;
+- }
++ card_desc->xpd_addr = xpd_addr;
++ spin_lock_irqsave(&xbus->lock, flags);
++ DBG("xpd=%d-%d type=%d rev=%d line_status=0x%04X\n",
++ xpd_addr.unit, xpd_addr.subunit, type, rev, line_status);
++ if(type == XPD_TYPE_NOMODULE)
++ XBUS_COUNTER(xbus, DEV_DESC_EMPTY)++;
++ else
++ XBUS_COUNTER(xbus, DEV_DESC_FULL)++;
++ atomic_inc(&xbus->count_poll_answers);
++ wake_up(&xbus->wait_for_polls);
++ list_add_tail(&card_desc->card_list, &xbus->poll_results);
++ spin_unlock_irqrestore(&xbus->lock, flags);
+ return 0;
+ }
+@@ -155,6 +165,7 @@
+ unsigned long flags;
+ int i;
+
++ BUG_ON(!xbus);
+ if(!xpd) {
+ #if 0
+ int xpd_num = XPD_NUM(pack->content.addr);
+@@ -177,7 +188,7 @@
+ }
+
/* Copy PCM and put each channel in its index */
- for (i = 0; i < CHANNELS_PERXPD; i++) {
+ for_each_line(xpd, i) {
if(IS_SET(lines, i)) {
memcpy((u_char *)r, pcm, ZT_CHUNKSIZE);
//memset((u_char *)r, 0x5A, ZT_CHUNKSIZE); // DEBUG
-@@ -195,12 +196,18 @@
+@@ -195,12 +206,19 @@
HANDLER_DEF(GLOBAL, SYNC_REPLY)
{
+ byte mask = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, mask);
+ bool setit = mask & 0x01;
+
++ BUG_ON(!xbus);
if(!xpd) {
int xpd_num = XPD_NUM(pack->content.addr);
NOTICE("%s: received %s for non-existing xpd: %d\n", __FUNCTION__, cmd->name, xpd_num);
@@ -2235,7 +2411,15 @@
return 0;
}
-@@ -239,7 +246,7 @@
+@@ -208,6 +226,7 @@
+ xproto_table_t PROTO_TABLE(GLOBAL) = {
+ .entries = {
+ /* Card Opcode */
++ XENTRY( GLOBAL, NULL_REPLY ),
+ XENTRY( GLOBAL, DEV_DESC ),
+ XENTRY( GLOBAL, PCM_READ ),
+ XENTRY( GLOBAL, SYNC_REPLY ),
+@@ -239,7 +258,7 @@
BUG_ON(!pack);
BUG_ON(pack->content.opcode != XPROTO_NAME(GLOBAL, PCM_READ));
@@ -2244,9 +2428,9 @@
if(IS_SET(lines, i))
count++;
if(pack->datalen != (sizeof(xpp_line_t) + count * 8)) {
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/card_global.h zaptel-xpp-8WuH7d_dist/xpp/card_global.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/card_global.h zaptel-xpp-oaIQ8i_dist/xpp/card_global.h
--- zaptel-1.2.6/xpp/card_global.h 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/card_global.h 2006-03-30 12:42:46.619481000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/card_global.h 2006-07-03 13:44:48.152691000 +0300
@@ -2,7 +2,7 @@
#define CARD_GLOBAL_H
/*
@@ -2256,7 +2440,15 @@
*
* All rights reserved.
*
-@@ -31,11 +31,11 @@
+@@ -24,6 +24,7 @@
+
+ #include "xdefs.h"
+
++DEF_RPACKET_DATA(GLOBAL, NULL_REPLY);
+ DEF_RPACKET_DATA(GLOBAL, DESC_REQ);
+ DEF_RPACKET_DATA(GLOBAL, DEV_DESC,
+ byte rev; /* Revision number */
+@@ -31,11 +32,11 @@
xpp_line_t line_status; /* hook/ring status, depending on unit */
);
DEF_RPACKET_DATA(GLOBAL, PCM_WRITE,
@@ -2270,9 +2462,9 @@
byte pcm[PCM_CHUNKSIZE];
);
DEF_RPACKET_DATA(GLOBAL, SYNC_SOURCE,
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/cards.c zaptel-xpp-8WuH7d_dist/xpp/cards.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/cards.c zaptel-xpp-oaIQ8i_dist/xpp/cards.c
--- zaptel-1.2.6/xpp/cards.c 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/cards.c 1970-01-01 02:00:00.000000000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/cards.c 1970-01-01 02:00:00.000000000 +0200
@@ -1,394 +0,0 @@
-#include <linux/module.h>
-#include "xpd.h"
@@ -2668,9 +2860,9 @@
- return NULL;
- return &xpd_card_ops[xpd_type];
-}
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/cards.h zaptel-xpp-8WuH7d_dist/xpp/cards.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/cards.h zaptel-xpp-oaIQ8i_dist/xpp/cards.h
--- zaptel-1.2.6/xpp/cards.h 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/cards.h 1970-01-01 02:00:00.000000000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/cards.h 1970-01-01 02:00:00.000000000 +0200
@@ -1,23 +0,0 @@
-#ifndef CARDS_H
-#define CARDS_H
@@ -2695,62 +2887,10 @@
-xops_t *get_xops(xpd_type_t xpd_type);
-
-#endif /* CARDS_H */
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/cmd2inc zaptel-xpp-8WuH7d_dist/xpp/cmd2inc
---- zaptel-1.2.6/xpp/cmd2inc 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/cmd2inc 2006-03-01 14:30:36.514598000 +0200
-@@ -0,0 +1,48 @@
-+#! /usr/bin/perl -w
-+
-+use strict;
-+
-+my $input;
-+my $header;
-+my $comment;
-+my $len;
-+
-+ at ARGV == 1 or @ARGV == 2 or die "Usage: $0 <infile> <outfile>\n";
-+$input = $ARGV[0];
-+$header = $ARGV[1];
-+open(IF, "$input") or die "Failed to open '$input': $!\n";
-+
-+if($header) {
-+ open(HF, ">$header") or die "Failed to write '$header': $!\n";
-+ select HF;
-+}
-+
-+while(<IF>) {
-+ chomp;
-+ undef $comment;
-+ s/\r//; # CRLF -> LF
-+ if(s/\s*[;#]\s*(.*?)$//) { # Comments
-+ $comment = $1;
-+ }
-+ if(/^\s*$/) { # Empty lines
-+ next;
-+ }
-+ my ($slic0, $slic1, $slic2, $slic3, $op, @data) = split;
-+ my $slic = "$slic3$slic2$slic1$slic0";
-+ die "Bad slic address '$slic'" if length($slic) != 8;
-+ die "Bad op (op=%op)\n" if $op !~ /^[WR][DI]$/;
-+ if($op =~ /D$/) { # Direct
-+ die "Bad input at line $.: @data=(@data)\n" if @data != 2;
-+ # len reg data
-+ printf "S_(0x$slic,\t0x02,\t0x%02s, 0x%02s),\t", $data[0], $data[1];
-+ } else { # Indirect
-+ die "Bad input at line $.: @data=(@data)\n" if @data != 3;
-+ # len data1 data2 reg
-+ printf "S_(0x$slic,\t0x06,\t0x1C, 0x%02s, 0x1D, 0x%02s, 0x1E, 0x%2s),\t", $data[2], $data[1], $data[0];
-+ }
-+} continue {
-+ if(defined($comment)) {
-+ print "// $comment";
-+ }
-+ print "\n";
-+}
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/FPGA_XPD.hex zaptel-xpp-8WuH7d_dist/xpp/FPGA_XPD.hex
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/gen_slic_init zaptel-xpp-8WuH7d_dist/xpp/gen_slic_init
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/FPGA_XPD.hex zaptel-xpp-oaIQ8i_dist/xpp/FPGA_XPD.hex
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/gen_slic_init zaptel-xpp-oaIQ8i_dist/xpp/gen_slic_init
--- zaptel-1.2.6/xpp/gen_slic_init 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/gen_slic_init 1970-01-01 02:00:00.000000000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/gen_slic_init 1970-01-01 02:00:00.000000000 +0200
@@ -1,37 +0,0 @@
-#! /usr/bin/perl -w
-
@@ -2789,9 +2929,9 @@
- }
- print HF "\n";
-}
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/init_data_3_19.cmd zaptel-xpp-8WuH7d_dist/xpp/init_data_3_19.cmd
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/init_data_3_19.cmd zaptel-xpp-oaIQ8i_dist/xpp/init_data_3_19.cmd
--- zaptel-1.2.6/xpp/init_data_3_19.cmd 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/init_data_3_19.cmd 2006-06-26 11:48:58.007317000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/init_data_3_19.cmd 2006-06-26 11:48:58.007317000 +0300
@@ -0,0 +1,169 @@
+#
+# Written by Oron Peled <oron at actcom.co.il>
@@ -2962,9 +3102,9 @@
+80 00 00 00 WD 03 00
+80 00 00 00 WD 04 39
+80 00 00 00 WD 05 00
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/init_data_3_20.cmd zaptel-xpp-8WuH7d_dist/xpp/init_data_3_20.cmd
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/init_data_3_20.cmd zaptel-xpp-oaIQ8i_dist/xpp/init_data_3_20.cmd
--- zaptel-1.2.6/xpp/init_data_3_20.cmd 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/init_data_3_20.cmd 2006-06-26 11:48:58.007317000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/init_data_3_20.cmd 2006-06-26 11:48:58.007317000 +0300
@@ -0,0 +1,170 @@
+#
+# Written by Oron Peled <oron at actcom.co.il>
@@ -3136,9 +3276,9 @@
+80 00 00 00 WD 03 00
+80 00 00 00 WD 04 38
+80 00 00 00 WD 05 00
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/init_data_4_19.cmd zaptel-xpp-8WuH7d_dist/xpp/init_data_4_19.cmd
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/init_data_4_19.cmd zaptel-xpp-oaIQ8i_dist/xpp/init_data_4_19.cmd
--- zaptel-1.2.6/xpp/init_data_4_19.cmd 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/init_data_4_19.cmd 2006-04-27 16:03:25.463235000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/init_data_4_19.cmd 2006-04-27 16:03:25.463235000 +0300
@@ -0,0 +1,69 @@
+#
+# Written by Oron Peled <oron at actcom.co.il>
@@ -3209,10 +3349,10 @@
+
+; ----------- DAA ONHOOK --------------------
+FF FF 00 00 WD 05 00
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/init_data_4_20.cmd zaptel-xpp-8WuH7d_dist/xpp/init_data_4_20.cmd
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/init_data_4_20.cmd zaptel-xpp-oaIQ8i_dist/xpp/init_data_4_20.cmd
--- zaptel-1.2.6/xpp/init_data_4_20.cmd 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/init_data_4_20.cmd 2006-04-27 16:03:25.463235000 +0300
-@@ -0,0 +1,69 @@
++++ zaptel-xpp-oaIQ8i_dist/xpp/init_data_4_20.cmd 2006-07-05 16:28:42.355959000 +0300
+@@ -0,0 +1,60 @@
+#
+# Written by Oron Peled <oron at actcom.co.il>
+# Copyright (C) 2006, Xorcom
@@ -3232,59 +3372,50 @@
+;
+; DAA's CMD Reg High Low
+
++; Start with a software reset:
++FF FF 00 00 WD 01 80
++
+; ----------------------------------==== 8-channel FXO unit initialization ===-----------------------------------------
+
+FF FF 00 00 WD 21 28
-+FF FF 00 00 WD 18 99
++; 99 also sets ring validation
++;FF FF 00 00 WD 18 99
+FF FF 00 00 WD 06 00
+
+; ----------- DAA PCM start offset ----------
+
-+01 00 00 00 WD 22 00
-+01 00 00 00 WD 23 00
-+01 00 00 00 WD 24 00
-+01 00 00 00 WD 25 00
++FF FF 00 00 WD 23 00
++FF FF 00 00 WD 25 00
+
-+02 00 00 00 WD 22 08
-+02 00 00 00 WD 23 00
-+02 00 00 00 WD 24 08
-+02 00 00 00 WD 25 00
++01 00 00 00 WD 22 00
++01 00 00 00 WD 24 00
+
-+04 00 00 00 WD 22 10
-+04 00 00 00 WD 23 00
-+04 00 00 00 WD 24 10
-+04 00 00 00 WD 25 00
++02 00 00 00 WD 22 08
++02 00 00 00 WD 24 08
+
-+08 00 00 00 WD 22 18
-+08 00 00 00 WD 23 00
-+08 00 00 00 WD 24 18
-+08 00 00 00 WD 25 00
++04 00 00 00 WD 22 10
++04 00 00 00 WD 24 10
+
-+10 00 00 00 WD 22 20
-+10 00 00 00 WD 23 00
-+10 00 00 00 WD 24 20
-+10 00 00 00 WD 25 00
++08 00 00 00 WD 22 18
++08 00 00 00 WD 24 18
+
-+20 00 00 00 WD 22 28
-+20 00 00 00 WD 23 00
-+20 00 00 00 WD 24 28
-+20 00 00 00 WD 25 00
++10 00 00 00 WD 22 20
++10 00 00 00 WD 24 20
+
-+40 00 00 00 WD 22 30
-+40 00 00 00 WD 23 00
-+40 00 00 00 WD 24 30
-+40 00 00 00 WD 25 00
++20 00 00 00 WD 22 28
++20 00 00 00 WD 24 28
+
-+80 00 00 00 WD 22 38
-+80 00 00 00 WD 23 00
-+80 00 00 00 WD 24 38
-+80 00 00 00 WD 25 00
++40 00 00 00 WD 22 30
++40 00 00 00 WD 24 30
+
++80 00 00 00 WD 22 38
++80 00 00 00 WD 24 38
++
+; ----------- DAA ONHOOK --------------------
-+FF FF 00 00 WD 05 00
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/initialize_registers zaptel-xpp-8WuH7d_dist/xpp/initialize_registers
++FF FF 00 00 WD 05 08
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/initialize_registers zaptel-xpp-oaIQ8i_dist/xpp/initialize_registers
--- zaptel-1.2.6/xpp/initialize_registers 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/initialize_registers 2006-05-01 12:49:12.732258000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/initialize_registers 2006-05-01 12:49:12.732258000 +0300
@@ -0,0 +1,39 @@
+#! /bin/sh
+# XPD_BUS - bus name
@@ -3325,9 +3456,9 @@
+$LOGGER "Wrote '$FILE' into '$SLICS'"
+
+exit 0
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/LICENSE.firmware zaptel-xpp-8WuH7d_dist/xpp/LICENSE.firmware
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/LICENSE.firmware zaptel-xpp-oaIQ8i_dist/xpp/LICENSE.firmware
--- zaptel-1.2.6/xpp/LICENSE.firmware 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/LICENSE.firmware 2006-05-01 22:45:43.558912000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/LICENSE.firmware 2006-05-01 22:45:43.558912000 +0300
@@ -0,0 +1,37 @@
+The firmware files (*.hex) in this directory are software for the
+Astribank itself and not intended to run on the Linux system itself.
@@ -3366,47 +3497,26 @@
+/* hardware or firmware either solely or in combination with the firmware. */
+/****************************************************************************/
+
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/Makefile zaptel-xpp-8WuH7d_dist/xpp/Makefile
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/Makefile zaptel-xpp-oaIQ8i_dist/xpp/Makefile
--- zaptel-1.2.6/xpp/Makefile 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/Makefile 2006-06-22 11:31:28.427315000 +0300
-@@ -1,5 +1,30 @@
++++ zaptel-xpp-oaIQ8i_dist/xpp/Makefile 2006-07-02 17:17:18.812352000 +0300
+@@ -1,5 +1,9 @@
-EXTRA_CFLAGS = -I$(src)/.. -DSOFT_SIMULATOR=0
-+EXTRA_CFLAGS = -I$(SUBDIRS) -DDEBUG -DWITH_ECHO_SUPPRESSION -DXPP_EC_CHUNK -DWITH_RBS # -DHARD_CODED_INIT # -DOLD_CARD
++EXTRA_CFLAGS = -I$(SUBDIRS) -DDEBUG -DPOLL_DIGITAL_INPUTS -DWITH_ECHO_SUPPRESSION -DXPP_EC_CHUNK -DWITH_RBS
-obj-m = xpd_fxs.o xpp.o xpp_usb.o
-xpp-y += xproto.o card_global.o xpp_zap.o zap_debug.o
-xpd_fxs-y += card_fxs.o slic.o
-+obj-m = xpp.o xpd_fxs.o xpd_fxo.o xpp_usb.o
++obj-m = xpp.o xpp_usb.o xpd_fxs.o xpd_fxo.o
+xpp-y += xbus-core.o xpp_zap.o xproto.o card_global.o
+xpd_fxs-y += card_fxs.o slic.o
+xpd_fxo-y += card_fxo.o slic.o
+
-+GENERATE_INIT_DATA := 1
-+INIT_DATA = init_data_3_19.inc init_data_3_20.inc init_data_4_19.inc init_data_4_20.inc
-+clean-files := $(INIT_DATA)
-+
-+cmd2inc=$(src)/cmd2inc
-+
-+define run_cmd2inc
-+if [ ! -x $(cmd2inc) ]; then chmod +x $(cmd2inc); fi
-+$(cmd2inc) $^ $@
-+endef
-+
-+ifeq ($(GENERATE_INIT_DATA),1)
-+
-+$(obj)/%.inc: $(src)/%.cmd
-+ @echo "Generating $@"
-+ @$(run_cmd2inc)
-+
-+init_data: $(INIT_DATA)
-+
-+$(obj)/card_fxs.o: $(obj)/init_data_3_19.inc $(obj)/init_data_3_20.inc
-+$(obj)/card_fxo.o: $(obj)/init_data_4_19.inc $(obj)/init_data_4_20.inc
-+
-+endif
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/README.Astribank zaptel-xpp-8WuH7d_dist/xpp/README.Astribank
++ctags:
++ ctags *.[ch]
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/README.Astribank zaptel-xpp-oaIQ8i_dist/xpp/README.Astribank
--- zaptel-1.2.6/xpp/README.Astribank 2006-03-03 21:11:53.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/README.Astribank 2006-06-19 11:29:10.334411000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/README.Astribank 2006-06-19 11:29:10.334411000 +0300
@@ -5,15 +5,63 @@
Building and Installation:
"""""""""""""""""""""""""
@@ -3520,9 +3630,9 @@
BTW: XPP here does not stand for X Printing Panel, XML Pull Parser,
X-Windows Phase Plane or XML Professional Publisher. It is simply the
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/slic.c zaptel-xpp-8WuH7d_dist/xpp/slic.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/slic.c zaptel-xpp-oaIQ8i_dist/xpp/slic.c
--- zaptel-1.2.6/xpp/slic.c 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/slic.c 2006-05-01 12:37:15.907543000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/slic.c 2006-05-01 12:37:15.907543000 +0300
@@ -1,6 +1,6 @@
/*
* Written by Oron Peled <oron at actcom.co.il>
@@ -3600,9 +3710,9 @@
EXPORT_SYMBOL(slic_cmd_direct_write);
EXPORT_SYMBOL(slic_cmd_direct_read);
EXPORT_SYMBOL(slic_cmd_indirect_write);
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/slic.h zaptel-xpp-8WuH7d_dist/xpp/slic.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/slic.h zaptel-xpp-oaIQ8i_dist/xpp/slic.h
--- zaptel-1.2.6/xpp/slic.h 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/slic.h 2006-04-02 18:33:25.346374000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/slic.h 2006-07-02 17:17:18.812352000 +0300
@@ -1,5 +1,26 @@
#ifndef SLIC_H
#define SLIC_H
@@ -3630,7 +3740,20 @@
#include "xdefs.h"
-@@ -60,6 +81,7 @@
+@@ -46,12 +67,6 @@
+ (slic_reg)->reg_data = data; \
+ } while(0);
+
+-/* OLD SLIC_INIT data */
+-typedef struct slic_data {
+- byte len;
+- byte data[40];
+-} __attribute__((packed)) slic_data_t;
+-
+
+ /*------------------------------ SLIC Initializers -------------------------*/
+
+@@ -60,6 +75,7 @@
int slic_cmd_indirect_write(slic_cmd_t *sc, xpp_line_t lines, byte reg, byte data_low, byte data_high);
int slic_cmd_indirect_read(slic_cmd_t *sc, xpp_line_t lines, byte reg);
void dump_slic_cmd(const char msg[], slic_cmd_t *sc);
@@ -3638,9 +3761,9 @@
#endif /* SLIC_H */
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/slic_init.inc zaptel-xpp-8WuH7d_dist/xpp/slic_init.inc
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/slic_init.inc zaptel-xpp-oaIQ8i_dist/xpp/slic_init.inc
--- zaptel-1.2.6/xpp/slic_init.inc 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/slic_init.inc 1970-01-01 02:00:00.000000000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/slic_init.inc 1970-01-01 02:00:00.000000000 +0200
@@ -1,65 +0,0 @@
-// ----------------------------------==== 8-channel FXS unit initialization ===-----------------------------------------
-
@@ -3707,9 +3830,9 @@
-S_(0x000000FF, 0x02, 0x42, 0x06),
-// -------------------------------------------------------------
-
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/supress/ec_xpp.h zaptel-xpp-8WuH7d_dist/xpp/supress/ec_xpp.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/supress/ec_xpp.h zaptel-xpp-oaIQ8i_dist/xpp/supress/ec_xpp.h
--- zaptel-1.2.6/xpp/supress/ec_xpp.h 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/supress/ec_xpp.h 2006-06-25 14:42:21.798100000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/supress/ec_xpp.h 2006-06-25 14:42:21.798100000 +0300
@@ -0,0 +1,100 @@
+#ifndef __EC_XPP_H__
+#define __EC_XPP_H__
@@ -3811,9 +3934,9 @@
+
+#endif
+
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/supress/suppressor.c zaptel-xpp-8WuH7d_dist/xpp/supress/suppressor.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/supress/suppressor.c zaptel-xpp-oaIQ8i_dist/xpp/supress/suppressor.c
--- zaptel-1.2.6/xpp/supress/suppressor.c 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/supress/suppressor.c 2006-06-25 14:42:21.798100000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/supress/suppressor.c 2006-06-25 14:42:21.798100000 +0300
@@ -0,0 +1,321 @@
+ /***********************************************************************
+ * Written by Sergey Serik.
@@ -4136,9 +4259,9 @@
+
+ return nearSample;
+}
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/supress/suppressor.h zaptel-xpp-8WuH7d_dist/xpp/supress/suppressor.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/supress/suppressor.h zaptel-xpp-oaIQ8i_dist/xpp/supress/suppressor.h
--- zaptel-1.2.6/xpp/supress/suppressor.h 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/supress/suppressor.h 2006-06-25 14:42:21.798100000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/supress/suppressor.h 2006-06-25 14:42:21.798100000 +0300
@@ -0,0 +1,160 @@
+#if 0 /* File Header */
+************************************************************************
@@ -4300,9 +4423,9 @@
+#endif
+
+#endif /* __SUPPRESSOR_H__ */
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/sync.sh zaptel-xpp-8WuH7d_dist/xpp/sync.sh
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/sync.sh zaptel-xpp-oaIQ8i_dist/xpp/sync.sh
--- zaptel-1.2.6/xpp/sync.sh 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/sync.sh 1970-01-01 02:00:00.000000000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/sync.sh 1970-01-01 02:00:00.000000000 +0200
@@ -1,31 +0,0 @@
-#!/bin/sh
-
@@ -4335,10 +4458,10 @@
-cp -a $XORTEL_DIR/gen_slic_init ${TARGET_DIR}/
-cp -a $XPP_DIR/Makefile ${TARGET_DIR}/
-cp -a $XPP_DIR/slic_init.inc ${TARGET_DIR}/
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/FPGA_FXS.hex zaptel-xpp-8WuH7d_dist/xpp/utils/FPGA_FXS.hex
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/fpga_load.8 zaptel-xpp-8WuH7d_dist/xpp/utils/fpga_load.8
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/FPGA_FXS.hex zaptel-xpp-oaIQ8i_dist/xpp/utils/FPGA_FXS.hex
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/fpga_load.8 zaptel-xpp-oaIQ8i_dist/xpp/utils/fpga_load.8
--- zaptel-1.2.6/xpp/utils/fpga_load.8 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/utils/fpga_load.8 2006-04-16 16:20:04.117881000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/utils/fpga_load.8 2006-04-16 16:20:04.117881000 +0300
@@ -0,0 +1,72 @@
+.TH "FPGA_LOAD" "8" "16 April 2006" "" ""
+
@@ -4412,9 +4535,9 @@
+
+On Debian systems, the complete text of the GNU General Public
+License can be found in /usr/share/common-licenses/GPL.
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/fpga_load.c zaptel-xpp-8WuH7d_dist/xpp/utils/fpga_load.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/fpga_load.c zaptel-xpp-oaIQ8i_dist/xpp/utils/fpga_load.c
--- zaptel-1.2.6/xpp/utils/fpga_load.c 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/utils/fpga_load.c 2006-06-01 11:50:28.294045000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/utils/fpga_load.c 2006-06-01 11:50:28.294045000 +0300
@@ -0,0 +1,822 @@
+#include <stdio.h>
+#include <assert.h>
@@ -5238,10 +5361,10 @@
+ usb_cleanup(handle);
+ return ret;
+}
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/genzaptelconf zaptel-xpp-8WuH7d_dist/xpp/utils/genzaptelconf
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/genzaptelconf zaptel-xpp-oaIQ8i_dist/xpp/utils/genzaptelconf
--- zaptel-1.2.6/xpp/utils/genzaptelconf 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/utils/genzaptelconf 2006-06-27 10:06:55.011704000 +0300
-@@ -0,0 +1,953 @@
++++ zaptel-xpp-oaIQ8i_dist/xpp/utils/genzaptelconf 2006-06-27 20:23:31.736538000 +0300
+@@ -0,0 +1,954 @@
+#! /bin/bash
+
+# genzaptelconf: generate as smartly as you can:
@@ -5278,8 +5401,9 @@
+# 0.5.3:
+# * Experimental support for Sangoma analog cards (A20x)
+# * Support OpenVox A1200P (A TDM400P clone refactored)
-+# * fixed timeout for Astribank load
++# * Fixed timeout for Astribank load
+# * Delete unsuccessfully-probe modules
++# * Pass callerid from trunks
+# 0.5.2:
+# * Now it should detect most PRI cards and even wcusb
+# 0.5.1:
@@ -5588,7 +5712,7 @@
+ fi
+ else # this is an FXO (trunk/phone: FXO signalling)
+ # we have may have set it. So reset it:
-+ echo "callerid=\"\" <0>"
++ echo "callerid=asrecieved"
+ echo "mailbox="
+ if [ "$group_manual" != "yes" ]
+ then
@@ -6025,7 +6149,7 @@
+ # NT is the same as FXS for us and TE is the same as FXO
+ if [ "$span_termtype" = 'nt' ]
+ then
-+ #echo "callerid=\"Channel $chan\" <$exten>"
++ echo "callerid=\"Channels $span_begin - $span_end\" <$span_begin>"
+ #echo "mailbox=$exten"
+ if [ "$group_manual" != "yes" ]
+ then
@@ -6036,7 +6160,7 @@
+ echo "context=$context_phones"
+ fi
+ else # we have may have set it. So reset it:
-+ #echo "callerid=\"\" <0>"
++ echo "callerid=asrecieved"
+ #echo "mailbox="
+ if [ "$group_manual" != "yes" ]
+ then
@@ -6195,9 +6319,9 @@
+fi
+
+# vim:ts=2:
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/genzaptelconf.8 zaptel-xpp-8WuH7d_dist/xpp/utils/genzaptelconf.8
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/genzaptelconf.8 zaptel-xpp-oaIQ8i_dist/xpp/utils/genzaptelconf.8
--- zaptel-1.2.6/xpp/utils/genzaptelconf.8 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/utils/genzaptelconf.8 2006-06-17 09:56:07.169240000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/utils/genzaptelconf.8 2006-06-17 09:56:07.169240000 +0300
@@ -0,0 +1,258 @@
+.TH GENZAPTELCONF 8 "July 18th, 2005" "Xorcom Rapid Asterisk" "Linux Programmer's Manual"
+.SH "NAME"
@@ -6457,9 +6581,9 @@
+
+On Debian systems, the complete text of the GNU General Public
+License can be found in /usr/share/common-licenses/GPL.
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/hexfile.c zaptel-xpp-8WuH7d_dist/xpp/utils/hexfile.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/hexfile.c zaptel-xpp-oaIQ8i_dist/xpp/utils/hexfile.c
--- zaptel-1.2.6/xpp/utils/hexfile.c 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/utils/hexfile.c 2006-06-18 17:05:04.917972000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/utils/hexfile.c 2006-06-18 17:05:04.917972000 +0300
@@ -0,0 +1,360 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
@@ -6821,9 +6945,9 @@
+ fclose(fp);
+}
+
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/hexfile.h zaptel-xpp-8WuH7d_dist/xpp/utils/hexfile.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/hexfile.h zaptel-xpp-oaIQ8i_dist/xpp/utils/hexfile.h
--- zaptel-1.2.6/xpp/utils/hexfile.h 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/utils/hexfile.h 2006-05-15 17:27:26.264723000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/utils/hexfile.h 2006-05-15 17:27:26.264723000 +0300
@@ -0,0 +1,120 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
@@ -6945,15 +7069,16 @@
+__END_DECLS
+
+#endif
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/Makefile zaptel-xpp-8WuH7d_dist/xpp/utils/Makefile
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/Makefile zaptel-xpp-oaIQ8i_dist/xpp/utils/Makefile
--- zaptel-1.2.6/xpp/utils/Makefile 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/utils/Makefile 2006-06-27 02:07:26.558841000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/utils/Makefile 2006-07-02 17:49:51.471281000 +0300
@@ -0,0 +1,50 @@
+PEDANTIC = -ansi -pedantic -std=c99
+
+CC = gcc
+RANLIB = ranlib
+INSTALL = install
++INSTALL_DATA = install -m 644
+
+BINDIR = /usr/sbin
+DATADIR = /usr/share/zaptel
@@ -6968,17 +7093,16 @@
+
+all: $(TARGETS)
+
-+# install: sets the executable bit
+install: all
+ $(INSTALL) -d $(DESTDIR)$(BINDIR)
+ $(INSTALL) genzaptelconf fpga_load $(DESTDIR)$(BINDIR)/
+ $(INSTALL) -d $(DESTDIR)$(DATADIR)
-+ cp -a $(DATA_FILES) $(DESTDIR)$(DATADIR)/
++ $(INSTALL_DATA) $(DATA_FILES) $(DESTDIR)$(DATADIR)/
+ $(INSTALL) ../initialize_registers $(DESTDIR)$(DATADIR)/
+ $(INSTALL) -d $(DESTDIR)$(MANDIR)
-+ cp -a fpga_load.8 genzaptelconf.8 $(DESTDIR)$(MANDIR)/
++ $(INSTALL_DATA) fpga_load.8 genzaptelconf.8 $(DESTDIR)$(MANDIR)/
+ $(INSTALL) -d $(DESTDIR)$(HOTPLUG_USB_DIR)
-+ cp -a xpp_fxloader.usermap $(DESTDIR)$(HOTPLUG_USB_DIR)/
++ $(INSTALL_DATA) xpp_fxloader.usermap $(DESTDIR)$(HOTPLUG_USB_DIR)/
+ $(INSTALL) xpp_fxloader $(DESTDIR)$(HOTPLUG_USB_DIR)/
+
+libhexfile.a: hexfile.o
@@ -6999,9 +7123,9 @@
+
+clean:
+ $(RM) *.o $(TARGETS)
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/test_parse.c zaptel-xpp-8WuH7d_dist/xpp/utils/test_parse.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/test_parse.c zaptel-xpp-oaIQ8i_dist/xpp/utils/test_parse.c
--- zaptel-1.2.6/xpp/utils/test_parse.c 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/utils/test_parse.c 2006-05-15 17:27:26.264723000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/utils/test_parse.c 2006-05-15 17:27:26.264723000 +0300
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <stdarg.h>
@@ -7037,12 +7161,12 @@
+ }
+ return 0;
+}
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/USB_1130.hex zaptel-xpp-8WuH7d_dist/xpp/utils/USB_1130.hex
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/USB_8613.hex zaptel-xpp-8WuH7d_dist/xpp/utils/USB_8613.hex
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/xpp_fxloader zaptel-xpp-8WuH7d_dist/xpp/utils/xpp_fxloader
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/USB_1130.hex zaptel-xpp-oaIQ8i_dist/xpp/utils/USB_1130.hex
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/USB_8613.hex zaptel-xpp-oaIQ8i_dist/xpp/utils/USB_8613.hex
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/xpp_fxloader zaptel-xpp-oaIQ8i_dist/xpp/utils/xpp_fxloader
--- zaptel-1.2.6/xpp/utils/xpp_fxloader 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/utils/xpp_fxloader 2006-06-27 02:07:26.558841000 +0300
-@@ -0,0 +1,158 @@
++++ zaptel-xpp-oaIQ8i_dist/xpp/utils/xpp_fxloader 2006-07-02 17:49:51.471281000 +0300
+@@ -0,0 +1,163 @@
+#!/bin/sh
+
+# xpp_fxload: load XPP firmware
@@ -7129,6 +7253,7 @@
+ devices=`find_dev $v_id $p_id`
+ for dev in $devices
+ do
++ $LOGGER "USB Firmware $FIRMWARE_DIR/$fw into $dev"
+ do_fxload -D $dev -I $FIRMWARE_DIR/$fw || exit 1
+ done
+
@@ -7143,23 +7268,24 @@
+}
+
+load_fpga() {
-+ dev=$1
-+
++ v_id=$1
++ p_id=$2
++ fw=$3
++
++ devices=`find_dev $v_id $p_id`
++ for dev in $devices
++ do
+ card_ver=`$FPGA_LOAD -d -D $dev`
-+ firm_ver=`hexfile_version $FIRM_FXS`
++ firm_ver=`hexfile_version $FIRMWARE_DIR/$fw`
+
-+ $LOGGER "considering fpga firmware version '$firm_ver' for $dev with version $card_ver."
-+ case "$card_ver" in
-+ 1.001)
-+ $LOGGER "Loading firmware '$FIRM_FXS' (version $firm_ver) into '$dev'"
-+ $FPGA_LOAD -D "$dev" -I "$FIRM_FXS" 2>&1 >/dev/null | $LOGGER
-+ status=$PIPESTATUS
-+ if [ $status != 0 ]; then
-+ echo "fpga_load failed with status $status" | $LOGGER
-+ exit 77
-+ fi
-+ ;;
-+ esac
++ $LOGGER "FPGA Firmware $FIRMWARE_DIR/$fw into $dev"
++ $FPGA_LOAD -D "$dev" -I "$FIRMWARE_DIR/$fw" 2>&1 >/dev/null | $LOGGER
++ status=$PIPESTATUS
++ if [ $status != 0 ]; then
++ echo "fpga_load failed with status $status" | $LOGGER
++ exit 77
++ fi
++ done
+}
+
+#########################
@@ -7169,11 +7295,13 @@
+
+# to run manually, pass the parameter 'xppdetect'
+if [ "$1" = 'xppdetect' ]; then
++ echo "--------- FIRMWARE LOADING"
+ load_fw 04b4 8613 USB_8613.hex
+ load_fw e4e4 1130 USB_1130.hex
-+ for dev in `find_dev e4e4 1131`; do
-+ load_fpga $dev
-+ done
++ load_fpga e4e4 1131 FPGA_FXS.hex
++
++ sleep 3 # Let it stabilize
++ echo "--------- FIRMWARE IS LOADED"
+ exit $?
+fi
+
@@ -7185,33 +7313,34 @@
+if [ "$ACTION" = "add" ] && [ -f "$DEVICE" ]
+then
+ $LOGGER "Trying to find what to do for product $PRODUCT, device $DEVICE"
++ prod_id=`echo "$PRODUCT" | cut -d/ -f2`
+ case "$PRODUCT" in
-+ 4b4/8613/*)
-+ FIRM_USB=$FIRMWARE_DIR/USB_8613.hex
++ 4b4/8613/*|e4e4/1130/*|e4e4/1140/*)
++ FIRM_USB="$FIRMWARE_DIR/USB_$prod_id.hex"
+ $LOGGER "Loading firmware '$FIRM_USB' into '$DEVICE'"
+ do_fxload -D "$DEVICE" -I "$FIRM_USB"
+ ;;
-+ e4e4/1130/*)
-+ FIRM_USB=$FIRMWARE_DIR/USB_1130.hex
-+ $LOGGER "Loading firmware '$FIRM_USB' into '$DEVICE'"
-+ do_fxload -D "$DEVICE" -I "$FIRM_USB"
++ e4e4/1131/*|e4e4/1141/*)
++ if [ "$prod_id" = 1131 ]; then
++ FIRM_FPGA="$FIRMWARE_DIR/FPGA_FXS.hex" # Legacy
++ else
++ FIRM_FPGA="$FIRMWARE_DIR/FPGA_$prod_id.hex"
++ fi
++ $FPGA_LOAD -D "$DEVICE" -I "$FIRM_FPGA" 2>&1 >/dev/null | $LOGGER
+ ;;
-+ e4e4/1131/*)
-+ load_fpga $DEVICE
-+ ;;
+ esac
+fi
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/xpp_fxloader.usermap zaptel-xpp-8WuH7d_dist/xpp/utils/xpp_fxloader.usermap
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/xpp_fxloader.usermap zaptel-xpp-oaIQ8i_dist/xpp/utils/xpp_fxloader.usermap
--- zaptel-1.2.6/xpp/utils/xpp_fxloader.usermap 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/utils/xpp_fxloader.usermap 2006-05-01 18:45:04.050100000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/utils/xpp_fxloader.usermap 2006-05-01 18:45:04.050100000 +0300
@@ -0,0 +1,4 @@
+# module match_flags idVendor idProduct bcdDevice_lo bcdDevice_hi bDeviceClass bDeviceSubClass bDeviceProtocol bInterfaceClass bInterfaceSubClass bInterfaceProtocol driver_info
+xpp_fxloader 0x0003 0x04b4 0x8613 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1130 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1131 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/xpp_modprobe zaptel-xpp-8WuH7d_dist/xpp/utils/xpp_modprobe
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/utils/xpp_modprobe zaptel-xpp-oaIQ8i_dist/xpp/utils/xpp_modprobe
--- zaptel-1.2.6/xpp/utils/xpp_modprobe 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/utils/xpp_modprobe 2006-05-01 17:08:34.781705000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/utils/xpp_modprobe 2006-05-01 17:08:34.781705000 +0300
@@ -0,0 +1,10 @@
+# Some debugging options for the brave of heart:
+#options zaptel debug=1
@@ -7223,10 +7352,10 @@
+
+# For pre-loading of card modules (e.g: xpp_fxs)
+#install xpp_usb /sbin/modprobe xpd_fxs && /sbin/modprobe --ignore-install xpp_usb
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xbus-core.c zaptel-xpp-8WuH7d_dist/xpp/xbus-core.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xbus-core.c zaptel-xpp-oaIQ8i_dist/xpp/xbus-core.c
--- zaptel-1.2.6/xpp/xbus-core.c 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/xbus-core.c 2006-04-26 15:44:38.391672000 +0300
-@@ -0,0 +1,677 @@
++++ zaptel-xpp-oaIQ8i_dist/xpp/xbus-core.c 2006-07-03 12:11:26.109424000 +0300
+@@ -0,0 +1,874 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * Copyright (C) 2004-2006, Xorcom
@@ -7259,21 +7388,23 @@
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/device.h>
++#include <linux/delay.h> /* for mdelay() to debug */
+#include "xpd.h"
+#include "xpp_zap.h"
+#include "xbus-core.h"
+#include "zap_debug.h"
+
-+static const char rcsid[] = "$Id: xbus-core.c 894 2006-04-26 12:44:38Z oron $";
++static const char rcsid[] = "$Id: xbus-core.c 1543 2006-07-03 09:11:26Z oron $";
+
+/* Defines */
++#define POLL_TIMEOUT (MAX_XPDS) /* in jiffies */
+#define PROC_XBUSES "xbuses"
+#define PROC_XBUS_SUMMARY "summary"
++#define PROC_XBUS_WAITFOR_XPDS "waitfor_xpds"
+
+/* Command line parameters */
+extern int print_dbg;
+extern int max_queue_len;
-+extern int ignore_xpds;
+
+/* Forward declarations */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
@@ -7287,10 +7418,13 @@
+static DEVICE_ATTR_FUNC(connector_show, dev, buf);
+static DEVICE_ATTR_FUNC(status_show, dev, buf);
+
++static int xbus_poll(void *data);
+static void xbus_release(struct device *dev);
+static int xbus_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data);
++static int xbus_read_waitfor_xpds(char *page, char **start, off_t off, int count, int *eof, void *data);
+
+/* Data structures */
++struct workqueue_struct *xpp_worker = NULL;
+static spinlock_t xbuses_lock = SPIN_LOCK_UNLOCKED;
+static xbus_t *xbuses_array[MAX_BUSES] = {};
+static int bus_count = 0;
@@ -7463,29 +7597,154 @@
+ return xbus->xpds[xpd_num];
+}
+
-+static void xbus_poll(xbus_t *xbus)
++int xbus_register_xpd(xbus_t *xbus, xpd_t *xpd)
+{
-+ int id;
-+ int ret;
-+ xpd_t **xpds;
-+ xpd_t *xpd;
++ unsigned int xpd_num = xpd->id;
++ unsigned long flags;
++ int ret = 0;
+
++ spin_lock_irqsave(&xbus->lock, flags);
++ if(!VALID_XPD_NUM(xpd_num)) {
++ ERR("%s: Bad xpd_num = %d\n", xbus->busname, xpd_num);
++ ret = -EINVAL;
++ goto out;
++ }
++ if(xbus->xpds[xpd_num] != NULL) {
++ xpd_t *other = xbus->xpds[xpd_num];
++
++ ERR("%s: xpd_num=%d is occupied by %p (%s)\n",
++ xbus->busname, xpd_num, other, other->xpdname);
++ ret = -EINVAL;
++ goto out;
++ }
++ xbus->xpds[xpd_num] = xpd;
++ xbus->num_xpds++;
++out:
++ spin_unlock_irqrestore(&xbus->lock, flags);
++ return ret;
++}
++
++int xbus_unregister_xpd(xbus_t *xbus, xpd_t *xpd)
++{
++ unsigned int xpd_num = xpd->id;
++ unsigned long flags;
++ int ret = 0;
++
++ spin_lock_irqsave(&xbus->lock, flags);
++ if(!VALID_XPD_NUM(xpd_num)) {
++ ERR("%s: Bad xpd_num = %d\n", xbus->busname, xpd_num);
++ ret = -EINVAL;
++ goto out;
++ }
++ if(xbus->xpds[xpd_num] != xpd) {
++ xpd_t *other = xbus->xpds[xpd_num];
++
++ ERR("%s: xpd_num=%d is occupied by %p (%s)\n",
++ xbus->busname, xpd_num, other, other->xpdname);
++ ret = -EINVAL;
++ goto out;
++ }
++ xbus->xpds[xpd_num] = NULL;
++ xbus->num_xpds--;
++ xpd->xbus = NULL;
++out:
++ spin_unlock_irqrestore(&xbus->lock, flags);
++ return ret;
++}
++
++/*
++ * This must be called from synchronous (non-interrupt) context
++ * it returns only when all XPD's on the bus are detected and
++ * initialized.
++ */
++static int xbus_poll(void *data)
++{
++ int id;
++ int ret;
++ unsigned long flags;
++ struct list_head *card;
++ struct list_head *next_card;
++ struct list_head removal_list;
++ struct list_head additions_list;
++ int count_removed;
++ int count_added;
++ int xpd_num;
++ xbus_t *xbus = data;
++
++ spin_lock_irqsave(&xbus->lock, flags);
+ DBG("%s\n", xbus->busname);
-+ xpds = xbus->xpds;
++
++ /*
++ * Send out the polls
++ */
++ atomic_set(&xbus->count_poll_answers, 0);
+ for(id = 0; id < MAX_XPDS; id++) {
+ if(!xbus->hardware_exists)
+ break;
-+ xpd = xpd_of(xbus, id);
-+ if(IS_SET(ignore_xpds, id)) { /* skip xpds */
-+ DBG(" Ignoring XPD #%d\n", id);
-+ continue;
-+ }
-+ DBG(" Polling slot %d %s\n", id, xbus->busname);
++ // DBG(" Polling slot %d %s\n", id, xbus->busname);
++ spin_unlock_irqrestore(&xbus->lock, flags);
+ ret = CALL_PROTO(GLOBAL, DESC_REQ, xbus, NULL, id);
++ spin_lock_irqsave(&xbus->lock, flags);
+ if(ret < 0) {
+ NOTICE("xpp: %s: Failed sending DESC_REQ to XPD #%d\n", __FUNCTION__, id);
++ break;
+ }
++ mdelay(1); /* FIXME: debugging for Dima */
+ }
++ spin_unlock_irqrestore(&xbus->lock, flags);
++ DBG("%s: Polled %d XPD's. Waiting for replies\n", xbus->busname, MAX_XPDS);
++ ret = wait_event_timeout(xbus->wait_for_polls, atomic_read(&xbus->count_poll_answers) >= MAX_XPDS, POLL_TIMEOUT);
++ if(ret < 0) {
++ ERR("%s: Poll timeout %d\n", xbus->busname, ret);
++ return ret;
++ }
++ DBG("%s: Poll finished. Start processing.\n", xbus->busname);
++ spin_lock_irqsave(&xbus->lock, flags);
++ INIT_LIST_HEAD(&removal_list);
++ INIT_LIST_HEAD(&additions_list);
++ count_removed = 0;
++ count_added = 0;
++ list_for_each_safe(card, next_card, &xbus->poll_results) {
++ struct card_desc_struct *card_desc = list_entry(card, struct card_desc_struct, card_list);
++ byte type = card_desc->type;
++ xpd_t *xpd;
++
++ BUG_ON(card_desc->magic != CARD_DESC_MAGIC);
++ xpd_num = xpd_addr2num(&card_desc->xpd_addr);
++ xpd = xpd_of(xbus, xpd_num);
++
++ if(xpd && type == XPD_TYPE_NOMODULE) { /* card removal */
++ list_move_tail(card, &removal_list);
++ count_removed++;
++ } else if(!xpd && type != XPD_TYPE_NOMODULE) { /* card detection */
++ list_move_tail(card, &additions_list);
++ count_added++;
++ } else { /* same same */
++ list_del(card);
++ kfree(card_desc);
++ }
++ }
++ spin_unlock_irqrestore(&xbus->lock, flags);
++ INFO("%s: Poll results: removals=%d additions=%d\n", xbus->busname, count_removed, count_added);
++ list_for_each_safe(card, next_card, &removal_list) {
++ struct card_desc_struct *card_desc = list_entry(card, struct card_desc_struct, card_list);
++ xpd_t *xpd;
++
++ list_del(card);
++ xpd_num = xpd_addr2num(&card_desc->xpd_addr);
++ xpd = xpd_of(xbus, xpd_num);
++ if(xpd)
++ xpd_disconnect(xpd);
++ kfree(card);
++ }
++ list_for_each_safe(card, next_card, &additions_list) {
++ struct card_desc_struct *card_desc = list_entry(card, struct card_desc_struct, card_list);
++
++ list_del(card);
++ card_detected(card_desc);
++ }
++ complete_all(&xbus->xpds_initialized);
++ return 0;
+}
+
+
@@ -7503,7 +7762,11 @@
+ xbus->hardware_exists = 1;
+ DBG("Activating: %s\n", xbus->busname);
+ /* Poll it */
-+ xbus_poll(xbus);
++ INIT_WORK(&xbus->xpds_init_work, (void (*)(void *))xbus_poll, (void *)xbus);
++ if(!queue_work(xpp_worker, &xbus->xpds_init_work)) {
++ ERR("Failed to queue xpd initialization work\n");
++ /* FIXME: need to return error */
++ }
+}
+
+void xbus_disconnect(xbus_t *xbus)
@@ -7577,6 +7840,11 @@
+ remove_proc_entry(PROC_XBUS_SUMMARY, xbus->proc_xbus_dir);
+ xbus->proc_xbus_summary = NULL;
+ }
++ if(xbus->proc_xbus_waitfor_xpds) {
++ DBG("Removing proc '%s' for %s\n", PROC_XBUS_WAITFOR_XPDS, xbus->busname);
++ remove_proc_entry(PROC_XBUS_WAITFOR_XPDS, xbus->proc_xbus_dir);
++ xbus->proc_xbus_waitfor_xpds = NULL;
++ }
+ DBG("Removing proc directory %s\n", xbus->busname);
+ remove_proc_entry(xbus->busname, xpp_proc_toplevel);
+ xbus->proc_xbus_dir = NULL;
@@ -7614,7 +7882,11 @@
+ INFO("New xbus: %s\n", xbus->busname);
+ init_waitqueue_head(&xbus->packet_cache_empty);
+ atomic_set(&xbus->packet_counter, 0);
++ atomic_set(&xbus->count_poll_answers, 0);
++ init_waitqueue_head(&xbus->wait_for_polls);
+ init_rwsem(&xbus->in_use);
++ INIT_LIST_HEAD(&xbus->poll_results);
++ init_completion(&xbus->xpds_initialized);
+ xbus->num_xpds = 0;
+ xbus_reset_counters(xbus);
+
@@ -7654,6 +7926,15 @@
+ err = -EIO;
+ goto nobus;
+ }
++ xbus->proc_xbus_summary->owner = THIS_MODULE;
++ xbus->proc_xbus_waitfor_xpds = create_proc_read_entry(PROC_XBUS_WAITFOR_XPDS, 0444, xbus->proc_xbus_dir,
++ xbus_read_waitfor_xpds, xbus);
++ if (!xbus->proc_xbus_waitfor_xpds) {
++ ERR("Failed to create '%s' proc file for xbus %s\n", PROC_XBUS_WAITFOR_XPDS, xbus->busname);
++ err = -EIO;
++ goto nobus;
++ }
++ xbus->proc_xbus_waitfor_xpds->owner = THIS_MODULE;
+#endif
+ /* Sanity checks */
+ if(!ops->packet_send) {
@@ -7736,7 +8017,9 @@
+ (xbus->hardware_exists) ? "connected" : "missing",
+ xbus->bus_type
+ );
-+ len += sprintf(page + len, "max_packet_size=%d open_counter=%d packet_count=%d\n",
++ len += sprintf(page + len, "POLLS: %d/%d\n", atomic_read(&xbus->count_poll_answers), MAX_XPDS);
++ len += sprintf(page + len, "XPDS_READY: %s\n", (xbus->xpds_initialized.done) ? "YES" : "NO");
++ len += sprintf(page + len, "\nmax_packet_size=%d open_counter=%d packet_count=%d\n",
+ xbus->max_packet_size,
+ xbus->open_counter,
+ atomic_read(&xbus->packet_counter)
@@ -7761,6 +8044,36 @@
+
+}
+
++static int xbus_read_waitfor_xpds(char *page, char **start, off_t off, int count, int *eof, void *data)
++{
++ int len = 0;
++ unsigned long flags;
++ xbus_t *xbus = data;
++ int i;
++
++ if(!xbus)
++ goto out;
++ i = wait_for_completion_interruptible_timeout(&xbus->xpds_initialized, 40*HZ);
++ if(i < 0) {
++ NOTICE("PID=%d waiting for XPDS initialization failed: %d\n", current->pid, i);
++ return i;
++ }
++ spin_lock_irqsave(&xbus->lock, flags);
++ len += sprintf(page + len, "XPDS_READY: %s\n", (xbus->xpds_initialized.done) ? "YES" : "NO");
++ spin_unlock_irqrestore(&xbus->lock, flags);
++out:
++ if (len <= off+count)
++ *eof = 1;
++ *start = page + off;
++ len -= off;
++ if (len > count)
++ len = count;
++ if (len < 0)
++ len = 0;
++ return len;
++
++}
++
+static int read_proc_xbuses(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ int len = 0;
@@ -7840,14 +8153,19 @@
+struct bus_type xbus_bus_type = {
+ .name = "xbus",
+ .match = xbus_match,
++/* FIXME: Hotplug replaced with uevent in 2.6.16 */
+#if 0
-+/* Hotplug replaced with uevent in 2.6.16 */
+ .hotplug = xbus_hotplug,
+#endif
+};
+
+static void xbus_core_cleanup(void)
+{
++ if (xpp_worker) {
++ flush_workqueue(xpp_worker);
++ destroy_workqueue(xpp_worker);
++ xpp_worker = NULL;
++ }
+#ifdef CONFIG_PROC_FS
+ if(proc_xbuses)
+ remove_proc_entry(PROC_XBUSES, xpp_proc_toplevel);
@@ -7867,12 +8185,20 @@
+ if(!packet_cache) {
+ return -ENOMEM;
+ }
++ xpp_worker = create_singlethread_workqueue("xppworker");
++ if(!xpp_worker) {
++ ERR("Failed to create card detector workqueue.\n");
++ xbus_core_cleanup();
++ return -ENOMEM;
++ }
+#ifdef CONFIG_PROC_FS
+ proc_xbuses = create_proc_read_entry(PROC_XBUSES, 0444, xpp_proc_toplevel, read_proc_xbuses, 0);
+ if (!proc_xbuses) {
++ ERR("Failed to create proc file %s\n", PROC_XBUSES);
+ xbus_core_cleanup();
+ return -EFAULT;
+ }
++ proc_xbuses->owner = THIS_MODULE;
+#endif
+ ret = bus_register(&xbus_bus_type);
+ if(ret) {
@@ -7904,10 +8230,10 @@
+EXPORT_SYMBOL(xbus_activate);
+EXPORT_SYMBOL(xbus_disconnect);
+EXPORT_SYMBOL(xbus_reset_counters);
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xbus-core.h zaptel-xpp-8WuH7d_dist/xpp/xbus-core.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xbus-core.h zaptel-xpp-oaIQ8i_dist/xpp/xbus-core.h
--- zaptel-1.2.6/xpp/xbus-core.h 1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/xbus-core.h 2006-03-13 14:24:00.628259000 +0200
-@@ -0,0 +1,53 @@
++++ zaptel-xpp-oaIQ8i_dist/xpp/xbus-core.h 2006-07-02 19:47:41.666262000 +0300
+@@ -0,0 +1,56 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * Copyright (C) 2004-2006, Xorcom
@@ -7959,11 +8285,14 @@
+
+void xbus_reset_counters(xbus_t *xbus);
+
++int xbus_register_xpd(xbus_t *xbus, xpd_t *xpd);
++int xbus_unregister_xpd(xbus_t *xbus, xpd_t *xpd);
++
+#endif /* XBUS_CORE_H */
+
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xdefs.h zaptel-xpp-8WuH7d_dist/xpp/xdefs.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xdefs.h zaptel-xpp-oaIQ8i_dist/xpp/xdefs.h
--- zaptel-1.2.6/xpp/xdefs.h 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/xdefs.h 2006-03-30 12:42:46.619481000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/xdefs.h 2006-07-03 12:11:26.109424000 +0300
@@ -2,7 +2,7 @@
#define XDEFS_H
/*
@@ -7991,15 +8320,20 @@
#include <stdint.h>
typedef uint32_t __u32;
-@@ -57,26 +52,17 @@
- typedef struct xpd xpd_t;
- typedef struct xpacket_raw xpacket_raw_t;
- typedef struct xpacket xpacket_t;
+@@ -50,33 +45,58 @@
+
+ #endif
+
+-typedef char *charp;
+-typedef unsigned char byte;
+-typedef int bool;
+-typedef struct xbus xbus_t;
+-typedef struct xpd xpd_t;
+-typedef struct xpacket_raw xpacket_raw_t;
+-typedef struct xpacket xpacket_t;
-typedef struct xops xops_t;
-typedef __u32 xpp_line_t; /* at most 31 lines for E1 */
-+typedef struct xops xops_t;
-+typedef __u32 xpp_line_t; /* at most 31 lines for E1 */
-+typedef int lineno_t;
++#define PACKED __attribute__((packed))
+#define ALL_LINES ((lineno_t)-1)
@@ -8010,24 +8344,63 @@
+#define BIT_SET(x,i) ((x) |= BIT(i))
+#define BIT_CLR(x,i) ((x) &= ~BIT(i))
+#define IS_SET(x,i) (((x) & BIT(i)) != 0)
++#define BITMASK(i) (BIT(i) - 1)
++
++#define CHANNELS_PERXPD 30 /* Depends on xpp_line_t and protocol fields */
-#undef SUPPORT_USB1
--
++#define MAX_SPANNAME 20 /* From zaptel.h */
++#define MAX_SPANDESC 40 /* From zaptel.h */
++#define MAX_CHANNAME 40 /* From zaptel.h */
++
++#define XPD_NAMELEN 10 /* must be <= from maximal workqueue name */
++#define XPD_DESCLEN 20
++#define XBUS_NAMELEN 20 /* must be <= from maximal workqueue name */
++#define XBUS_DESCLEN 40
++
++#define UNIT_BITS 4 /* Bit for Astribank unit number */
++#define SUBUNIT_BITS 4 /* Bit for Astribank subunit number */
++
++#define MAX_UNIT 4 /* 1 FXS + 3 FXS/FXO */
++#define MAX_SUBUNIT 1 /* Firmware does not support subunits yet */
+
-#ifdef SUPPORT_USB1
--/*
+ /*
- * packet size <= 64 bytes:
- * ZT_CHUNKSIZE * 7 channels + header size <= 64
-- */
++ * Compile time sanity checks
+ */
-#define CHANNELS_PERXPD 7 /* 7 * ZT_CHUNKSIZE + header <= 64 bytes */
-#else
- #define CHANNELS_PERXPD 30 /* Depends on xpp_line_t and protocol fields */
--#endif
--
+-#define CHANNELS_PERXPD 30 /* Depends on xpp_line_t and protocol fields */
++#if MAX_UNIT > BIT(UNIT_BITS)
++#error "MAX_UNIT too large"
++#endif
++
++#if MAX_SUBUNIT > BIT(SUBUNIT_BITS)
++#error "MAX_SUBUNIT too large"
+ #endif
++#define MAX_XPDS (MAX_UNIT*MAX_SUBUNIT)
++
++#define VALID_XPD_NUM(x) ((x) < MAX_XPDS && (x) >= 0)
++
++typedef char *charp;
++typedef unsigned char byte;
++typedef int bool;
++typedef struct xbus xbus_t;
++typedef struct xpd xpd_t;
++typedef struct xpacket_raw xpacket_raw_t;
++typedef struct xpacket xpacket_t;
++typedef struct xops xops_t;
++typedef __u32 xpp_line_t; /* at most 31 lines for E1 */
++typedef int lineno_t;
++
+
#endif /* XDEFS_H */
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpd.h zaptel-xpp-8WuH7d_dist/xpp/xpd.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpd.h zaptel-xpp-oaIQ8i_dist/xpp/xpd.h
--- zaptel-1.2.6/xpp/xpd.h 2006-03-03 22:14:09.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/xpd.h 2006-06-22 11:31:28.427315000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/xpd.h 2006-07-03 12:11:26.109424000 +0300
@@ -3,7 +3,7 @@
/*
@@ -8045,20 +8418,28 @@
#include <asm/atomic.h>
#include <asm/semaphore.h>
#include <linux/moduleparam.h>
-@@ -61,9 +62,9 @@
+@@ -61,20 +62,6 @@
#endif // __KERNEL__
-#define MAX_SPANNAME 20
-#define MAX_SPANDESC 40
-#define MAX_CHANNAME 20
-+#define MAX_SPANNAME 20 /* From zaptel.h */
-+#define MAX_SPANDESC 40 /* From zaptel.h */
-+#define MAX_CHANNAME 40 /* From zaptel.h */
+-
+-#define XPD_NAMELEN 10 /* must be <= from maximal workqueue name */
+-#define XPD_DESCLEN 20
+-#define XBUS_NAMELEN 20 /* must be <= from maximal workqueue name */
+-#define XBUS_DESCLEN 40
+-
+-/* Hardware does not check bank_num yet. So only 4 cards can be used */
+-#define MAX_XPDS 4 // 1 FXS + 2 E1/T1 + 1 (Quad * E1/T1)
+-
+-#define VALID_XPD_NUM(x) ((x) < MAX_XPDS && (x) >= 0)
+-
+ typedef struct xbus_ops xbus_ops_t;
- #define XPD_NAMELEN 10 /* must be <= from maximal workqueue name */
- #define XPD_DESCLEN 20
-@@ -100,6 +101,9 @@
+ typedef enum xbus_type {
+@@ -100,15 +87,17 @@
void (*packet_free)(xbus_t *xbus, xpacket_t *p);
};
@@ -8067,9 +8448,35 @@
+ */
enum {
XBUS_N_DESC_REQ,
- XBUS_N_DEV_DESC,
-@@ -133,30 +137,22 @@
+- XBUS_N_DEV_DESC,
++ XBUS_N_DEV_DESC_FULL,
++ XBUS_N_DEV_DESC_EMPTY,
+ XBUS_N_PCM_WRITE,
+ XBUS_N_PCM_READ,
+ XBUS_N_TX_BYTES,
+ XBUS_N_RX_BYTES,
+- XBUS_N_SOFTSIM_PACKETS,
+- XBUS_N_SIM_PACKETS,
+ };
+ #define XBUS_COUNTER(xbus, counter) ((xbus)->counters[XBUS_N_ ## counter])
+@@ -120,68 +109,76 @@
+ char *name;
+ } xbus_counters[] = {
+ C_(DESC_REQ),
+- C_(DEV_DESC),
++ C_(DEV_DESC_FULL),
++ C_(DEV_DESC_EMPTY),
+ C_(PCM_WRITE),
+ C_(PCM_READ),
+ C_(TX_BYTES),
+ C_(RX_BYTES),
+- C_(SOFTSIM_PACKETS),
+- C_(SIM_PACKETS),
+ };
+
+ #undef C_
+
#define XBUS_COUNTER_MAX ARRAY_SIZE(xbus_counters)
-struct xpd_sim {
@@ -8078,46 +8485,87 @@
- int loopto;
- xpd_type_t xpd_type;
- xpp_line_t hookstate;
--};
--
--
++#define CARD_DESC_MAGIC 0xca9dde5c
++
++struct card_desc_struct {
++ struct list_head card_list;
++ u32 magic;
++ xbus_t *xbus;
++ byte rev; /* Revision number */
++ byte type; /* LSB: 1 - to_phone, 0 - to_line */
++ xpd_addr_t xpd_addr;
+ };
+
+
+/*
+ * An xbus is a transport layer for Xorcom Protocol commands
+ */
struct xbus {
- char busname[XBUS_NAMELEN]; /* only xbus_new set this */
- char busdesc[XBUS_DESCLEN]; /* lowlevel drivers set this */
- int num;
- xbus_ops_t *ops;
- struct xpd *xpds[MAX_XPDS];
-+ int max_packet_size;
-+
-+ /* Device-Model */
-+ struct device the_bus;
+- char busname[XBUS_NAMELEN]; /* only xbus_new set this */
+- char busdesc[XBUS_DESCLEN]; /* lowlevel drivers set this */
+- int num;
+- xbus_ops_t *ops;
+- struct xpd *xpds[MAX_XPDS];
++ char busname[XBUS_NAMELEN]; /* only xbus_new set this */
++ char busdesc[XBUS_DESCLEN]; /* lowlevel drivers set this */
++ int num;
++ xbus_ops_t *ops;
++ struct xpd *xpds[MAX_XPDS];
++ int max_packet_size;
- /* Simulator data */
- xbus_type_t bus_type;
+- /* Simulator data */
+- xbus_type_t bus_type;
-#if SOFT_SIMULATOR
- struct xpd_sim sim[MAX_XPDS];
- struct workqueue_struct *sim_workqueue;
- struct work_struct sim_work; // workqueue job for running simulator
- packet_queue_t sim_packet_queue;
-#endif
++ /* Device-Model */
++ struct device the_bus;
- spinlock_t lock;
+- spinlock_t lock;
++ /* Simulator data */
++ xbus_type_t bus_type;
-@@ -170,10 +166,6 @@
- int num_xpds;
- void *priv; /* Pointer to transport level data structures */
+- bool hardware_exists; /* Hardware is functional */
+- int open_counter; /* Number of open channels */
+- atomic_t packet_counter; /* Allocated packets */
+- wait_queue_head_t packet_cache_empty;
+-
+- struct timer_list poll_timer;
+- struct rw_semaphore in_use;
+- int num_xpds;
+- void *priv; /* Pointer to transport level data structures */
++ spinlock_t lock;
-#ifdef XPP_PACKET_LOG
- struct cyclic_buff *packet_log;
-#endif
--
++ bool hardware_exists; /* Hardware is functional */
++ int open_counter; /* Number of open channels */
++ atomic_t packet_counter; /* Allocated packets */
++ wait_queue_head_t packet_cache_empty;
++
++ struct timer_list poll_timer;
++ /*
++ * Bus scanning
++ */
++ atomic_t count_poll_answers;
++ struct list_head poll_results;
++ wait_queue_head_t wait_for_polls;
++ struct work_struct xpds_init_work;
++ struct completion xpds_initialized;
++
++ struct rw_semaphore in_use;
++ int num_xpds;
++ void *priv; /* Pointer to transport level data structures */
+
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_xbus_dir;
struct proc_dir_entry *proc_xbus_summary;
-@@ -181,7 +173,6 @@
++ struct proc_dir_entry *proc_xbus_waitfor_xpds;
+ #endif
/* statistics */
int counters[XBUS_COUNTER_MAX];
@@ -8125,7 +8573,7 @@
};
#endif
-@@ -190,15 +181,11 @@
+@@ -190,15 +187,11 @@
TO_PSTN = 1,
} xpd_direction_t;
@@ -8144,7 +8592,7 @@
enum {
XPD_N_PCM_READ,
XPD_N_PCM_WRITE,
-@@ -222,55 +209,69 @@
+@@ -222,60 +215,74 @@
#define XPD_COUNTER_MAX (sizeof(xpd_counters)/sizeof(xpd_counters[0]))
@@ -8181,7 +8629,7 @@
xpd_type_t type;
+ byte revision; /* Card revision */
xpd_direction_t direction; /* TO_PHONE, TO_PSTN */
- xpp_line_t enabled_chans; /* hardware activation: 0 - off, 1 - on */
+- xpp_line_t enabled_chans; /* hardware activation: 0 - off, 1 - on */
- xpp_line_t hookstate; /* 0 - ONHOOK, 1 - OFHOOK */
- xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */
+ xpp_line_t no_pcm; /* Temporary: disable PCM (for USB-1) */
@@ -8199,13 +8647,13 @@
+
+ wait_queue_head_t txstateq[CHANNELS_PERXPD]; /* waiting on the tx state to change */
+ int delay_until_dialtone[CHANNELS_PERXPD];
-+
+
+- struct work_struct xpd_post_init;
+- xbus_t *xbus;
+ enum fxs_state lasttxhook[CHANNELS_PERXPD];
+ int idletxhookstate[CHANNELS_PERXPD]; /* IDLE changing hook state */
+ int ohttimer[CHANNELS_PERXPD];
-
-- struct work_struct xpd_post_init;
-- xbus_t *xbus;
++
+ xbus_t *xbus; /* The XBUS we are connected to */
spinlock_t lock;
@@ -8236,23 +8684,25 @@
unsigned int recv_errors;
unsigned int seq_errors;
-@@ -285,6 +286,13 @@
+ unsigned long last_response; /* in jiffies */
+ unsigned id;
++ xpd_addr_t addr;
+ struct list_head xpd_list;
+ unsigned int timer_count;
+ volatile u_char *writechunk; /* Double-word aligned write memory */
+@@ -285,6 +292,9 @@
u_char ec_chunk2[CHANNELS_PERXPD][ZT_CHUNKSIZE];
};
+#define for_each_line(xpd,i) \
+ for((i) = 0; (i) < (xpd)->channels; (i)++)
+
-+#define for_each_enabled_line(xpd,i) \
-+ for((i) = 0; (i) < (xpd)->channels; (i)++) \
-+ if(IS_SET((xpd)->enabled_chans,(i)))
-+
#endif
#endif /* XPD_H */
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_fxloader zaptel-xpp-8WuH7d_dist/xpp/xpp_fxloader
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_fxloader zaptel-xpp-oaIQ8i_dist/xpp/xpp_fxloader
--- zaptel-1.2.6/xpp/xpp_fxloader 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/xpp_fxloader 1970-01-01 02:00:00.000000000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/xpp_fxloader 1970-01-01 02:00:00.000000000 +0200
@@ -1,24 +0,0 @@
-#!/bin/sh
-
@@ -8278,15 +8728,15 @@
- fxload -t fx2 -D "$DEVICE" -I "$FIRMWARE" || exit 1
-fi
-
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_fxloader.usermap zaptel-xpp-8WuH7d_dist/xpp/xpp_fxloader.usermap
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_fxloader.usermap zaptel-xpp-oaIQ8i_dist/xpp/xpp_fxloader.usermap
--- zaptel-1.2.6/xpp/xpp_fxloader.usermap 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/xpp_fxloader.usermap 1970-01-01 02:00:00.000000000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/xpp_fxloader.usermap 1970-01-01 02:00:00.000000000 +0200
@@ -1,2 +0,0 @@
-# module match_flags idVendor idProduct bcdDevice_lo bcdDevice_hi bDeviceClass bDeviceSubClass bDeviceProtocol bInterfaceClass bInterfaceSubClass bInterfaceProtocol driver_info
-xpp_fxloader 0x0003 0x04b4 0x8613 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_modprobe zaptel-xpp-8WuH7d_dist/xpp/xpp_modprobe
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_modprobe zaptel-xpp-oaIQ8i_dist/xpp/xpp_modprobe
--- zaptel-1.2.6/xpp/xpp_modprobe 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/xpp_modprobe 1970-01-01 02:00:00.000000000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/xpp_modprobe 1970-01-01 02:00:00.000000000 +0200
@@ -1,10 +0,0 @@
-# Some debugging options for the brave of heart:
-#options zaptel debug=1
@@ -8298,9 +8748,9 @@
-
-# For auto loading of card modules
-alias xpd-type-3 xpd_fxs
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_proto.c zaptel-xpp-8WuH7d_dist/xpp/xpp_proto.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_proto.c zaptel-xpp-oaIQ8i_dist/xpp/xpp_proto.c
--- zaptel-1.2.6/xpp/xpp_proto.c 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/xpp_proto.c 1970-01-01 02:00:00.000000000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/xpp_proto.c 1970-01-01 02:00:00.000000000 +0200
@@ -1,1044 +0,0 @@
-#include <linux/module.h>
-#include <linux/delay.h> /* for udelay */
@@ -9346,9 +9796,9 @@
-EXPORT_SYMBOL(packet_receive);
-EXPORT_SYMBOL(proc_xpd_slic_read);
-EXPORT_SYMBOL(proc_xpd_slic_write);
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_proto.h zaptel-xpp-8WuH7d_dist/xpp/xpp_proto.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_proto.h zaptel-xpp-oaIQ8i_dist/xpp/xpp_proto.h
--- zaptel-1.2.6/xpp/xpp_proto.h 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/xpp_proto.h 1970-01-01 02:00:00.000000000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/xpp_proto.h 1970-01-01 02:00:00.000000000 +0200
@@ -1,188 +0,0 @@
-#ifndef XPP_PROTO_H
-#define XPP_PROTO_H
@@ -9538,9 +9988,9 @@
-#endif
-
-#endif /* XPP_PROTO_H */
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_usb.c zaptel-xpp-8WuH7d_dist/xpp/xpp_usb.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_usb.c zaptel-xpp-oaIQ8i_dist/xpp/xpp_usb.c
--- zaptel-1.2.6/xpp/xpp_usb.c 2006-04-03 10:08:13.000000000 +0300
-+++ zaptel-xpp-8WuH7d_dist/xpp/xpp_usb.c 2006-05-01 18:45:04.050100000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/xpp_usb.c 2006-07-04 17:49:04.495340000 +0300
@@ -1,6 +1,6 @@
/*
* Written by Oron Peled <oron at actcom.co.il>
@@ -9572,7 +10022,7 @@
+#endif
-static const char revision[] = "$Revision: 995 $";
-+static const char rcsid[] = "$Id: xpp_usb.c 1104 2006-05-01 15:45:04Z oron $";
++static const char rcsid[] = "$Id: xpp_usb.c 1576 2006-07-04 14:49:04Z oron $";
DEF_PARM(int, print_dbg, 0, "Print DBG statements"); /* must be before zap_debug.h */
@@ -9602,10 +10052,12 @@
};
static int xusb_packet_send(xbus_t *xbus, xpacket_t *pack);
-@@ -110,18 +115,22 @@
+@@ -110,18 +115,24 @@
#define XUSB_COUNTER_MAX ARRAY_SIZE(xusb_counters)
++#define MAX_PENDING_WRITES 100
++
+enum xusb_dir {
+ XUSB_RECV = 0,
+ XUSB_SEND = 1,
@@ -9628,8 +10080,11 @@
struct urb *read_urb;
-@@ -131,10 +140,10 @@
+@@ -129,12 +140,13 @@
+
+ int present; /* if the device is not disconnected */
int reading; /* is the read_urb reading (listening) */
++ atomic_t pending_writes; /* submited but not out yet */
struct semaphore sem; /* locks this structure */
int counters[XUSB_COUNTER_MAX];
-};
@@ -9641,7 +10096,7 @@
static unsigned bus_count = 0;
-@@ -153,7 +162,7 @@
+@@ -153,7 +165,7 @@
static void xusb_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
#endif
static void xpp_urb_delete(struct urb *urb);
@@ -9650,7 +10105,7 @@
static void xpp_send_callback(struct urb *urb, struct pt_regs *regs);
static void xpp_receive_callback(struct urb *urb, struct pt_regs *regs);
-@@ -208,42 +217,34 @@
+@@ -208,42 +220,34 @@
//DBG("Decremented packet_counter of bus %s (freed packet) to %d\n",
// xbus->busname, atomic_read(&xbus->packet_counter));
}
@@ -9693,11 +10148,11 @@
- if(pack->content.opcode == XPROTO_NAME(GLOBAL,PCM_WRITE)) {
- XUSB_COUNTER(xusb, PCM_WRITES)++;
+#else
-
++
+static void packet_debug(const char msg[], xusb_t *xusb, xpacket_t *pack)
+{
+ char title[XBUS_DESCLEN];
-+
+
+ if(pack->content.opcode == XPROTO_NAME(GLOBAL,PCM_READ)) {
+#ifdef DEBUG_PCM_TIMING
+ /*
@@ -9716,7 +10171,7 @@
#ifdef DEBUG_PCM_TIMING
/*
* DEBUG: high-res timing of PCM_READ to PCM_WRITE
-@@ -253,50 +254,88 @@
+@@ -253,50 +257,96 @@
#endif
#if 0
static int rate_limit;
@@ -9790,6 +10245,14 @@
}
- return 0;
-error:
++ atomic_inc(&xusb->pending_writes);
++ if(atomic_read(&xusb->pending_writes) > MAX_PENDING_WRITES) {
++ static int rate_limit;
++
++ if((rate_limit++ % 1000) < 10)
++ ERR("%s: %s: more than %d pending writes. Dropping.\n", __FUNCTION__, xbus->busname, MAX_PENDING_WRITES);
++ ret = -ENODEV;
++ }
+ if(pack->content.opcode == XPROTO_NAME(GLOBAL,PCM_WRITE))
+ XUSB_COUNTER(xusb, PCM_WRITES)++;
+out:
@@ -9822,7 +10285,7 @@
struct urb *urb;
unsigned char *buffer; /* the buffer to send data */
unsigned int epnum = ep_addr & USB_ENDPOINT_NUMBER_MASK;
-@@ -304,6 +343,8 @@
+@@ -304,6 +354,8 @@
? usb_rcvbulkpipe(udev, epnum)
: usb_sndbulkpipe(udev, epnum);
@@ -9831,7 +10294,7 @@
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
err("No free urbs available");
-@@ -326,30 +367,40 @@
+@@ -326,32 +378,36 @@
usb_free_urb(urb);
return NULL;
}
@@ -9873,16 +10336,14 @@
-// { USB_DEVICE(0x04B4, 0x1004), .driver_info=(int)&model_table[1] }, // FPGA_bulkloop.hex
-// { USB_DEVICE(0x04B4, 0x1004), .driver_info=(int)&model_table[2] }, // FIXME: temporary test for Dima
- { USB_DEVICE(0xE4E4, 0x2211), .driver_info=(int)&model_table[2] }, // FPGA_XPD.hex
-+ { USB_DEVICE(0x0547, 0x1002), .driver_info=(kernel_ulong_t)&model_table[0] }, // bulkloop.hex
-+// { USB_DEVICE(0x04B4, 0x1004), .driver_info=(kernel_ulong_t)&model_table[1] }, // FPGA_bulkloop.hex
-+// { USB_DEVICE(0x04B4, 0x1004), .driver_info=(kernel_ulong_t)&model_table[2] }, // FIXME: temporary test for Dima
+- //{ USB_DEVICE(0x0548, 0x1) },
+- //{ USB_DEVICE(0x062a, 0x0) },
+ { USB_DEVICE(0xE4E4, 0x2211), .driver_info=(kernel_ulong_t)&model_table[2] }, // FPGA_XPD.hex
+ { USB_DEVICE(0xE4E4, 0x1132), .driver_info=(kernel_ulong_t)&model_table[2] }, // FPGA_XPD.hex
-+// { USB_DEVICE(0x04B4, 0x1004), .driver_info=(kernel_ulong_t)&model_table[2] }, // TEST ONLY
- //{ USB_DEVICE(0x0548, 0x1) },
- //{ USB_DEVICE(0x062a, 0x0) },
/* "Gadget Zero" firmware runs under Linux */
-@@ -363,7 +414,7 @@
+ //{ USB_DEVICE(0x0525, 0xa4a0) },
+ { } /* Terminating entry */
+@@ -363,7 +419,7 @@
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver xusb_driver = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
@@ -9891,7 +10352,7 @@
#endif
.name = "xpp_usb",
.probe = xusb_probe,
-@@ -412,10 +463,12 @@
+@@ -412,10 +468,12 @@
* check out the endpoints
* FIXME: Should be simplified (above 2.6.10) to use usb_dev->ep_in[0..16] and usb_dev->ep_out[0..16]
*/
@@ -9905,7 +10366,7 @@
int i;
iface_desc = &interface->altsetting[0];
-@@ -425,37 +478,40 @@
+@@ -425,37 +483,40 @@
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
@@ -9961,7 +10422,7 @@
return 1;
}
-@@ -468,10 +524,11 @@
+@@ -468,10 +529,11 @@
static int xusb_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(interface);
@@ -9976,7 +10437,7 @@
unsigned long flags;
int retval = -ENOMEM;
int i;
-@@ -490,13 +547,13 @@
+@@ -490,15 +552,16 @@
}
/* allocate memory for our device state and initialize it */
@@ -9991,8 +10452,11 @@
+ memset(xusb, 0, sizeof(xusb_t));
init_MUTEX (&xusb->sem);
++ atomic_set(&xusb->pending_writes, 0);
xusb->udev = udev;
-@@ -507,12 +564,14 @@
+ xusb->interface = interface;
+ xusb->model_info = model_info;
+@@ -507,12 +570,14 @@
retval = -ENODEV;
goto probe_failed;
}
@@ -10008,7 +10472,7 @@
/* allow device read, write and ioctl */
xusb->present = 1;
-@@ -521,7 +580,7 @@
+@@ -521,7 +586,7 @@
retval = usb_register_dev (interface, &xusb_class);
if (retval) {
/* something prevented us from registering this driver */
@@ -10017,7 +10481,7 @@
goto probe_failed;
}
-@@ -531,33 +590,31 @@
+@@ -531,33 +596,31 @@
INFO ("USB XPP device now attached to minor %d\n", xusb->minor);
/* Allocate high level structures */
@@ -10054,7 +10518,7 @@
DBG("GOT XPP USB BUS #%d: %s (type=%d)\n", i, xbus->busdesc, xbus->bus_type);
-@@ -568,7 +625,6 @@
+@@ -568,20 +631,22 @@
DBG("Creating proc entry " PROC_USBXPP_SUMMARY " in bus proc dir.\n");
procsummary = create_proc_read_entry(PROC_USBXPP_SUMMARY, 0444, xbus->proc_xbus_dir,
xusb_read_proc, xusb);
@@ -10062,9 +10526,10 @@
if (!procsummary) {
ERR("Failed to create proc read entry for xbus %s\n", xbus->busname);
// FIXME: better error handling
-@@ -576,12 +632,14 @@
+ retval = -EIO;
goto probe_failed;
}
++ procsummary->owner = THIS_MODULE;
#endif
+ bus_count++;
retval = usb_submit_urb(xusb->read_urb, GFP_ATOMIC);
@@ -10079,7 +10544,7 @@
return retval;
probe_failed:
ERR("Failed to initialize xpp usb bus: %d\n", retval);
-@@ -593,6 +651,13 @@
+@@ -593,6 +658,13 @@
usb_deregister_dev(interface, &xusb_class);
kfree(xusb);
}
@@ -10093,7 +10558,7 @@
return retval;
}
-@@ -609,7 +674,7 @@
+@@ -609,7 +681,7 @@
*/
static void xusb_disconnect(struct usb_interface *interface)
{
@@ -10102,7 +10567,7 @@
xbus_t *xbus;
int minor;
int i;
-@@ -636,7 +701,7 @@
+@@ -636,7 +708,7 @@
}
#endif
xusb->present = 0;
@@ -10111,7 +10576,7 @@
down (&xusb->sem);
-@@ -645,6 +710,7 @@
+@@ -645,6 +717,7 @@
/* give back our minor */
usb_deregister_dev (interface, &xusb_class);
@@ -10119,7 +10584,7 @@
/* terminate an ongoing write */
// FIXME: Does it really kill pending URB's?
-@@ -657,12 +723,12 @@
+@@ -657,59 +730,71 @@
kfree(xusb);
up (&disconnect_sem);
@@ -10134,7 +10599,8 @@
xbus_t *xbus = xusb->xbus;
BUG_ON(!xbus);
-@@ -670,7 +736,7 @@
++ atomic_dec(&xusb->pending_writes);
+ /* sync/async unlink faults aren't errors */
if (urb->status && !(urb->status == -ENOENT || urb->status == -ECONNRESET)) {
static int rate_limit;
if((rate_limit++ % 1000) < 10)
@@ -10142,8 +10608,15 @@
+ DBG("nonzero read bulk status received: %d\n", urb->status);
XUSB_COUNTER(xusb, TX_ERRORS)++;
}
++ xpp_urb_delete(urb);
if(!xusb->present) {
-@@ -684,32 +750,43 @@
+ ERR("A packet from non-connected device?\n");
+ return;
+ }
+- xpp_urb_delete(urb);
+ /* allow device read, write and ioctl */
+ XUSB_COUNTER(xusb, TX_PACKETS)++;
+ }
static void xpp_receive_callback(struct urb *urb, struct pt_regs *regs)
{
@@ -10204,7 +10677,7 @@
}
pack = xbus->ops->packet_new(xbus, GFP_ATOMIC);
if(!pack) {
-@@ -723,42 +800,21 @@
+@@ -723,42 +808,21 @@
pack->datalen = size - sizeof(xpd_addr_t) - 1; // opcode size
// DBG("datalen of new packet: %d\n", pack->datalen);
@@ -10259,7 +10732,7 @@
}
}
-@@ -768,14 +824,14 @@
+@@ -768,14 +832,14 @@
int __init xpp_usb_init(void)
{
int result;
@@ -10277,7 +10750,7 @@
return result;
}
return 0;
-@@ -784,34 +840,7 @@
+@@ -784,34 +848,7 @@
void __exit xpp_usb_cleanup(void)
{
@@ -10312,7 +10785,7 @@
/* deregister this driver with the USB subsystem */
usb_deregister(&xusb_driver);
}
-@@ -822,30 +851,29 @@
+@@ -822,31 +859,31 @@
static int xusb_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
{
@@ -10352,9 +10825,11 @@
+ xusb->endpoints[XUSB_SEND].ep_addr,
+ xusb->endpoints[XUSB_SEND].max_size
);
++ len += sprintf(page + len, "\npending_writes=%d\n", atomic_read(&xusb->pending_writes));
#ifdef DEBUG_PCM_TIMING
len += sprintf(page + len, "\nstamp_last_pcm_read=%lld accumulate_diff=%lld\n", stamp_last_pcm_read, accumulate_diff);
-@@ -878,7 +906,7 @@
+ #endif
+@@ -878,7 +915,7 @@
MODULE_DESCRIPTION("XPP USB Driver");
MODULE_AUTHOR("Oron Peled <oron at actcom.co.il>");
MODULE_LICENSE("GPL");
@@ -10363,10 +10838,10 @@
module_init(xpp_usb_init);
module_exit(xpp_usb_cleanup);
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_zap.c zaptel-xpp-8WuH7d_dist/xpp/xpp_zap.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_zap.c zaptel-xpp-oaIQ8i_dist/xpp/xpp_zap.c
--- zaptel-1.2.6/xpp/xpp_zap.c 2006-04-03 10:08:13.000000000 +0300
-+++ zaptel-xpp-8WuH7d_dist/xpp/xpp_zap.c 2006-06-27 19:12:43.273949228 +0300
-@@ -33,40 +33,34 @@
++++ zaptel-xpp-oaIQ8i_dist/xpp/xpp_zap.c 2006-07-08 03:48:48.529239179 +0300
+@@ -33,245 +33,64 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
@@ -10382,7 +10857,7 @@
#include "xpp_zap.h"
-static char revision[] = "$Revision: 995 $";
-+static const char rcsid[] = "$Id: xpp_zap.c 1435 2006-06-22 10:07:06Z oron $";
++static const char rcsid[] = "$Id: xpp_zap.c 1588 2006-07-06 11:10:00Z tzafrir $";
#ifdef CONFIG_PROC_FS
-struct proc_dir_entry *xpp_procdir = NULL;
@@ -10413,33 +10888,35 @@
+static xpd_t *sync_master = NULL; // Start with host based sync
static unsigned int xpp_timer_count = 0;
static unsigned int xpp_last_jiffies = 0;
- struct workqueue_struct *xpp_worker = NULL;
-@@ -75,203 +69,35 @@
+-struct workqueue_struct *xpp_worker = NULL;
+-
+-static LIST_HEAD(xpd_list);
DEF_PARM(int, print_dbg, 0, "Print DBG statements");
DEF_PARM(int, max_queue_len, MAX_QUEUE_LEN, "Maximum Queue Length.");
-DEF_PARM(int, xbus_err_disable_bus, 1000, "Number of errors needed to disable bus");
- DEF_PARM(int, ignore_xpds, 0, "a bitmask of xpd numbers to ignore");
+-DEF_PARM(int, ignore_xpds, 0, "a bitmask of xpd numbers to ignore");
-#ifdef SOFT_SIMULATOR
-DEF_PARM(ulong, softloop_xpds, 0, "a bitmask of software xpd numbers");
-#endif
-+DEF_PARM(int, xbus_err_disable_bus, 1000, "Number of errors needed to disable bus"); // FIXME: unused now.
- DEF_PARM(ulong, pcm_gen, 0, "a bitmask of line numbers for hardware tone generator");
+-DEF_PARM(ulong, pcm_gen, 0, "a bitmask of line numbers for hardware tone generator");
+-
+-DEF_ARRAY(ulong, enabled_channels, MAX_XPDS, ~0, "Enabled channels for each xpd");
+DEF_PARM(bool, have_sync_bus, 0, "True if all Astribank(TM) devices are connected via a sync-cable");
+DEF_PARM(bool, zap_autoreg, 1, "Register spans automatically (1) or not (0)");
- DEF_ARRAY(ulong, enabled_channels, MAX_XPDS, ~0, "Enabled channels for each xpd");
-
#include "zap_debug.h"
--
+#ifdef XPP_EC_CHUNK
+#include "supress/ec_xpp.h"
+#endif
- static int xpd_zaptel_register(xpd_t *xpd);
- static int xpd_zaptel_unregister(xpd_t *xpd);
+
+-static int xpd_zaptel_register(xpd_t *xpd);
+-static int xpd_zaptel_unregister(xpd_t *xpd);
-static void xbus_remove(xbus_t *xbus);
-static void xpd_blink_leds(xpd_t *xpd);
++static int zaptel_register_xpd(xpd_t *xpd);
++static int zaptel_unregister_xpd(xpd_t *xpd);
static void xpp_ring_generate(xpd_t *xpd);
static void xpp_transmitprep(xpd_t *xpd);
static void xpp_receiveprep(xpd_t *xpd);
@@ -10627,7 +11104,7 @@
for(i = 0; i < MAX_BUSES; i++) {
xbus_t *xbus = xbus_of(i);
if(!xbus)
-@@ -279,21 +105,26 @@
+@@ -279,21 +98,26 @@
if (!xbus->hardware_exists)
continue;
for(j = 0; j < MAX_XPDS; j++) {
@@ -10662,7 +11139,7 @@
external_sync(NULL);
if(!timer_pending(&xpp_timer)) {
xpp_timer.function = xpp_tick;
-@@ -301,10 +132,6 @@
+@@ -301,10 +125,6 @@
xpp_timer.expires = jiffies + 1; /* Must be 1KHz rate */
add_timer(&xpp_timer);
}
@@ -10673,7 +11150,7 @@
}
}
-@@ -337,42 +164,45 @@
+@@ -337,43 +157,49 @@
continue;
if (!xbus->hardware_exists)
continue;
@@ -10722,17 +11199,23 @@
return;
xbus = xpd->xbus;
- xpd_card_disable(xpd);
++ if(!xbus)
++ return;
DBG("%s/%s\n", xbus->busname, xpd->xpdname);
++ xbus_unregister_xpd(xbus, xpd);
#ifdef CONFIG_PROC_FS
if(xpd->proc_xpd_dir) {
-@@ -391,109 +221,145 @@
+ if(xpd->proc_xpd_summary) {
+@@ -391,109 +217,149 @@
xpd->proc_xpd_dir = NULL;
}
#endif
+ if(xpd->writechunk)
+ kfree((void *)xpd->writechunk);
++ xpd->writechunk = NULL;
+ if(xpd->xproto)
+ xproto_put(xpd->xproto);
++ xpd->xproto = NULL;
+ kfree(xpd);
}
@@ -10797,14 +11280,13 @@
-void xbus_enqueue_packet(xbus_t *xbus, packet_queue_t *q, xpacket_t *pack)
+/*
+ * Synchronous part of XPD detection.
-+ * Called from xpp_worker workqueue.
++ * Called from xbus_poll()
+ */
-+void card_detected(void *data)
++void card_detected(struct card_desc_struct *card_desc)
{
- unsigned long flags;
-
- spin_lock_irqsave(&q->lock, flags);
-+ struct card_desc_struct *card_desc = (struct card_desc_struct *)data;
+ xbus_t *xbus;
+ xpd_t *xpd = NULL;
+ int xpd_num;
@@ -10823,22 +11305,24 @@
+ BUG_ON(!card_desc);
+ BUG_ON(card_desc->magic != CARD_DESC_MAGIC);
+ xbus = card_desc->xbus;
-+ xpd_num = card_desc->xpd_num;
++ xpd_num = xpd_addr2num(&card_desc->xpd_addr);
+ type = card_desc->type;
+ rev = card_desc->rev;
+ BUG_ON(!xbus);
+ if(!good_rev(rev)) {
-+ NOTICE("%s: New XPD #%d type=%d has bad firmware revision %d.%d\n", xbus->busname,
-+ xpd_num, type, rev / 10, rev % 10);
++ NOTICE("%s: New XPD #%d (%d-%d) type=%d has bad firmware revision %d.%d\n", xbus->busname,
++ xpd_num, card_desc->xpd_addr.unit, card_desc->xpd_addr.subunit,
++ type, rev / 10, rev % 10);
+ goto err;
+ }
-+ INFO("%s: New XPD #%d type=%d Revision %d.%d\n", xbus->busname,
-+ xpd_num, type, rev / 10, rev % 10);
++ INFO("%s: New XPD #%d (%d-%d) type=%d Revision %d.%d\n", xbus->busname,
++ xpd_num, card_desc->xpd_addr.unit, card_desc->xpd_addr.subunit,
++ type, rev / 10, rev % 10);
+ xpd = xpd_of(xbus, xpd_num);
+ if(xpd) {
+ if(type == XPD_TYPE_NOMODULE) {
+ NOTICE("%s: xpd #%d: removed\n", __FUNCTION__, xpd_num);
-+ xpd_disconnect(xpd);
++ BUG();
+ goto out;
}
- q->overflows++;
@@ -10891,13 +11375,14 @@
+ NOTICE("card_new(%s,%d,%d,%d) failed. Ignored.\n", xbus->busname, xpd_num, proto_table->type, rev);
+ goto err;
+ }
++ xpd->addr = card_desc->xpd_addr;
+
+ /* For USB-1 disable some channels */
+ if(xbus->max_packet_size < RPACKET_SIZE(GLOBAL, PCM_WRITE)) {
+ xpp_line_t no_pcm;
+
+ no_pcm = 0x7F | xpd->digital_outputs | xpd->digital_inputs;
-+ xpd->no_pcm = no_pcm & xpd->enabled_chans;
++ xpd->no_pcm = no_pcm;
+ NOTICE("%s: max packet size = %d, disabling some PCM channels. no_pcm=0x%04X\n",
+ xbus->busname, xbus->max_packet_size, xpd->no_pcm);
+ }
@@ -10914,28 +11399,28 @@
+ ERR("Failed to create proc '%s' for %s/%s\n", PROC_XPD_SUMMARY, xbus->busname, xpd->xpdname);
+ goto err;
+ }
++ xpd->proc_xpd_summary->owner = THIS_MODULE;
+ xpd->proc_xpd_ztregister = create_proc_entry(PROC_XPD_ZTREGISTER, 0644, xpd->proc_xpd_dir);
+ if (!xpd->proc_xpd_ztregister) {
+ ERR("Failed to create proc '%s' for %s/%s\n", PROC_XPD_ZTREGISTER, xbus->busname, xpd->xpdname);
+ goto err;
+ }
++ xpd->proc_xpd_ztregister->owner = THIS_MODULE;
+ xpd->proc_xpd_ztregister->data = xpd;
+ xpd->proc_xpd_ztregister->read_proc = proc_xpd_ztregister_read;
+ xpd->proc_xpd_ztregister->write_proc = proc_xpd_ztregister_write;
+#endif
++ xbus_register_xpd(xbus, xpd);
+ if(CALL_XMETHOD(card_init, xbus, xpd) < 0)
+ goto err;
-+ list_add(&xpd->xpd_list, &xpd_list);
-+ xbus->xpds[xpd->id] = xpd;
-+ xbus->num_xpds++;
+ // Turn off all channels
+ CALL_XMETHOD(CHAN_ENABLE, xbus, xpd, ~0, 0);
+ xpd->card_present = 1;
-+ // Turn on enabled channels
-+ CALL_XMETHOD(CHAN_ENABLE, xbus, xpd, xpd->enabled_chans, 1);
++ // Turn on all channels
++ CALL_XMETHOD(CHAN_ENABLE, xbus, xpd, ALL_LINES, 1);
+
+ if(zap_autoreg)
-+ xpd_zaptel_register(xpd);
++ zaptel_register_xpd(xpd);
out:
- spin_unlock_irqrestore(&q->lock, flags);
- return pack;
@@ -10953,7 +11438,7 @@
#ifdef CONFIG_PROC_FS
/**
-@@ -510,83 +376,82 @@
+@@ -510,83 +376,78 @@
int len = 0;
xpd_t *xpd = data;
xbus_t *xbus;
@@ -10985,11 +11470,10 @@
xpd->timer_count, xpd->span.mainttimer
);
len += sprintf(page + len, "STATES:");
- len += sprintf(page + len, "\n\t%-17s: ", "enabled");
+- len += sprintf(page + len, "\n\t%-17s: ", "enabled");
- for(i = 0; i < channels; i++) {
-+ for_each_line(xpd, i) {
- len += sprintf(page + len, "%d ", IS_SET(xpd->enabled_chans, i));
- }
+- len += sprintf(page + len, "%d ", IS_SET(xpd->enabled_chans, i));
+- }
len += sprintf(page + len, "\n\t%-17s: ", "output_relays");
- for(i = 0; i < channels; i++) {
+ for_each_line(xpd, i) {
@@ -11073,7 +11557,7 @@
struct zt_chan *chan = &xpd->span.chans[i];
len += sprintf(page + len, "\t%2d> sigcap=0x%04X sig=0x%04X\n", i, chan->sigcap, chan->sig);
}
-@@ -620,7 +485,9 @@
+@@ -620,10 +481,11 @@
xpd_t *xpd_alloc(size_t privsize, xbus_t *xbus, int xpd_num, const xproto_table_t *proto_table, int channels, byte revision)
{
xpd_t *xpd = NULL;
@@ -11081,9 +11565,13 @@
size_t alloc_size = sizeof(xpd_t) + privsize;
+ int i;
- INFO("New XPD #%d (Revision %d.%d) detected on xbus %s\n",
- xpd_num, revision / 10, revision % 10, xbus->busname);
-@@ -645,14 +512,20 @@
+- INFO("New XPD #%d (Revision %d.%d) detected on xbus %s\n",
+- xpd_num, revision / 10, revision % 10, xbus->busname);
++ DBG("%s: xpd #%d\n", xbus->busname, xpd_num);
+ if(!VALID_XPD_NUM(xpd_num)) {
+ ERR("%s: illegal xpd id = %d\n", __FUNCTION__, xpd_num);
+ goto err;
+@@ -645,14 +507,19 @@
xpd->id = xpd_num;
xpd->channels = channels;
xpd->chans = NULL;
@@ -11094,7 +11582,7 @@
xpd->type = proto_table->type;
+ xpd->xproto = proto_table;
xpd->xops = &proto_table->xops;
- xpd->enabled_chans = enabled_channels[xpd_num];
+- xpd->enabled_chans = enabled_channels[xpd_num];
xpd->digital_outputs = 0;
xpd->digital_inputs = 0;
+
@@ -11105,7 +11593,7 @@
atomic_set(&xpd->open_counter, 0);
xpd->chans = kmalloc(sizeof(struct zt_chan)*xpd->channels, GFP_KERNEL);
-@@ -660,33 +533,47 @@
+@@ -660,33 +527,61 @@
ERR("%s: Unable to allocate channels\n", __FUNCTION__);
goto err;
}
@@ -11142,12 +11630,20 @@
}
-static void xpd_card_disable(xpd_t *xpd)
++/* FIXME: this should be removed once digium patch their zaptel.h
++ * I simply wish to avoid changing zaptel.h in the xpp patches.
++ */
++#ifndef ZT_EVENT_REMOVED
++#define ZT_EVENT_REMOVED (20)
++#endif
++
+void xpd_disconnect(xpd_t *xpd)
{
+ unsigned long flags;
+
BUG_ON(!xpd);
- atomic_set(&xpd->card_present, 0);
+- if(SPAN_REGISTERED(xpd))
+
+ // TODO: elect a new sync master
+ if(sync_master == xpd)
@@ -11158,27 +11654,37 @@
+ if(!xpd->card_present) /* Multiple reports */
+ goto out;
+ xpd->card_present = 0;
- if(SPAN_REGISTERED(xpd))
++ if(SPAN_REGISTERED(xpd)) {
++ int i;
++
update_xpd_status(xpd, ZT_ALARM_NOTOPEN);
++ /* TODO: Should this be done before releasing the spinlock? */
++ DBG("Queuing ZT_EVENT_REMOVED on all channels to ask user to release them\n");
++ for (i=0; i<xpd->span.channels; i++)
++ zt_qevent_lock(&xpd->chans[i],ZT_EVENT_REMOVED);
++ }
+out:
+ spin_unlock_irqrestore(&xpd->lock, flags);
}
void xpd_remove(xpd_t *xpd)
-@@ -696,22 +583,16 @@
+@@ -695,23 +590,14 @@
+
BUG_ON(!xpd);
xbus = xpd->xbus;
- INFO("Remove XPD #%d from xbus=%s\n", xpd->id, xbus->busname);
+- INFO("Remove XPD #%d from xbus=%s\n", xpd->id, xbus->busname);
-#if 0
- // TODO: elect a new sync master
- if(sync_master == xpd)
- set_sync_master(NULL);
-#endif
+- xpd_zaptel_unregister(xpd);
+- xbus->xpds[xpd->id] = NULL;
+- list_del(&xpd->xpd_list);
+- xbus->num_xpds--;
++ INFO("%s: Remove XPD #%d from\n", xbus->busname, xpd->id);
+
- xpd_zaptel_unregister(xpd);
- xbus->xpds[xpd->id] = NULL;
- list_del(&xpd->xpd_list);
- xbus->num_xpds--;
++ zaptel_unregister_xpd(xpd);
CALL_XMETHOD(card_remove, xbus, xpd);
- xpd_cleanup(xpd);
- kfree((void *)xpd->writechunk);
@@ -11191,19 +11697,24 @@
{
struct zt_span *span = &xpd->span;
-@@ -734,80 +615,6 @@
+@@ -734,78 +620,16 @@
DBG("Update XPD alarms: %s -> %02X\n", xpd->span.name, alarm_flag);
}
-void phone_hook(xpd_t *xpd, int channo, bool offhook)
--{
++void update_line_status(xpd_t *xpd, int pos, bool good)
+ {
- struct zt_chan *chan = &xpd->span.chans[channo];
--
++ struct zt_chan *chan;
+
- if(offhook && !IS_SET(xpd->hookstate, channo)) { // OFFHOOK
- DBG("OFFHOOK: channo=%d\n", chan->channo);
- xpd->ringing[channo] = 0;
- BIT_SET(xpd->hookstate, channo);
-- zt_hooksig(chan, ZT_RXSIG_OFFHOOK);
++ BUG_ON(!xpd);
++ chan = &xpd->chans[pos];
++ if(good)
+ zt_hooksig(chan, ZT_RXSIG_OFFHOOK);
- if(!IS_SET(xpd->digital_outputs, channo) && !IS_SET(xpd->digital_inputs, channo)) {
- CALL_XMETHOD(CHAN_POWER, xpd->xbus, xpd, BIT(channo), 0); // Power down (prevent overheating!!!)
- CALL_XMETHOD(LED, xpd->xbus, xpd, BIT(channo), LED_GREEN, 1);
@@ -11212,7 +11723,8 @@
- DBG("ONHOOK channo=%d\n", chan->channo);
- xpd->ringing[channo] = 0;
- BIT_CLR(xpd->hookstate, channo);
-- zt_hooksig(chan, ZT_RXSIG_ONHOOK);
++ else
+ zt_hooksig(chan, ZT_RXSIG_ONHOOK);
- if(!IS_SET(xpd->digital_outputs, channo) && !IS_SET(xpd->digital_inputs, channo)) {
- CALL_XMETHOD(CHAN_POWER, xpd->xbus, xpd, BIT(channo), 0); // Power down (prevent overheating!!!)
- CALL_XMETHOD(LED, xpd->xbus, xpd, BIT(channo), LED_GREEN, 0);
@@ -11267,21 +11779,19 @@
- }
- }
- spin_unlock_irqrestore(&xpd->lock, flags);
--}
--
+ }
+
static void xpp_ring_generate(xpd_t *xpd)
- {
- int i;
-@@ -829,7 +636,7 @@
+@@ -829,7 +653,7 @@
* Ring detect logic:
* fxo_power is toggled
*/
- for(i = 0; i < xpd->channels; i++) {
-+ for_each_enabled_line(xpd, i) {
++ for_each_line(xpd, i) {
if(xpd->ringing[i] || xpd->ringer_on[i]) {
// ring state is only changed once per second:
if((xpd->timer_count % 1000) == 0) {
-@@ -839,10 +646,7 @@
+@@ -839,10 +663,7 @@
} else {
zt_hooksig(&xpd->chans[i], ZT_RXSIG_RING);
}
@@ -11292,7 +11802,7 @@
}
}
}
-@@ -850,98 +654,13 @@
+@@ -850,98 +671,13 @@
spin_unlock_irqrestore(&xpd->lock, flags);
}
@@ -11394,7 +11904,7 @@
len += sprintf(page + len, "# To modify sync source write into this file:\n");
len += sprintf(page + len, "# HOST - For host based sync\n");
-@@ -952,8 +671,8 @@
+@@ -952,8 +688,8 @@
else
len += sprintf(page + len, "%s/%s\n", sync_master->xbus->busname, sync_master->xpdname);
len += sprintf(page + len, "tick: #%d\n", xpp_timer_count);
@@ -11405,7 +11915,7 @@
if(now - xpp_last_jiffies > 0) {
xpp_timer_rate = ((xpp_timer_count % SAMPLE_TICKS) * 1000) / (now - xpp_last_jiffies);
len += sprintf(page + len, "tick rate: %4d/second (average over %d seconds)\n", xpp_timer_rate, SAMPLE_TICKS/HZ);
-@@ -971,7 +690,6 @@
+@@ -971,7 +707,6 @@
static int proc_sync_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
@@ -11413,7 +11923,7 @@
const int NUM_SIZE = 100;
char buf[NUM_SIZE];
int xbus_num;
-@@ -979,31 +697,47 @@
+@@ -979,31 +714,47 @@
xbus_t *xbus;
xpd_t *xpd;
int ret;
@@ -11468,12 +11978,10 @@
out:
return count;
}
-@@ -1048,348 +782,75 @@
- if(ret != 1)
- return -EINVAL;
+@@ -1050,346 +801,73 @@
DBG("%s: %s/%s %s\n", __FUNCTION__,
-- xpd->xbus->busname, xpd->xpdname, (zt_reg) ? "register" : "unregister");
-- if(zt_reg)
+ xpd->xbus->busname, xpd->xpdname, (zt_reg) ? "register" : "unregister");
+ if(zt_reg)
- ret = xpd_zaptel_register(xpd);
- else
- ret = xpd_zaptel_unregister(xpd);
@@ -11690,8 +12198,12 @@
- }
-#endif
- kfree(xbus);
--}
--
++ ret = zaptel_register_xpd(xpd);
++ else
++ ret = zaptel_unregister_xpd(xpd);
++ return (ret < 0) ? ret : count;
+ }
+
-xbus_t *xbus_new(ulong loopback_xpds)
-{
- unsigned long flags;
@@ -11717,14 +12229,7 @@
- xbuses_array[xbus_num] = xbus;
- bus_count++;
- spin_unlock_irqrestore(&xbuses_lock, flags);
-+ xpd->xbus->busname, xpd->xpdname, (zt_reg) ? "register" : "unregister");
-+ if(zt_reg)
-+ ret = xpd_zaptel_register(xpd);
-+ else
-+ ret = xpd_zaptel_unregister(xpd);
-+ return (ret < 0) ? ret : count;
-+}
-
+-
- /* Init data structures */
- spin_lock_init(&xbus->lock);
- snprintf(xbus->busname, XBUS_NAMELEN, "XBUS-%d", xbus_num);
@@ -11875,7 +12380,7 @@
}
-@@ -1407,12 +868,12 @@
+@@ -1407,12 +885,12 @@
int i;
int channels = xpd->channels;
struct zt_chan *chans = xpd->span.chans;
@@ -11890,7 +12395,7 @@
if (xpd->timer_count & 1) {
/* First part */
w = writechunk = xpd->writechunk /* + 1 */;
-@@ -1422,18 +883,26 @@
+@@ -1422,18 +900,26 @@
zt_transmit(&xpd->span);
for (i = 0; i < channels; i++) {
@@ -11921,7 +12426,7 @@
}
void fill_beep(u_char *buf, int duration)
-@@ -1446,20 +915,46 @@
+@@ -1446,20 +932,46 @@
static u_char beep[] = {
// 0x7F, 0xBE, 0xD8, 0xBE, 0x80, 0x41, 0x24, 0x41, /* Dima */
// 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, /* silence */
@@ -11970,7 +12475,7 @@
// if((xpd->timer_count % PREP_REPORT_RATE) == 0)
// DBG("%d\n", xpd->timer_count);
-@@ -1472,20 +967,29 @@
+@@ -1472,20 +984,29 @@
for (i = 0; i < channels; i++) {
if(IS_SET(xpd->hookstate, i)) {
@@ -12001,7 +12506,7 @@
}
static int xpp_startup(struct zt_span *span)
-@@ -1540,13 +1044,18 @@
+@@ -1540,13 +1061,18 @@
spin_lock_irqsave(&xbus->lock, flags);
xbus->open_counter--;
atomic_dec(&xpd->open_counter);
@@ -12021,7 +12526,7 @@
return 0;
}
-@@ -1560,10 +1069,11 @@
+@@ -1560,10 +1086,11 @@
case ZT_ONHOOKTRANSFER:
if (get_user(x, (int *)arg))
return -EFAULT;
@@ -12036,7 +12541,21 @@
}
DBG("xpd=%d: ZT_ONHOOKTRANSFER (%d millis) chan=%d\n", xpd->id, x, pos);
return -ENOTTY;
-@@ -1590,109 +1100,15 @@
+@@ -1574,6 +1101,13 @@
+ xpd->id, pos, (x & ZT_TONEDETECT_ON), (x & ZT_TONEDETECT_MUTE));
+ return -ENOTTY;
+ default:
++ /* Some span-specific commands before we give up: */
++ if (xpd->xops->card_ioctl != NULL) {
++ x = xpd->xops->card_ioctl(xpd, pos, cmd, arg);
++ if (x != -ENOTTY)
++ return x;
++ }
++
+ DBG("ENOTTY: chan=%d cmd=0x%x\n", pos, cmd);
+ DBG(" IOC_TYPE=0x%02X\n", _IOC_TYPE(cmd));
+ DBG(" IOC_DIR=0x%02X\n", _IOC_DIR(cmd));
+@@ -1590,109 +1124,15 @@
xpd_t *xpd = chan->pvt;
xbus_t *xbus;
int pos = chan->chanpos - 1;
@@ -12153,7 +12672,7 @@
static int xpp_sethook(struct zt_chan *chan, int hookstate)
{
-@@ -1701,102 +1117,15 @@
+@@ -1701,102 +1141,15 @@
xbus_t *xbus;
int ret = 0;
@@ -12260,7 +12779,7 @@
/* Req: Set the requested chunk size. This is the unit in which you must
report results for conferencing, etc */
int xpp_setchunksize(struct zt_span *span, int chunksize);
-@@ -1815,7 +1144,6 @@
+@@ -1815,7 +1168,6 @@
switch(cmd) {
case ZT_MAINT_NONE:
printk("XXX Turn off local and remote loops XXX\n");
@@ -12268,7 +12787,7 @@
break;
case ZT_MAINT_LOCALLOOP:
printk("XXX Turn on local loopback XXX\n");
-@@ -1825,12 +1153,10 @@
+@@ -1825,12 +1177,10 @@
break;
case ZT_MAINT_LOOPUP:
printk("XXX Send loopup code XXX\n");
@@ -12281,7 +12800,7 @@
break;
case ZT_MAINT_LOOPSTOP:
printk("XXX Stop sending loop codes XXX\n");
-@@ -1848,8 +1174,7 @@
+@@ -1848,8 +1198,7 @@
/* Set signalling type (if appropriate) */
static int xpp_chanconfig(struct zt_chan *chan, int sigtype)
{
@@ -12291,7 +12810,7 @@
// FIXME: sanity checks:
// - should be supported (within the sigcap)
// - should not replace fxs <->fxo ??? (covered by previous?)
-@@ -1878,6 +1203,29 @@
+@@ -1878,6 +1227,29 @@
int (*sethook)(struct zt_chan *chan, int hookstate);
#endif
@@ -12321,23 +12840,12 @@
#ifdef CONFIG_ZAPTEL_WATCHDOG
/*
* If the watchdog detects no received data, it will call the
-@@ -1893,6 +1241,13 @@
- }
- #endif
-
-+/* FIXME: this should be removed once digium patch their zaptel.h
-+ * I simply wish to avoid changing zaptel.h in the xpp patches.
-+ */
-+#ifndef ZT_EVENT_REMOVED
-+#define ZT_EVENT_REMOVED (20)
-+#endif
-+
- /**
- * Unregister an xpd from zaptel and release related resources
- * @xpd The xpd to be unregistered
-@@ -1906,20 +1261,33 @@
+@@ -1904,33 +1276,40 @@
+ * - User action through /proc
+ * - During xpd_remove()
*/
- static int xpd_zaptel_unregister(xpd_t *xpd)
+-static int xpd_zaptel_unregister(xpd_t *xpd)
++static int zaptel_unregister_xpd(xpd_t *xpd)
{
+ unsigned long flags;
+
@@ -12354,26 +12862,45 @@
+ sync_master_is(NULL); // FIXME: it's better to elect a new prince
update_xpd_status(xpd, ZT_ALARM_NOTOPEN);
if(atomic_read(&xpd->open_counter)) {
-+ int i;
NOTICE("%s: %s is busy (open_counter=%d). Skipping.\n", __FUNCTION__, xpd->xpdname, atomic_read(&xpd->open_counter));
+ spin_unlock_irqrestore(&xpd->lock, flags);
-+ /* TODO: Should this be done before releasing the spinlock? */
-+ DBG("Queuing ZT_EVENT_REMOVED on all channels to ask user to release them\n");
-+ for (i=0; i<xpd->span.channels; i++)
-+ zt_qevent_lock(&xpd->chans[i],ZT_EVENT_REMOVED);
return -EBUSY;
}
mdelay(2); // FIXME: This is to give chance for transmit/receiveprep to finish.
+ spin_unlock_irqrestore(&xpd->lock, flags);
+ if(xpd->card_present)
-+ xpd->xops->card_zaptel_registration(xpd, 0);
++ xpd->xops->card_zaptel_preregistration(xpd, 0);
zt_unregister(&xpd->span);
++ if(xpd->card_present)
++ xpd->xops->card_zaptel_postregistration(xpd, 0);
return 0;
}
-@@ -1952,33 +1320,20 @@
+
+-static int xpd_zaptel_register(xpd_t *xpd)
++static int zaptel_register_xpd(xpd_t *xpd)
+ {
+- struct zt_chan *cur_chan;
+ struct zt_span *span;
+ xbus_t *xbus;
+- int sigfxs;
+- int i;
+ int cn;
+ const xops_t *xops;
+
+@@ -1941,7 +1320,6 @@
+ ERR("xpd %s already registered\n", xpd->xpdname);
+ return -EEXIST;
+ }
+- sigfxs = ! (xpd->direction == TO_PHONE); /* signaling is opposite */
+ cn = xpd->channels;
+ DBG("Initializing span: xpd %d have %d channels.\n", xpd->id, cn);
+
+@@ -1950,59 +1328,7 @@
+
+ span = &xpd->span;
xbus = xpd->xbus;
- snprintf(span->name, MAX_SPANNAME, "%s/%s",
- xbus->busname, xpd->xpdname);
+- snprintf(span->name, MAX_SPANNAME, "%s/%s",
+- xbus->busname, xpd->xpdname);
- {
- char tmp[MAX_SPANNAME];
-#if SOFT_SIMULATOR
@@ -12386,30 +12913,50 @@
- tmp[0] = '\0';
-
- snprintf(span->desc, MAX_SPANDESC, "Xorcom XPD #%d/%d: %s%s",
-+ snprintf(span->desc, MAX_SPANDESC, "Xorcom XPD #%d/%d: %s",
- xbus->num, xpd->id,
+- xbus->num, xpd->id,
- (xpd->direction == TO_PHONE) ? "FXS" : "FXO",
- tmp
-+ (xpd->direction == TO_PHONE) ? "FXS" : "FXO"
- );
+- );
- }
- for(i = 0; i < cn; i++) {
-
- cur_chan = &xpd->chans[i];
- DBG("setting channel %d (sigfxs=%d)\n", i, sigfxs);
- if(IS_SET(xpd->digital_outputs, i)) {
+- for(i = 0; i < cn; i++) {
+-
+- cur_chan = &xpd->chans[i];
+- DBG("setting channel %d (sigfxs=%d)\n", i, sigfxs);
+- if(IS_SET(xpd->digital_outputs, i)) {
- snprintf(cur_chan->name, MAX_CHANNAME, "XPP_OUT/%d-%d", xpd->id, i);
-+ snprintf(cur_chan->name, MAX_CHANNAME, "XPP_OUT/%d/%d/%d", xbus->num, xpd->id, i);
- } else if(IS_SET(xpd->digital_inputs, i)) {
+- } else if(IS_SET(xpd->digital_inputs, i)) {
- snprintf(cur_chan->name, MAX_CHANNAME, "XPP_IN/%d-%d", xpd->id, i);
-+ snprintf(cur_chan->name, MAX_CHANNAME, "XPP_IN/%d/%d/%d", xbus->num, xpd->id, i);
- } else {
+- } else {
- snprintf(cur_chan->name, MAX_CHANNAME, "XPP_%s/%d-%d", (sigfxs) ? "FXO" : "FXS", xpd->id, i);
-+ snprintf(cur_chan->name, MAX_CHANNAME, "XPP_%s/%d/%d/%d", (sigfxs) ? "FXO" : "FXS", xbus->num, xpd->id, i);
- }
- cur_chan->chanpos = i + 1;
- cur_chan->pvt = xpd;
-@@ -2023,6 +1378,9 @@
+- }
+- cur_chan->chanpos = i + 1;
+- cur_chan->pvt = xpd;
+- if (sigfxs)
+- cur_chan->sigcap =
+-#if 1
+- ZT_SIG_FXSKS |
+- ZT_SIG_FXSLS |
+-#else
+- ZT_SIG_SF |
+-#endif
+- 0;
+- else
+- cur_chan->sigcap =
+-#if 1
+- ZT_SIG_FXOKS |
+- ZT_SIG_FXOLS |
+- ZT_SIG_FXOGS |
+-#else
+- ZT_SIG_SF |
+- ZT_SIG_EM |
+-#endif
+- 0;
+- }
++ snprintf(span->name, MAX_SPANNAME, "%s/%s", xbus->busname, xpd->xpdname);
+ span->deflaw = ZT_LAW_MULAW;
+ init_waitqueue_head(&span->maintq);
+ span->pvt = xpd;
+@@ -2023,67 +1349,28 @@
#endif
span->ioctl = xpp_ioctl;
span->maint = xpp_maint;
@@ -12419,14 +12966,24 @@
#ifdef CONFIG_ZAPTEL_WATCHDOG
span->watchdog = xpp_watchdog;
#endif
-@@ -2038,52 +1396,14 @@
- xbus->num_xpds--;
+
+- DBG("Finished span_load: ZT_FLAG_RUNNING=%d\n", span->flags & ZT_FLAG_RUNNING);
+-
+ DBG("Registering span of %s.\n", xpd->xpdname);
++ xpd->xops->card_zaptel_preregistration(xpd, 1);
+ if(zt_register(&xpd->span, 1)) {
+ xbus_t *xbus = xpd->xbus;
+- ERR("Failed to zt_register of span of xpd %s.\n", xpd->xpdname);
+- xbus->xpds[xpd->id] = NULL;
+- list_del(&xpd->xpd_list);
+- xbus->num_xpds--;
++ ERR("%s/%s: Failed to zt_register span\n", xbus->busname, xpd->xpdname);
return -ENODEV;
}
-// if(xpd->id == 0)
-// set_sync_master(xpd);
-
-+ xpd->xops->card_zaptel_registration(xpd, 1);
++ xpd->xops->card_zaptel_postregistration(xpd, 1);
return 0;
}
@@ -12473,7 +13030,7 @@
#if 0
static int xpp_zap_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
-@@ -2097,6 +1417,7 @@
+@@ -2097,6 +1384,7 @@
#define MINOR_XBUS_NUM(m) ((m) >> 4)
#define MINOR_XPD_NUM(m) ((m) & 0xF);
@@ -12481,7 +13038,16 @@
static int xpp_sys_open (struct inode * inode, struct file * file)
{
xbus_t *xbus;
-@@ -2186,6 +1507,7 @@
+@@ -2164,7 +1452,7 @@
+ if (copy_from_user (pack_tx->content.raw, buf, count)) {
+ return -EFAULT;
+ }
+- XPD_ADDR_SET(pack_tx->content.addr, xpdnum);
++ xpd_set_addr(&pack_tx->content.addr, xpdnum);
+ pack_tx->datalen = count;
+ // pack_tx->flags |= XPP_PACKET_FIREANDFORGET;
+ DBG("sending op=%d to %d\n", pack_tx->content.opcode, xpdnum);
+@@ -2186,6 +1474,7 @@
.release = xpp_sys_release,
};
@@ -12489,33 +13055,28 @@
/*------------------------- Initialization -------------------------*/
-@@ -2193,42 +1515,52 @@
+@@ -2193,42 +1482,47 @@
{
if(timer_pending(&xpp_timer))
del_timer_sync(&xpp_timer);
-- unregister_chrdev(XPP_CTL_MAJOR, THIS_MODULE->name);
--#ifdef CONFIG_PROC_FS
++#if 0
+ unregister_chrdev(XPP_CTL_MAJOR, THIS_MODULE->name);
++#endif
+ #ifdef CONFIG_PROC_FS
- remove_proc_entry(PROC_SYNC, xpp_procdir);
- remove_proc_entry(PROC_XBUSES, xpp_procdir);
- if(xpp_procdir) {
-- remove_proc_entry(PROC_DIR, NULL);
++ remove_proc_entry(PROC_SYNC, xpp_proc_toplevel);
++ if(xpp_proc_toplevel) {
+ remove_proc_entry(PROC_DIR, NULL);
+ }
+ #endif
+- if (xpp_worker) {
+- flush_workqueue(xpp_worker);
+- destroy_workqueue(xpp_worker);
+- xpp_worker = NULL;
- }
--#endif
- if (xpp_worker) {
- flush_workqueue(xpp_worker);
- destroy_workqueue(xpp_worker);
- xpp_worker = NULL;
- }
- kmem_cache_destroy(packet_cache);
-+#if 0
-+ unregister_chrdev(XPP_CTL_MAJOR, THIS_MODULE->name);
-+#endif
-+#ifdef CONFIG_PROC_FS
-+ remove_proc_entry(PROC_SYNC, xpp_proc_toplevel);
-+ if(xpp_proc_toplevel) {
-+ remove_proc_entry(PROC_DIR, NULL);
-+ }
-+#endif
}
int __init xpp_zap_init(void)
@@ -12563,7 +13124,7 @@
if(!ent) {
do_cleanup();
return -EFAULT;
-@@ -2236,11 +1568,6 @@
+@@ -2236,67 +1530,42 @@
ent->read_proc = proc_sync_read;
ent->write_proc = proc_sync_write;
ent->data = NULL;
@@ -12573,18 +13134,16 @@
- return -EFAULT;
- }
#endif
- xpp_worker = create_singlethread_workqueue("xppworker");
- if(!xpp_worker) {
-@@ -2248,55 +1575,40 @@
- do_cleanup();
- return -ENOMEM;
- }
+- xpp_worker = create_singlethread_workqueue("xppworker");
+- if(!xpp_worker) {
+- ERR("Failed to create card detector workqueue.\n");
+ ret = xbus_core_init();
+ if(ret) {
+ ERR("xbus_core_init failed (%d)\n", ret);
-+ do_cleanup();
+ do_cleanup();
+- return -ENOMEM;
+ return ret;
-+ }
+ }
+#if 0
if (register_chrdev(XPP_CTL_MAJOR, THIS_MODULE->name, &xpp_fops)) {
@@ -12633,6 +13192,7 @@
+EXPORT_SYMBOL(xpd_disconnect);
EXPORT_SYMBOL(packet_send);
+EXPORT_SYMBOL(update_xpd_status);
++EXPORT_SYMBOL(update_line_status);
EXPORT_SYMBOL(fill_beep);
-EXPORT_SYMBOL(xbus_enqueue_packet);
-EXPORT_SYMBOL(xbus_dequeue_packet);
@@ -12643,7 +13203,7 @@
EXPORT_SYMBOL(xpp_tick);
EXPORT_SYMBOL(xpp_open);
EXPORT_SYMBOL(xpp_close);
-@@ -2306,7 +1618,7 @@
+@@ -2306,7 +1575,7 @@
MODULE_DESCRIPTION("XPP Zaptel Driver");
MODULE_AUTHOR("Oron Peled <oron at actcom.co.il>");
MODULE_LICENSE("GPL");
@@ -12652,10 +13212,10 @@
module_init(xpp_zap_init);
module_exit(xpp_zap_cleanup);
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_zap.h zaptel-xpp-8WuH7d_dist/xpp/xpp_zap.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xpp_zap.h zaptel-xpp-oaIQ8i_dist/xpp/xpp_zap.h
--- zaptel-1.2.6/xpp/xpp_zap.h 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/xpp_zap.h 2006-03-30 12:42:46.619481000 +0200
-@@ -1,37 +1,44 @@
++++ zaptel-xpp-oaIQ8i_dist/xpp/xpp_zap.h 2006-07-02 19:47:41.666262000 +0300
+@@ -1,58 +1,54 @@
#ifndef XPP_ZAP_H
#define XPP_ZAP_H
+/*
@@ -12703,10 +13263,12 @@
-void phone_hook(xpd_t *xpd, int channo, bool offhook);
-void xpp_check_hookstate(xpd_t *xpd, xpp_line_t fxs_off_hook);
-xpd_t *xpd_of(xbus_t *xbus, int xpd_num);
- void card_detected(void *data);
+-void card_detected(void *data);
++void card_detected(struct card_desc_struct *card_desc);
xpd_t *xpd_alloc(size_t privsize, xbus_t *xbus, int xpd_num, const xproto_table_t *proto_table, int channels, byte revision);
void xpd_remove(xpd_t *xpd);
+void update_xpd_status(xpd_t *xpd, int alarm_flag);
++void update_line_status(xpd_t *xpd, int pos, bool good);
void fill_beep(u_char *buf, int duration);
void xpp_tick(unsigned long param);
int xpp_open(struct zt_chan *chan);
@@ -12715,9 +13277,18 @@
int xpp_maint(struct zt_span *span, int cmd);
+void sync_master_is(xpd_t *xpd);
- #define CARD_DESC_MAGIC 0xca9dde5c
+-#define CARD_DESC_MAGIC 0xca9dde5c
+-
+-struct card_desc_struct {
+- struct work_struct work;
+- u32 magic;
+- xbus_t *xbus;
+- byte rev; /* Revision number */
+- byte type; /* LSB: 1 - to_phone, 0 - to_line */
+- byte xpd_num;
+-};
+ extern struct workqueue_struct *xpp_worker;
-@@ -48,11 +55,9 @@
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
@@ -12731,9 +13302,9 @@
+#define SPAN_REGISTERED(xpd) ((xpd)->span.flags & ZT_FLAG_REGISTERED)
#endif /* XPP_ZAP_H */
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xproto.c zaptel-xpp-8WuH7d_dist/xpp/xproto.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xproto.c zaptel-xpp-oaIQ8i_dist/xpp/xproto.c
--- zaptel-1.2.6/xpp/xproto.c 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/xproto.c 2006-06-22 11:31:28.427315000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/xproto.c 2006-07-03 12:11:26.109424000 +0300
@@ -1,6 +1,6 @@
/*
* Written by Oron Peled <oron at actcom.co.il>
@@ -12742,7 +13313,7 @@
*
* All rights reserved.
*
-@@ -23,9 +23,11 @@
+@@ -23,35 +23,36 @@
#include "xpd.h"
#include "xproto.h"
#include "xpp_zap.h"
@@ -12751,11 +13322,45 @@
#include <linux/module.h>
-static const char rcsid[] = "$Id: xproto.c 949 2006-02-15 02:24:18Z kpfleming $";
-+static const char rcsid[] = "$Id: xproto.c 1431 2006-06-22 08:31:28Z oron $";
++static const char rcsid[] = "$Id: xproto.c 1543 2006-07-03 09:11:26Z oron $";
extern int print_dbg;
static int packet_process(xbus_t *xbus, int xpd_num, xpacket_t *pack);
-@@ -75,7 +77,7 @@
+
+ static const xproto_table_t *xprotocol_tables[XPD_TYPE_NOMODULE];
+
++#if MAX_UNIT*MAX_SUBUNIT > MAX_XPDS
++#error MAX_XPDS is too small
++#endif
++
+ bool valid_xpd_addr(const xpd_addr_t *addr)
+ {
+- return ((addr->bank_num & ~0x1) == 0) && ((addr->card_id & ~0x3) == 0);
++ return ((addr->subunit & ~0x1) == 0) && ((addr->unit & ~0x3) == 0);
+ }
+
+ int xpd_addr2num(const xpd_addr_t *addr)
+ {
+ BUG_ON(!valid_xpd_addr(addr));
+- return addr->bank_num * 4 + addr->card_id;
++ return addr->unit + addr->subunit * MAX_UNIT;
+ }
+
+ void xpd_set_addr(xpd_addr_t *addr, int xpd_num)
+ {
+- if(xpd_num < 4) {
+- addr->card_id = xpd_num;
+- addr->bank_num = 0;
+- } else {
+- addr->card_id = xpd_num % 4;
+- addr->bank_num = xpd_num / 4;
+- }
++ addr->unit = xpd_num % MAX_UNIT;
++ addr->subunit = xpd_num / MAX_UNIT;
+ }
+
+
+@@ -75,7 +76,7 @@
return xe;
}
@@ -12764,7 +13369,7 @@
{
return xproto_card_handler(&PROTO_TABLE(GLOBAL), opcode);
}
-@@ -87,7 +89,7 @@
+@@ -87,7 +88,7 @@
return xprotocol_tables[cardtype];
}
@@ -12773,7 +13378,7 @@
{
const xproto_table_t *xtable;
-@@ -95,18 +97,34 @@
+@@ -95,18 +96,34 @@
return NULL;
xtable = xprotocol_tables[cardtype];
if(!xtable) { /* Try to load the relevant module */
@@ -12811,7 +13416,7 @@
{
const xproto_entry_t *xe;
-@@ -115,7 +133,7 @@
+@@ -115,7 +132,7 @@
return xe->handler;
}
@@ -12820,7 +13425,7 @@
{
const xproto_entry_t *xe;
-@@ -136,18 +154,6 @@
+@@ -136,18 +153,6 @@
return xe;
}
@@ -12839,7 +13444,7 @@
int packet_receive(xbus_t *xbus, xpacket_t *pack)
{
int xpd_num;
-@@ -161,7 +167,7 @@
+@@ -161,7 +166,7 @@
return -EPROTO;
}
xpd_num = XPD_NUM(pack->content.addr);
@@ -12848,6 +13453,30 @@
if(xbus->sim[xpd_num].simulated) {
//dump_packet("packet_receive -> simulate", pack, print_dbg);
return simulate_xpd(xbus, xpd_num, pack);
+@@ -189,7 +194,8 @@
+ xe = find_xproto_entry(xpd, op);
+ /*-------- Validations -----------*/
+ if(!xe) {
+- ERR("xpp: %s -- bad command op=0x%02X\n", __FUNCTION__, op);
++ ERR("xpp: %s: %s unit #%d: bad command op=0x%02X\n",
++ __FUNCTION__, xbus->busname, xpd_num, op);
+ dump_packet("packet_process -- bad command", pack, print_dbg);
+ ret = -EPROTO;
+ goto out;
+@@ -221,10 +227,10 @@
+
+ if(!print_dbg)
+ return;
+- DBG("%s: @0x%1X%1X OP=0x%02X LEN=%d\n",
++ DBG("%s: U=0x%1X S=0x%1X OP=0x%02X LEN=%d\n",
+ msg,
+- packet->content.addr.bank_num,
+- packet->content.addr.card_id,
++ packet->content.addr.unit,
++ packet->content.addr.subunit,
+ op,
+ (byte)packet->datalen);
+ #if VERBOSE_DEBUG
@@ -256,7 +262,7 @@
{
const xproto_table_t *proto_table;
@@ -12866,16 +13495,18 @@
NOTICE("%s: Bad xproto type %d\n", __FUNCTION__, type);
return -EINVAL;
}
-@@ -290,14 +296,18 @@
+@@ -290,14 +296,20 @@
CHECK_XOP(card_init);
CHECK_XOP(card_remove);
CHECK_XOP(card_tick);
-+ CHECK_XOP(card_zaptel_registration);
++ CHECK_XOP(card_zaptel_preregistration);
++ CHECK_XOP(card_zaptel_postregistration);
+#ifdef WITH_RBS
+ CHECK_XOP(card_hooksig);
+#else
+ CHECK_XOP(card_sethook);
+#endif
++ // CHECK_XOP(card_ioctl); // optional method -- call after testing
CHECK_XOP(SYNC_SOURCE);
CHECK_XOP(PCM_WRITE);
CHECK_XOP(CHAN_ENABLE);
@@ -12887,7 +13518,7 @@
CHECK_XOP(RELAY_OUT);
xprotocol_tables[type] = proto_table;
-@@ -313,7 +323,7 @@
+@@ -313,7 +325,7 @@
type = proto_table->type;
name = proto_table->name;
DBG("%s (%d)\n", name, type);
@@ -12896,9 +13527,9 @@
NOTICE("%s: Bad xproto type %s (%d)\n", __FUNCTION__, name, type);
return;
}
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xproto.h zaptel-xpp-8WuH7d_dist/xpp/xproto.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/xproto.h zaptel-xpp-oaIQ8i_dist/xpp/xproto.h
--- zaptel-1.2.6/xpp/xproto.h 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/xproto.h 2006-06-22 11:31:28.427315000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/xproto.h 2006-07-03 13:44:48.152691000 +0300
@@ -2,7 +2,7 @@
#define XPROTO_H
/*
@@ -12908,7 +13539,7 @@
*
* All rights reserved.
*
-@@ -26,18 +26,22 @@
+@@ -26,31 +26,39 @@
#ifdef __KERNEL__
#include <linux/list.h>
@@ -12923,8 +13554,13 @@
- XPD_TYPE(FXS) = 0x03,
- XPD_TYPE(NOMODULE) = 0x0F,
-} xpd_type_t;
-+#define XPD_TYPE_FXS 3
-+#define XPD_TYPE_FXO 4
++/*
++ * The LSB of the type number signifies:
++ * 0 - TO_PSTN
++ * 1 - TO_PHONE
++ */
++#define XPD_TYPE_FXS 3 // TO_PHONE
++#define XPD_TYPE_FXO 4 // TO_PSTN
+#define XPD_TYPE_NOMODULE 15
+
+typedef byte xpd_type_t;
@@ -12938,7 +13574,64 @@
#define PCM_CHUNKSIZE (CHANNELS_PERXPD * 8) /* samples of 8 bytes */
typedef struct xpd_addr {
-@@ -124,14 +128,13 @@
+- byte card_id:4;
+- byte bank_num:4;
+-} __attribute__((packed)) xpd_addr_t;
++ byte unit:UNIT_BITS;
++ byte subunit:SUBUNIT_BITS;
++} PACKED xpd_addr_t;
+
+ bool valid_xpd_addr(const xpd_addr_t *addr);
+ int xpd_addr2num(const xpd_addr_t *addr);
+ void xpd_set_addr(xpd_addr_t *addr, int xpd_num);
+
+ #define XPD_NUM(x) xpd_addr2num(&x)
+-#define XPD_ADDR_SET(x,val) xpd_set_addr(&x, val)
+ #define MAX_XPACKET_DATALEN 100
+
+ #define XPROTO_NAME(card,op) card ## _ ## op
+@@ -82,11 +90,12 @@
+ byte opcode; \
+ xpd_addr_t addr; \
+ __VA_ARGS__ \
+- } __attribute__((packed))
++ } PACKED
+
+ #define RPACKET_CAST(p,card,op) ((RPACKET_TYPE(card,op) *)p)
+ #define RPACKET_FIELD(p,card,op,field) (RPACKET_CAST(p,card,op)->field)
+ #define RPACKET_SIZE(card,op) sizeof(RPACKET_TYPE(card,op))
++#define RPACKET_DATALEN(card,op) (RPACKET_SIZE(card,op) - sizeof(xpd_addr_t) - 1)
+
+ #define PACKET_LEN(p) \
+ ((p)->datalen + sizeof(xpd_addr_t) + 1)
+@@ -94,7 +103,7 @@
+ #define XENTRY(card,op) \
+ [ XPROTO_NAME(card,op) ] { \
+ .handler = XPROTO_HANDLER(card,op), \
+- .datalen = RPACKET_SIZE(card,op), \
++ .datalen = RPACKET_DATALEN(card,op), \
+ .name = #op, \
+ .table = &PROTO_TABLE(card) \
+ }
+@@ -103,7 +112,7 @@
+ #define XPACKET_INIT(p, card, op) \
+ do { \
+ p->content.opcode = XPROTO_NAME(card,op); \
+- p->datalen = RPACKET_SIZE(card,op); \
++ p->datalen = RPACKET_DATALEN(card,op); \
+ } while(0)
+
+ #define XPACKET_NEW(p, xbus, card, op, to) \
+@@ -112,7 +121,7 @@
+ if(!p) \
+ return -ENOMEM; \
+ XPACKET_INIT(p, card, op); \
+- XPD_ADDR_SET(p->content.addr, to); \
++ xpd_set_addr(&p->content.addr, to); \
+ } while(0);
+
+ typedef struct xproto_entry xproto_entry_t;
+@@ -124,14 +133,13 @@
const xproto_entry_t *cmd,
xpacket_t *pack);
@@ -12957,16 +13650,18 @@
#define CALL_XMETHOD(name, xbus, xpd, ...) \
(xpd)->xops->name(xbus, xpd, ## __VA_ARGS__ )
-@@ -141,23 +144,23 @@
+@@ -141,23 +149,25 @@
int (*card_init)(xbus_t *xbus, xpd_t *xpd);
int (*card_remove)(xbus_t *xbus, xpd_t *xpd);
int (*card_tick)(xbus_t *xbus, xpd_t *xpd);
-+ int (*card_zaptel_registration)(xpd_t *xpd, bool on);
++ int (*card_zaptel_preregistration)(xpd_t *xpd, bool on);
++ int (*card_zaptel_postregistration)(xpd_t *xpd, bool on);
+#ifdef WITH_RBS
+ int (*card_hooksig)(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig);
+#else
+ int (*card_sethook)(xbus_t *xbus, xpd_t *xpd, int pos, int hookstate);
+#endif
++ int (*card_ioctl)(xpd_t *xpd, int pos, unsigned int cmd, unsigned long arg);
int (*SYNC_SOURCE)(xbus_t *xbus, xpd_t *xpd, bool setit, bool is_master);
int (*PCM_WRITE)(xbus_t *xbus, xpd_t *xpd, xpp_line_t hookstate, volatile byte *buf);
@@ -12989,7 +13684,7 @@
struct xproto_entry {
xproto_handler_t handler;
int datalen;
-@@ -166,6 +169,7 @@
+@@ -166,6 +176,7 @@
};
struct xproto_table {
@@ -12997,16 +13692,19 @@
xproto_entry_t entries[255]; /* Indexed by opcode */
xops_t xops;
xpd_type_t type;
-@@ -176,6 +180,7 @@
+@@ -176,8 +187,10 @@
#include "card_global.h"
#include "card_fxs.h"
+#include "card_fxo.h"
enum opcodes {
++ XPROTO_NAME(GLOBAL, NULL_REPLY) = 0xFE,
XPROTO_NAME(GLOBAL, DESC_REQ) = 0x04,
-@@ -186,21 +191,6 @@
+ XPROTO_NAME(GLOBAL, DEV_DESC) = 0x05,
/**/
+@@ -186,21 +199,6 @@
+ /**/
XPROTO_NAME(GLOBAL, SYNC_SOURCE) = 0x19,
XPROTO_NAME(GLOBAL, SYNC_REPLY) = 0x1A,
-
@@ -13027,21 +13725,28 @@
};
-@@ -218,6 +208,13 @@
+@@ -210,6 +208,7 @@
+ byte opcode;
+ xpd_addr_t addr;
+ union {
++ MEMBER(GLOBAL, NULL_REPLY);
+ MEMBER(GLOBAL, DESC_REQ);
+ MEMBER(GLOBAL, DEV_DESC);
+ MEMBER(GLOBAL, PCM_WRITE);
+@@ -218,15 +217,21 @@
MEMBER(FXS, SIG_CHANGED);
MEMBER(FXS, SLIC_REPLY);
-+ MEMBER(FXS, SLIC_INIT);
+ MEMBER(FXS, SLIC_WRITE);
+
+ MEMBER(FXO, SIG_CHANGED);
+ MEMBER(FXO, DAA_REPLY);
-+ MEMBER(FXO, DAA_INIT);
+ MEMBER(FXO, DAA_WRITE);
byte data[0];
};
-@@ -225,8 +222,9 @@
+-} __attribute__((packed));
++} PACKED;
struct xpacket {
xpacket_raw_t content;
@@ -13052,9 +13757,9 @@
};
void dump_packet(const char *msg, xpacket_t *packet, bool print_dbg);
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/zap_debug.c zaptel-xpp-8WuH7d_dist/xpp/zap_debug.c
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/zap_debug.c zaptel-xpp-oaIQ8i_dist/xpp/zap_debug.c
--- zaptel-1.2.6/xpp/zap_debug.c 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/zap_debug.c 2006-03-30 12:42:46.619481000 +0200
++++ zaptel-xpp-oaIQ8i_dist/xpp/zap_debug.c 2006-03-30 12:42:46.619481000 +0200
@@ -1,6 +1,6 @@
/*
* Written by Oron Peled <oron at actcom.co.il>
@@ -13147,9 +13852,9 @@
EXPORT_SYMBOL(dump_poll);
-EXPORT_SYMBOL(event2str);
-EXPORT_SYMBOL(dump_sigtype);
-diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/zap_debug.h zaptel-xpp-8WuH7d_dist/xpp/zap_debug.h
+diff -uNr -x .svn -x debian zaptel-1.2.6/xpp/zap_debug.h zaptel-xpp-oaIQ8i_dist/xpp/zap_debug.h
--- zaptel-1.2.6/xpp/zap_debug.h 2006-02-15 04:24:18.000000000 +0200
-+++ zaptel-xpp-8WuH7d_dist/xpp/zap_debug.h 2006-06-19 10:36:29.741020000 +0300
++++ zaptel-xpp-oaIQ8i_dist/xpp/zap_debug.h 2006-06-19 10:36:29.741020000 +0300
@@ -1,16 +1,125 @@
#ifndef ZAP_DEBUG_H
#define ZAP_DEBUG_H
More information about the Pkg-voip-commits
mailing list