summaryrefslogtreecommitdiff
path: root/xpp
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-12-01 05:22:55 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-12-01 05:22:55 +0000
commit61cc6e4ac8324b1e38a5c3bb543d1d262552bb78 (patch)
treef7bb41b90f90de1da1fd639af14ebe33b9a8c5f3 /xpp
parentb3764b4070cb7a595062bf986236eafc03a4ef0b (diff)
Merging from 1.2:
* Removing -DSOFT_RING: unused, useless code. * Register init scripts are not as noisy by default. * Register init scripts read configuration from a standard location. * Fixed a FXO spinlock race. (Log was lost on previos merge) git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1680 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp')
-rw-r--r--xpp/Makefile2
-rw-r--r--xpp/README.Astribank28
-rwxr-xr-xxpp/calibrate_slics42
-rw-r--r--xpp/card_fxo.c115
-rw-r--r--xpp/card_fxs.c6
-rw-r--r--xpp/card_global.c41
-rwxr-xr-xxpp/init_card_3_2319
-rwxr-xr-xxpp/init_card_4_2322
-rw-r--r--xpp/utils/Makefile6
-rw-r--r--xpp/xbus-core.c32
10 files changed, 153 insertions, 160 deletions
diff --git a/xpp/Makefile b/xpp/Makefile
index bef84cf..e0a9152 100644
--- a/xpp/Makefile
+++ b/xpp/Makefile
@@ -1,4 +1,4 @@
-EXTRA_CFLAGS = -g3 -I$(SUBDIRS) -DDEBUG -DPOLL_DIGITAL_INPUTS -DWITH_ECHO_SUPPRESSION # -DSOFT_RING
+EXTRA_CFLAGS = -g3 -I$(SUBDIRS) -DDEBUG -DPOLL_DIGITAL_INPUTS -DWITH_ECHO_SUPPRESSION
obj-m += xpp.o xpd_fxs.o xpd_fxo.o
diff --git a/xpp/README.Astribank b/xpp/README.Astribank
index e45bde9..f0f93b5 100644
--- a/xpp/README.Astribank
+++ b/xpp/README.Astribank
@@ -329,6 +329,34 @@ file.
(There are a bunch of other status files under /proc/xpp/ )
+Zaptel Init Configuration File
+""""""""""""""""""""""""""""""
+The zaptel init.d script, genzaptelconf and the XPD init scripts source
+the file /etc/init.d/zaptel (on Debian) or /etc/sysconfig/zaptel (on
+RedHats). A number of useful values for there:
+
+###############################
+# Lines beginning with '#' are considered comments and ignored.
+
+# A two-letter country code. genzaptelconf uses it to better guess
+# the configuration it generates. E.g: the signalling of E1 spans, and
+# a few other country-specific settings.
+lc_country=us
+
+# See genzaptelconf(8) and the script itself for a longer list of
+# variables.
+
+# Equivalent to the parameter opermode to the module wctdm: country-specific
+# settings to the FXO lines. For a complete list of possible values, see
+# /usr/share/zaptel/init_fxo_mode .
+#opermode=FCC
+#opermode=FRANCE
+
+# If you feel like flooding your logs with debug output of the calibration
+# process:
+#DEBUG_CALIBRATION=1
+###############################
+
Useful Module Parameters:
""""""""""""""""""""""""
zap_autoreg: (xpp)
diff --git a/xpp/calibrate_slics b/xpp/calibrate_slics
index 72ca202..c639832 100755
--- a/xpp/calibrate_slics
+++ b/xpp/calibrate_slics
@@ -15,11 +15,21 @@ if ( ! -f $SlicsFile ) {
exit 1
}
+my $debug = 0;
+# set DEBUG_CALIBRATION in /etc/default/zaptel or similar
+if (exists $ENV{DEBUG_CALIBRATION}) {
+ $debug = 1;
+}
+
sub logger($) {
print STDERR "LOG: @_\n";
system("logger @_");
}
+sub debug($) {
+ logger(@_) if ($debug);
+}
+
sub write_to_slic_file($) {
my $write_str = shift;
@@ -45,11 +55,11 @@ sub read_reg($$$) {
my @reply = ();
while(<SLICS>){
#if (/^ /) {
- # print STDERR "answer line: $_";
+ # debug "answer line: $_";
#}
if (/^ \d*\s+[RW][DIS]\s+[[:xdigit:]]+\s+([[:xdigit:]]+)\s+([[:xdigit:]]+)/){
@reply = (hex($1), hex($2));
- #print STDERR "got [$reply]\n";
+ #debug "got [$reply]\n";
last;
}
}
@@ -83,7 +93,7 @@ sub log_calib_params() {
for my $slic (@SlicNums) {
$line .= " ".read_reg($slic, $i, 'D');
}
- logger($line);
+ debug($line);
}
}
@@ -209,17 +219,17 @@ sub manual_calibrate_loop($$) {
# wait until all slics have finished calibration, or for timeout
while ($calibration_in_progress) {
$calibration_in_progress = 0; # until proven otherwise
- print STDERR "ManualCalib:: ";
+ my $debug_calib_str = "ManualCalib:: ";
for my $slic(@SlicNums) {
my $value = read_reg($slic, $read_reg, 'D');
- print STDERR " [$slic_counters[$slic]:$value]";
+ $debug_calib_str .= " [$slic_counters[$slic]:$value]";
if ($value != 0 && $slic_counters[$slic] >= 0) {
$calibration_in_progress = 1;
$slic_counters[$slic]--;
write_reg($slic,$write_reg,'D',$slic_counters[$slic]);
}
}
- print STDERR "\n";
+ debug($debug_calib_str);
# TODO: unnecessary sleep in the last round:
sleep $ManualCalibrationSleepTime;
}
@@ -247,20 +257,20 @@ sub auto_calibrate($$) {
my $end_time=time() + 2;
my $timeout=0;
CALIB_LOOP: for my $slic (@SlicNums) {
- logger("checking slic $slic");
+ debug("checking slic $slic");
while(1) {
if ((read_reg($slic, 60, 'D')) == 0) {
# move to next register
- logger("slic $slic calibrated");
+ debug("slic $slic calibrated");
last;
}
my $time=time();
if ( $time > $end_time) {
$timeout=1;
- logger("Exiting on timeout: $end_time < $time.");
+ debug("Exiting on timeout: $end_time < $time.");
last CALIB_LOOP;
}
- logger("auto_calibrate not done yet: slic #$slic\n");
+ debug("auto_calibrate not done yet: slic #$slic\n");
sleep(0.1);
}
}
@@ -277,17 +287,17 @@ sub auto_calibrate($$) {
#read_reg($slic, 0x0B, 'D'): 0x33
#read_reg($slic, 0x40, 'D'): 0x00 (?)
-print STDERR "starting\n";
+debug "starting\n";
init_indirect_registers();
-print STDERR "after init_indirect_registers\n";
+debug "after init_indirect_registers\n";
init_early_direct_regs();
-print STDERR "after init_early_direct_regs\n";
+debug "after init_early_direct_regs\n";
auto_calibrate(0x47, 0x1E);
-print STDERR "after auto_calibrate\n";
+debug "after auto_calibrate\n";
manual_calibrate();
-print STDERR "after manul_calibrate\n";
+debug "after manul_calibrate\n";
auto_calibrate(0x40, 0x01);
-print STDERR "after auto_calibrate 2\n";
+debug "after auto_calibrate 2\n";
diff --git a/xpp/card_fxo.c b/xpp/card_fxo.c
index 7672db3..d3e7637 100644
--- a/xpp/card_fxo.c
+++ b/xpp/card_fxo.c
@@ -80,11 +80,6 @@ static int handle_register_command(xpd_t *xpd, char *cmdline);
#define PROC_REGISTER_FNAME "slics"
#define PROC_FXO_INFO_FNAME "fxo_info"
-#ifdef SOFT_RING
-#define POLL_RING_INTERVAL 2
-#define RING_THRESHOLD 3
-#define NORING_THRESHOLD 10
-#endif
#define DAA_RING_REGISTER 0x05
struct FXO_priv_data {
@@ -96,15 +91,6 @@ struct FXO_priv_data {
xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */
xpp_line_t ledcontrol[NUM_LEDS]; /* 0 - OFF, 1 - ON */
int blinking[NUM_LEDS][CHANNELS_PERXPD];
-#ifdef SOFT_RING
- ushort ring_thresh[CHANNELS_PERXPD];
- ushort noring_thresh[CHANNELS_PERXPD];
- /* ring_sig is set when Reg5, bit 2 (Ring Detect) is set.
- * While ring_sig=1 we check R5 bit 20H and 40H for ringing.
- * When it drops to 0 that's the end of the ring sequence and
- * we clear the ring detection variables */
- ushort ring_sig[CHANNELS_PERXPD];
-#endif
};
/*---------------- FXO: Static functions ----------------------------------*/
@@ -187,7 +173,7 @@ static void handle_fxo_leds(xpd_t *xpd)
spin_unlock_irqrestore(&xpd->lock, flags);
}
-static void mark_ring(xpd_t *xpd, lineno_t pos, bool on)
+static void mark_ring(xpd_t *xpd, lineno_t pos, bool on, bool update_zap)
{
struct FXO_priv_data *priv;
@@ -197,13 +183,15 @@ static void mark_ring(xpd_t *xpd, lineno_t pos, bool on)
DBG("%s/%s/%d: START\n", xpd->xbus->busname, xpd->xpdname, pos);
xpd->ringing[pos] = 1;
MARK_BLINK(priv, pos, LED_GREEN, LED_BLINK);
- update_zap_ring(xpd, pos, 1);
+ if(update_zap)
+ update_zap_ring(xpd, pos, on);
} else if(!on && xpd->ringing[pos]) {
DBG("%s/%s/%d: STOP\n", xpd->xbus->busname, xpd->xpdname, pos);
xpd->ringing[pos] = 0;
if(IS_BLINKING(priv, pos, LED_GREEN))
MARK_BLINK(priv, pos, LED_GREEN, 0);
- update_zap_ring(xpd, pos, 0);
+ if(update_zap)
+ update_zap_ring(xpd, pos, on);
}
}
@@ -224,14 +212,11 @@ static int do_sethook(xpd_t *xpd, int pos, bool to_offhook)
NOTICE("%s/%s/%d: WARNING: called while battery is off\n", xbus->busname, xpd->xpdname, pos);
}
spin_lock_irqsave(&xpd->lock, flags);
- mark_ring(xpd, pos, 0); // No more rings
+ mark_ring(xpd, pos, 0, 0); // No more rings
value = (to_offhook) ? 0x09 : 0x08; /* Bit 3 is for CID */
DBG("%s/%s/%d: SETHOOK: value=0x%02X %s\n", xbus->busname, xpd->xpdname, pos, value, (to_offhook)?"OFFHOOK":"ONHOOK");
MARK_LED(xpd, pos, LED_GREEN, (to_offhook)?LED_ON:LED_OFF);
ret = DAA_DIRECT_REQUEST(xbus, xpd, pos, DAA_WRITE, DAA_RING_REGISTER, value);
-#ifdef SOFT_RING
- priv->ring_sig[pos] = 0;
-#endif
if(to_offhook) {
BIT_SET(xpd->offhook, pos);
} else {
@@ -362,7 +347,7 @@ static int FXO_card_zaptel_preregistration(xpd_t *xpd, bool on)
MARK_LED(xpd, ALL_LINES, LED_GREEN, LED_OFF);
for_each_line(xpd, i) {
MARK_LED(xpd, i, LED_GREEN, LED_ON);
- mdelay(50);
+ msleep(50);
}
return 0;
}
@@ -381,7 +366,7 @@ static int FXO_card_zaptel_postregistration(xpd_t *xpd, bool on)
DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on);
for_each_line(xpd, i) {
MARK_LED(xpd, i, LED_GREEN, LED_OFF);
- mdelay(50);
+ msleep(50);
}
return 0;
}
@@ -420,21 +405,6 @@ static void poll_battery(xbus_t *xbus, xpd_t *xpd)
}
}
-#ifdef SOFT_RING
-static void poll_ring(xbus_t *xbus, xpd_t *xpd)
-{
- int i;
- struct FXO_priv_data *priv;
-
- priv = xpd->priv;
- BUG_ON(!priv);
- for_each_line(xpd, i) {
- if(priv->ring_sig[i])
- DAA_DIRECT_REQUEST(xbus, xpd, i, DAA_READ, DAA_RING_REGISTER, 0);
- }
-}
-#endif
-
static int FXO_card_tick(xbus_t *xbus, xpd_t *xpd)
{
struct FXO_priv_data *priv;
@@ -445,10 +415,6 @@ static int FXO_card_tick(xbus_t *xbus, xpd_t *xpd)
if(poll_battery_interval != 0 && (priv->poll_counter % poll_battery_interval) == 0) {
poll_battery(xbus, xpd);
}
-#ifdef SOFT_RING
- if((priv->poll_counter % POLL_RING_INTERVAL) == 0)
- poll_ring(xbus, xpd);
-#endif
handle_fxo_leds(xpd);
priv->poll_counter++;
return 0;
@@ -489,7 +455,7 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
ret = handle_register_command(xpd, buf);
if(ret < 0)
return ret;
- mdelay(1);
+ msleep(1);
}
DBG("-- Set echo registers successfully\n");
@@ -546,11 +512,11 @@ static /* 0x0F */ HOSTCMD(FXO, XPD_STATE, bool on)
if(on) {
for_each_line(xpd, i) {
MARK_LED(xpd, i, LED_GREEN, LED_ON);
- mdelay(20);
+ msleep(20);
}
for_each_line(xpd, i) {
MARK_LED(xpd, i, LED_GREEN, LED_OFF);
- mdelay(20);
+ msleep(20);
}
}
return ret;
@@ -606,21 +572,7 @@ HANDLER_DEF(FXO, SIG_CHANGED)
xbus->busname, xpd->xpdname, i);
continue;
}
- if(IS_SET(sig_status, i)) {
-#ifdef SOFT_RING
- priv->ring_sig[i]=1; /* trigger register polling */
- /* reset ring check counters */
- priv->ring_thresh[i] = 0;
- priv->noring_thresh[i] = 0;
-#else
- mark_ring(xpd, i, 1);
-#endif
- } else {
-#ifdef SOFT_RING
- priv->ring_sig[i] = 0;
-#endif
- mark_ring(xpd, i, 0);
- }
+ mark_ring(xpd, i, IS_SET(sig_status, i), 1);
}
}
spin_unlock_irqrestore(&xpd->lock, flags);
@@ -667,25 +619,6 @@ HANDLER_DEF(FXO, DAA_REPLY)
}
}
}
-#ifdef SOFT_RING
- if(REG_FIELD(info, regnum) == DAA_RING_REGISTER && priv->ring_sig[chipsel]) {
- bool ringit = (REG_FIELD(info, data_low) & (0x20 | 0x40)) ? 1 : 0; /* Ring positive | Ring negative */
-
- if(ringit) {
- if(priv->ring_thresh[chipsel] > RING_THRESHOLD) {
- mark_ring(xpd, chipsel, 1);
- priv->noring_thresh[chipsel] = 0;
- } else
- priv->ring_thresh[chipsel]++;
- } else {
- if(priv->noring_thresh[chipsel] > NORING_THRESHOLD) {
- mark_ring(xpd, chipsel, 0);
- priv->ring_thresh[chipsel] = 0;
- } else
- priv->noring_thresh[chipsel]++;
- }
- }
-#endif
#if 0
DBG("DAA_REPLY: xpd #%d %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
xpd->id, (info->size == 3)?"I":"D",
@@ -779,23 +712,6 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count, in
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
len += sprintf(page + len, "%2d ", IS_BLINKING(priv,i,LED_GREEN));
}
-#ifdef SOFT_RING
- len += sprintf(page + len, "\n\t%-17s: ", "ring_thresh");
- for_each_line(xpd, i) {
- if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
- len += sprintf(page + len, "%2d ", priv->ring_thresh[i]);
- }
- len += sprintf(page + len, "\n\t%-17s: ", "noring_thresh");
- for_each_line(xpd, i) {
- if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
- len += sprintf(page + len, "%2d ", priv->noring_thresh[i]);
- }
- len += sprintf(page + len, "\n\t%-17s: ", "ring_sig");
- for_each_line(xpd, i) {
- if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
- len += sprintf(page + len, "%2d ", priv->ring_sig[i]);
- }
-#endif
len += sprintf(page + len, "\n\t%-17s: ", "battery");
for_each_line(xpd, i) {
len += sprintf(page + len, "%2d ", IS_SET(priv->battery, i));
@@ -942,7 +858,7 @@ static int proc_xpd_register_write(struct file *file, const char __user *buffer,
ret = handle_register_command(xpd, buf);
if(ret < 0)
return ret;
- mdelay(1);
+ msleep(1);
}
return count;
}
@@ -982,11 +898,6 @@ static int proc_xpd_register_read(char *page, char **start, off_t off, int count
int __init card_fxo_startup(void)
{
INFO("%s revision %s\n", THIS_MODULE->name, ZAPTEL_VERSION);
-#ifdef SOFT_RING
- INFO("FEATURE: %s with SOFT_RING\n", THIS_MODULE->name);
-#else
- INFO("FEATURE: %s without SOFT_RING\n", THIS_MODULE->name);
-#endif
xproto_register(&PROTO_TABLE(FXO));
return 0;
}
diff --git a/xpp/card_fxs.c b/xpp/card_fxs.c
index 3d659fa..b5c6538 100644
--- a/xpp/card_fxs.c
+++ b/xpp/card_fxs.c
@@ -343,7 +343,7 @@ static int FXS_card_zaptel_preregistration(xpd_t *xpd, bool on)
spin_unlock_irqrestore(&xpd->lock, flags);
for_each_line(xpd, i) {
MARK_LED(priv, i, color, LED_ON);
- mdelay(50);
+ msleep(50);
}
return 0;
}
@@ -363,7 +363,7 @@ static int FXS_card_zaptel_postregistration(xpd_t *xpd, bool on)
DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on);
for_each_line(xpd, i) {
MARK_LED(priv, i, color, LED_OFF);
- mdelay(50);
+ msleep(50);
}
return 0;
}
@@ -946,7 +946,7 @@ static int proc_xpd_register_write(struct file *file, const char __user *buffer,
ret = handle_register_command(xpd, buf);
if(ret < 0)
return ret;
- mdelay(1);
+ msleep(1);
}
return count;
}
diff --git a/xpp/card_global.c b/xpp/card_global.c
index 4740eab..22456bc 100644
--- a/xpp/card_global.c
+++ b/xpp/card_global.c
@@ -30,15 +30,6 @@
static const char rcsid[] = "$Id$";
DEF_PARM(charp,initdir, "/usr/share/zaptel", "The directory of card initialization scripts");
-/*
- * BRI: Temporary software workaround for firmware limitation:
- * - The BRI firmware count PCM channel number globally across subunits.
- * - The module parameter 'bri_pcmshift' enables us to cheat and shift
- * each B-channel, 4 bits for each subsequent subunit.
- * - Eventually, this should be fixed in the firmware, otherwise we won't
- * handle PRI (all the space we have is 32bits).
- */
-DEF_PARM(bool,bri_pcmshift, 1, "TESTING: shift bri PCM bits by subunit number");
extern int print_dbg;
static bool pcm_valid(xpd_t *xpd, xpacket_t *pack);
@@ -94,7 +85,11 @@ static void global_packet_dump(const char *msg, xpacket_t *pack);
}
buf += ZT_CHUNKSIZE;
}
- if(bri_pcmshift) { /* workaround for pcm problem in BRI */
+ /*
+ * BRI: Software workaround for firmware limitation.
+ * The BRI firmware count PCM channel number globally across subunits.
+ */
+ if(xpd->type == XPD_TYPE_BRI_NT || xpd->type == XPD_TYPE_BRI_TE) {
lines = lines << (xpd->addr.subunit * 4);
RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = lines;
}
@@ -153,17 +148,22 @@ HANDLER_DEF(GLOBAL, DEV_DESC)
card_desc->type = type;
card_desc->rev = rev;
card_desc->xpd_addr = xpd_addr;
+ 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);
- 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);
+ /*
+ * 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);
return 0;
}
@@ -176,6 +176,7 @@ HANDLER_DEF(GLOBAL, PCM_READ)
volatile u_char *r;
unsigned long flags;
int i;
+ xpp_line_t old_lines = lines;
BUG_ON(!xbus);
if(!xpd) {
@@ -188,11 +189,20 @@ HANDLER_DEF(GLOBAL, PCM_READ)
}
// DBG("lines=0x%04X\n", lines);
- if(bri_pcmshift) { /* workaround for pcm problem in BRI */
+ /*
+ * BRI: Software workaround for firmware limitation.
+ * The BRI firmware count PCM channel number globally across subunits.
+ */
+ if(xpd->type == XPD_TYPE_BRI_NT || xpd->type == XPD_TYPE_BRI_TE) {
lines = (lines >> (xpd->addr.subunit * 4)) & 0x7;
RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = lines;
}
if(!pcm_valid(xpd, pack)) {
+ static int rate_limit;
+
+ if((rate_limit++ % 5001) == 0)
+ ERR("%s/%s: old_lines=0x%04X lines=0x%04X subunit=%d\n",
+ xpd->xbus->busname, xpd->xpdname, old_lines, lines, xpd->addr.subunit);
return -EPROTO;
}
spin_lock_irqsave(&xpd->lock, flags);
@@ -313,7 +323,8 @@ static bool pcm_valid(xpd_t *xpd, xpacket_t *pack)
XPD_COUNTER(xpd, RECV_ERRORS)++;
if((rate_limit++ % 1000) <= 10) {
- ERR("BAD PCM REPLY: pack->datalen=%d, count=%d\n", pack->datalen, count);
+ ERR("%s/%s: BAD PCM REPLY: pack->datalen=%d, count=%d\n",
+ xpd->xbus->busname, xpd->xpdname, pack->datalen, count);
dump_packet("BAD PCM REPLY", pack, 1);
}
return 0;
diff --git a/xpp/init_card_3_23 b/xpp/init_card_3_23
index 5698484..3f07578 100755
--- a/xpp/init_card_3_23
+++ b/xpp/init_card_3_23
@@ -46,10 +46,21 @@ XPP_BASE=/proc/xpp
export XPP_BASE
LOGGER="logger -s -t $me"
+ZAPTEL_BOOT_DEBIAN=${ZAPTEL_BOOT_DEBIAN:-/etc/default/zaptel}
+ZAPTEL_BOOT_FEDORA=${ZAPTEL_BOOT_FEDORA:-/etc/sysconfig/zaptel}
+
+# read default configuration from /etc/default/zaptel
+if [ -r $ZAPTEL_BOOT_DEBIAN ]; then . $ZAPTEL_BOOT_DEBIAN; fi
+if [ -r $ZAPTEL_BOOT_FEDORA ]; then . $ZAPTEL_BOOT_FEDORA; fi
+
+if [ "$DEBUG_CALIBRATION"=1 ]; then
+ LOGGER=":"
+fi
+
# Always redirect stderr somewhere, otherwise the shell script will die
# when it tries to do I/O related stuff on closed file descriptor.
# Our default is to throw it down the bit-bucket.
-exec 2> /dev/null
+exec 2> /dev/console
## If you wish to trace this script:
#exec 2> /tmp/xpp_init_$XPD_NAME
## Altenativly, if you have multiple XBUS'es:
@@ -65,8 +76,7 @@ $LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Calibrating '$0'"
$LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Continue '$0'"
-sed -e 's/[;#].*$//' -e '/^[ ]*$/d' <<END_OF_FILE
-
+echo "
# Change SLICs states to "Open state"s (Off,all transfers tristated to avoid data collision), Voltage sense
31 WD 40 00
@@ -169,8 +179,7 @@ sed -e 's/[;#].*$//' -e '/^[ ]*$/d' <<END_OF_FILE
#31 WD 4A 34
#31 WD 4B 10
-
-END_OF_FILE
+" | sed -e 's/[;#].*$//' -e '/^[ ]*$/d'
$LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Ending '$0'"
exit 0
diff --git a/xpp/init_card_4_23 b/xpp/init_card_4_23
index 155a029..7a2e275 100755
--- a/xpp/init_card_4_23
+++ b/xpp/init_card_4_23
@@ -44,10 +44,21 @@ XPP_BASE=/proc/xpp
export XPP_BASE
LOGGER="logger -s -t $me"
+ZAPTEL_BOOT_DEBIAN=${ZAPTEL_BOOT_DEBIAN:-/etc/default/zaptel}
+ZAPTEL_BOOT_FEDORA=${ZAPTEL_BOOT_FEDORA:-/etc/sysconfig/zaptel}
+
+# read default configuration from /etc/default/zaptel
+if [ -r $ZAPTEL_BOOT_DEBIAN ]; then . $ZAPTEL_BOOT_DEBIAN; fi
+if [ -r $ZAPTEL_BOOT_FEDORA ]; then . $ZAPTEL_BOOT_FEDORA; fi
+
+if [ "$DEBUG_CALIBRATION"=1 ]; then
+ LOGGER=":"
+fi
+
# Always redirect stderr somewhere, otherwise the shell script will die
# when it tries to do I/O related stuff on closed file descriptor.
# Our default is to throw it down the bit-bucket.
-exec 2> /dev/null
+exec 2> /dev/console
## If you wish to trace this script:
#exec 2> /tmp/xpp_init_$XPD_NAME
## Altenativly, if you have multiple XBUS'es:
@@ -69,12 +80,12 @@ set_daa_country_params() {
. $INIT_DIR/init_fxo_modes
fi
# Our register numbers are HEXADECIMAL!
- cat <<EOF
+ echo "
31 WD 10 $reg16
31 WD 1A $reg26
31 WD 1E $reg30
31 WD 1F $reg31
-EOF
+"
# for the FXS:
#if [ "$ring_osc" != '' ]; then
# /bin/echo "31 WI __ $ring_osc"
@@ -86,7 +97,7 @@ EOF
# Remove empty lines and commets. Not strictly necessary
# but works around some limitations of the proc interface:
-sed -e 's/[;#].*$//' -e '/^[ ]*$/d' <<END_OF_FILE
+echo "
31 WD 21 28
@@ -141,8 +152,7 @@ sed -e 's/[;#].*$//' -e '/^[ ]*$/d' <<END_OF_FILE
# Set tip to ring voltage to 3.5 volts while off-hook
# instead of default of 3.1
31 WD 1A C0
-
-END_OF_FILE
+" | sed -e 's/[;#].*$//' -e '/^[ ]*$/d'
set_daa_country_params "$opermode"
diff --git a/xpp/utils/Makefile b/xpp/utils/Makefile
index 64341f7..c565093 100644
--- a/xpp/utils/Makefile
+++ b/xpp/utils/Makefile
@@ -66,14 +66,14 @@ test_parse.o: test_parse.c hexfile.h
test_parse: test_parse.o libhexfile.a
$(CC) -L. -o $@ $@.o $(EXTRA_LIBS) -lhexfile -lusb
-print_modes.o: print_modes.c wctdm_fxomodes.h
- $(HOSTCC) $(CFLAGS) -c $<
+print_modes: print_modes.c wctdm_fxomodes.h
+ $(HOSTCC) -o $@ $(CFLAGS) $<
wctdm_fxomodes.h: $(WCTDM)
perl -n -e 'print if (/^static struct fxo_mode {$$/ .. /};$$/)' $(WCTDM) >$@
init_fxo_modes: print_modes
- ./$^ >$@
+ ./$< >$@
clean:
$(RM) *.o $(TARGETS)
diff --git a/xpp/xbus-core.c b/xpp/xbus-core.c
index 9f73a86..59db079 100644
--- a/xpp/xbus-core.c
+++ b/xpp/xbus-core.c
@@ -33,7 +33,7 @@
#include <linux/ctype.h>
#endif
#include <linux/device.h>
-#include <linux/delay.h> /* for mdelay() to debug */
+#include <linux/delay.h> /* for msleep() to debug */
#include "xpd.h"
#include "xpp_zap.h"
#include "xbus-core.h"
@@ -42,7 +42,7 @@
static const char rcsid[] = "$Id$";
/* Defines */
-#define POLL_TIMEOUT (MAX_XPDS) /* in jiffies */
+#define POLL_TIMEOUT (2*MAX_XPDS) /* in jiffies */
#define INITIALIZATION_TIMEOUT (40*HZ) /* in jiffies */
#define PROC_XBUSES "xbuses"
#define PROC_XBUS_SUMMARY "summary"
@@ -55,6 +55,7 @@ static int proc_xbus_command_write(struct file *file, const char __user *buffer,
/* Command line parameters */
extern int print_dbg;
+DEF_PARM(uint, poll_timeout, POLL_TIMEOUT,"Timeout (in jiffies) waiting for units to reply (default " __stringify(POLL_TIMEOUT) ")");
/* Forward declarations */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
@@ -226,7 +227,7 @@ static int xbus_poll(void *data)
ERR("%s is being removed...\n", xbus->busname);
return -EBUSY;
}
- mdelay(2); /* roundtrip for older polls */
+ msleep(2); /* roundtrip for older polls */
spin_lock_irqsave(&xbus->lock, flags);
DBG("%s\n", xbus->busname);
@@ -250,16 +251,18 @@ static int xbus_poll(void *data)
/*
* 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);
+ 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);
if(ret == 0) {
- ERR("%s: Poll timeout\n", xbus->busname);
- goto out;
+ ERR("%s: Poll timeout. Continuing anyway.\n", xbus->busname);
+ /*
+ * Continue processing. Maybe some units did reply.
+ */
} else if(ret < 0) {
ERR("%s: Poll interrupted %d\n", xbus->busname, ret);
goto out;
- }
- DBG("%s: Poll finished in %d jiffies. Start processing.\n", xbus->busname, POLL_TIMEOUT - ret);
+ } else
+ DBG("%s: Poll finished in %d jiffies.\n", xbus->busname, poll_timeout - ret);
/*
* Build removals/additions lists
*/
@@ -288,6 +291,10 @@ static int xbus_poll(void *data)
kfree(card_desc);
}
}
+ /*
+ * 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);
spin_unlock_irqrestore(&xbus->lock, flags);
INFO("%s: Poll results: removals=%d additions=%d\n", xbus->busname, count_removed, count_added);
@@ -659,7 +666,14 @@ static int xbus_read_waitfor_xpds(char *page, char **start, off_t off, int count
if(!xbus)
goto out;
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.
+ * To prevent race conditions we test both:
+ * - 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),
INITIALIZATION_TIMEOUT);
if(ret == 0) {