[svn-commits] tzafrir: linux/trunk r5663 - /linux/trunk/drivers/dahdi/xpp/
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Sun Jan 18 03:55:49 CST 2009
Author: tzafrir
Date: Sun Jan 18 03:55:48 2009
New Revision: 5663
URL: http://svn.digium.com/svn-view/dahdi?view=rev&rev=5663
Log:
xpp.r6616: More sysfs migration, FXO enhancements, BRI fixes
* Fix cases where the command_queue overflowed during initialization.
* More migrations to sysfs:
- Add a 'transport' attribute to our astribank devices which
points to the usb device we use. E.g:
/sys/bus/astribanks/devices/xbus-00/transport is symlinked to
../../../../../../devices/pci0000:00/0000:00:10.4/usb5/5-4
- Move /proc/xpp/XBUS-??/XPD-??/span to
/sys/bus/xpds/devices/??:?:?/span
- Migrate from /proc/xpp/sync to:
/sys/bus/astribanks/drivers/xppdrv/sync
* PRI: change the "timing" priority to match the convention used by
other PRI cards -- I.e: lower numbers (not 0) have higher
priority.
* FXO:
- Power denial: create two module parameters instead of hard-coded
constants (power_denial_safezone, power_denial_minlen).
For sites that get non-standard power-denial signals from central
office on offhook.
- Don't hangup on power-denial, just notify Dahdi and wait for
- Fix caller-id detection for the case central office sends it before
first ring without any indication before.
Asterisk's desicion.
Modified:
linux/trunk/drivers/dahdi/xpp/card_bri.c
linux/trunk/drivers/dahdi/xpp/card_fxo.c
linux/trunk/drivers/dahdi/xpp/card_fxs.c
linux/trunk/drivers/dahdi/xpp/card_global.c
linux/trunk/drivers/dahdi/xpp/card_pri.c
linux/trunk/drivers/dahdi/xpp/init_card_1_30
linux/trunk/drivers/dahdi/xpp/init_card_2_30
linux/trunk/drivers/dahdi/xpp/init_card_3_30
linux/trunk/drivers/dahdi/xpp/init_card_4_30
linux/trunk/drivers/dahdi/xpp/xbus-core.c
linux/trunk/drivers/dahdi/xpp/xbus-core.h
linux/trunk/drivers/dahdi/xpp/xbus-pcm.c
linux/trunk/drivers/dahdi/xpp/xbus-pcm.h
linux/trunk/drivers/dahdi/xpp/xbus-sysfs.c
linux/trunk/drivers/dahdi/xpp/xpd.h
linux/trunk/drivers/dahdi/xpp/xpp_dahdi.c
linux/trunk/drivers/dahdi/xpp/xpp_dahdi.h
linux/trunk/drivers/dahdi/xpp/xpp_usb.c
linux/trunk/drivers/dahdi/xpp/xproto.c
linux/trunk/drivers/dahdi/xpp/xproto.h
Modified: linux/trunk/drivers/dahdi/xpp/card_bri.c
URL: http://svn.digium.com/svn-view/dahdi/linux/trunk/drivers/dahdi/xpp/card_bri.c?view=diff&rev=5663&r1=5662&r2=5663
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/card_bri.c (original)
+++ linux/trunk/drivers/dahdi/xpp/card_bri.c Sun Jan 18 03:55:48 2009
@@ -208,7 +208,6 @@
bool reg30_good;
uint reg30_ticks;
bool layer1_up;
- xpp_line_t card_pcm_mask;
/*
* D-Chan: buffers + extra state info.
@@ -460,8 +459,8 @@
#ifdef XPP_DEBUGFS
xbus_log(xbus, xpd, 0, regcmd, sizeof(reg_cmd_t)); /* 0 = RX */
#endif
- dchan = xpd->span.chans[2];
- if(!IS_SET(xpd->offhook, 2)) { /* D-chan is used? */
+ dchan = XPD_CHAN(xpd, 2);
+ if(!IS_OFFHOOK(xpd, 2)) { /* D-chan is used? */
static int rate_limit;
if((rate_limit++ % 1000) == 0)
@@ -525,7 +524,7 @@
static int tx_dchan(xpd_t *xpd)
{
struct BRI_priv_data *priv;
- struct dahdi_chan *dchan;
+ struct dahdi_chan *dchan;
int len;
int eoframe;
int ret;
@@ -534,7 +533,7 @@
BUG_ON(!priv);
if(!SPAN_REGISTERED(xpd) || !(xpd->span.flags & DAHDI_FLAG_RUNNING))
return 0;
- dchan = xpd->chans[2];
+ dchan = XPD_CHAN(xpd, 2);
len = dchan->bytes2transmit; /* dchan's hdlc package len */
eoframe = dchan->eoftx; /* dchan's end of frame */
dchan->bytes2transmit = 0;
@@ -561,6 +560,7 @@
priv->txframe_begin = 1;
else
priv->txframe_begin = 0;
+ XPD_DBG(COMMANDS, xpd, "eoframe=%d len=%d\n", eoframe, len);
ret = send_multibyte_request(xpd->xbus, xpd->addr.unit, xpd->addr.subunit,
eoframe, priv->dchan_tbuf, len);
if(ret < 0)
@@ -657,9 +657,6 @@
{
xbus_t *xbus;
struct BRI_priv_data *priv;
- xpp_line_t tmp_pcm_mask;
- int tmp_pcm_len;
- unsigned long flags;
int i;
BUG_ON(!xpd);
@@ -676,7 +673,7 @@
xpd->span.deflaw = DAHDI_LAW_ALAW;
BIT_SET(xpd->digital_signalling, 2); /* D-Channel */
for_each_line(xpd, i) {
- struct dahdi_chan *cur_chan = xpd->chans[i];
+ struct dahdi_chan *cur_chan = XPD_CHAN(xpd, i);
XPD_DBG(GENERAL, xpd, "setting BRI channel %d\n", i);
snprintf(cur_chan->name, MAX_CHANNAME, "XPP_%s/%02d/%1d%1d/%d",
@@ -701,35 +698,11 @@
} else
cur_chan->sigcap = BRI_BCHAN_SIGCAP;
}
- xpd->offhook = BIT(0) | BIT(1); /* 2*bchan */
-
- /*
- * Compute PCM lentgh and mask
- * We know all cards have been initialized until now
- */
- tmp_pcm_mask = 0;
- if(xpd->addr.subunit == 0) {
- int line_count = 0;
-
- for(i = 0; i < MAX_SUBUNIT; i++) {
- xpd_t *sub_xpd = xpd_byaddr(xbus, xpd->addr.unit, i);
- if(sub_xpd) {
- tmp_pcm_mask |= PCM_SHIFT(sub_xpd->wanted_pcm_mask, i);
- line_count += 2;
- }
- }
- tmp_pcm_len = RPACKET_HEADERSIZE + sizeof(xpp_line_t) + line_count * DAHDI_CHUNKSIZE;
- } else
- tmp_pcm_len = 0;
- spin_lock_irqsave(&xpd->lock, flags);
- xpd->pcm_len = tmp_pcm_len;
- xpd->wanted_pcm_mask = xpd->offhook;
- priv->card_pcm_mask = tmp_pcm_mask;
+ CALL_XMETHOD(card_pcm_recompute, xbus, xpd, 0);
xpd->span.spanconfig = bri_spanconfig;
xpd->span.chanconfig = bri_chanconfig;
xpd->span.startup = bri_startup;
xpd->span.shutdown = bri_shutdown;
- spin_unlock_irqrestore(&xpd->lock, flags);
return 0;
}
@@ -939,15 +912,38 @@
return 0;
}
+static int BRI_card_open(xpd_t *xpd, lineno_t pos)
+{
+ struct BRI_priv_data *priv;
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ if(pos == 2) {
+ LINE_DBG(SIGNAL, xpd, pos, "OFFHOOK the whole span\n");
+ BIT_SET(xpd->offhook_state, 0);
+ BIT_SET(xpd->offhook_state, 1);
+ BIT_SET(xpd->offhook_state, 2);
+ CALL_XMETHOD(card_pcm_recompute, xpd->xbus, xpd, 0);
+ }
+ return 0;
+}
+
static int BRI_card_close(xpd_t *xpd, lineno_t pos)
{
- struct dahdi_chan *chan = xpd->span.chans[pos];
+ struct dahdi_chan *chan = XPD_CHAN(xpd, pos);
/* Clear D-Channel pending data */
chan->bytes2receive = 0;
chan->eofrx = 0;
chan->bytes2transmit = 0;
chan->eoftx = 0;
+ if(pos == 2) {
+ LINE_DBG(SIGNAL, xpd, pos, "ONHOOK the whole span\n");
+ BIT_CLR(xpd->offhook_state, 0);
+ BIT_CLR(xpd->offhook_state, 1);
+ BIT_CLR(xpd->offhook_state, 2);
+ CALL_XMETHOD(card_pcm_recompute, xpd->xbus, xpd, 0);
+ }
return 0;
}
@@ -1014,7 +1010,7 @@
{
xpd_t *xpd = span->pvt;
struct BRI_priv_data *priv;
- struct dahdi_chan *dchan;
+ struct dahdi_chan *dchan;
BUG_ON(!xpd);
priv = xpd->priv;
@@ -1027,7 +1023,7 @@
// Turn on all channels
CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 1);
if(SPAN_REGISTERED(xpd)) {
- dchan = span->chans[2];
+ dchan = XPD_CHAN(xpd, 2);
span->flags |= DAHDI_FLAG_RUNNING;
/*
* Dahdi (wrongly) assume that D-Channel need HDLC decoding
@@ -1062,14 +1058,74 @@
return 0;
}
-static void BRI_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpp_line_t wanted_lines, xpacket_t *pack)
+void BRI_card_pcm_recompute(xbus_t *xbus, xpd_t *xpd, xpp_line_t dont_care)
+{
+ int i;
+ int line_count;
+ xpp_line_t pcm_mask;
+ xpd_t *main_xpd;
+ unsigned long flags;
+
+ BUG_ON(!xpd);
+ main_xpd = xpd_byaddr(xbus, xpd->addr.unit, 0);
+ if(!main_xpd) {
+ XPD_DBG(DEVICES, xpd, "Unit 0 is already gone. Ignore request\n");
+ return;
+ }
+ /*
+ * We calculate all subunits, so use the main lock
+ * as a mutex for the whole operation.
+ */
+ spin_lock_irqsave(&main_xpd->lock_recompute_pcm, flags);
+ line_count = 0;
+ pcm_mask = 0;
+ for(i = 0; i < MAX_SUBUNIT; i++) {
+ xpd_t *sub_xpd = xpd_byaddr(xbus, main_xpd->addr.unit, i);
+
+ if(sub_xpd) {
+ xpp_line_t lines =
+ sub_xpd->offhook_state & ~sub_xpd->digital_signalling;
+
+ if(lines) {
+ pcm_mask |= PCM_SHIFT(lines, i);
+ line_count += 2;
+ }
+ /* subunits have fake pcm_len and wanted_pcm_mask */
+ if(i > 0) {
+ sub_xpd->pcm_len = 0;
+ sub_xpd->wanted_pcm_mask = lines;
+ }
+ }
+ }
+ /*
+ * FIXME: Workaround a bug in sync code of the Astribank.
+ * Send dummy PCM for sync.
+ */
+ if(main_xpd->addr.unit == 0 && line_count == 0) {
+ pcm_mask = BIT(0);
+ line_count = 1;
+ }
+ /*
+ * The main unit account for all subunits (pcm_len and wanted_pcm_mask).
+ */
+ main_xpd->pcm_len = (line_count)
+ ? RPACKET_HEADERSIZE + sizeof(xpp_line_t) + line_count * DAHDI_CHUNKSIZE
+ : 0L;
+ main_xpd->wanted_pcm_mask = pcm_mask;
+ XPD_DBG(SIGNAL, main_xpd, "pcm_len=%d wanted_pcm_mask=0x%X (%s)\n",
+ main_xpd->pcm_len, main_xpd->wanted_pcm_mask,
+ xpd->xpdname);
+ spin_unlock_irqrestore(&main_xpd->lock_recompute_pcm, flags);
+}
+
+static void BRI_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack)
{
byte *pcm;
- struct dahdi_chan **chans;
unsigned long flags;
int i;
int subunit;
xpp_line_t pcm_mask = 0;
+ xpp_line_t wanted_lines;
BUG_ON(!xbus);
@@ -1083,18 +1139,20 @@
if(!tmp_xpd || !tmp_xpd->card_present)
continue;
spin_lock_irqsave(&tmp_xpd->lock, flags);
- chans = tmp_xpd->span.chans;
+ wanted_lines = tmp_xpd->wanted_pcm_mask;
for_each_line(tmp_xpd, i) {
+ struct dahdi_chan *chan = XPD_CHAN(tmp_xpd, i);
+
if(IS_SET(wanted_lines, i)) {
if(SPAN_REGISTERED(tmp_xpd)) {
#ifdef DEBUG_PCMTX
- int channo = tmp_xpd->span.chans[i]->channo;
+ int channo = chan->channo;
if(pcmtx >= 0 && pcmtx_chan == channo)
memset((u_char *)pcm, pcmtx, DAHDI_CHUNKSIZE);
else
#endif
- memcpy((u_char *)pcm, chans[i]->writechunk, DAHDI_CHUNKSIZE);
+ memcpy((u_char *)pcm, chan->writechunk, DAHDI_CHUNKSIZE);
} else
memset((u_char *)pcm, 0x7F, DAHDI_CHUNKSIZE);
pcm += DAHDI_CHUNKSIZE;
@@ -1138,7 +1196,7 @@
volatile u_char *r;
if(IS_SET(tmp_mask, i)) {
- r = tmp_xpd->span.chans[i]->readchunk;
+ r = XPD_CHAN(tmp_xpd, i)->readchunk;
// memset((u_char *)r, 0x5A, DAHDI_CHUNKSIZE); // DEBUG
memcpy((u_char *)r, pcm, DAHDI_CHUNKSIZE);
pcm += DAHDI_CHUNKSIZE;
@@ -1391,9 +1449,11 @@
.card_dahdi_postregistration = BRI_card_dahdi_postregistration,
.card_hooksig = BRI_card_hooksig,
.card_tick = BRI_card_tick,
+ .card_pcm_recompute = BRI_card_pcm_recompute,
.card_pcm_fromspan = BRI_card_pcm_fromspan,
.card_pcm_tospan = BRI_card_pcm_tospan,
.card_ioctl = BRI_card_ioctl,
+ .card_open = BRI_card_open,
.card_close = BRI_card_close,
.card_register_reply = BRI_card_register_reply,
Modified: linux/trunk/drivers/dahdi/xpp/card_fxo.c
URL: http://svn.digium.com/svn-view/dahdi/linux/trunk/drivers/dahdi/xpp/card_fxo.c?view=diff&rev=5663&r1=5662&r2=5663
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/card_fxo.c (original)
+++ linux/trunk/drivers/dahdi/xpp/card_fxo.c Sun Jan 18 03:55:48 2009
@@ -40,6 +40,8 @@
#endif
static DEF_PARM(int, ring_debounce, 50, 0644, "Number of ticks to debounce a false RING indication");
static DEF_PARM(int, caller_id_style, 0, 0444, "Caller-Id detection style: 0 - [BELL], 1 - [ETSI_FSK], 2 - [ETSI_DTMF]");
+static DEF_PARM(int, power_denial_safezone, 650, 0644, "msec after offhook to ignore power-denial ( (0 - disable power-denial)");
+static DEF_PARM(int, power_denial_minlen, 80, 0644, "Minimal detected power-denial length (msec) (0 - disable power-denial)");
enum cid_style {
CID_STYLE_BELL = 0, /* E.g: US (Bellcore) */
@@ -71,8 +73,6 @@
#define BAT_THRESHOLD 3
#define BAT_DEBOUNCE 1000 /* compensate for battery voltage fluctuation (in ticks) */
#define POWER_DENIAL_CURRENT 3
-#define POWER_DENIAL_TIME 80 /* ticks */
-#define POWER_DENIAL_SAFEZONE 100 /* ticks */
#define POWER_DENIAL_DELAY 2500 /* ticks */
/* Shortcuts */
@@ -138,10 +138,8 @@
enum polarity_state polarity[CHANNELS_PERXPD];
ushort polarity_debounce[CHANNELS_PERXPD];
enum power_state power[CHANNELS_PERXPD];
- xpp_line_t maybe_power_denial;
- ushort power_denial_debounce[CHANNELS_PERXPD];
ushort power_denial_delay[CHANNELS_PERXPD];
- ushort power_denial_minimum[CHANNELS_PERXPD];
+ ushort power_denial_length[CHANNELS_PERXPD];
ushort power_denial_safezone[CHANNELS_PERXPD];
xpp_line_t cidfound; /* 0 - OFF, 1 - ON */
unsigned int cidtimer[CHANNELS_PERXPD];
@@ -169,14 +167,33 @@
/*---------------- FXO: Static functions ----------------------------------*/
+static const char *power2str(enum power_state pw)
+{
+ switch(pw) {
+ case POWER_UNKNOWN: return "UNKOWN";
+ case POWER_OFF: return "OFF";
+ case POWER_ON: return "ON";
+ }
+ return NULL;
+}
+
+static void power_change(xpd_t *xpd, int portno, enum power_state pw)
+{
+ struct FXO_priv_data *priv;
+
+ priv = xpd->priv;
+ LINE_DBG(SIGNAL, xpd, portno, "power: %s -> %s\n",
+ power2str(priv->power[portno]),
+ power2str(pw));
+ priv->power[portno] = pw;
+}
+
static void reset_battery_readings(xpd_t *xpd, lineno_t pos)
{
struct FXO_priv_data *priv = xpd->priv;
priv->nobattery_debounce[pos] = 0;
- priv->power_denial_debounce[pos] = 0;
priv->power_denial_delay[pos] = 0;
- BIT_CLR(priv->maybe_power_denial, pos);
}
static const int led_register_mask[] = { BIT(7), BIT(6), BIT(5) };
@@ -259,30 +276,15 @@
static void update_dahdi_ring(xpd_t *xpd, int pos, bool on)
{
- enum dahdi_rxsig rxsig;
-
BUG_ON(!xpd);
- if(on) {
- if(caller_id_style == CID_STYLE_BELL) {
- LINE_DBG(SIGNAL, xpd, pos, "Caller-ID PCM: off\n");
- BIT_CLR(xpd->cid_on, pos);
- }
- rxsig = DAHDI_RXSIG_RING;
- } else {
- if(caller_id_style == CID_STYLE_BELL) {
- LINE_DBG(SIGNAL, xpd, pos, "Caller-ID PCM: on\n");
- BIT_SET(xpd->cid_on, pos);
- }
- rxsig = DAHDI_RXSIG_OFFHOOK;
- }
- pcm_recompute(xpd, 0);
+ if(caller_id_style == CID_STYLE_BELL)
+ oht_pcm(xpd, pos, !on);
/*
* We should not spinlock before calling dahdi_hooksig() as
* it may call back into our xpp_hooksig() and cause
* a nested spinlock scenario
*/
- if(SPAN_REGISTERED(xpd))
- dahdi_hooksig(xpd->chans[pos], rxsig);
+ notify_rxsig(xpd, pos, (on) ? DAHDI_RXSIG_RING : DAHDI_RXSIG_OFFHOOK);
}
static void mark_ring(xpd_t *xpd, lineno_t pos, bool on, bool update_dahdi)
@@ -343,24 +345,22 @@
else
MARK_OFF(priv, pos, LED_GREEN);
ret = DAA_DIRECT_REQUEST(xbus, xpd, pos, DAA_WRITE, REG_DAA_CONTROL1, value);
- if(to_offhook) {
- BIT_SET(xpd->offhook, pos);
- } else {
- BIT_CLR(xpd->offhook, pos);
- }
- if(caller_id_style != CID_STYLE_ETSI_DTMF) {
- LINE_DBG(SIGNAL, xpd, pos, "Caller-ID PCM: off\n");
- BIT_CLR(xpd->cid_on, pos);
- }
+ mark_offhook(xpd, pos, to_offhook);
+ if(caller_id_style != CID_STYLE_ETSI_DTMF)
+ oht_pcm(xpd, pos, 0);
#ifdef WITH_METERING
priv->metering_count[pos] = 0;
priv->metering_tone_state = 0L;
DAA_DIRECT_REQUEST(xbus, xpd, pos, DAA_WRITE, DAA_REG_METERING, 0x2D);
#endif
reset_battery_readings(xpd, pos); /* unstable during hook changes */
- priv->power_denial_safezone[pos] = (to_offhook) ? POWER_DENIAL_SAFEZONE : 0;
- if(!to_offhook)
- priv->power[pos] = POWER_UNKNOWN;
+ if(to_offhook) {
+ priv->power_denial_safezone[pos] = power_denial_safezone;
+ } else {
+ power_change(xpd, pos, POWER_UNKNOWN);
+ priv->power_denial_length[pos] = 0;
+ priv->power_denial_safezone[pos] = 0;
+ }
priv->cidtimer[pos] = xpd->timer_count;
spin_unlock_irqrestore(&xpd->lock, flags);
return ret;
@@ -461,10 +461,11 @@
for_each_line(xpd, i) {
do_sethook(xpd, i, 0);
priv->polarity[i] = POL_UNKNOWN; /* will be updated on next battery sample */
+ priv->polarity_debounce[i] = 0;
priv->battery[i] = BATTERY_UNKNOWN; /* will be updated on next battery sample */
priv->power[i] = POWER_UNKNOWN; /* will be updated on next battery sample */
if(caller_id_style == CID_STYLE_ETSI_DTMF)
- BIT_SET(xpd->cid_on, i);
+ oht_pcm(xpd, i, 1);
}
XPD_DBG(GENERAL, xpd, "done\n");
for_each_line(xpd, i) {
@@ -478,7 +479,7 @@
do_led(xpd, i, LED_GREEN, 0);
msleep(50);
}
- pcm_recompute(xpd, 0);
+ CALL_XMETHOD(card_pcm_recompute, xbus, xpd, 0);
return 0;
}
@@ -509,7 +510,7 @@
XPD_DBG(GENERAL, xpd, "%s\n", (on)?"ON":"OFF");
xpd->span.spantype = "FXO";
for_each_line(xpd, i) {
- struct dahdi_chan *cur_chan = xpd->chans[i];
+ struct dahdi_chan *cur_chan = XPD_CHAN(xpd, i);
XPD_DBG(GENERAL, xpd, "setting FXO channel %d\n", i);
snprintf(cur_chan->name, MAX_CHANNAME, "XPP_FXO/%02d/%1d%1d/%d",
@@ -563,7 +564,6 @@
/* XXX Enable hooksig for FXO XXX */
switch(txsig) {
case DAHDI_TXSIG_START:
- break;
case DAHDI_TXSIG_OFFHOOK:
ret = do_sethook(xpd, pos, 1);
break;
@@ -575,7 +575,6 @@
txsig2str(txsig), txsig);
return -EINVAL;
}
- pcm_recompute(xpd, 0);
return ret;
}
@@ -592,11 +591,11 @@
break;
case BATTERY_OFF:
LINE_DBG(SIGNAL, xpd, chan, "Send DAHDI_ALARM_RED\n");
- dahdi_alarm_channel(xpd->chans[chan], DAHDI_ALARM_RED);
+ dahdi_alarm_channel(XPD_CHAN(xpd, chan), DAHDI_ALARM_RED);
break;
case BATTERY_ON:
LINE_DBG(SIGNAL, xpd, chan, "Send DAHDI_ALARM_NONE\n");
- dahdi_alarm_channel(xpd->chans[chan], DAHDI_ALARM_NONE);
+ dahdi_alarm_channel(XPD_CHAN(xpd, chan), DAHDI_ALARM_NONE);
break;
}
}
@@ -626,7 +625,7 @@
int i;
for_each_line(xpd, i) {
- if (IS_SET(xpd->offhook, i))
+ if (IS_OFFHOOK(xpd, i))
DAA_DIRECT_REQUEST(xbus, xpd, i, DAA_READ, DAA_REG_METERING, 0);
}
}
@@ -656,20 +655,13 @@
struct FXO_priv_data *priv;
int i;
- priv = xpd->priv;
- for_each_line(xpd, i) {
- if(priv->power_denial_minimum[i] > 0) {
- priv->power_denial_minimum[i]--;
- if(priv->power_denial_minimum[i] <= 0) {
- /*
- * But maybe the FXS started to ring (and the firmware haven't
- * detected it yet). This would cause false power denials.
- * So we just flag it and schedule more ticks to wait.
- */
- LINE_DBG(SIGNAL, xpd, i, "Possible Power Denial Hangup\n");
- priv->power_denial_debounce[i] = 0;
- BIT_SET(priv->maybe_power_denial, i);
- }
+ if(!power_denial_safezone)
+ return; /* Ignore power denials */
+ priv = xpd->priv;
+ for_each_line(xpd, i) {
+ if(xpd->ringing[i] || !IS_OFFHOOK(xpd, i)) {
+ priv->power_denial_delay[i] = 0;
+ continue;
}
if(priv->power_denial_safezone[i] > 0) {
if(--priv->power_denial_safezone[i]) {
@@ -678,25 +670,36 @@
*/
DAA_DIRECT_REQUEST(xpd->xbus, xpd, i, DAA_READ, DAA_REG_CURRENT, 0);
}
- }
- if(IS_SET(priv->maybe_power_denial, i) && !xpd->ringing[i] && IS_SET(xpd->offhook, i)) {
+ continue;
+ }
+ if(priv->power_denial_length[i] > 0) {
+ priv->power_denial_length[i]--;
+ if(priv->power_denial_length[i] <= 0) {
+ /*
+ * But maybe the FXS started to ring (and the firmware haven't
+ * detected it yet). This would cause false power denials.
+ * So we just flag it and schedule more ticks to wait.
+ */
+ LINE_DBG(SIGNAL, xpd, i, "Possible Power Denial Hangup\n");
+ priv->power_denial_delay[i] = POWER_DENIAL_DELAY;
+ }
+ continue;
+ }
+ if (priv->power_denial_delay[i] > 0) {
/*
* Ring detection by the firmware takes some time.
* Therefore we delay our decision until we are
* sure that no ring has started during this time.
*/
- priv->power_denial_delay[i]++;
- if (priv->power_denial_delay[i] >= POWER_DENIAL_DELAY) {
+ priv->power_denial_delay[i]--;
+ if (priv->power_denial_delay[i] <= 0) {
LINE_DBG(SIGNAL, xpd, i, "Power Denial Hangup\n");
priv->power_denial_delay[i] = 0;
- BIT_CLR(priv->maybe_power_denial, i);
- do_sethook(xpd, i, 0);
- update_line_status(xpd, i, 0);
- pcm_recompute(xpd, 0);
+ /*
+ * Let Asterisk decide what to do
+ */
+ notify_rxsig(xpd, i, DAHDI_RXSIG_ONHOOK);
}
- } else {
- priv->power_denial_delay[i] = 0;
- BIT_CLR(priv->maybe_power_denial, i);
}
}
}
@@ -705,7 +708,7 @@
* For caller-id CID_STYLE_ETSI_DTMF:
* - No indication is passed before the CID
* - We try to detect it and send "fake" polarity reversal.
- * - The zapata.conf should have cidstart=polarity
+ * - The chan_dahdi.conf should have cidstart=polarity
* - Based on an idea in http://bugs.digium.com/view.php?id=9096
*/
static void check_etsi_dtmf(xpd_t *xpd)
@@ -721,7 +724,7 @@
timer_count = xpd->timer_count;
for_each_line(xpd, portno) {
/* Skip offhook and ringing ports */
- if(IS_SET(xpd->offhook, portno) || xpd->ringing[portno])
+ if(IS_OFFHOOK(xpd, portno) || xpd->ringing[portno])
continue;
if(IS_SET(priv->cidfound, portno)) {
if(timer_count > priv->cidtimer[portno] + 4000) {
@@ -733,7 +736,7 @@
continue;
}
if(timer_count > priv->cidtimer[portno] + 400) {
- struct dahdi_chan *chan = xpd->span.chans[portno];
+ struct dahdi_chan *chan = XPD_CHAN(xpd, portno);
int sample;
int i;
@@ -773,7 +776,6 @@
return 0;
}
-/* FIXME: based on data from from wctdm.h */
#include <dahdi/wctdm_user.h>
/*
* The first register is the ACIM, the other are coefficient registers.
@@ -912,8 +914,11 @@
priv->battery[portno] = BATTERY_OFF;
if(SPAN_REGISTERED(xpd))
dahdi_report_battery(xpd, portno);
- priv->polarity[portno] = POL_UNKNOWN; /* What's the polarity ? */
- priv->power[portno] = POWER_UNKNOWN; /* What's the current ? */
+ /* What's the polarity ? */
+ priv->polarity[portno] = POL_UNKNOWN;
+ priv->polarity_debounce[portno] = 0;
+ /* What's the current ? */
+ power_change(xpd, portno, POWER_UNKNOWN);
/*
* Stop further processing for now
*/
@@ -966,7 +971,7 @@
msec = priv->polarity_debounce[portno]++ * poll_battery_interval;
if (msec >= POLREV_THRESHOLD) {
priv->polarity_debounce[portno] = 0;
- if(pol != POL_UNKNOWN) {
+ if(pol != POL_UNKNOWN && priv->polarity[portno] != POL_UNKNOWN) {
char *polname = NULL;
if(pol == POL_POSITIVE)
@@ -983,14 +988,12 @@
* 2. In some countries used to report caller-id during onhook
* but before first ring.
*/
- if(caller_id_style == CID_STYLE_ETSI_FSK) {
- LINE_DBG(SIGNAL, xpd, portno, "Caller-ID PCM: on\n");
- BIT_SET(xpd->cid_on, portno); /* will be cleared on ring/offhook */
- }
+ if(caller_id_style == CID_STYLE_ETSI_FSK)
+ oht_pcm(xpd, portno, 1); /* will be cleared on ring/offhook */
if(SPAN_REGISTERED(xpd)) {
LINE_DBG(SIGNAL, xpd, portno,
"Send DAHDI_EVENT_POLARITY: %s\n", polname);
- dahdi_qevent_lock(xpd->chans[portno], DAHDI_EVENT_POLARITY);
+ dahdi_qevent_lock(XPD_CHAN(xpd, portno), DAHDI_EVENT_POLARITY);
}
}
priv->polarity[portno] = pol;
@@ -1014,7 +1017,7 @@
* During ringing, current is not stable.
* During onhook there should not be current anyway.
*/
- if(xpd->ringing[portno] || !IS_SET(xpd->offhook, portno))
+ if(xpd->ringing[portno] || !IS_OFFHOOK(xpd, portno))
goto ignore_it;
/*
* Power denial with no battery voltage is meaningless
@@ -1026,20 +1029,20 @@
goto ignore_it;
if(data_low < POWER_DENIAL_CURRENT) {
if(priv->power[portno] == POWER_ON) {
- LINE_DBG(SIGNAL, xpd, portno, "power: ON -> OFF\n");
- priv->power[portno] = POWER_OFF;
- priv->power_denial_minimum[portno] = POWER_DENIAL_TIME;
+ power_change(xpd, portno, POWER_OFF);
+ priv->power_denial_length[portno] = power_denial_minlen;
}
} else {
- LINE_DBG(SIGNAL, xpd, portno, "power: ON\n");
- priv->power[portno] = POWER_ON;
- priv->power_denial_minimum[portno] = 0;
- update_line_status(xpd, portno, 1);
+ if(priv->power[portno] != POWER_ON) {
+ power_change(xpd, portno, POWER_ON);
+ priv->power_denial_length[portno] = 0;
+ /* We are now OFFHOOK */
+ hookstate_changed(xpd, portno, 1);
+ }
}
return;
ignore_it:
- BIT_CLR(priv->maybe_power_denial, portno);
- priv->power_denial_debounce[portno] = 0;
+ priv->power_denial_delay[portno] = 0;
}
#ifdef WITH_METERING
@@ -1125,6 +1128,7 @@
.card_dahdi_postregistration = FXO_card_dahdi_postregistration,
.card_hooksig = FXO_card_hooksig,
.card_tick = FXO_card_tick,
+ .card_pcm_recompute = generic_card_pcm_recompute,
.card_pcm_fromspan = generic_card_pcm_fromspan,
.card_pcm_tospan = generic_card_pcm_tospan,
.card_ioctl = FXO_card_ioctl,
@@ -1241,14 +1245,6 @@
else
curr = ".";
len += sprintf(page + len, "%4s ", curr);
- }
- len += sprintf(page + len, "\n\t%-17s: ", "maybe");
- for_each_line(xpd, i) {
- len += sprintf(page + len, "%4d ", IS_SET(priv->maybe_power_denial, i));
- }
- len += sprintf(page + len, "\n\t%-17s: ", "debounce");
- for_each_line(xpd, i) {
- len += sprintf(page + len, "%4d ", priv->power_denial_debounce[i]);
}
len += sprintf(page + len, "\n\t%-17s: ", "safezone");
for_each_line(xpd, i) {
Modified: linux/trunk/drivers/dahdi/xpp/card_fxs.c
URL: http://svn.digium.com/svn-view/dahdi/linux/trunk/drivers/dahdi/xpp/card_fxs.c?view=diff&rev=5663&r1=5662&r2=5663
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/card_fxs.c (original)
+++ linux/trunk/drivers/dahdi/xpp/card_fxs.c Sun Jan 18 03:55:48 2009
@@ -172,6 +172,21 @@
BUG_ON(!xpd);
LINE_DBG(SIGNAL, xpd, chan, "%s\n", (on) ? "up" : "down");
return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, REG_BATTERY, value);
+}
+
+static void vmwi_search(xpd_t *xpd, lineno_t pos, bool on)
+{
+ struct FXS_priv_data *priv;
+
+ priv = xpd->priv;
+ BUG_ON(!xpd);
+ if(vmwineon && on) {
+ LINE_DBG(SIGNAL, xpd, pos, "START\n");
+ BIT_SET(priv->search_fsk_pattern, pos);
+ } else {
+ LINE_DBG(SIGNAL, xpd, pos, "STOP\n");
+ BIT_CLR(priv->search_fsk_pattern, pos);
+ }
}
/*
@@ -286,7 +301,7 @@
priv = xpd->priv;
for_each_line(xpd, i) {
- if(IS_SET(xpd->offhook, i))
+ if(IS_OFFHOOK(xpd, i))
MARK_ON(priv, i, LED_GREEN);
else
MARK_OFF(priv, i, LED_GREEN);
@@ -436,7 +451,7 @@
msleep(50);
}
restore_leds(xpd);
- pcm_recompute(xpd, 0);
+ CALL_XMETHOD(card_pcm_recompute, xbus, xpd, 0);
/*
* We should query our offhook state long enough time after we
* set the linefeed_control()
@@ -479,7 +494,7 @@
XPD_DBG(GENERAL, xpd, "%s\n", (on)?"on":"off");
xpd->span.spantype = "FXS";
for_each_line(xpd, i) {
- struct dahdi_chan *cur_chan = xpd->chans[i];
+ struct dahdi_chan *cur_chan = XPD_CHAN(xpd, i);
XPD_DBG(GENERAL, xpd, "setting FXS channel %d\n", i);
if(IS_SET(xpd->digital_outputs, i)) {
@@ -536,19 +551,18 @@
BIT_SET(xpd->mute_dtmf, pos);
else
BIT_CLR(xpd->mute_dtmf, pos);
-}
-
-static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos, int on)
+ CALL_XMETHOD(card_pcm_recompute, xpd->xbus, xpd, 0); /* already spinlocked */
+}
+
+static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos, bool msg_waiting)
{
int ret = 0;
BUG_ON(!xbus);
BUG_ON(!xpd);
- LINE_DBG(SIGNAL, xpd, pos, "%s%s\n", (on)?"ON":"OFF", (vmwineon)?"":" (Ignored)");
- if (!vmwineon)
- return 0;
- if (on) {
+ if (vmwineon && msg_waiting) {
/* A write to register 0x40 will now turn on/off the VM led */
+ LINE_DBG(SIGNAL, xpd, pos, "NEON\n");
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x16, 0xE8, 0x03);
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x15, 0xEF, 0x7B);
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x14, 0x9F, 0x00);
@@ -561,6 +575,7 @@
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x1D, 0x00, 0x46);
} else {
/* A write to register 0x40 will now turn on/off the ringer */
+ LINE_DBG(SIGNAL, xpd, pos, "RINGER\n");
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x16, 0x00, 0x00);
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x15, 0x60, 0x01);
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x14, 0xF0, 0x7E);
@@ -572,7 +587,6 @@
ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x33, 0x00);
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x1D, 0x00, 0x36);
}
-
return (ret ? -EPROTO : 0);
}
@@ -582,7 +596,7 @@
bool on;
BUG_ON(!xpd);
- if (!vmwineon || IS_SET(xpd->digital_outputs | xpd->digital_inputs, pos))
+ if (IS_SET(xpd->digital_outputs | xpd->digital_inputs, pos))
return;
priv = xpd->priv;
on = IS_SET(xpd->msg_waiting, pos);
@@ -651,17 +665,16 @@
return 0;
}
if(SPAN_REGISTERED(xpd))
- chan = xpd->span.chans[pos];
+ chan = XPD_CHAN(xpd, pos);
switch(txsig) {
case DAHDI_TXSIG_ONHOOK:
spin_lock_irqsave(&xpd->lock, flags);
xpd->ringing[pos] = 0;
- BIT_CLR(xpd->cid_on, pos);
- BIT_CLR(priv->search_fsk_pattern, pos);
+ oht_pcm(xpd, pos, 0);
+ vmwi_search(xpd, pos, 0);
BIT_CLR(priv->want_dtmf_events, pos);
BIT_CLR(priv->want_dtmf_mute, pos);
__do_mute_dtmf(xpd, pos, 0);
- __pcm_recompute(xpd, 0); /* already spinlocked */
spin_unlock_irqrestore(&xpd->lock, flags);
if(IS_SET(xpd->digital_outputs, pos)) {
LINE_DBG(SIGNAL, xpd, pos, "%s -> digital output OFF\n", txsig2str(txsig));
@@ -674,11 +687,11 @@
*/
LINE_DBG(SIGNAL, xpd, pos, "KEWL STOP\n");
linefeed_control(xbus, xpd, pos, FXS_LINE_POL_ACTIVE);
- if(IS_SET(xpd->offhook, pos))
+ if(IS_OFFHOOK(xpd, pos))
MARK_ON(priv, pos, LED_GREEN);
}
ret = send_ring(xpd, pos, 0); // RING off
- if (!IS_SET(xpd->offhook, pos))
+ if (!IS_OFFHOOK(xpd, pos))
start_stop_vm_led(xbus, xpd, pos);
txhook = priv->lasttxhook[pos];
if(chan) {
@@ -702,8 +715,7 @@
}
txhook = priv->lasttxhook[pos];
if(xpd->ringing[pos]) {
- BIT_SET(xpd->cid_on, pos);
- pcm_recompute(xpd, 0);
+ oht_pcm(xpd, pos, 1);
txhook = FXS_LINE_OHTRANS;
}
xpd->ringing[pos] = 0;
@@ -721,9 +733,8 @@
break;
case DAHDI_TXSIG_START:
xpd->ringing[pos] = 1;
- BIT_CLR(xpd->cid_on, pos);
- BIT_CLR(priv->search_fsk_pattern, pos);
- pcm_recompute(xpd, 0);
+ oht_pcm(xpd, pos, 0);
+ vmwi_search(xpd, pos, 0);
if(IS_SET(xpd->digital_outputs, pos)) {
LINE_DBG(SIGNAL, xpd, pos, "%s -> digital output ON\n", txsig2str(txsig));
ret = relay_out(xpd, pos, 1);
@@ -778,14 +789,15 @@
LINE_DBG(SIGNAL, xpd, pos, "DAHDI_ONHOOKTRANSFER (%d millis)\n", val);
if (IS_SET(xpd->digital_inputs | xpd->digital_outputs, pos))
return 0; /* Nothing to do */
- BIT_CLR(xpd->cid_on, pos);
+ oht_pcm(xpd, pos, 1); /* Get ready of VMWI FSK tones */
if(priv->lasttxhook[pos] == FXS_LINE_POL_ACTIVE) {
- priv->ohttimer[pos] = OHT_TIMER;
+ priv->ohttimer[pos] = val;
priv->idletxhookstate[pos] = FXS_LINE_POL_OHTRANS;
- BIT_SET(priv->search_fsk_pattern, pos);
- pcm_recompute(xpd, priv->search_fsk_pattern);
- }
- if(!IS_SET(xpd->offhook, pos))
+ vmwi_search(xpd, pos, 1);
+ CALL_XMETHOD(card_pcm_recompute, xbus, xpd, priv->search_fsk_pattern);
+ LINE_DBG(SIGNAL, xpd, pos, "Start OHT_TIMER. wanted_pcm_mask=0x%X\n", xpd->wanted_pcm_mask);
+ }
+ if(vmwineon && !IS_OFFHOOK(xpd, pos))
start_stop_vm_led(xbus, xpd, pos);
return 0;
case DAHDI_TONEDETECT:
@@ -804,7 +816,6 @@
BIT_CLR(priv->want_dtmf_events, pos);
BIT_CLR(priv->want_dtmf_mute, pos);
__do_mute_dtmf(xpd, pos, 0);
- __pcm_recompute(xpd, 0); /* already spinlocked */
spin_unlock_irqrestore(&xpd->lock, flags);
return -ENOTTY;
}
@@ -836,7 +847,6 @@
} else {
BIT_CLR(priv->want_dtmf_mute, pos);
__do_mute_dtmf(xpd, pos, 0);
- __pcm_recompute(xpd, 0);
}
spin_unlock_irqrestore(&xpd->lock, flags);
return 0;
@@ -882,12 +892,10 @@
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);
- if(is_offhook)
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ if(IS_OFFHOOK(xpd, chan))
LINE_NOTICE(xpd, chan, "Already offhook during open. OK.\n");
else
LINE_DBG(SIGNAL, xpd, chan, "is onhook\n");
@@ -953,10 +961,10 @@
if (priv->ohttimer[i]) {
priv->ohttimer[i]--;
if (!priv->ohttimer[i]) {
+ LINE_DBG(SIGNAL, xpd, i, "ohttimer expired\n");
priv->idletxhookstate[i] = FXS_LINE_POL_ACTIVE;
- BIT_CLR(xpd->cid_on, i);
- BIT_CLR(priv->search_fsk_pattern, i);
- pcm_recompute(xpd, 0);
+ oht_pcm(xpd, i, 0);
+ vmwi_search(xpd, i, 0);
if (priv->lasttxhook[i] == FXS_LINE_POL_OHTRANS) {
/* Apply the change if appropriate */
linefeed_control(xpd->xbus, xpd, i, FXS_LINE_POL_ACTIVE);
@@ -992,16 +1000,23 @@
static const byte FSK_ON_PATTERN[] = { 0xA2, 0x2C, 0x1F, 0x2C, 0xBB, 0xA1, 0xA5, 0xFF };
static const byte FSK_OFF_PATTERN[] = { 0xA2, 0x2C, 0x28, 0xA5, 0xB1, 0x21, 0x49, 0x9F };
int i;
+ xpp_line_t ignore_mask;
BUG_ON(!xpd);
xbus = xpd->xbus;
priv = xpd->priv;
BUG_ON(!priv);
+ ignore_mask =
+ xpd->offhook_state |
+ ~xpd->oht_pcm_pass |
+ ~priv->search_fsk_pattern |
+ xpd->digital_inputs |
+ xpd->digital_outputs;
for_each_line(xpd, i) {
- struct dahdi_chan *chan = xpd->span.chans[i];
+ struct dahdi_chan *chan = XPD_CHAN(xpd, i);
byte *writechunk = chan->writechunk;
- if(IS_SET(xpd->offhook | xpd->cid_on | xpd->digital_inputs | xpd->digital_outputs, i))
+ if(IS_SET(ignore_mask, i))
continue;
#if 0
if(writechunk[0] != 0x7F && writechunk[0] != 0) {
@@ -1016,10 +1031,12 @@
printk("\n");
}
#endif
- if(unlikely(mem_equal(writechunk, FSK_COMMON_PATTERN, DAHDI_CHUNKSIZE)))
+ if(unlikely(mem_equal(writechunk, FSK_COMMON_PATTERN, DAHDI_CHUNKSIZE))) {
+ LINE_DBG(SIGNAL, xpd, i, "Found common FSK pattern. Start looking for ON/OFF patterns.\n");
BIT_SET(priv->found_fsk_pattern, i);
- else if(unlikely(IS_SET(priv->found_fsk_pattern, i))) {
+ } else if(unlikely(IS_SET(priv->found_fsk_pattern, i))) {
BIT_CLR(priv->found_fsk_pattern, i);
+ oht_pcm(xpd, i, 0);
if(unlikely(mem_equal(writechunk, FSK_ON_PATTERN, DAHDI_CHUNKSIZE))) {
LINE_DBG(SIGNAL, xpd, i, "MSG WAITING ON\n");
BIT_SET(xpd->msg_waiting, i);
@@ -1056,25 +1073,27 @@
#endif
handle_fxs_leds(xpd);
handle_linefeed(xpd);
- if(priv->update_offhook_state) { /* set in FXS_card_open() */
- int i;
+ /*
+ * Hack alert (FIXME):
+ * Asterisk did FXS_card_open() and we wanted to report
+ * offhook state. However, the channel is spinlocked by dahdi
+ * so we marked it in the priv->update_offhook_state mask and
+ * now we take care of notification to dahdi and Asterisk
+ */
+ if(priv->update_offhook_state) {
+ enum dahdi_rxsig rxsig;
+ int i;
for_each_line(xpd, i) {
if(!IS_SET(priv->update_offhook_state, i))
continue;
- /*
- * Update dahdi with current state of line.
- */
- if(IS_SET(xpd->offhook, i)) {
- update_line_status(xpd, i, 1);
- } else {
- update_line_status(xpd, i, 0);
- }
+ rxsig = IS_OFFHOOK(xpd, i) ? DAHDI_RXSIG_OFFHOOK : DAHDI_RXSIG_ONHOOK;
+ notify_rxsig(xpd, i, rxsig); /* Notify after open() */
BIT_CLR(priv->update_offhook_state, i);
}
}
if(SPAN_REGISTERED(xpd)) {
- if(vmwineon && !vmwi_ioctl)
+ if(vmwineon && !vmwi_ioctl && priv->search_fsk_pattern)
detect_vmwi(xpd); /* Detect via FSK modulation */
}
return 0;
@@ -1123,11 +1142,11 @@
if(IS_SET(offhook, i)) {
LINE_DBG(SIGNAL, xpd, i, "OFFHOOK\n");
MARK_ON(priv, i, LED_GREEN);
- update_line_status(xpd, i, 1);
+ hookstate_changed(xpd, i, 1);
} else {
LINE_DBG(SIGNAL, xpd, i, "ONHOOK\n");
MARK_OFF(priv, i, LED_GREEN);
- update_line_status(xpd, i, 0);
+ hookstate_changed(xpd, i, 0);
}
/*
* Must switch to low power. In high power, an ONHOOK
@@ -1136,7 +1155,6 @@
do_chan_power(xbus, xpd, i, 0);
}
}
- __pcm_recompute(xpd, 0); /* in a spinlock */
}
HANDLER_DEF(FXS, SIG_CHANGED)
@@ -1178,12 +1196,12 @@
BIT_CLR(lines, channo);
BIT_SET(lines, newchanno);
xpd->ringing[newchanno] = 0; // Stop ringing. No leds for digital inputs.
- if(offhook && !IS_SET(xpd->offhook, newchanno)) { // OFFHOOK
+ if(offhook && !IS_OFFHOOK(xpd, newchanno)) { // OFFHOOK
LINE_DBG(SIGNAL, xpd, newchanno, "OFFHOOK\n");
- update_line_status(xpd, newchanno, 1);
- } else if(!offhook && IS_SET(xpd->offhook, newchanno)) { // ONHOOK
+ hookstate_changed(xpd, newchanno, 1);
+ } else if(!offhook && IS_OFFHOOK(xpd, newchanno)) { // ONHOOK
LINE_DBG(SIGNAL, xpd, newchanno, "ONHOOK\n");
- update_line_status(xpd, newchanno, 0);
+ hookstate_changed(xpd, newchanno, 0);
}
}
}
@@ -1249,11 +1267,10 @@
__do_mute_dtmf(xpd, portnum, 1);
else
__do_mute_dtmf(xpd, portnum, 0);
- __pcm_recompute(xpd, 0); /* XPD is locked */
if(want_event) {
int event = (key_down) ? DAHDI_EVENT_DTMFDOWN : DAHDI_EVENT_DTMFUP;
- dahdi_qevent_lock(xpd->chans[portnum], event | digit);
+ dahdi_qevent_lock(XPD_CHAN(xpd, portnum), event | digit);
}
}
@@ -1330,6 +1347,7 @@
.card_dahdi_postregistration = FXS_card_dahdi_postregistration,
.card_hooksig = FXS_card_hooksig,
.card_tick = FXS_card_tick,
+ .card_pcm_recompute = generic_card_pcm_recompute,
.card_pcm_fromspan = generic_card_pcm_fromspan,
.card_pcm_tospan = generic_card_pcm_tospan,
.card_open = FXS_card_open,
Modified: linux/trunk/drivers/dahdi/xpp/card_global.c
URL: http://svn.digium.com/svn-view/dahdi/linux/trunk/drivers/dahdi/xpp/card_global.c?view=diff&rev=5663&r1=5662&r2=5663
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/card_global.c (original)
+++ linux/trunk/drivers/dahdi/xpp/card_global.c Sun Jan 18 03:55:48 2009
@@ -374,7 +374,9 @@
XPD_NOTICE(xpd, "Failed writing command: '%s'\n", buf);
return ret;
}
- msleep(1); /* don't overflow command queue */
+ /* Don't flood command_queue */
+ if(xframe_queue_count(&xpd->xbus->command_queue) > 5)
+ msleep(6);
}
return count;
}
Modified: linux/trunk/drivers/dahdi/xpp/card_pri.c
URL: http://svn.digium.com/svn-view/dahdi/linux/trunk/drivers/dahdi/xpp/card_pri.c?view=diff&rev=5663&r1=5662&r2=5663
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/card_pri.c (original)
+++ linux/trunk/drivers/dahdi/xpp/card_pri.c Sun Jan 18 03:55:48 2009
@@ -587,7 +587,7 @@
xbus_t *xbus;
xpd_t *best_xpd = NULL;
int best_subunit = -1; /* invalid */
- int best_subunit_prio = 0;
+ unsigned int best_subunit_prio = INT_MAX;
int i;
xbus = xpd->xbus;
@@ -602,7 +602,7 @@
priv = subxpd->priv;
if(priv->alarms != 0)
continue;
- if(subxpd->timing_priority > best_subunit_prio) {
+ if(subxpd->timing_priority > 0 && subxpd->timing_priority < best_subunit_prio) {
best_xpd = subxpd;
best_subunit = i;
best_subunit_prio = subxpd->timing_priority;
@@ -1016,7 +1016,7 @@
xpd->span.linecompat = pri_linecompat(priv->pri_protocol);
xpd->span.deflaw = priv->deflaw;
for_each_line(xpd, i) {
- struct dahdi_chan *cur_chan = xpd->chans[i];
+ struct dahdi_chan *cur_chan = XPD_CHAN(xpd, i);
bool is_dchan = i == PRI_DCHAN_IDX(priv);
XPD_DBG(GENERAL, xpd, "setting PRI channel %d (%s)\n", i,
@@ -1032,7 +1032,7 @@
} else
cur_chan->sigcap = PRI_BCHAN_SIGCAP;
}
- xpd->offhook = xpd->wanted_pcm_mask;
+ xpd->offhook_state = xpd->wanted_pcm_mask;
xpd->span.spanconfig = pri_spanconfig;
xpd->span.chanconfig = pri_chanconfig;
xpd->span.startup = pri_startup;
@@ -1081,9 +1081,9 @@
if(SPAN_REGISTERED(xpd) && d >= 0 && d < xpd->channels) {
byte *pcm;
- pcm = (byte *)xpd->span.chans[d]->readchunk;
+ pcm = (byte *)XPD_CHAN(xpd, d)->readchunk;
pcm[0] = 0x00;
- pcm = (byte *)xpd->span.chans[d]->writechunk;
+ pcm = (byte *)XPD_CHAN(xpd, d)->writechunk;
pcm[0] = 0x00;
}
XPD_DBG(SIGNAL, xpd, "STATE CHANGE: D-Channel STOPPED\n");
@@ -1212,7 +1212,7 @@
static int PRI_card_close(xpd_t *xpd, lineno_t pos)
{
- //struct dahdi_chan *chan = &xpd->span.chans[pos];
+ //struct dahdi_chan *chan = XPD_CHAN(xpd, pos);
dchan_state(xpd, 0);
return 0;
}
@@ -1321,13 +1321,13 @@
* send 31 channels to the device, but they should be called 1-31 rather
* than 0-30 .
*/
[... 1409 lines stripped ...]
More information about the svn-commits
mailing list