From 4ba510314a8dcd24bbcd32af137439c75f4c652f Mon Sep 17 00:00:00 2001 From: tzafrir Date: Sun, 30 Nov 2008 12:10:03 +0000 Subject: xpp: PCM changes and related bugfixes. * Power-denial signalling is now sent to Zaptel to decide if we're LS or KS (and not hang up ourselves always). * Fix card_fxo's caller_id_style=1 (FSK). * Macro XPD_CHAN: s/xpd->chans[i]/XPD_CHAN(xpd, i)/ to reduce diff from DAHDI. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@4590 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- kernel/xpp/xbus-pcm.c | 65 +++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 36 deletions(-) (limited to 'kernel/xpp/xbus-pcm.c') diff --git a/kernel/xpp/xbus-pcm.c b/kernel/xpp/xbus-pcm.c index a5c186c..ef92a88 100644 --- a/kernel/xpp/xbus-pcm.c +++ b/kernel/xpp/xbus-pcm.c @@ -580,19 +580,18 @@ void elect_syncer(const char *msg) * This function is used by FXS/FXO. The pcm_mask argument signifies * channels which should be *added* to the automatic calculation. * Normally, this argument is 0. - * - * The caller should spinlock the XPD before calling it. */ -void __pcm_recompute(xpd_t *xpd, xpp_line_t pcm_mask) +void generic_card_pcm_recompute(xbus_t *xbus, xpd_t *xpd, xpp_line_t pcm_mask) { int i; int line_count = 0; + unsigned long flags; - XPD_DBG(SIGNAL, xpd, "pcm_mask=0x%X\n", pcm_mask); + spin_lock_irqsave(&xpd->lock_recompute_pcm, flags); + //XPD_DBG(SIGNAL, xpd, "pcm_mask=0x%X\n", pcm_mask); /* Add/remove all the trivial cases */ - pcm_mask |= xpd->offhook; - pcm_mask |= xpd->cid_on; - pcm_mask &= ~xpd->digital_signalling; /* No PCM in D-Channels */ + pcm_mask |= xpd->offhook_state; + pcm_mask |= xpd->oht_pcm_pass; pcm_mask &= ~xpd->digital_inputs; pcm_mask &= ~xpd->digital_outputs; for_each_line(xpd, i) @@ -610,18 +609,9 @@ void __pcm_recompute(xpd_t *xpd, xpp_line_t pcm_mask) ? RPACKET_HEADERSIZE + sizeof(xpp_line_t) + line_count * ZT_CHUNKSIZE : 0L; xpd->wanted_pcm_mask = pcm_mask; -} - -/* - * A spinlocked version of __pcm_recompute() - */ -void pcm_recompute(xpd_t *xpd, xpp_line_t pcm_mask) -{ - unsigned long flags; - - spin_lock_irqsave(&xpd->lock, flags); - __pcm_recompute(xpd, pcm_mask); - spin_unlock_irqrestore(&xpd->lock, flags); + XPD_DBG(SIGNAL, xpd, "pcm_len=%d wanted_pcm_mask=0x%X\n", + xpd->pcm_len, xpd->wanted_pcm_mask); + spin_unlock_irqrestore(&xpd->lock_recompute_pcm, flags); } void fill_beep(u_char *buf, int num, int duration) @@ -676,11 +666,12 @@ static inline void xpp_ec_chunk(struct zt_chan *chan, unsigned char *rxchunk, co static void do_ec(xpd_t *xpd) { #ifdef WITH_ECHO_SUPPRESSION - struct zt_chan *chans = xpd->span.chans; int i; /* FIXME: need to Echo cancel double buffered data */ for (i = 0;i < xpd->span.channels; i++) { + struct zt_chan *chan = XPD_CHAN(xpd, i); + if(unlikely(IS_SET(xpd->digital_signalling, i))) /* Don't echo cancel BRI D-chans */ continue; if(!IS_SET(xpd->wanted_pcm_mask, i)) /* No ec for unwanted PCM */ @@ -688,12 +679,12 @@ static void do_ec(xpd_t *xpd) #ifdef XPP_EC_CHUNK /* even if defined, parameterr xpp_ec can override at run-time */ if (xpp_ec) - xpp_ec_chunk(&chans[i], chans[i].readchunk, xpd->ec_chunk2[i]); + xpp_ec_chunk(chan, chan->readchunk, xpd->ec_chunk2[i]); else #endif - zt_ec_chunk(&chans[i], chans[i].readchunk, xpd->ec_chunk2[i]); + zt_ec_chunk(chan, chan->readchunk, xpd->ec_chunk2[i]); memcpy(xpd->ec_chunk2[i], xpd->ec_chunk1[i], ZT_CHUNKSIZE); - memcpy(xpd->ec_chunk1[i], chans[i].writechunk, ZT_CHUNKSIZE); + memcpy(xpd->ec_chunk1[i], chan->writechunk, ZT_CHUNKSIZE); } #endif } @@ -821,31 +812,33 @@ dropit: * Generic implementations of card_pcmfromspan()/card_pcmtospan() * For FXS/FXO */ -void generic_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, xpacket_t *pack) +void generic_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack) { byte *pcm; - struct zt_chan *chans; unsigned long flags; + xpp_line_t wanted_lines; int i; BUG_ON(!xbus); BUG_ON(!xpd); BUG_ON(!pack); - RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = lines; + wanted_lines = xpd->wanted_pcm_mask; + RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = wanted_lines; pcm = RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, pcm); spin_lock_irqsave(&xpd->lock, flags); - chans = xpd->span.chans; for (i = 0; i < xpd->channels; i++) { - if(IS_SET(lines, i)) { + struct zt_chan *chan = XPD_CHAN(xpd, i); + + if(IS_SET(wanted_lines, i)) { if(SPAN_REGISTERED(xpd)) { #ifdef DEBUG_PCMTX - int channo = xpd->span.chans[i].channo; + int channo = chan->channo; if(pcmtx >= 0 && pcmtx_chan == channo) memset((u_char *)pcm, pcmtx, ZT_CHUNKSIZE); else #endif - memcpy((u_char *)pcm, chans[i].writechunk, ZT_CHUNKSIZE); + memcpy((u_char *)pcm, chan->writechunk, ZT_CHUNKSIZE); } else memset((u_char *)pcm, 0x7F, ZT_CHUNKSIZE); pcm += ZT_CHUNKSIZE; @@ -874,7 +867,7 @@ void generic_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack) if(!SPAN_REGISTERED(xpd)) goto out; for (i = 0; i < xpd->channels; i++) { - volatile u_char *r = xpd->span.chans[i].readchunk; + volatile u_char *r = XPD_CHAN(xpd, i)->readchunk; bool got_data = IS_SET(pcm_mask, i); if(got_data && !IS_SET(pcm_mute, i)) { @@ -974,7 +967,6 @@ static void xbus_tick(xbus_t *xbus) xpd_t *xpd; xframe_t *xframe = NULL; xpacket_t *pack = NULL; - size_t pcm_len; bool sent_sync_bit = 0; /* @@ -990,7 +982,7 @@ static void xbus_tick(xbus_t *xbus) xmit_mask |= xpd->silence_pcm; xmit_mask |= xpd->digital_signalling; for_each_line(xpd, j) { - xpd->chans[j].chanmute = (optimize_chanmute) + XPD_CHAN(xpd, j)->chanmute = (optimize_chanmute) ? !IS_SET(xmit_mask, j) : 0; } @@ -1006,6 +998,8 @@ static void xbus_tick(xbus_t *xbus) * Fill xframes */ for(i = 0; i < MAX_XPDS; i++) { + size_t pcm_len; + if((xpd = xpd_of(xbus, i)) == NULL) continue; pcm_len = xpd->pcm_len; @@ -1038,7 +1032,7 @@ static void xbus_tick(xbus_t *xbus) XPACKET_ADDR_SYNC(pack) = 1; sent_sync_bit = 1; } - CALL_XMETHOD(card_pcm_fromspan, xbus, xpd, xpd->wanted_pcm_mask, pack); + CALL_XMETHOD(card_pcm_fromspan, xbus, xpd, pack); XBUS_COUNTER(xbus, TX_PACK_PCM)++; } } @@ -1301,8 +1295,7 @@ EXPORT_SYMBOL(xpp_echocan); #ifdef ZAPTEL_SYNC_TICK EXPORT_SYMBOL(zaptel_sync_tick); #endif -EXPORT_SYMBOL(__pcm_recompute); -EXPORT_SYMBOL(pcm_recompute); +EXPORT_SYMBOL(generic_card_pcm_recompute); EXPORT_SYMBOL(generic_card_pcm_tospan); EXPORT_SYMBOL(generic_card_pcm_fromspan); #ifdef DEBUG_PCMTX -- cgit v1.2.3