summaryrefslogtreecommitdiff
path: root/kernel/xpp/xbus-pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/xpp/xbus-pcm.c')
-rw-r--r--kernel/xpp/xbus-pcm.c65
1 files changed, 29 insertions, 36 deletions
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