[zaptel-commits] tzafrir: branch tzafrir/sync r2228 -
/team/tzafrir/sync/xpp/
zaptel-commits at lists.digium.com
zaptel-commits at lists.digium.com
Sun Feb 25 14:45:37 MST 2007
Author: tzafrir
Date: Sun Feb 25 15:45:36 2007
New Revision: 2228
URL: http://svn.digium.com/view/zaptel?view=rev&rev=2228
Log:
A version of the xpp driver that uses the sync method, amongst many
other changes.
This version still only logs the lag and does not yet attempt to synchronize.
Modified:
team/tzafrir/sync/xpp/card_fxo.c
team/tzafrir/sync/xpp/card_fxs.c
team/tzafrir/sync/xpp/card_global.c
team/tzafrir/sync/xpp/xbus-core.c
team/tzafrir/sync/xpp/xbus-core.h
team/tzafrir/sync/xpp/xpd.h
team/tzafrir/sync/xpp/xpp_usb.c
team/tzafrir/sync/xpp/xpp_zap.c
team/tzafrir/sync/xpp/xpp_zap.h
team/tzafrir/sync/xpp/xproto.c
team/tzafrir/sync/xpp/xproto.h
Modified: team/tzafrir/sync/xpp/card_fxo.c
URL: http://svn.digium.com/view/zaptel/team/tzafrir/sync/xpp/card_fxo.c?view=diff&rev=2228&r1=2227&r2=2228
==============================================================================
--- team/tzafrir/sync/xpp/card_fxo.c (original)
+++ team/tzafrir/sync/xpp/card_fxo.c Sun Feb 25 15:45:36 2007
@@ -417,6 +417,23 @@
return 0;
}
+static int FXO_card_open(xpd_t *xpd, lineno_t chan)
+{
+ struct FXO_priv_data *priv;
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ /*
+ * We pretend to have battery. If this is really the case
+ * than next calls to update_battery_status() won't change it.
+ * If we don't have battery, than on the next calls to
+ * update_battery_status() a battery_debounce[] cycle would start.
+ * Than, if no-battery is persistent, asterisk would be notified.
+ */
+ BIT_SET(priv->battery, chan);
+ return 0;
+}
+
static void poll_battery(xbus_t *xbus, xpd_t *xpd)
{
int i;
@@ -634,13 +651,17 @@
if(IS_SET(priv->battery, chipsel) && priv->battery_debounce[chipsel]++ > BAT_DEBOUNCE) {
DBG("%s/%s/%d: BATTERY OFF voltage=%d\n", xpd->xbus->busname, xpd->xpdname, chipsel, bat);
BIT_CLR(priv->battery, chipsel);
- update_line_status(xpd, chipsel, 0);
+ if(SPAN_REGISTERED(xpd))
+ zt_qevent_lock(&xpd->chans[chipsel], ZT_EVENT_ALARM);
+
}
} else {
priv->battery_debounce[chipsel] = 0;
if(!IS_SET(priv->battery, chipsel)) {
DBG("%s/%s/%d: BATTERY ON voltage=%d\n", xpd->xbus->busname, xpd->xpdname, chipsel, bat);
BIT_SET(priv->battery, chipsel);
+ if(SPAN_REGISTERED(xpd))
+ zt_qevent_lock(&xpd->chans[chipsel], ZT_EVENT_NOALARM);
}
}
/*
@@ -757,12 +778,11 @@
.card_hooksig = FXO_card_hooksig,
.card_tick = FXO_card_tick,
.card_ioctl = FXO_card_ioctl,
+ .card_open = FXO_card_open,
.RING = XPROTO_CALLER(FXO, RING),
.RELAY_OUT = XPROTO_CALLER(FXO, RELAY_OUT),
.XPD_STATE = XPROTO_CALLER(FXO, XPD_STATE),
-
- .SYNC_SOURCE = XPROTO_CALLER(GLOBAL, SYNC_SOURCE),
},
.packet_is_valid = fxo_packet_is_valid,
.packet_dump = fxo_packet_dump,
Modified: team/tzafrir/sync/xpp/card_fxs.c
URL: http://svn.digium.com/view/zaptel/team/tzafrir/sync/xpp/card_fxs.c?view=diff&rev=2228&r1=2227&r2=2228
==============================================================================
--- team/tzafrir/sync/xpp/card_fxs.c (original)
+++ team/tzafrir/sync/xpp/card_fxs.c Sun Feb 25 15:45:36 2007
@@ -34,7 +34,8 @@
static const char rcsid[] = "$Id$";
DEF_PARM(int, print_dbg, 0, 0600, "Print DBG statements"); /* must be before zap_debug.h */
-DEF_PARM_BOOL(poll_digital_inputs, 1, 0600, "Poll Digital Inputs"); /* must be before zap_debug.h */
+DEF_PARM_BOOL(poll_digital_inputs, 1, 0600, "Poll Digital Inputs");
+DEF_PARM_BOOL(reversepolarity, 0, 0600, "Reverse Line Polarity");
/* Signaling is opposite (fxo signalling for fxs card) */
#if 1
@@ -69,6 +70,22 @@
#define VALID_CHIPSEL(x) (((chipsel) >= 0 && (chipsel) <= 7) || (chipsel) == ALL_CHANS)
+/* Values of SLIC linefeed control register (0x40) */
+enum fxs_state {
+ FXS_LINE_OPEN = 0x00, /* Open */
+ FXS_LINE_ACTIVE = 0x01, /* Forward active */
+ FXS_LINE_OHTRANS = 0x02, /* Forward on-hook transmission */
+ FXS_LINE_TIPOPEN = 0x03, /* TIP open */
+ FXS_LINE_RING = 0x04, /* Ringing */
+ FXS_LINE_REV_ACTIVE = 0x05, /* Reverse active */
+ FXS_LINE_REV_OHTRANS = 0x06, /* Reverse on-hook transmission */
+ FXS_LINE_RING_OPEN = 0x07 /* RING open */
+};
+
+#define FXS_LINE_POL_ACTIVE ((reversepolarity) ? FXS_LINE_REV_ACTIVE : FXS_LINE_ACTIVE)
+#define FXS_LINE_POL_OHTRANS ((reversepolarity) ? FXS_LINE_REV_OHTRANS : FXS_LINE_OHTRANS)
+
+
/*---------------- FXS Protocol Commands ----------------------------------*/
static /* 0x0F */ DECLARE_CMD(FXS, XPD_STATE, bool on);
@@ -86,13 +103,18 @@
#define PROC_FXS_INFO_FNAME "fxs_info"
struct FXS_priv_data {
- struct proc_dir_entry *regfile;
- struct proc_dir_entry *fxs_info;
- xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */
- xpp_line_t ledcontrol[NUM_LEDS]; /* 0 - OFF, 1 - ON */
- xpp_line_t found_fsk_pattern;
- xpp_line_t msg_waiting;
- int led_counter[NUM_LEDS][CHANNELS_PERXPD];
+ struct proc_dir_entry *regfile;
+ struct proc_dir_entry *fxs_info;
+ xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */
+ xpp_line_t ledcontrol[NUM_LEDS]; /* 0 - OFF, 1 - ON */
+ xpp_line_t found_fsk_pattern;
+ xpp_line_t msg_waiting;
+ xpp_line_t update_offhook_state;
+ int led_counter[NUM_LEDS][CHANNELS_PERXPD];
+ int ohttimer[CHANNELS_PERXPD];
+#define OHT_TIMER 6000 /* How long after RING to retain OHT */
+ enum fxs_state idletxhookstate[CHANNELS_PERXPD]; /* IDLE changing hook state */
+ enum fxs_state lasttxhook[CHANNELS_PERXPD];
};
/*
@@ -108,6 +130,16 @@
#define LED_BLINK_RING (1000/8) /* in ticks */
/*---------------- FXS: Static functions ----------------------------------*/
+static int linefeed_control(xbus_t *xbus, xpd_t *xpd, lineno_t chan, enum fxs_state value)
+{
+ struct FXS_priv_data *priv;
+
+ priv = xpd->priv;
+ DBG("%s/%s/%d: value=0x%02X\n", xbus->busname, xpd->xpdname, chan, value);
+ priv->lasttxhook[chan] = value;
+ return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x40, value);
+}
+
static int do_chan_power(xbus_t *xbus, xpd_t *xpd, lineno_t chan, bool on)
{
int value = (on) ? 0x06 : 0x00;
@@ -223,20 +255,19 @@
}
}
-static int do_callerid(xbus_t *xbus, xpd_t *xpd, lineno_t chan)
-{
- int ret = 0;
- int i;
-
- BUG_ON(!xbus);
- BUG_ON(!xpd);
- DBG("%s/%s/%d:\n", xbus->busname, xpd->xpdname, chan);
- ret = SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x40, FXS_LINE_CID);
- for_each_line(xpd, i)
- xpd->lasttxhook[i] = FXS_LINE_CID;
- return ret;
-}
-
+static void restore_leds(xpd_t *xpd)
+{
+ struct FXS_priv_data *priv;
+ int i;
+
+ priv = xpd->priv;
+ for_each_line(xpd, i) {
+ if(IS_SET(xpd->offhook, i))
+ MARK_ON(priv, i, LED_GREEN);
+ else
+ MARK_OFF(priv, i, LED_GREEN);
+ }
+}
/*---------------- FXS: Methods -------------------------------------------*/
@@ -310,6 +341,9 @@
priv->regfile->read_proc = proc_xpd_register_read;
priv->regfile->data = xpd;
#endif
+ for_each_line(xpd, i) {
+ priv->idletxhookstate[i] = FXS_LINE_POL_ACTIVE;
+ }
ret = run_initialize_registers(xpd);
if(ret < 0)
goto err;
@@ -333,6 +367,7 @@
do_led(xpd, i, LED_GREEN, 0);
msleep(50);
}
+ restore_leds(xpd);
return 0;
err:
clean_proc(xbus, xpd);
@@ -404,19 +439,26 @@
MARK_OFF(priv, i, LED_RED);
msleep(2);
}
+ restore_leds(xpd);
return 0;
}
int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
{
- int ret = 0;
+ struct FXS_priv_data *priv;
+ int ret = 0;
+ struct zt_chan *chan = NULL;
+ enum fxs_state txhook;
DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, pos, txsig2str(txsig));
+ priv = xpd->priv;
BUG_ON(xpd->direction != TO_PHONE);
if (IS_SET(xpd->digital_inputs, pos)) {
DBG("Ignoring signal sent to digital input line\n");
return 0;
}
+ if(SPAN_REGISTERED(xpd))
+ chan = &xpd->span.chans[pos];
switch(txsig) {
case ZT_TXSIG_ONHOOK:
xpd->ringing[pos] = 0;
@@ -426,41 +468,54 @@
ret = CALL_XMETHOD(RELAY_OUT, xpd->xbus, xpd, pos-8, 0);
return ret;
}
+ if (priv->lasttxhook[pos] == FXS_LINE_OPEN) {
+ /*
+ * Restore state after KEWL hangup.
+ */
+ DBG("%s/%s/%d: KEWL STOP\n",
+ xbus->busname, xpd->xpdname, pos);
+ linefeed_control(xbus, xpd, pos, FXS_LINE_POL_ACTIVE);
+ if(IS_SET(xpd->offhook, pos))
+ MARK_ON(priv, pos, LED_GREEN);
+ }
ret = CALL_XMETHOD(RING, xbus, xpd, pos, 0); // RING off
if (!IS_SET(xpd->offhook, pos))
start_stop_vm_led(xbus, xpd, pos);
-#if 0
- switch(chan->sig) {
- case ZT_SIG_EM:
- case ZT_SIG_FXOKS:
- case ZT_SIG_FXOLS:
- xpd->lasttxhook[pos] = xpd->idletxhookstate[pos];
- break;
- case ZT_SIG_FXOGS:
- xpd->lasttxhook[pos] = FXS_LINE_TIPOPEN;
- break;
+ txhook = priv->lasttxhook[pos];
+ if(chan) {
+ switch(chan->sig) {
+ case ZT_SIG_EM:
+ case ZT_SIG_FXOKS:
+ case ZT_SIG_FXOLS:
+ txhook = priv->idletxhookstate[pos];
+ break;
+ case ZT_SIG_FXOGS:
+ txhook = FXS_LINE_TIPOPEN;
+ break;
+ }
}
-#endif
+ ret = linefeed_control(xbus, xpd, pos, txhook);
break;
case ZT_TXSIG_OFFHOOK:
+ txhook = priv->lasttxhook[pos];
if(xpd->ringing[pos]) {
BIT_SET(xpd->cid_on, pos);
- ret = do_callerid(xpd->xbus, xpd, pos); // CALLER ID
+ txhook = FXS_LINE_OHTRANS;
}
xpd->ringing[pos] = 0;
-#if 0
- switch(chan->sig) {
- case ZT_SIG_EM:
- xpd->lasttxhook[pos] = FXS_LINE_REV_ACTIVE;
- break;
- default:
- xpd->lasttxhook[pos] = xpd->idletxhookstate[pos];
- break;
+ if(chan) {
+ switch(chan->sig) {
+ case ZT_SIG_EM:
+ txhook = FXS_LINE_POL_ACTIVE;
+ break;
+ default:
+ txhook = priv->idletxhookstate[pos];
+ break;
+ }
}
-#endif
+ ret = linefeed_control(xbus, xpd, pos, txhook);
break;
case ZT_TXSIG_START:
- xpd->lasttxhook[pos] = FXS_LINE_RING;
xpd->ringing[pos] = 1;
BIT_CLR(xpd->cid_on, pos);
if(IS_SET(xpd->digital_outputs, pos)) {
@@ -471,7 +526,9 @@
ret = CALL_XMETHOD(RING, xbus, xpd, pos, 1); // RING on
break;
case ZT_TXSIG_KEWL:
- xpd->lasttxhook[pos] = FXS_LINE_DISABLED;
+ DBG("%s/%s/%d: KEWL START\n", xbus->busname, xpd->xpdname, pos);
+ linefeed_control(xbus, xpd, pos, FXS_LINE_OPEN);
+ MARK_OFF(priv, pos, LED_GREEN);
break;
default:
NOTICE("%s: Can't set tx state to %s (%d)\n", __FUNCTION__, txsig2str(txsig), txsig);
@@ -553,32 +610,68 @@
static void start_stop_vm_led(xbus_t *xbus, xpd_t *xpd, lineno_t pos)
{
+ struct FXS_priv_data *priv;
bool on;
+ BUG_ON(!xpd);
if (IS_SET(xpd->digital_outputs | xpd->digital_inputs, pos))
return;
+ priv = xpd->priv;
on = IS_SET(((struct FXS_priv_data *)xpd->priv)->msg_waiting, pos);
DBG("%s/%s/%d %s\n", xbus->busname, xpd->xpdname, pos, (on)?"ON":"OFF");
set_vm_led_mode(xbus, xpd, pos, on);
do_chan_power(xbus, xpd, pos, on);
- SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x40, (on) ? 0x04 : 0x01);
+ linefeed_control(xbus, xpd, pos, (on) ? FXS_LINE_RING : priv->idletxhookstate[pos]);
}
static int FXS_chan_onhooktransfer(xbus_t *xbus, xpd_t *xpd, lineno_t chan, int millies)
{
- int ret = 0;
-
- BUG_ON(!xpd);
+ struct FXS_priv_data *priv;
+ int ret = 0;
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
BUG_ON(chan == ALL_CHANS);
DBG("%s/%s/%d: (%d millies)\n", xbus->busname, xpd->xpdname, chan, millies);
- xpd->ohttimer[chan] = millies << 3;
- xpd->idletxhookstate[chan] = FXS_LINE_CID; /* OHT mode when idle */
- if (xpd->lasttxhook[chan] == FXS_LINE_ENABLED) {
+ priv->ohttimer[chan] = millies;
+ priv->idletxhookstate[chan] = FXS_LINE_POL_OHTRANS; /* OHT mode when idle */
+ if (priv->lasttxhook[chan] == FXS_LINE_POL_ACTIVE) {
/* Apply the change if appropriate */
- ret = do_callerid(xpd->xbus, xpd, chan); // CALLER ID
+ ret = linefeed_control(xbus, xpd, chan, FXS_LINE_OHTRANS);
}
start_stop_vm_led(xbus, xpd, chan);
return ret;
+}
+
+static int FXS_card_open(xpd_t *xpd, lineno_t chan)
+{
+ struct FXS_priv_data *priv;
+ bool is_offhook;
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ is_offhook = IS_SET(xpd->offhook, chan);
+ DBG("%s/%s:%d (is %shook)\n", xpd->xbus->busname, xpd->xpdname,
+ chan, (is_offhook)?"off":"on");
+ /*
+ * Delegate updating zaptel to FXS_card_tick():
+ * The problem is that zt_hooksig() is spinlocking the channel and
+ * we are called by zaptel with the spinlock already held on the
+ * same channel.
+ */
+ BIT_SET(priv->update_offhook_state, chan);
+ return 0;
+}
+
+static int FXS_card_close(xpd_t *xpd, lineno_t chan)
+{
+ struct FXS_priv_data *priv;
+
+ BUG_ON(!xpd);
+ DBG("%s/%s:%d\n", xpd->xbus->busname, xpd->xpdname, chan);
+ priv = xpd->priv;
+ priv->idletxhookstate[chan] = FXS_LINE_POL_ACTIVE;
+ return 0;
}
/*
@@ -600,6 +693,36 @@
byte pos = input_channels[i];
SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_READ, 0x06, 0);
+ }
+}
+
+void handle_linefeed(xpd_t *xpd)
+{
+ struct FXS_priv_data *priv;
+ int i;
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ for_each_line(xpd, i) {
+ if (priv->lasttxhook[i] == FXS_LINE_RING) {
+ /* RINGing, prepare for OHT */
+ priv->ohttimer[i] = OHT_TIMER;
+ priv->idletxhookstate[i] = FXS_LINE_POL_OHTRANS;
+ } else {
+ if (priv->ohttimer[i]) {
+ priv->ohttimer[i]--;
+ if (!priv->ohttimer[i]) {
+ priv->idletxhookstate[i] = FXS_LINE_POL_ACTIVE;
+ if (priv->lasttxhook[i] == FXS_LINE_POL_OHTRANS) {
+ enum fxs_state txhook = FXS_LINE_POL_ACTIVE;
+ /* Apply the change if appropriate */
+ BIT_CLR(xpd->cid_on, i);
+ linefeed_control(xpd->xbus, xpd, i, txhook);
+ }
+ }
+ }
+ }
}
}
@@ -678,6 +801,28 @@
}
#endif
handle_fxs_leds(xpd);
+ handle_linefeed(xpd);
+ if(priv->update_offhook_state) { /* set in FXS_card_open() */
+ int i;
+
+ for_each_line(xpd, i) {
+ if(!IS_SET(priv->update_offhook_state, i))
+ continue;
+ /*
+ * Update LEDs and zaptel with current state of line.
+ */
+ if(IS_SET(xpd->offhook, i)) {
+ NOTICE("%s/%s/%d: Already offhook during open. OK.\n",
+ xbus->busname, xpd->xpdname, i);
+ MARK_ON(priv, i, LED_GREEN);
+ update_line_status(xpd, i, 1);
+ } else {
+ MARK_OFF(priv, i, LED_GREEN);
+ update_line_status(xpd, i, 0);
+ }
+ BIT_CLR(priv->update_offhook_state, i);
+ }
+ }
#ifndef VMWI_IOCTL
if(SPAN_REGISTERED(xpd))
detect_vmwi(xpd);
@@ -721,9 +866,8 @@
static /* 0x0F */ HOSTCMD(FXS, XPD_STATE, bool on)
{
- int ret = 0;
int i;
- enum fxs_state value = (on) ? 0x01 : 0x00;
+ enum fxs_state value = (on) ? FXS_LINE_POL_ACTIVE : FXS_LINE_OPEN;
unsigned long flags;
struct FXS_priv_data *priv;
@@ -732,23 +876,22 @@
priv = xpd->priv;
spin_lock_irqsave(&xpd->lock, flags);
DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on) ? "on" : "off");
- ret = SLIC_DIRECT_REQUEST(xbus, xpd, ALL_CHANS, SLIC_WRITE, 0x40, value);
for_each_line(xpd, i)
- xpd->lasttxhook[i] = value;
+ linefeed_control(xbus, xpd, i, value);
if(on) {
MARK_ON(priv, ALL_CHANS, LED_GREEN);
} else {
MARK_OFF(priv, ALL_CHANS, LED_GREEN);
}
spin_unlock_irqrestore(&xpd->lock, flags);
- return ret;
+ return 0;
}
static /* 0x0F */ HOSTCMD(FXS, RING, lineno_t chan, bool on)
{
int ret = 0;
struct FXS_priv_data *priv;
- enum fxs_state value = (on) ? 0x04 : 0x01;
+ enum fxs_state value = (on) ? FXS_LINE_RING : FXS_LINE_POL_ACTIVE;
BUG_ON(!xbus);
BUG_ON(!xpd);
@@ -756,8 +899,7 @@
priv = xpd->priv;
set_vm_led_mode(xbus, xpd, chan, 0);
do_chan_power(xbus, xpd, chan, on); // Power up (for ring)
- ret = SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x40, value);
- xpd->lasttxhook[chan] = value;
+ ret = linefeed_control(xbus, xpd, chan, value);
if(on) {
MARK_BLINK(priv, chan, LED_GREEN, LED_BLINK_RING);
} else {
@@ -819,7 +961,6 @@
DBG("%s/%s/%d: ONHOOK\n", xbus->busname, xpd->xpdname, i);
MARK_OFF(priv, i, LED_GREEN);
update_line_status(xpd, i, 0);
- start_stop_vm_led(xbus, xpd, i);
}
}
}
@@ -910,6 +1051,8 @@
.card_hooksig = FXS_card_hooksig,
.card_tick = FXS_card_tick,
.chan_onhooktransfer = FXS_chan_onhooktransfer,
+ .card_open = FXS_card_open,
+ .card_close = FXS_card_close,
#ifdef VMWI_IOCTL
.card_ioctl = FXS_card_ioctl,
#endif
@@ -917,8 +1060,6 @@
.RING = XPROTO_CALLER(FXS, RING),
.RELAY_OUT = XPROTO_CALLER(FXS, RELAY_OUT),
.XPD_STATE = XPROTO_CALLER(FXS, XPD_STATE),
-
- .SYNC_SOURCE = XPROTO_CALLER(GLOBAL, SYNC_SOURCE),
},
.packet_is_valid = fxs_packet_is_valid,
.packet_dump = fxs_packet_dump,
@@ -954,10 +1095,28 @@
spin_lock_irqsave(&xpd->lock, flags);
priv = xpd->priv;
BUG_ON(!priv);
- len += sprintf(page + len, "\t%-17s: ", "Channel");
+ len += sprintf(page + len, "%-8s %-10s %-10s %-10s\n",
+ "Channel",
+ "idletxhookstate",
+ "lasttxhook",
+ "ohttimer"
+ );
for_each_line(xpd, i) {
- if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
- len += sprintf(page + len, "%d ", i % 10);
+ char pref;
+
+ if(IS_SET(xpd->digital_outputs, i))
+ pref = 'O';
+ else if(IS_SET(xpd->digital_inputs, i))
+ pref = 'I';
+ else
+ pref = ' ';
+ len += sprintf(page + len, "%c%7d %10d %10d %10d\n",
+ pref,
+ i,
+ priv->idletxhookstate[i],
+ priv->lasttxhook[i],
+ priv->ohttimer[i]
+ );
}
len += sprintf(page + len, "\n");
for(led = 0; led < NUM_LEDS; led++) {
Modified: team/tzafrir/sync/xpp/card_global.c
URL: http://svn.digium.com/view/zaptel/team/tzafrir/sync/xpp/card_global.c?view=diff&rev=2228&r1=2227&r2=2228
==============================================================================
--- team/tzafrir/sync/xpp/card_global.c (original)
+++ team/tzafrir/sync/xpp/card_global.c Sun Feb 25 15:45:36 2007
@@ -59,6 +59,9 @@
return ret;
}
+/*
+ * The XPD parameter is totaly ignored by the driver and firmware as well.
+ */
/* 0x19 */ HOSTCMD(GLOBAL, SYNC_SOURCE, bool setit, bool is_master)
{
xframe_t *xframe;
@@ -66,14 +69,14 @@
byte mask = 0;
BUG_ON(!xbus);
- BUG_ON(!xpd);
if(is_master)
mask |= BIT(0);
if(!setit)
mask |= BIT(1);
- DBG("SYNC_SOURCE %s setit=%s is_master=%s (mask=0x%X)\n",
- xpd->xpdname, (setit)?"yes":"no", (is_master)?"yes":"no", mask);
- XFRAME_NEW(xframe, pack, xbus, GLOBAL, SYNC_SOURCE, xpd->id);
+ DBG("%s: setit=%s is_master=%s\n",
+ xbus->busname,
+ (setit)?"yes":"no", (is_master)?"yes":"no");
+ XFRAME_NEW(xframe, pack, xbus, GLOBAL, SYNC_SOURCE, 0);
RPACKET_FIELD(pack, GLOBAL, SYNC_SOURCE, mask) = mask;
xframe_send(xbus, xframe);
return 0;
@@ -94,7 +97,6 @@
xpp_line_t line_status = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, line_status);
xpd_addr_t xpd_addr = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, addr);
struct card_desc_struct *card_desc;
- unsigned long flags;
BUG_ON(!xbus);
if((card_desc = kmalloc(sizeof(struct card_desc_struct), GFP_ATOMIC)) == NULL) {
@@ -108,22 +110,10 @@
card_desc->type = type;
card_desc->rev = rev;
card_desc->xpd_addr = xpd_addr;
+ card_desc->line_status = line_status;
DBG("%s: xpd=%d-%d type=%d rev=%d line_status=0x%04X\n",
xbus->busname, xpd_addr.unit, xpd_addr.subunit, type, rev, line_status);
- spin_lock_irqsave(&xbus->lock, flags);
- if(type == XPD_TYPE_NOMODULE)
- XBUS_COUNTER(xbus, DEV_DESC_EMPTY)++;
- else
- XBUS_COUNTER(xbus, DEV_DESC_FULL)++;
- atomic_inc(&xbus->count_poll_answers);
- list_add_tail(&card_desc->card_list, &xbus->poll_results);
- spin_unlock_irqrestore(&xbus->lock, flags);
- /*
- * wake_up only after exiting our critical section.
- * We suspect that otherwise a spinlock nesting may occur
- * and cause a panic (if spinlock debugging is compiled in).
- */
- wake_up(&xbus->wait_for_polls);
+ xbus_poller_notify(xbus, card_desc);
return 0;
}
@@ -219,8 +209,11 @@
NOTICE("%s: received %s for non-existing xpd: addr=0x%02X\n", __FUNCTION__, cmd->name, xpd_num);
return -EPROTO;
}
- DBG("%s/%s: SYNC_REPLY: 0x%X %s\n", xpd->xbus->busname, xpd->xpdname,
- mask, (setit) ? "SET SYNC MASTER" : "");
+ DBG("%s/%s: mask=0x%X %s\n",
+ xpd->xbus->busname, xpd->xpdname,
+ mask,
+ (setit) ? "SET SYNC MASTER" : "");
+ dump_packet("SYNC_REPLY", pack, 1);
return 0;
}
Modified: team/tzafrir/sync/xpp/xbus-core.c
URL: http://svn.digium.com/view/zaptel/team/tzafrir/sync/xpp/xbus-core.c?view=diff&rev=2228&r1=2227&r2=2228
==============================================================================
--- team/tzafrir/sync/xpp/xbus-core.c (original)
+++ team/tzafrir/sync/xpp/xbus-core.c Sun Feb 25 15:45:36 2007
@@ -32,6 +32,7 @@
#ifdef PROTOCOL_DEBUG
#include <linux/ctype.h>
#endif
+#include <linux/workqueue.h>
#include <linux/device.h>
#include <linux/delay.h> /* for msleep() to debug */
#include "xpd.h"
@@ -77,7 +78,6 @@
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;
@@ -264,15 +264,22 @@
/*
* Return pointer to next packet slot in the frame
* or NULL if the frame is full.
+ *
+ * FIXME: we do not use atomic_add_return() because kernel-2.6.8
+ * does not have it. This make this code a little racy,
+ * but we currently call xframe_next_packet() only in the
+ * PCM loop (xbus_tick() etc.)
*/
xpacket_t *xframe_next_packet(xframe_t *frm, int len)
{
- int newlen = atomic_add_return(len, &frm->frame_len);
+ int newlen = atomic_read(&frm->frame_len);
+
+ newlen += len;
// DBG("len=%d, newlen=%d, frm->frame_len=%d\n", len, newlen, XFRAME_LEN(frm));
if (newlen > XFRAME_DATASIZE) {
- atomic_sub(len, &frm->frame_len);
return NULL;
}
+ atomic_add(len, &frm->frame_len);
return (xpacket_t *)(frm->packets + newlen - len);
}
@@ -435,13 +442,12 @@
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
static void xbus_poll(struct work_struct *work)
{
- xbus_t *xbus = container_of(work, xbus_t, xpds_init_work);
+ struct xbus_poller *poller = container_of(work, struct xbus_poller, xpds_init_work);
#else
static void xbus_poll(void *data)
{
- xbus_t *xbus = data;
-#endif
-
+ struct xbus_poller *poller = data;
+#endif
int id;
int ret = 0;
unsigned long flags;
@@ -451,7 +457,11 @@
struct list_head additions_list;
int count_removed;
int count_added;
-
+ xbus_t *xbus;
+
+ BUG_ON(!poller);
+ xbus = poller->xbus;
+ BUG_ON(!xbus);
if(!down_read_trylock(&xbus->in_use)) {
ERR("%s is being removed...\n", xbus->busname);
return;
@@ -459,6 +469,7 @@
msleep(2); /* roundtrip for older polls */
spin_lock_irqsave(&xbus->lock, flags);
DBG("%s\n", xbus->busname);
+ poller->is_polling = 1;
/*
* Send out the polls
@@ -481,7 +492,7 @@
* Wait for replies
*/
DBG("%s: Polled %d XPD's. Waiting for replies max %d jiffies\n", xbus->busname, MAX_XPDS, poll_timeout);
- ret = wait_event_interruptible_timeout(xbus->wait_for_polls, atomic_read(&xbus->count_poll_answers) >= MAX_XPDS, poll_timeout);
+ ret = wait_event_interruptible_timeout(poller->wait_for_polls, atomic_read(&poller->count_poll_answers) >= MAX_XPDS, poll_timeout);
if(ret == 0) {
ERR("%s: Poll timeout. Continuing anyway.\n", xbus->busname);
/*
@@ -500,7 +511,7 @@
INIT_LIST_HEAD(&additions_list);
count_removed = 0;
count_added = 0;
- list_for_each_safe(card, next_card, &xbus->poll_results) {
+ list_for_each_safe(card, next_card, &poller->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;
@@ -523,7 +534,7 @@
* We set this *after* poll is finished, so wait_for_xpd_initialization can
* tell we already know how many units we have.
*/
- atomic_set(&xbus->count_xpds_to_initialize, count_added);
+ atomic_set(&poller->count_xpds_to_initialize, count_added);
spin_unlock_irqrestore(&xbus->lock, flags);
INFO("%s: Poll results: removals=%d additions=%d\n", xbus->busname, count_removed, count_added);
/*
@@ -548,39 +559,144 @@
list_del(card);
/* FIXME: card_detected() should have a return value for count_xpds_initialized */
card_detected(card_desc);
- atomic_inc(&xbus->count_xpds_initialized);
- }
- wake_up(&xbus->wait_for_xpd_initialization);
+ atomic_inc(&poller->count_xpds_initialized);
+ }
+ wake_up(&poller->wait_for_xpd_initialization);
out:
+ poller->is_polling = 0;
up_read(&xbus->in_use);
return;
}
+void xbus_poller_notify(xbus_t *xbus, struct card_desc_struct *card_desc)
+{
+ struct xbus_poller *poller;
+ unsigned long flags;
+
+ BUG_ON(!xbus);
+ poller = xbus->poller;
+ BUG_ON(!poller);
+ if(!poller->is_polling) {
+ NOTICE("%s: %d-%d replied not during poll. Ignore\n",
+ xbus->busname,
+ card_desc->xpd_addr.unit,
+ card_desc->xpd_addr.subunit);
+ kfree(card_desc);
+ return;
+ }
+ spin_lock_irqsave(&xbus->lock, flags);
+ if(card_desc->type == XPD_TYPE_NOMODULE)
+ XBUS_COUNTER(xbus, DEV_DESC_EMPTY)++;
+ else
+ XBUS_COUNTER(xbus, DEV_DESC_FULL)++;
+ atomic_inc(&poller->count_poll_answers);
+ list_add_tail(&card_desc->card_list, &poller->poll_results);
+ spin_unlock_irqrestore(&xbus->lock, flags);
+ /*
+ * wake_up only after exiting our critical section.
+ * We suspect that otherwise a spinlock nesting may occur
+ * and cause a panic (if spinlock debugging is compiled in).
+ */
+ wake_up(&poller->wait_for_polls);
+ return;
+}
+
+static void poller_destroy(struct xbus_poller *poller)
+{
+ if(!poller)
+ return;
+ if(poller->xbus) {
+ DBG("%s: detach poller\n", poller->xbus->busname);
+ poller->xbus->poller = NULL;
+ }
+ if (poller->wq) {
+ DBG("%s: destroy workqueue\n", poller->xbus->busname);
+ flush_workqueue(poller->wq);
+ destroy_workqueue(poller->wq);
+ poller->wq = NULL;
+ }
+ kfree(poller);
+}
+
+/*
+ * Allocate a poller for the xbus including the nessessary workqueue.
+ * May call blocking operations, but only briefly (as we are called
+ * from xbus_new() which is called from khubd.
+ */
+static struct xbus_poller *poller_new(xbus_t *xbus)
+{
+ struct xbus_poller *poller;
+
+ BUG_ON(xbus->busname[0] == '\0'); /* No name? */
+ BUG_ON(xbus->poller); /* Hmmm... overrun pollers? */
+ DBG("%s\n", xbus->busname);
+ poller = kmalloc(sizeof(*poller), SLAB_KERNEL);
+ if(!poller)
+ goto err;
+ memset(poller, 0, sizeof(*poller));
+ poller->xbus = xbus;
+ xbus->poller = poller;
+ /* poll related variables */
+ atomic_set(&poller->count_poll_answers, 0);
+ atomic_set(&poller->count_xpds_to_initialize, 0);
+ atomic_set(&poller->count_xpds_initialized, 0);
+ INIT_LIST_HEAD(&poller->poll_results);
+ init_waitqueue_head(&poller->wait_for_polls);
+ init_waitqueue_head(&poller->wait_for_xpd_initialization);
+ poller->wq = create_singlethread_workqueue(xbus->busname);
+ if(!poller->wq) {
+ ERR("%s: Failed to create poller workqueue.\n", xbus->busname);
+ goto err;
+ }
+ return poller;
+err:
+ poller_destroy(poller);
+ return NULL;
+}
+
+/*
+ * Sends an xbus_poll() work to the poller workqueue of the given xbus.
+ */
+static int poller_dispatch(xbus_t *xbus)
+{
+ struct xbus_poller *poller = xbus->poller;
+
+ if(!poller) {
+ ERR("%s: missing poller\n", xbus->busname);
+ return 0;
+ }
+ /* Initialize the work. (adapt to kernel API changes). */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ INIT_WORK(&poller->xpds_init_work, xbus_poll);
+#else
+ INIT_WORK(&poller->xpds_init_work, xbus_poll, poller);
+#endif
+ /* Now send it */
+ if(!queue_work(poller->wq, &poller->xpds_init_work)) {
+ ERR("%s: Failed to queue xpd initialization work\n",
+ xbus->busname);
+ return 0;
+ }
+ return 1;
+}
void xbus_activate(xbus_t *xbus)
{
- xbus_ops_t *ops;
+ xbus_ops_t *ops;
+ struct xbus_poller *poller;
BUG_ON(!xbus);
ops = xbus->ops;
BUG_ON(!ops);
+ poller = xbus->poller;
+ BUG_ON(!poller);
/* Sanity checks */
BUG_ON(!ops->xframe_send);
BUG_ON(!ops->xframe_new || !ops->xframe_free);
xbus->hardware_exists = 1;
DBG("Activating: %s\n", xbus->busname);
-
/* Poll it */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- INIT_WORK(&xbus->xpds_init_work, xbus_poll);
-#else
- INIT_WORK(&xbus->xpds_init_work, xbus_poll, xbus);
-#endif
-
- if(!queue_work(xpp_worker, &xbus->xpds_init_work)) {
- ERR("Failed to queue xpd initialization work\n");
- /* FIXME: need to return error */
- }
+ poller_dispatch(xbus);
}
void xbus_disconnect(xbus_t *xbus)
@@ -685,6 +801,7 @@
device_remove_file(&xbus->the_bus, &dev_attr_status);
device_remove_file(&xbus->the_bus, &dev_attr_connector);
device_unregister(&xbus->the_bus);
+ poller_destroy(xbus->poller);
kfree(xbus);
}
@@ -697,17 +814,16 @@
DBG("%s\n", xbus->busname);
}
-
xbus_t *xbus_new(xbus_ops_t *ops)
{
- int err;
- xbus_t *xbus = NULL;
+ int err;
+ xbus_t *xbus = NULL;
+ struct xbus_poller *poller;
BUG_ON(!ops);
xbus = xbus_alloc();
if(!xbus)
return NULL;
-
/* Init data structures */
spin_lock_init(&xbus->lock);
snprintf(xbus->busname, XBUS_NAMELEN, "XBUS-%02d", xbus->num);
@@ -715,14 +831,13 @@
init_waitqueue_head(&xbus->packet_cache_empty);
atomic_set(&xbus->packet_counter, 0);
- /* poll related variables */
- atomic_set(&xbus->count_poll_answers, 0);
- atomic_set(&xbus->count_xpds_to_initialize, 0);
- atomic_set(&xbus->count_xpds_initialized, 0);
- INIT_LIST_HEAD(&xbus->poll_results);
- init_waitqueue_head(&xbus->wait_for_polls);
- init_waitqueue_head(&xbus->wait_for_xpd_initialization);
xbus->num_xpds = 0;
+ poller = poller_new(xbus);
+ if(!poller) {
+ ERR("Failed to allocate poller\n");
+ xbus_free(xbus);
+ return NULL;
+ }
init_rwsem(&xbus->in_use);
xbus_reset_counters(xbus);
@@ -866,14 +981,16 @@
#if CONFIG_PROC_FS
static int xbus_read_proc(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;
+ xbus_t *xbus = data;
+ struct xbus_poller *poller;
+ unsigned long flags;
+ int len = 0;
+ int i;
if(!xbus)
goto out;
spin_lock_irqsave(&xbus->lock, flags);
+ poller = xbus->poller;
len += sprintf(page + len, "%s: CONNECTOR=%s STATUS=%s bus_type=%d\n",
xbus->busname,
@@ -882,10 +999,10 @@
xbus->bus_type
);
len += sprintf(page + len, "POLLS: %d/%d\n",
- atomic_read(&xbus->count_poll_answers), MAX_XPDS);
+ atomic_read(&poller->count_poll_answers), MAX_XPDS);
len += sprintf(page + len, "XPDS_READY: %d/%d\n",
- atomic_read(&xbus->count_xpds_initialized),
- atomic_read(&xbus->count_xpds_to_initialize));
+ atomic_read(&poller->count_xpds_initialized),
+ atomic_read(&poller->count_xpds_to_initialize));
len += sprintf(page + len, "\nmax_packet_size=%d open_counter=%d packet_count=%d\n",
xbus->max_packet_size,
xbus->open_counter,
@@ -916,10 +1033,12 @@
int len = 0;
unsigned long flags;
xbus_t *xbus = data;
+ struct xbus_poller *poller;
int ret;
if(!xbus)
goto out;
+ poller = xbus->poller;
DBG("%s: Waiting for card initialization of %d XPD's max %d seconds\n", xbus->busname, MAX_XPDS, INITIALIZATION_TIMEOUT/HZ);
/*
* xbus_poll sets count_xpds_to_initialize only when polling is finished.
@@ -927,9 +1046,9 @@
* - It is none zero -- meaning we already have the poll results.
* - And all units have finished initialization.
*/
- ret = wait_event_interruptible_timeout(xbus->wait_for_xpd_initialization,
- atomic_read(&xbus->count_xpds_to_initialize) &&
- atomic_read(&xbus->count_xpds_initialized) >= atomic_read(&xbus->count_xpds_to_initialize),
+ ret = wait_event_interruptible_timeout(poller->wait_for_xpd_initialization,
+ atomic_read(&poller->count_xpds_to_initialize) &&
+ atomic_read(&poller->count_xpds_initialized) >= atomic_read(&poller->count_xpds_to_initialize),
INITIALIZATION_TIMEOUT);
if(ret == 0) {
ERR("%s: Card Initialization Timeout\n", xbus->busname);
@@ -942,8 +1061,8 @@
spin_lock_irqsave(&xbus->lock, flags);
len += sprintf(page + len, "XPDS_READY: %s: %d/%d\n",
xbus->busname,
- atomic_read(&xbus->count_xpds_initialized),
- atomic_read(&xbus->count_xpds_to_initialize));
+ atomic_read(&poller->count_xpds_initialized),
+ atomic_read(&poller->count_xpds_to_initialize));
spin_unlock_irqrestore(&xbus->lock, flags);
out:
if (len <= off+count)
@@ -1105,11 +1224,6 @@
static void xbus_core_cleanup(void)
{
- if (xpp_worker) {
- flush_workqueue(xpp_worker);
- destroy_workqueue(xpp_worker);
- xpp_worker = NULL;
- }
#ifdef XPP_DEBUGFS
if(debugfs_root) {
DBG("Removing xpp from debugfs\n");
@@ -1143,12 +1257,6 @@
NULL, NULL);
if(!xframes_cache) {
return -ENOMEM;
- }
- xpp_worker = create_singlethread_workqueue("xppworker");
- if(!xpp_worker) {
- ERR("Failed to create card detector workqueue.\n");
- ret = -ENOMEM;
- goto err;
}
#ifdef CONFIG_PROC_FS
proc_xbuses = create_proc_read_entry(PROC_XBUSES, 0444, xpp_proc_toplevel, read_proc_xbuses, NULL);
@@ -1201,6 +1309,7 @@
EXPORT_SYMBOL(xbus_reset_counters);
EXPORT_SYMBOL(xframe_next_packet);
EXPORT_SYMBOL(dump_xframe);
+EXPORT_SYMBOL(xbus_poller_notify);
#ifdef XPP_DEBUGFS
EXPORT_SYMBOL(xbus_log);
#endif
Modified: team/tzafrir/sync/xpp/xbus-core.h
URL: http://svn.digium.com/view/zaptel/team/tzafrir/sync/xpp/xbus-core.h?view=diff&rev=2228&r1=2227&r2=2228
==============================================================================
--- team/tzafrir/sync/xpp/xbus-core.h (original)
+++ team/tzafrir/sync/xpp/xbus-core.h Sun Feb 25 15:45:36 2007
@@ -61,6 +61,7 @@
void xbus_activate(xbus_t *xbus);
void xbus_disconnect(xbus_t *xbus);
+void xbus_poller_notify(xbus_t *xbus, struct card_desc_struct *card_desc);
void xbus_reset_counters(xbus_t *xbus);
int xbus_register_xpd(xbus_t *xbus, xpd_t *xpd);
Modified: team/tzafrir/sync/xpp/xpd.h
URL: http://svn.digium.com/view/zaptel/team/tzafrir/sync/xpp/xpd.h?view=diff&rev=2228&r1=2227&r2=2228
==============================================================================
--- team/tzafrir/sync/xpp/xpd.h (original)
+++ team/tzafrir/sync/xpp/xpd.h Sun Feb 25 15:45:36 2007
@@ -155,12 +155,34 @@
byte rev; /* Revision number */
byte type; /* LSB: 1 - to_phone, 0 - to_line */
xpd_addr_t xpd_addr;
+ xpp_line_t line_status; /* Initial line status (offhook) */
};
#ifdef XPP_DEBUGFS
/* definition in xbus-core.c */
struct debugfs_data;
#endif
+
+/*
+ * Encapsulate all poll related data of a single xbus.
+ */
+struct xbus_poller {
+ /*
+ * Bus scanning
+ */
+ xbus_t *xbus;
+ struct workqueue_struct *wq;
+ bool is_polling;
+ atomic_t count_poll_answers;
+ struct list_head poll_results;
+ wait_queue_head_t wait_for_polls;
+
+ struct work_struct xpds_init_work;
+
+ atomic_t count_xpds_to_initialize;
+ atomic_t count_xpds_initialized;
+ wait_queue_head_t wait_for_xpd_initialization;
+};
/*
* An xbus is a transport layer for Xorcom Protocol commands
@@ -186,18 +208,7 @@
atomic_t packet_counter; /* Allocated packets */
wait_queue_head_t packet_cache_empty;
- /*
- * 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;
-
- atomic_t count_xpds_to_initialize;
- atomic_t count_xpds_initialized;
- wait_queue_head_t wait_for_xpd_initialization;
+ struct xbus_poller *poller;
struct rw_semaphore in_use;
int num_xpds;
@@ -254,16 +265,6 @@
#undef C_
#define XPD_COUNTER_MAX (sizeof(xpd_counters)/sizeof(xpd_counters[0]))
-
-/* Values of SLIC register 0x40 */
-enum fxs_state {
- FXS_LINE_DISABLED = 0x00,
- FXS_LINE_ENABLED = 0x01,
- FXS_LINE_CID = 0x02,
- FXS_LINE_TIPOPEN = 0x03, /* For GroundStart signalling */
- FXS_LINE_RING = 0x04,
- FXS_LINE_REV_ACTIVE = 0x05
-};
/*
* An XPD is a single Xorcom Protocol Device
@@ -285,10 +286,6 @@
bool ringing[CHANNELS_PERXPD];
- enum fxs_state lasttxhook[CHANNELS_PERXPD];
- int idletxhookstate[CHANNELS_PERXPD]; /* IDLE changing hook state */
- int ohttimer[CHANNELS_PERXPD];
-
xbus_t *xbus; /* The XBUS we are connected to */
spinlock_t lock;
Modified: team/tzafrir/sync/xpp/xpp_usb.c
URL: http://svn.digium.com/view/zaptel/team/tzafrir/sync/xpp/xpp_usb.c?view=diff&rev=2228&r1=2227&r2=2228
==============================================================================
--- team/tzafrir/sync/xpp/xpp_usb.c (original)
+++ team/tzafrir/sync/xpp/xpp_usb.c Sun Feb 25 15:45:36 2007
@@ -266,8 +266,9 @@
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);
+ if((rate_limit++ % 5000) == 0)
+ ERR("%s: %s: more than %d pending writes (%d). Dropping.\n",
+ __FUNCTION__, xbus->busname, MAX_PENDING_WRITES, rate_limit);
ret = -ENODEV;
goto freepack;
}
Modified: team/tzafrir/sync/xpp/xpp_zap.c
URL: http://svn.digium.com/view/zaptel/team/tzafrir/sync/xpp/xpp_zap.c?view=diff&rev=2228&r1=2227&r2=2228
==============================================================================
--- team/tzafrir/sync/xpp/xpp_zap.c (original)
+++ team/tzafrir/sync/xpp/xpp_zap.c Sun Feb 25 15:45:36 2007
@@ -63,11 +63,30 @@
static unsigned int xpp_timer_count = 0;
static unsigned int xpp_last_jiffies = 0;
+#ifdef ZAPTEL_SYNC_TICK
+/*
+ * Statistics variables
+ */
+static struct timeval ticked_zaptel;
+static struct timeval ticked_xpp;
+static long usec_lag_curr; /* current: zaptel - xpp */
+static long usec_lag_prev; /* previous: zaptel - xpp */
+static long usec_delta; /* previous - current */
+static long usec_sigma; /* sum of deltas */
+static long status_cleared_at;
+static long since_status_clear;
+static bool zaptel_is_ticking;
+
+DEF_PARM_BOOL(sync_tick_active, 1, 0600, "Measure via zaptel sync_tick() method");
+
+static void sync_status_clear(void);
+#endif
+
DEF_PARM_BOOL(pcm_tasklet, 0, 0600, "Handle PCM in a tasklet (lower interrupt load)");
DEF_PARM(int, disable_pcm, 0, 0600, "Disable all PCM transmissions");
DEF_PARM(int, print_dbg, 0, 0600, "Print DBG statements");
-DEF_PARM_BOOL(zap_autoreg, 1, 0600, "Register spans automatically (1) or not (0)");
+DEF_PARM_BOOL(zap_autoreg, 0, 0600, "Register spans automatically (1) or not (0)");
DEF_PARM_BOOL(prefmaster, 1, 0600, "Do we want to be zaptel preferred sync master");
#ifdef XPP_EC_CHUNK
DEF_PARM_BOOL(xpp_ec, 1, 0400, "Do we use our own (1) or Zaptel's (0) echo canceller");
@@ -96,11 +115,11 @@
static DECLARE_TASKLET(tasklet_tick, xpp_tick, 0L);
static atomic_t missed_ticks = ATOMIC_INIT(0); /* In pcm_tasklet mode */
-static void external_sync(xpd_t *the_xpd)
-{
- int i, j;
-
- DBG("SYNC %s\n", (the_xpd)?"Astribanks":"HOST");
+static void external_sync(xbus_t *the_xbus)
+{
+ int i;
+
+ DBG("%s\n", (the_xbus) ? the_xbus->busname : "HOST");
// Shut all down
for(i = 0; i < MAX_BUSES; i++) {
xbus_t *xbus = xbus_of(i);
@@ -108,25 +127,27 @@
continue;
if (!xbus->hardware_exists)
continue;
- for(j = 0; j < MAX_XPDS; j++) {
- xpd_t *xpd = xpd_of(xbus, j);
- if(xpd) {
- CALL_XMETHOD(SYNC_SOURCE, xbus, xpd, 1, 0);
- }
- }
- }
- if(the_xpd)
- CALL_XMETHOD(SYNC_SOURCE, the_xpd->xbus, the_xpd, 1, 1);
+ CALL_PROTO(GLOBAL, SYNC_SOURCE, xbus, NULL, 1, 0);
+ }
+ if(the_xbus)
+ CALL_PROTO(GLOBAL, SYNC_SOURCE, the_xbus, NULL, 1, 1);
}
/*
* Change sync_master. May block. Cannot be called from atomic context
*/
-void sync_master_is(xpd_t *xpd)
-{
- DBG("SYNC MASTER CHANGED: %s => %s\n",
- (sync_master) ? sync_master->xpdname : "HOST",
- (xpd) ? xpd->xpdname : "HOST");
+static void sync_master_is(xbus_t *xbus)
+{
+ xpd_t *xpd = (xbus)? xpd_of(xbus, 0) : NULL;
+
+ if(xbus && !xpd) {
+ NOTICE("Cannot set sync master to %s (has no XPD #0).\n",
+ xbus->busname);
+ xbus = NULL; /* Fallback to HOST */
+ }
+ DBG("SYNC MASTER CHANGING: %s => %s\n",
+ (sync_master) ? sync_master->xbus->busname : "HOST",
+ (xbus) ? xbus->busname : "HOST");
/* First stop all generators */
[... 397 lines stripped ...]
More information about the zaptel-commits
mailing list