diff options
Diffstat (limited to 'xpp/card_fxs.c')
-rw-r--r-- | xpp/card_fxs.c | 339 |
1 files changed, 219 insertions, 120 deletions
diff --git a/xpp/card_fxs.c b/xpp/card_fxs.c index d2413f3..41b503e 100644 --- a/xpp/card_fxs.c +++ b/xpp/card_fxs.c @@ -34,15 +34,21 @@ static const char rcsid[] = "$Id$"; DEF_PARM(int, print_dbg, 0, "Print DBG statements"); /* must be before zap_debug.h */ +DEF_PARM(bool, poll_digital_inputs, 1, "Poll Digital Inputs"); /* must be before zap_debug.h */ + +/* Signaling is opposite (fxo signalling for fxs card) */ +#if 1 +#define FXS_DEFAULT_SIGCAP (ZT_SIG_FXOKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS) +#else +#define FXS_DEFAULT_SIGCAP (ZT_SIG_SF | ZT_SIG_EM) +#endif #define LINES_REGULAR 8 #define LINES_DIGI_OUT 2 #define LINES_DIGI_INP 4 -#define MASK_BITS(b) ((1U << (b)) - 1) - -#define MASK_DIGI_OUT (MASK_BITS(LINES_DIGI_OUT) << LINES_REGULAR) -#define MASK_DIGI_INP (MASK_BITS(LINES_DIGI_INP) << (LINES_REGULAR + LINES_DIGI_OUT)) +#define MASK_DIGI_OUT (BITMASK(LINES_DIGI_OUT) << LINES_REGULAR) +#define MASK_DIGI_INP (BITMASK(LINES_DIGI_INP) << (LINES_REGULAR + LINES_DIGI_OUT)) enum fxs_leds { LED_GREEN, @@ -52,14 +58,27 @@ enum fxs_leds { #define NUM_LEDS 2 +static int SLIC_DIRECT_REQUEST(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, byte reg, byte dL) +{ + xpacket_t *pack; + slic_cmd_t *sc; + int len; + + XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id); + sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd); + len = slic_cmd_direct_write(sc, lines, reg, dL); + pack->datalen = len; + packet_send(xbus, pack); + return 0; +} + /*---------------- FXS Protocol Commands ----------------------------------*/ static /* 0x0F */ DECLARE_CMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on); -static /* 0x0F */ DECLARE_CMD(FXS, CHAN_CID, xpp_line_t lines); +static /* 0x0F */ DECLARE_CMD(FXS, CHAN_CID, int pos); static /* 0x0F */ DECLARE_CMD(FXS, RING, int pos, bool on); static /* 0x0F */ DECLARE_CMD(FXS, SETHOOK, int pos, bool offhook); static /* 0x0F */ DECLARE_CMD(FXS, RELAY_OUT, byte which, bool on); -static /* 0x0F */ DECLARE_CMD(FXS, SLIC_INIT); static /* 0x0F */ DECLARE_CMD(FXS, SLIC_QUERY, int pos, byte reg_num); static bool fxs_packet_is_valid(xpacket_t *pack); @@ -68,26 +87,6 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data); static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data); -#define S_(s,l,...) \ - { \ - .lines = s, \ - { \ - .len = l, \ - .data = { __VA_ARGS__ }, \ - } \ - } -struct slic_init_data { - xpp_line_t lines; - slic_data_t slic_data; -} slic_init_data[] = { -#ifdef OLD_CARD -#include "init_data_3_19.inc" -#else -#include "init_data_3_20.inc" -#endif -}; -#undef S_ - #define PROC_SLIC_FNAME "slics" #define PROC_FXS_INFO_FNAME "fxs_info" @@ -111,7 +110,6 @@ static int do_chan_power(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, bool on) BUG_ON(!xbus); BUG_ON(!xpd); - lines &= xpd->enabled_chans; // Ignore disabled channels if(!lines) { return 0; } @@ -132,8 +130,8 @@ static int do_chan_power(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, bool on) } #define IS_BLINKING(priv,pos,color) ((priv)->blinking[color][pos] != 0) -#define DO_BLINK(priv,pos,color,val) ((priv)->blinking[color][pos] = (val)) -#define DO_LED(priv,pos,color,val) ((val)?BIT_SET((priv)->ledcontrol[color],(pos)):BIT_CLR((priv)->ledcontrol[color],(pos))) +#define MARK_BLINK(priv,pos,color,val) ((priv)->blinking[color][pos] = (val)) +#define MARK_LED(priv,pos,color,val) ((val)?BIT_SET((priv)->ledcontrol[color],(pos)):BIT_CLR((priv)->ledcontrol[color],(pos))) /* * LED and RELAY control is done via SLIC register 0x06: @@ -195,7 +193,7 @@ static int do_led(xpd_t *xpd, lineno_t pos, byte which, bool on) BIT_CLR(priv->ledstate[which], pos); } } - if(!(lines & xpd->enabled_chans)) // Ignore disabled channels + if(!lines) // Nothing to do goto out; DBG("%s/%s: LED: lines=0x%04X which=%d -- %s\n", xbus->busname, xpd->xpdname, lines, which, (on) ? "on" : "off"); value = BIT(2) | BIT(3); @@ -222,11 +220,11 @@ static void handle_fxs_leds(xpd_t *xpd) struct FXS_priv_data *priv; BUG_ON(!xpd); - priv = xpd->priv; spin_lock_irqsave(&xpd->lock, flags); + priv = xpd->priv; timer_count = xpd->timer_count; for(color = 0; color < ARRAY_SIZE(colors); color++) { - for_each_enabled_line(xpd, i) { + for_each_line(xpd, i) { if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i)) continue; if(IS_BLINKING(priv, i, color)) { // Blinking @@ -282,6 +280,7 @@ static void clean_proc(xbus_t *xbus, xpd_t *xpd) #ifdef CONFIG_PROC_FS if(priv->xpd_slic) { DBG("Removing xpd SLIC file %s/%s\n", xbus->busname, xpd->xpdname); + priv->xpd_slic->data = NULL; remove_proc_entry(PROC_SLIC_FNAME, xpd->proc_xpd_dir); } if(priv->fxs_info) { @@ -304,31 +303,45 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd) if(!priv->fxs_info) { ERR("Failed to create proc '%s' for %s/%s\n", PROC_FXS_INFO_FNAME, xbus->busname, xpd->xpdname); ret = -ENOENT; - goto out; + goto err; } + priv->fxs_info->owner = THIS_MODULE; DBG("Creating SLICs file for %s/%s\n", xbus->busname, xpd->xpdname); priv->xpd_slic = create_proc_entry(PROC_SLIC_FNAME, 0644, xpd->proc_xpd_dir); if(!priv->xpd_slic) { ERR("Failed to create proc file for SLICs of %s/%s\n", xbus->busname, xpd->xpdname); ret = -ENOENT; - goto out; + goto err; } + priv->xpd_slic->owner = THIS_MODULE; priv->xpd_slic->write_proc = proc_xpd_slic_write; priv->xpd_slic->read_proc = proc_xpd_slic_read; priv->xpd_slic->data = xpd; #endif -#ifdef HARD_CODED_INIT - CALL_PROTO(FXS, SLIC_INIT, xbus, xpd); -#else ret = run_initialize_registers(xpd); + if(ret < 0) + goto err; + /* + * Setup ring timers + */ +#ifdef WITH_RBS + /* Software controled ringing (for CID) */ + ret = SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x22, 0x00); /* Ringing Oscilator Control */ +#else + /* Hardware controled ringing (no CID) */ + ret += SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x30, 0x80); /* Active timer low byte */ + ret += SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x31, 0x3E); /* Active timer high byte */ + ret += SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x32, 0x80); /* Inactive timer low byte */ + ret += SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x33, 0x3E); /* Inactive timer high byte */ + ret += SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x22, 0x18); /* Ringing Oscilator Control */ #endif -out: - if(ret < 0) { - clean_proc(xbus, xpd); - ERR("%s/%s: Failed initializing registers (%d)\n", xbus->busname, xpd->xpdname, ret); - } else { - DBG("done: %s/%s\n", xbus->busname, xpd->xpdname); - } + if(ret < 0) + goto err; + DBG("%s/%s: done\n", xbus->busname, xpd->xpdname); + return 0; +err: + clean_proc(xbus, xpd); + ERR("%s/%s: Failed initializing registers (%d)\n", xbus->busname, xpd->xpdname, ret); return ret; } @@ -343,46 +356,139 @@ static int FXS_card_remove(xbus_t *xbus, xpd_t *xpd) return 0; } -static int FXS_card_zaptel_registration(xpd_t *xpd, bool on) +static int FXS_card_zaptel_preregistration(xpd_t *xpd, bool on) { xbus_t *xbus; struct FXS_priv_data *priv; + int i; unsigned long flags; - int i; + const enum fxs_leds color = (on) ? LED_GREEN : LED_RED; BUG_ON(!xpd); xbus = xpd->xbus; - priv = xpd->priv; BUG_ON(!xbus); - DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on)?"on":"off"); - if(on) { - spin_lock_irqsave(&xpd->lock, flags); - do_led(xpd, ALL_LINES, LED_GREEN, LED_OFF); - spin_unlock_irqrestore(&xpd->lock, flags); - for_each_enabled_line(xpd, i) { - DO_LED(priv,i,LED_GREEN,LED_ON); - mdelay(50); - } - for_each_enabled_line(xpd, i) { - DO_LED(priv,i,LED_GREEN,LED_OFF); - mdelay(50); - } - } else { - spin_lock_irqsave(&xpd->lock, flags); - do_led(xpd, ALL_LINES, LED_RED, LED_OFF); - spin_unlock_irqrestore(&xpd->lock, flags); - for_each_enabled_line(xpd, i) { - DO_LED(priv,i,LED_RED,LED_ON); - mdelay(50); - } - for_each_enabled_line(xpd, i) { - DO_LED(priv,i,LED_RED,LED_OFF); - mdelay(50); + priv = xpd->priv; + BUG_ON(!priv); + DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on); + snprintf(xpd->span.desc, MAX_SPANDESC, "Xorcom XPD #%d/%d: FXS", xbus->num, xpd->id); + for_each_line(xpd, i) { + struct zt_chan *cur_chan = &xpd->chans[i]; + + DBG("setting FXS channel %d\n", i); + if(IS_SET(xpd->digital_outputs, i)) { + snprintf(cur_chan->name, MAX_CHANNAME, "XPP_OUT/%d/%d/%d", xbus->num, xpd->id, i); + } else if(IS_SET(xpd->digital_inputs, i)) { + snprintf(cur_chan->name, MAX_CHANNAME, "XPP_IN/%d/%d/%d", xbus->num, xpd->id, i); + } else { + snprintf(cur_chan->name, MAX_CHANNAME, "XPP_FXS/%d/%d/%d", xbus->num, xpd->id, i); } + cur_chan->chanpos = i + 1; + cur_chan->pvt = xpd; + cur_chan->sigcap = FXS_DEFAULT_SIGCAP; + } + spin_lock_irqsave(&xpd->lock, flags); + do_led(xpd, ALL_LINES, color, LED_OFF); + spin_unlock_irqrestore(&xpd->lock, flags); + for_each_line(xpd, i) { + MARK_LED(priv, i, color, LED_ON); + mdelay(50); } return 0; } +static int FXS_card_zaptel_postregistration(xpd_t *xpd, bool on) +{ + xbus_t *xbus; + struct FXS_priv_data *priv; + int i; + const enum fxs_leds color = (on) ? LED_GREEN : LED_RED; + + BUG_ON(!xpd); + xbus = xpd->xbus; + BUG_ON(!xbus); + priv = xpd->priv; + BUG_ON(!priv); + DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on); + for_each_line(xpd, i) { + MARK_LED(priv, i, color, LED_OFF); + mdelay(50); + } + return 0; +} + +#ifdef WITH_RBS +int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig) +{ + int ret = 0; + + DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, pos, txsig2str(txsig)); + BUG_ON(xpd->direction != TO_PHONE); + if (IS_SET(xpd->digital_inputs, pos)) { + DBG("Ignoring signal sent to digital input line\n"); + return 0; + } + switch(txsig) { + case ZT_TXSIG_ONHOOK: + xpd->ringing[pos] = 0; + BIT_CLR(xpd->cid_on, pos); + if(IS_SET(xpd->digital_outputs, pos)) { + DBG("%s/%s/%d: digital output OFF\n", xbus->busname, xpd->xpdname, pos); + ret = CALL_XMETHOD(RELAY_OUT, xpd->xbus, xpd, pos-8, 0); + return ret; + } + ret = CALL_XMETHOD(RING, xbus, xpd, pos, 0); // RING off +#if 0 + switch(chan->sig) { + case ZT_SIG_EM: + case ZT_SIG_FXOKS: + case ZT_SIG_FXOLS: + xpd->lasttxhook[pos] = xpd->idletxhookstate[pos]; + break; + case ZT_SIG_FXOGS: + xpd->lasttxhook[pos] = FXS_LINE_TIPOPEN; + break; + } +#endif + break; + case ZT_TXSIG_OFFHOOK: + if(xpd->ringing[pos]) { + BIT_SET(xpd->cid_on, pos); + ret = CALL_XMETHOD(CHAN_CID, xpd->xbus, xpd, pos); // CALLER ID + } + xpd->ringing[pos] = 0; +#if 0 + switch(chan->sig) { + case ZT_SIG_EM: + xpd->lasttxhook[pos] = FXS_LINE_REV_ACTIVE; + break; + default: + xpd->lasttxhook[pos] = xpd->idletxhookstate[pos]; + break; + } +#endif + break; + case ZT_TXSIG_START: + xpd->lasttxhook[pos] = FXS_LINE_RING; + xpd->ringing[pos] = 1; + BIT_CLR(xpd->cid_on, pos); + if(IS_SET(xpd->digital_outputs, pos)) { + DBG("%s/%s/%d: %s digital output ON\n", xbus->busname, xpd->xpdname, pos, txsig2str(txsig)); + ret = CALL_XMETHOD(RELAY_OUT, xpd->xbus, xpd, pos-8, 1); + return ret; + } + ret = CALL_XMETHOD(RING, xbus, xpd, pos, 1); // RING on + break; + case ZT_TXSIG_KEWL: + xpd->lasttxhook[pos] = FXS_LINE_DISABLED; + break; + default: + NOTICE("%s: Can't set tx state to %s (%d)\n", __FUNCTION__, txsig2str(txsig), txsig); + ret = -EINVAL; + } + return ret; +} + +#else int FXS_card_sethook(xbus_t *xbus, xpd_t *xpd, int pos, int hookstate) { int ret = 0; @@ -417,7 +523,7 @@ int FXS_card_sethook(xbus_t *xbus, xpd_t *xpd, int pos, int hookstate) DBG("%s/%s/%d: fall through ZT_OFFHOOK\n", xbus->busname, xpd->xpdname, pos); // Fall through case ZT_OFFHOOK: - DBG("%s/%s/%d: ignoring (PHONE)\n", xbus->busname, xpd->xpdname, pos); + DBG("%s/%s/%d: ZT_OFFHOOK (ignoring for PHONES)\n", xbus->busname, xpd->xpdname, pos); break; case ZT_WINK: WARN("No code yet\n"); @@ -426,7 +532,7 @@ int FXS_card_sethook(xbus_t *xbus, xpd_t *xpd, int pos, int hookstate) WARN("No code yet\n"); break; case ZT_RING: - DBG("%s/%s/%d: ringing[%d]=%d\n", xbus->busname, xpd->xpdname, pos, pos, xpd->ringing[pos]); + DBG("%s/%s/%d: ZT_RING: %d\n", xbus->busname, xpd->xpdname, pos, xpd->ringing[pos]); if(IS_SET(xpd->digital_inputs, pos)) { NOTICE("%s: Trying to RING a digital input channel %d. Ignoring\n", __FUNCTION__, pos); return -EINVAL; @@ -448,6 +554,7 @@ int FXS_card_sethook(xbus_t *xbus, xpd_t *xpd, int pos, int hookstate) } return ret; } +#endif /* * INPUT polling is done via SLIC register 0x06 (same as LEDS): @@ -463,6 +570,7 @@ static void poll_inputs(xbus_t *xbus, xpd_t *xpd) { int i; + BUG_ON(xpd->id != 0); // Only unit #0 has digital inputs for(i = 0; i < ARRAY_SIZE(input_channels); i++) { int pos = input_channels[i]; @@ -478,9 +586,13 @@ static int FXS_card_tick(xbus_t *xbus, xpd_t *xpd) BUG_ON(!xpd); priv = xpd->priv; BUG_ON(!priv); - if((rate_limit++ % 1000) == 0) { - poll_inputs(xbus, xpd); +#if POLL_DIGITAL_INPUTS + if(poll_digital_inputs && xpd->id == 0) { + if((rate_limit++ % 1000) == 0) { + poll_inputs(xbus, xpd); + } } +#endif handle_fxs_leds(xpd); return 0; } @@ -499,11 +611,14 @@ static /* 0x0F */ HOSTCMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on) BUG_ON(!xbus); BUG_ON(!xpd); - lines &= xpd->enabled_chans; // Ignore disabled channels if(!lines) { return 0; } DBG("Channel Activation: 0x%4X %s\n", lines, (on) ? "on" : "off"); + // Make sure we use normal (low battery) power + for_each_line(xpd, i) + if (BIT_SET(lines,i)) + do_chan_power(xbus, xpd, BIT(i), 0); XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id); sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd); len = slic_cmd_direct_write(sc, lines, 0x40, value); @@ -522,20 +637,21 @@ static /* 0x0F */ HOSTCMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on) return ret; } -static /* 0x0F */ HOSTCMD(FXS, CHAN_CID, xpp_line_t lines) +static /* 0x0F */ HOSTCMD(FXS, CHAN_CID, int pos) { int ret = 0; xpacket_t *pack; slic_cmd_t *sc; int i; + xpp_line_t lines = BIT(pos); BUG_ON(!xbus); BUG_ON(!xpd); - lines &= xpd->enabled_chans; // Ignore disabled channels if(!lines) { return 0; } - DBG("Channel CID: 0x%04X\n", lines); + DBG("%s/%s/%d:\n", xbus->busname, xpd->xpdname, pos); + //do_chan_power(xbus, xpd, BIT(pos), 0); // Low battery for normal (non-ring) operation XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id); sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd); pack->datalen = slic_cmd_direct_write(sc, lines, 0x40, FXS_LINE_CID); @@ -552,14 +668,13 @@ static /* 0x0F */ HOSTCMD(FXS, RING, int pos, bool on) struct FXS_priv_data *priv; xpacket_t *pack; slic_cmd_t *sc; - xpp_line_t mask = (1 << pos); + xpp_line_t mask = BIT(pos); int len; enum fxs_state value = (on) ? 0x04 : 0x01; BUG_ON(!xbus); BUG_ON(!xpd); priv = xpd->priv; - mask &= xpd->enabled_chans; // Ignore disabled channels if(!mask) { return 0; } @@ -573,10 +688,10 @@ static /* 0x0F */ HOSTCMD(FXS, RING, int pos, bool on) packet_send(xbus, pack); if(on) { - DO_BLINK(priv,pos,LED_GREEN,LED_BLINK); + MARK_BLINK(priv,pos,LED_GREEN,LED_BLINK); } else { if(IS_BLINKING(priv, pos, LED_GREEN)) - DO_BLINK(priv,pos,LED_GREEN,0); + MARK_BLINK(priv,pos,LED_GREEN,0); } return ret; } @@ -617,33 +732,6 @@ static /* 0x0F */ HOSTCMD(FXS, RELAY_OUT, byte which, bool on) return ret; } -static /* 0x0F */ HOSTCMD(FXS, SLIC_INIT) -{ - int ret = 0; - xpacket_t *pack; - slic_data_t *slic; - struct slic_init_data *source; - int i; - - BUG_ON(!xbus); - BUG_ON(!xpd); - DBG("INITIALIZING SLIC\n"); - for(i = 0; i < ARRAY_SIZE(slic_init_data); i++) { - source = &slic_init_data[i]; - XPACKET_NEW(pack, xbus, FXS, SLIC_INIT, xpd->id); - RPACKET_FIELD(pack, FXS, SLIC_INIT, lines) = source->lines; - - slic = &RPACKET_FIELD(pack, FXS, SLIC_INIT, slic_data); - slic->len = source->slic_data.len; - memcpy(slic->data, source->slic_data.data, source->slic_data.len); - pack->datalen = sizeof(xpp_line_t) + slic->len + 1; -// dump_packet("SLIC", pack, print_dbg); - packet_send(xbus, pack); - mdelay(1); // FIXME: check with Dima - } - return ret; -} - static /* 0x0F */ HOSTCMD(FXS, SLIC_QUERY, int pos, byte reg_num) { int ret = 0; @@ -683,7 +771,7 @@ HANDLER_DEF(FXS, SIG_CHANGED) } #if 0 Is this needed? - for_each_enabled_line(xpd, i) { + for_each_line(xpd, i) { if(IS_SET(sig_toggles, i)) do_chan_power(xpd->xbus, xpd, BIT(i), 0); // Power down (prevent overheating!!!) } @@ -695,15 +783,15 @@ HANDLER_DEF(FXS, SIG_CHANGED) struct zt_chan *chan = &xpd->span.chans[i]; xpd->ringing[i] = 0; // No more ringing... - DO_BLINK(priv,i,LED_GREEN,0); + MARK_BLINK(priv,i,LED_GREEN,0); if(IS_SET(sig_status, i)) { DBG("OFFHOOK: channo=%d\n", chan->channo); - DO_LED(priv,i,LED_GREEN,LED_ON); + MARK_LED(priv,i,LED_GREEN,LED_ON); BIT_SET(xpd->hookstate, i); zt_hooksig(chan, ZT_RXSIG_OFFHOOK); } else { DBG("ONHOOK channo=%d\n", chan->channo); - DO_LED(priv,i,LED_GREEN,LED_OFF); + MARK_LED(priv,i,LED_GREEN,LED_OFF); BIT_CLR(xpd->hookstate, i); zt_hooksig(chan, ZT_RXSIG_ONHOOK); } @@ -770,7 +858,6 @@ HANDLER_DEF(FXS, SLIC_REPLY) return 0; } - xproto_table_t PROTO_TABLE(FXS) = { .owner = THIS_MODULE, .entries = { @@ -784,8 +871,13 @@ xproto_table_t PROTO_TABLE(FXS) = { .card_new = FXS_card_new, .card_init = FXS_card_init, .card_remove = FXS_card_remove, - .card_zaptel_registration = FXS_card_zaptel_registration, + .card_zaptel_preregistration = FXS_card_zaptel_preregistration, + .card_zaptel_postregistration = FXS_card_zaptel_postregistration, +#ifdef WITH_RBS + .card_hooksig = FXS_card_hooksig, +#else .card_sethook = FXS_card_sethook, +#endif .card_tick = FXS_card_tick, .RING = XPROTO_CALLER(FXS, RING), @@ -826,7 +918,8 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in int i; int led; - BUG_ON(!xpd); + if(!xpd) + return -ENODEV; spin_lock_irqsave(&xpd->lock, flags); priv = xpd->priv; BUG_ON(!priv); @@ -984,9 +1077,8 @@ static int process_slic_cmdline(xpd_t *xpd, char *cmdline) len = parse_slic_cmd(p, &sc, &priv->requested_reply); if(len < 0) return len; - sc.lines &= xpd->enabled_chans; // Ignore disabled channels if(!sc.lines) { - NOTICE("%s: no enabled channels are marked. Skip.\n", __FUNCTION__); + NOTICE("%s: no channels are marked. Skip.\n", __FUNCTION__); return 0; } dump_slic_cmd("WRITE_SLIC", &sc); @@ -1006,7 +1098,8 @@ static int proc_xpd_slic_write(struct file *file, const char __user *buffer, uns int i; int ret; - BUG_ON(!xpd); + if(!xpd) + return -ENODEV; for(i = 0; i < count; /* noop */) { for(p = buf; p < buf + LINE_LEN; p++) { /* read a line */ if(i >= count) @@ -1032,6 +1125,12 @@ static int proc_xpd_slic_write(struct file *file, const char __user *buffer, uns int __init card_fxs_startup(void) { INFO("%s revision %s\n", THIS_MODULE->name, ZAPTEL_VERSION); +#ifdef POLL_DIGITAL_INPUTS + INFO("FEATURE: %s with DIGITAL INPUTS support (%s activated)\n", + THIS_MODULE->name, (poll_digital_inputs) ? "is" : "is not"); +#else + INFO("FEATURE: %s without DIGITAL INPUTS support\n", THIS_MODULE->name); +#endif xproto_register(&PROTO_TABLE(FXS)); return 0; } |