summaryrefslogtreecommitdiff
path: root/xpp/xbus-pcm.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-01-10 18:12:27 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-01-10 18:12:27 +0000
commit9899bafe997a4e020f302c99a6e025b4e8b25191 (patch)
tree8a108b05d0f319c95ba83f1d5984ae261572bebf /xpp/xbus-pcm.c
parent1d7d5b07325a186785b22abf09ff531dfc2edd54 (diff)
xpp.r5254:
* Improved polarity reversal hangups in FXO (r5194). Fixed false detection of polarity reversals. * Optimize xframe allocation, by not zeroing the whole memory (in get_xframe()). * Fixed erronous error message that appeared sometimes from fpga_load during USB renumeration. * Zaptel::Chans now provides battery() reporting for some FXO channels (Astribank FXO and wcfxo). git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3643 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/xbus-pcm.c')
-rw-r--r--xpp/xbus-pcm.c48
1 files changed, 30 insertions, 18 deletions
diff --git a/xpp/xbus-pcm.c b/xpp/xbus-pcm.c
index eb63b11..0b1e5d1 100644
--- a/xpp/xbus-pcm.c
+++ b/xpp/xbus-pcm.c
@@ -40,6 +40,9 @@ extern int print_dbg;
#include "supress/ec_xpp.h"
DEF_PARM_BOOL(xpp_ec, 0, 0444, "Do we use our own (1) or Zaptel's (0) echo canceller");
#endif
+#ifdef OPTIMIZE_CHANMUTE
+DEF_PARM_BOOL(optimize_chanmute, 1, 0644, "Optimize by muting inactive channels");
+#endif
DEF_PARM(int, disable_pcm, 0, 0644, "Disable all PCM transmissions");
#ifdef DEBUG_PCMTX
@@ -542,7 +545,7 @@ static void do_ec(xpd_t *xpd)
#ifdef WITH_ECHO_SUPPRESSION
/* FIXME: need to Echo cancel double buffered data */
for (i = 0;i < xpd->span.channels; i++) {
- if(unlikely(IS_SET(xpd->digital_signalling, i))) /* Don't echo cancel PRI/BRI D-chans */
+ if(unlikely(IS_SET(xpd->digital_signalling, i))) /* Don't echo cancel BRI D-chans */
continue;
#ifdef XPP_EC_CHUNK
/* even if defined, parameterr xpp_ec can override at run-time */
@@ -646,7 +649,7 @@ static inline void pcm_frame_out(xbus_t *xbus, xframe_t *xframe)
do_gettimeofday(&now);
if(unlikely(disable_pcm || !TRANSPORT_RUNNING(xbus)))
goto dropit;
- if(XPACKET_ADDR((xpacket_t *)xframe->packets).sync_master) {
+ if(XPACKET_ADDR_SYNC((xpacket_t *)xframe->packets)) {
usec = usec_diff(&now, &xbus->last_tx_sync);
xbus->last_tx_sync = now;
/* ignore startup statistics */
@@ -728,8 +731,11 @@ void generic_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack)
for (i = 0; i < xpd->channels; i++) {
volatile u_char *r = xpd->span.chans[i].readchunk;
- if(!IS_SET(xpd->wanted_pcm_mask, i))
+ if(!IS_SET(xpd->wanted_pcm_mask, i)) {
+ if(IS_SET(xpd->silence_pcm, i))
+ memset((u_char *)r, 0x7F, ZT_CHUNKSIZE); // SILENCE
continue;
+ }
pcm_mask &= ~xpd->mute_dtmf;
if(IS_SET(pcm_mask, i)) {
// memset((u_char *)r, 0x5A, ZT_CHUNKSIZE); // DEBUG
@@ -788,7 +794,7 @@ static int copy_pcm_tospan(xbus_t *xbus, xframe_t *xframe)
}
goto out;
}
- xpd = xpd_byaddr(xbus, XPACKET_ADDR(pack).unit, XPACKET_ADDR(pack).subunit);
+ xpd = xpd_byaddr(xbus, XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack));
if(unlikely(!xpd)) {
static int rate_limit;
@@ -827,16 +833,22 @@ static void xbus_tick(xbus_t *xbus)
for(i = 0; i < MAX_XPDS; i++) {
xpd = xpd_of(xbus, i);
if(xpd && SPAN_REGISTERED(xpd)) {
+#ifdef OPTIMIZE_CHANMUTE
+ int j;
+ xpp_line_t xmit_mask = xpd->wanted_pcm_mask;
+
+ xmit_mask |= xpd->silence_pcm;
+ xmit_mask |= xpd->digital_signalling;
+ for_each_line(xpd, j) {
+ xpd->chans[j].chanmute = (optimize_chanmute)
+ ? !IS_SET(xmit_mask, j)
+ : 0;
+ }
+#endif
/*
* calls to zt_transmit should be out of spinlocks, as it may call back
* our hook setting methods.
*/
-#ifdef OPTIMIZE_CHANMUTE
- int j;
-
- for_each_line(xpd, j)
- xpd->chans[j].chanmute = !IS_SET(xpd->wanted_pcm_mask, j) && !IS_SET(xpd->digital_signalling, j);
-#endif
zt_transmit(&xpd->span);
}
}
@@ -873,7 +885,7 @@ static void xbus_tick(xbus_t *xbus)
XPACKET_INIT(pack, GLOBAL, PCM_WRITE, xpd->xbus_idx, 1, 0);
XPACKET_LEN(pack) = pcm_len;
if(!sent_sync_bit) {
- XPACKET_ADDR(pack).sync_master = 1;
+ XPACKET_ADDR_SYNC(pack) = 1;
sent_sync_bit = 1;
}
CALL_XMETHOD(card_pcm_fromspan, xbus, xpd, xpd->wanted_pcm_mask, pack);
@@ -889,7 +901,7 @@ static void xbus_tick(xbus_t *xbus)
i = atomic_read(&xbus->pcm_rx_counter) & 1;
while((xframe = xframe_dequeue(&xbus->pcm_tospan[i])) != NULL) {
copy_pcm_tospan(xbus, xframe);
- if(XPACKET_ADDR((xpacket_t *)xframe->packets).sync_master) {
+ if(XPACKET_ADDR_SYNC((xpacket_t *)xframe->packets)) {
struct timeval now;
unsigned long usec;
@@ -920,6 +932,7 @@ static void xbus_tick(xbus_t *xbus)
do_ec(xpd);
zt_receive(&xpd->span);
}
+ xpd->silence_pcm = 0; /* silence was injected */
xpd->timer_count = xbus->global_counter;
/*
* Must be called *after* tx/rx so
@@ -967,7 +980,7 @@ void xframe_receive_pcm(xbus_t *xbus, xframe_t *xframe)
* of the frame, regardless of the XPD that is sync master.
* FIXME: what about PRI split?
*/
- if(XPACKET_ADDR((xpacket_t *)xframe->packets).sync_master) {
+ if(XPACKET_ADDR_SYNC((xpacket_t *)xframe->packets)) {
do_tick(xbus, xframe->tv_received);
atomic_inc(&xbus->pcm_rx_counter);
} else
@@ -1050,11 +1063,6 @@ static int proc_sync_write(struct file *file, const char __user *buffer, unsigne
ERR("No bus %d exists\n", xbus_num);
return -ENXIO;
}
- if((xpd = xpd_of(xbus, 0)) == NULL) {
- XBUS_ERR(xbus, "No xpd 0 exists\n");
- put_xbus(xbus);
- return -ENXIO;
- }
update_sync_master(xbus);
put_xbus(xbus);
} else if(sscanf(buf, "QUERY=%d", &xbus_num) == 1) {
@@ -1101,6 +1109,10 @@ int xbus_pcm_init(struct proc_dir_entry *toplevel)
struct proc_dir_entry *ent;
#endif
+#ifdef OPTIMIZE_CHANMUTE
+ INFO("FEATURE: with CHANMUTE optimization (%sactivated)\n",
+ (optimize_chanmute)?"":"de");
+#endif
#ifdef WITH_ECHO_SUPPRESSION
INFO("FEATURE: with ECHO_SUPPRESSION\n");
#else