diff options
Diffstat (limited to 'xpp/card_fxs.c')
-rw-r--r-- | xpp/card_fxs.c | 223 |
1 files changed, 108 insertions, 115 deletions
diff --git a/xpp/card_fxs.c b/xpp/card_fxs.c index 8392e73..359591d 100644 --- a/xpp/card_fxs.c +++ b/xpp/card_fxs.c @@ -52,13 +52,9 @@ DEF_PARM_BOOL(vmwi_ioctl, 0, 0644, "Asterisk support VMWI notification via ioctl #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_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, LED_RED, @@ -127,8 +123,8 @@ struct FXS_priv_data { struct proc_dir_entry *fxs_info; xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */ xpp_line_t ledcontrol[NUM_LEDS]; /* 0 - OFF, 1 - ON */ + xpp_line_t search_fsk_pattern; xpp_line_t found_fsk_pattern; - xpp_line_t msg_waiting; xpp_line_t update_offhook_state; xpp_line_t dtmf_keypressed; int led_counter[NUM_LEDS][CHANNELS_PERXPD]; @@ -156,7 +152,7 @@ static int linefeed_control(xbus_t *xbus, xpd_t *xpd, lineno_t chan, enum fxs_st struct FXS_priv_data *priv; priv = xpd->priv; - DBG("%s/%s/%d: value=0x%02X\n", xbus->busname, xpd->xpdname, chan, value); + LINE_DBG(xpd, chan, "value=0x%02X\n", value); priv->lasttxhook[chan] = value; return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x40, value); } @@ -167,7 +163,7 @@ static int do_chan_power(xbus_t *xbus, xpd_t *xpd, lineno_t chan, bool on) BUG_ON(!xbus); BUG_ON(!xpd); - DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, chan, (on) ? "up" : "down"); + LINE_DBG(xpd, chan, "%s\n", (on) ? "up" : "down"); return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x42, value); } @@ -226,7 +222,7 @@ static int do_led(xpd_t *xpd, lineno_t chan, byte which, bool on) BIT_CLR(priv->ledstate[which], chan); } } - DBG("%s/%s/%d: LED: which=%d -- %s\n", xbus->busname, xpd->xpdname, chan, which, (on) ? "on" : "off"); + LINE_DBG(xpd, chan, "LED: which=%d -- %s\n", which, (on) ? "on" : "off"); value = BIT(2) | BIT(3); value |= ((BIT(5) | BIT(6) | BIT(7)) & ~led_register_mask[which]); if(on) @@ -258,8 +254,7 @@ static void handle_fxs_leds(xpd_t *xpd) mod_value = DEFAULT_LED_PERIOD; /* safety value */ // led state is toggled if((timer_count % mod_value) == 0) { - DBG("%s/%s/%d ledstate=%s\n", xpd->xbus->busname, xpd->xpdname, i, - (IS_SET(priv->ledstate[color], i))?"ON":"OFF"); + LINE_DBG(xpd, i, "ledstate=%s\n", (IS_SET(priv->ledstate[color], i))?"ON":"OFF"); if(!IS_SET(priv->ledstate[color], i)) { do_led(xpd, i, color, 1); } else { @@ -295,29 +290,33 @@ static int metering_gen(xpd_t *xpd, lineno_t chan, bool on) { byte value = (on) ? 0x94 : 0x00; - DBG("%s/%s/%d: METERING Generate: %s\n", - xpd->xbus->busname, xpd->xpdname, chan, - (on)?"ON":"OFF"); + LINE_DBG(xpd, chan, "METERING Generate: %s\n", (on)?"ON":"OFF"); return SLIC_DIRECT_REQUEST(xpd->xbus, xpd, chan, SLIC_WRITE, 0x23, value); } #endif /*---------------- FXS: Methods -------------------------------------------*/ -static xpd_t *FXS_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte revision) +static xpd_t *FXS_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, byte revision) { xpd_t *xpd = NULL; - int channels = min(8, CHANNELS_PERXPD); - + int channels; + int regular_channels; + + if(subtype == 2) + regular_channels = min(6, CHANNELS_PERXPD); + else + regular_channels = min(8, CHANNELS_PERXPD); + channels = regular_channels; if(unit == 0) channels += 6; /* 2 DIGITAL OUTPUTS, 4 DIGITAL INPUTS */ xpd = xpd_alloc(sizeof(struct FXS_priv_data), proto_table, channels); if(!xpd) return NULL; if(unit == 0) { - DBG("First XPD on %s detected. Initialize digital outputs/inputs\n", xbus->busname); - xpd->digital_outputs = MASK_DIGI_OUT; - xpd->digital_inputs = MASK_DIGI_INP; + XBUS_DBG(xbus, "First XPD detected. Initialize digital outputs/inputs\n"); + xpd->digital_outputs = BITMASK(LINES_DIGI_OUT) << regular_channels; + xpd->digital_inputs = BITMASK(LINES_DIGI_INP) << (regular_channels + LINES_DIGI_OUT); } xpd->direction = TO_PHONE; xpd->revision = revision; @@ -333,21 +332,21 @@ static void clean_proc(xbus_t *xbus, xpd_t *xpd) priv = xpd->priv; #ifdef CONFIG_PROC_FS if(priv->regfile) { - DBG("Removing xpd SLIC file %s/%s\n", xbus->busname, xpd->xpdname); + XPD_DBG(xpd, "Removing xpd SLIC file\n"); priv->regfile->data = NULL; remove_proc_entry(PROC_REGISTER_FNAME, xpd->proc_xpd_dir); priv->regfile = NULL; } #ifdef WITH_METERING if(priv->meteringfile) { - DBG("Removing xpd metering tone file %s/%s\n", xbus->busname, xpd->xpdname); + XPD_DBG(xpd, "Removing xpd metering tone file\n"); priv->meteringfile->data = NULL; remove_proc_entry(PROC_METERING_FNAME, xpd->proc_xpd_dir); priv->meteringfile = NULL; } #endif if(priv->fxs_info) { - DBG("Removing xpd FXS_INFO file %s/%s\n", xbus->busname, xpd->xpdname); + XPD_DBG(xpd, "Removing xpd FXS_INFO file\n"); remove_proc_entry(PROC_FXS_INFO_FNAME, xpd->proc_xpd_dir); priv->fxs_info = NULL; } @@ -363,19 +362,19 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd) BUG_ON(!xpd); priv = xpd->priv; #ifdef CONFIG_PROC_FS - DBG("Creating FXS_INFO file for %s/%s\n", xbus->busname, xpd->xpdname); + XPD_DBG(xpd, "Creating FXS_INFO file\n"); priv->fxs_info = create_proc_read_entry(PROC_FXS_INFO_FNAME, 0444, xpd->proc_xpd_dir, proc_fxs_info_read, xpd); if(!priv->fxs_info) { - ERR("Failed to create proc '%s' for %s/%s\n", PROC_FXS_INFO_FNAME, xbus->busname, xpd->xpdname); + XPD_ERR(xpd, "Failed to create proc file '%s'\n", PROC_FXS_INFO_FNAME); ret = -ENOENT; goto err; } priv->fxs_info->owner = THIS_MODULE; #ifdef WITH_METERING - DBG("Creating Metering tone file for %s/%s\n", xbus->busname, xpd->xpdname); + XPD_DBG(xpd, "Creating Metering tone file\n"); priv->meteringfile = create_proc_entry(PROC_METERING_FNAME, 0200, xpd->proc_xpd_dir); if(!priv->meteringfile) { - ERR("Failed to create proc file for SLICs of %s/%s\n", xbus->busname, xpd->xpdname); + XPD_ERR(xpd, "Failed to create proc file '%s'\n", PROC_METERING_FNAME); ret = -ENOENT; goto err; } @@ -384,10 +383,10 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd) priv->meteringfile->read_proc = NULL; priv->meteringfile->data = xpd; #endif - DBG("Creating SLICs file for %s/%s\n", xbus->busname, xpd->xpdname); + XPD_DBG(xpd, "Creating SLICs file\n"); priv->regfile = create_proc_entry(PROC_REGISTER_FNAME, 0644, xpd->proc_xpd_dir); if(!priv->regfile) { - ERR("Failed to create proc file for SLICs of %s/%s\n", xbus->busname, xpd->xpdname); + XPD_ERR(xpd, "Failed to create proc file '%s'\n", PROC_REGISTER_FNAME); ret = -ENOENT; goto err; } @@ -409,7 +408,7 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd) ret = SLIC_DIRECT_REQUEST(xbus, xpd, ALL_CHANS, SLIC_WRITE, 0x22, 0x00); /* Ringing Oscilator Control */ if(ret < 0) goto err; - DBG("%s/%s: done\n", xbus->busname, xpd->xpdname); + XPD_DBG(xpd, "done\n"); for_each_line(xpd, i) { do_led(xpd, i, LED_GREEN, 0); do_led(xpd, i, LED_RED, 0); @@ -423,11 +422,11 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd) msleep(50); } restore_leds(xpd); - pcm_recompute(xpd); + pcm_recompute(xpd, xpd->offhook | xpd->cid_on); return 0; err: clean_proc(xbus, xpd); - ERR("%s/%s: Failed initializing registers (%d)\n", xbus->busname, xpd->xpdname, ret); + XPD_ERR(xpd, "Failed initializing registers (%d)\n", ret); return ret; } @@ -437,7 +436,7 @@ static int FXS_card_remove(xbus_t *xbus, xpd_t *xpd) BUG_ON(!xpd); priv = xpd->priv; - DBG("%s/%s\n", xbus->busname, xpd->xpdname); + XPD_DBG(xpd, "\n"); clean_proc(xbus, xpd); return 0; } @@ -453,11 +452,11 @@ static int FXS_card_zaptel_preregistration(xpd_t *xpd, bool on) BUG_ON(!xbus); priv = xpd->priv; BUG_ON(!priv); - DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on); + XPD_DBG(xpd, "%s\n", (on)?"on":"off"); for_each_line(xpd, i) { struct zt_chan *cur_chan = &xpd->chans[i]; - DBG("setting FXS channel %d\n", i); + XPD_DBG(xpd, "setting FXS channel %d\n", i); if(IS_SET(xpd->digital_outputs, i)) { snprintf(cur_chan->name, MAX_CHANNAME, "XPP_OUT/%02d/%1d%1d/%d", xbus->num, xpd->addr.unit, xpd->addr.subunit, i); @@ -490,7 +489,7 @@ static int FXS_card_zaptel_postregistration(xpd_t *xpd, bool on) BUG_ON(!xbus); priv = xpd->priv; BUG_ON(!priv); - DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on); + XPD_DBG(xpd, "%s\n", (on)?"on":"off"); for_each_line(xpd, i) { MARK_OFF(priv, i, LED_GREEN); msleep(2); @@ -508,11 +507,11 @@ int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig) struct zt_chan *chan = NULL; enum fxs_state txhook; - DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, pos, txsig2str(txsig)); + LINE_DBG(xpd, pos, "%s\n", txsig2str(txsig)); priv = xpd->priv; BUG_ON(xpd->direction != TO_PHONE); if (IS_SET(xpd->digital_inputs, pos)) { - DBG("Ignoring signal sent to digital input line\n"); + LINE_DBG(xpd, pos, "Ignoring signal sent to digital input line\n"); return 0; } if(SPAN_REGISTERED(xpd)) @@ -521,9 +520,10 @@ int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig) case ZT_TXSIG_ONHOOK: xpd->ringing[pos] = 0; BIT_CLR(xpd->cid_on, pos); - pcm_recompute(xpd); + BIT_CLR(priv->search_fsk_pattern, pos); + pcm_recompute(xpd, xpd->offhook | xpd->cid_on); if(IS_SET(xpd->digital_outputs, pos)) { - DBG("%s/%s/%d: digital output OFF\n", xbus->busname, xpd->xpdname, pos); + LINE_DBG(xpd, pos, "digital output OFF\n"); ret = CALL_XMETHOD(RELAY_OUT, xpd->xbus, xpd, pos-8, 0); return ret; } @@ -531,8 +531,7 @@ int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig) /* * Restore state after KEWL hangup. */ - DBG("%s/%s/%d: KEWL STOP\n", - xbus->busname, xpd->xpdname, pos); + LINE_DBG(xpd, pos, "KEWL STOP\n"); linefeed_control(xbus, xpd, pos, FXS_LINE_POL_ACTIVE); if(IS_SET(xpd->offhook, pos)) MARK_ON(priv, pos, LED_GREEN); @@ -559,7 +558,7 @@ int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig) txhook = priv->lasttxhook[pos]; if(xpd->ringing[pos]) { BIT_SET(xpd->cid_on, pos); - pcm_recompute(xpd); + pcm_recompute(xpd, xpd->offhook | xpd->cid_on); txhook = FXS_LINE_OHTRANS; } xpd->ringing[pos] = 0; @@ -578,21 +577,23 @@ int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig) case ZT_TXSIG_START: xpd->ringing[pos] = 1; BIT_CLR(xpd->cid_on, pos); - pcm_recompute(xpd); + BIT_CLR(priv->search_fsk_pattern, pos); + pcm_recompute(xpd, xpd->offhook | xpd->cid_on); if(IS_SET(xpd->digital_outputs, pos)) { - DBG("%s/%s/%d: %s digital output ON\n", xbus->busname, xpd->xpdname, pos, txsig2str(txsig)); + LINE_DBG(xpd, pos, "%s digital output ON\n", 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: - DBG("%s/%s/%d: KEWL START\n", xbus->busname, xpd->xpdname, pos); + LINE_DBG(xpd, pos, "KEWL START\n"); linefeed_control(xbus, xpd, pos, FXS_LINE_OPEN); MARK_OFF(priv, pos, LED_GREEN); break; default: - NOTICE("%s: Can't set tx state to %s (%d)\n", __FUNCTION__, txsig2str(txsig), txsig); + XPD_NOTICE(xpd, "%s: Can't set tx state to %s (%d)\n", + __FUNCTION__, txsig2str(txsig), txsig); ret = -EINVAL; } return ret; @@ -615,7 +616,8 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a BUG_ON(!xbus); if (pos < 0 || pos >= xpd->channels) { - NOTICE("%s/%s: Bad channel number %d in %s(), cmd=%u\n", xbus->busname, xpd->xpdname, pos, __FUNCTION__, cmd); + XPD_NOTICE(xpd, "Bad channel number %d in %s(), cmd=%u\n", + pos, __FUNCTION__, cmd); return -EINVAL; } @@ -623,19 +625,20 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a case ZT_ONHOOKTRANSFER: if (get_user(val, (int __user *)arg)) return -EFAULT; - DBG("%s/%s/%d: ZT_ONHOOKTRANSFER (%d millis)\n", - xbus->busname, xpd->xpdname, pos, val); + LINE_DBG(xpd, pos, "ZT_ONHOOKTRANSFER (%d millis)\n", val); BUG_ON(pos == ALL_CHANS); if (IS_SET(xpd->digital_inputs | xpd->digital_outputs, pos)) return 0; /* Nothing to do */ + BIT_CLR(xpd->cid_on, pos); + BIT_SET(priv->search_fsk_pattern, pos); + pcm_recompute(xpd, xpd->offhook | xpd->cid_on | priv->search_fsk_pattern); if(!IS_SET(xpd->offhook, pos)) start_stop_vm_led(xbus, xpd, pos); return 0; case ZT_TONEDETECT: if (get_user(val, (int __user *)arg)) return -EFAULT; - DBG("%s/%s/%d: ZT_TONEDETECT: %s %s (dtmf_detection=%s)\n", - xbus->busname, xpd->xpdname, pos, + LINE_DBG(xpd, pos, "ZT_TONEDETECT: %s %s (dtmf_detection=%s)\n", (val & ZT_TONEDETECT_ON) ? "ON" : "OFF", (val & ZT_TONEDETECT_MUTE) ? "MUTE" : "NO-MUTE", (dtmf_detection ? "YES" : "NO")); @@ -645,17 +648,16 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a if (get_user(val, (int __user *)arg)) return -EFAULT; if(!vmwi_ioctl) { - NOTICE("%s/%s/%d: Got ZT_VMWI notification but vmwi_ioctl parameter is off. Ignoring.\n", - xbus->busname, xpd->xpdname, pos); + LINE_NOTICE(xpd, pos, "Got ZT_VMWI notification but vmwi_ioctl parameter is off. Ignoring.\n"); return 0; } /* Digital inputs/outputs don't have VM leds */ if (IS_SET(xpd->digital_inputs | xpd->digital_outputs, pos)) return 0; if (val) - BIT_SET(priv->msg_waiting, pos); + BIT_SET(xpd->msg_waiting, pos); else - BIT_CLR(priv->msg_waiting, pos); + BIT_CLR(xpd->msg_waiting, pos); return 0; #endif } @@ -668,9 +670,9 @@ static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos, int on) BUG_ON(!xbus); BUG_ON(!xpd); + LINE_DBG(xpd, pos, "%s%s\n", (on)?"ON":"OFF", (vmwineon)?"":" (Ignored)"); if (!vmwineon) return 0; - if (on) { /* A write to register 0x40 will now turn on/off the VM led */ ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x16, 0xE8, 0x03); @@ -709,8 +711,8 @@ static void start_stop_vm_led(xbus_t *xbus, xpd_t *xpd, lineno_t pos) if (IS_SET(xpd->digital_outputs | xpd->digital_inputs, pos)) return; priv = xpd->priv; - on = IS_SET(((struct FXS_priv_data *)xpd->priv)->msg_waiting, pos); - DBG("%s/%s/%d %s\n", xbus->busname, xpd->xpdname, pos, (on)?"ON":"OFF"); + on = IS_SET(xpd->msg_waiting, pos); + LINE_DBG(xpd, pos, "%s\n", (on)?"ON":"OFF"); set_vm_led_mode(xbus, xpd, pos, on); do_chan_power(xbus, xpd, pos, on); linefeed_control(xbus, xpd, pos, (on) ? FXS_LINE_RING : priv->idletxhookstate[pos]); @@ -724,8 +726,7 @@ static int FXS_card_open(xpd_t *xpd, lineno_t chan) BUG_ON(!xpd); priv = xpd->priv; is_offhook = IS_SET(xpd->offhook, chan); - DBG("%s/%s:%d (is %shook)\n", xpd->xbus->busname, xpd->xpdname, - chan, (is_offhook)?"off":"on"); + LINE_DBG(xpd, chan, "(is %shook)\n", (is_offhook)?"off":"on"); /* * Delegate updating zaptel to FXS_card_tick(): * The problem is that zt_hooksig() is spinlocking the channel and @@ -741,7 +742,7 @@ static int FXS_card_close(xpd_t *xpd, lineno_t chan) struct FXS_priv_data *priv; BUG_ON(!xpd); - DBG("%s/%s:%d\n", xpd->xbus->busname, xpd->xpdname, chan); + LINE_DBG(xpd, chan, "\n"); priv = xpd->priv; priv->idletxhookstate[chan] = FXS_LINE_POL_ACTIVE; return 0; @@ -801,7 +802,7 @@ void handle_linefeed(xpd_t *xpd) enum fxs_state txhook = FXS_LINE_POL_ACTIVE; /* Apply the change if appropriate */ BIT_CLR(xpd->cid_on, i); - pcm_recompute(xpd); + pcm_recompute(xpd, xpd->offhook | xpd->cid_on); linefeed_control(xpd->xbus, xpd, i, txhook); } } @@ -837,25 +838,26 @@ static void detect_vmwi(xpd_t *xpd) int i; BUG_ON(!xpd); - if (!vmwineon) - return; xbus = xpd->xbus; priv = xpd->priv; BUG_ON(!priv); for_each_line(xpd, i) { - byte *writechunk = xpd->span.chans[i].writechunk; + struct zt_chan *chan = &xpd->span.chans[i]; + byte *writechunk = chan->writechunk; if(IS_SET(xpd->offhook | xpd->cid_on | xpd->digital_inputs | xpd->digital_outputs, i)) continue; #if 0 - if(i == 0 && writechunk[0] != 0x7F) { + if(writechunk[0] != 0x7F && writechunk[0] != 0) { int j; - DBG("%s/%s/%d: MSG:", xbus->busname, xpd->xpdname, i); + LINE_DBG(xpd, pos, "MSG:"); for(j = 0; j < ZT_CHUNKSIZE; j++) { - printk(" %02X", writechunk[j]); + if(print_dbg) + printk(" %02X", writechunk[j]); } - printk("\n"); + if(print_dbg) + printk("\n"); } #endif if(unlikely(mem_equal(writechunk, FSK_COMMON_PATTERN, ZT_CHUNKSIZE))) @@ -863,17 +865,17 @@ static void detect_vmwi(xpd_t *xpd) else if(unlikely(IS_SET(priv->found_fsk_pattern, i))) { BIT_CLR(priv->found_fsk_pattern, i); if(unlikely(mem_equal(writechunk, FSK_ON_PATTERN, ZT_CHUNKSIZE))) { - DBG("%s/%s/%d: MSG WAITING ON\n", xbus->busname, xpd->xpdname, i); - BIT_SET(priv->msg_waiting, i); + LINE_DBG(xpd, i, "MSG WAITING ON\n"); + BIT_SET(xpd->msg_waiting, i); start_stop_vm_led(xbus, xpd, i); } else if(unlikely(mem_equal(writechunk, FSK_OFF_PATTERN, ZT_CHUNKSIZE))) { - DBG("%s/%s/%d: MSG WAITING OFF\n", xbus->busname, xpd->xpdname, i); - BIT_CLR(priv->msg_waiting, i); + LINE_DBG(xpd, i, "MSG WAITING OFF\n"); + BIT_CLR(xpd->msg_waiting, i); start_stop_vm_led(xbus, xpd, i); } else { int j; - NOTICE("%s/%s/%d: MSG WAITING Unexpected:", xbus->busname, xpd->xpdname, i); + LINE_NOTICE(xpd, i, "MSG WAITING Unexpected:"); for(j = 0; j < ZT_CHUNKSIZE; j++) { printk(" %02X", writechunk[j]); } @@ -908,8 +910,7 @@ static int FXS_card_tick(xbus_t *xbus, xpd_t *xpd) * Update LEDs and zaptel with current state of line. */ if(IS_SET(xpd->offhook, i)) { - NOTICE("%s/%s/%d: Already offhook during open. OK.\n", - xbus->busname, xpd->xpdname, i); + LINE_NOTICE(xpd, i, "Already offhook during open. OK.\n"); MARK_ON(priv, i, LED_GREEN); update_line_status(xpd, i, 1); } else { @@ -920,8 +921,8 @@ static int FXS_card_tick(xbus_t *xbus, xpd_t *xpd) } } if(SPAN_REGISTERED(xpd)) { - if(!vmwi_ioctl) - detect_vmwi(xpd); + if(vmwineon && !vmwi_ioctl) + detect_vmwi(xpd); /* Detect via FSK modulation */ if(dtmf_detection && (xpd->timer_count % POLL_DTMF_INTERVAL) == 0) poll_dtmf(xpd); @@ -944,8 +945,7 @@ static int FXS_card_tick(xbus_t *xbus, xpd_t *xpd) } XFRAME_NEW(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx); #if 0 - DBG("%s/%s/%d: %c%c R%02X S%02X %02X %02X\n", - xbus->busname, xpd->xpdname, chipsel, + LINE_DBG(xpd, chipsel, "%c%c R%02X S%02X %02X %02X\n", (writing)?'W':'R', (do_subreg)?'S':'D', regnum, subreg, data_low, data_high); @@ -974,7 +974,7 @@ static /* 0x0F */ HOSTCMD(FXS, XPD_STATE, bool on) BUG_ON(!xpd); priv = xpd->priv; spin_lock_irqsave(&xpd->lock, flags); - DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on) ? "on" : "off"); + XPD_DBG(xpd, "%s\n", (on)?"on":"off"); for_each_line(xpd, i) linefeed_control(xbus, xpd, i, value); if(on) { @@ -994,7 +994,7 @@ static /* 0x0F */ HOSTCMD(FXS, RING, lineno_t chan, bool on) BUG_ON(!xbus); BUG_ON(!xpd); - DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, chan, (on) ? "on" : "off"); + LINE_DBG(xpd, chan, "%s\n", (on)?"on":"off"); priv = xpd->priv; set_vm_led_mode(xbus, xpd, chan, 0); do_chan_power(xbus, xpd, chan, on); // Power up (for ring) @@ -1015,7 +1015,7 @@ static /* 0x0F */ HOSTCMD(FXS, RELAY_OUT, byte which, bool on) BUG_ON(!xbus); BUG_ON(!xpd); - DBG("RELAY_OUT: which=%d -- %s\n", which, (on) ? "on" : "off"); + XPD_DBG(xpd, "RELAY_OUT: which=%d -- %s\n", which, (on) ? "on" : "off"); which = which % ARRAY_SIZE(relay_channels); value = BIT(2) | BIT(3); value |= ((BIT(5) | BIT(6) | BIT(7)) & ~led_register_mask[OUTPUT_RELAY]); @@ -1037,7 +1037,7 @@ HANDLER_DEF(FXS, SIG_CHANGED) BUG_ON(!xpd); BUG_ON(xpd->direction != TO_PHONE); priv = xpd->priv; - DBG("%s/%s: (PHONE) sig_toggles=0x%04X sig_status=0x%04X\n", xbus->busname, xpd->xpdname, sig_toggles, sig_status); + XPD_DBG(xpd, "(PHONE) sig_toggles=0x%04X sig_status=0x%04X\n", sig_toggles, sig_status); #if 0 Is this needed? for_each_line(xpd, i) { @@ -1057,18 +1057,18 @@ HANDLER_DEF(FXS, SIG_CHANGED) #endif MARK_BLINK(priv, i, LED_GREEN, 0); if(IS_SET(sig_status, i)) { - DBG("%s/%s/%d: OFFHOOK\n", xbus->busname, xpd->xpdname, i); + LINE_DBG(xpd, i, "OFFHOOK\n"); MARK_ON(priv, i, LED_GREEN); update_line_status(xpd, i, 1); } else { - DBG("%s/%s/%d: ONHOOK\n", xbus->busname, xpd->xpdname, i); + LINE_DBG(xpd, i, "ONHOOK\n"); MARK_OFF(priv, i, LED_GREEN); update_line_status(xpd, i, 0); } } } spin_unlock_irqrestore(&xpd->lock, flags); - pcm_recompute(xpd); /* it's spinlocked */ + pcm_recompute(xpd, xpd->offhook | xpd->cid_on); /* it's spinlocked */ return 0; } @@ -1084,15 +1084,15 @@ static void process_digital_inputs(xpd_t *xpd, const reg_cmd_t *info) int newchanno; if(IS_SET(lines, channo)) { - newchanno = LINES_REGULAR + LINES_DIGI_OUT + i; + newchanno = xpd->channels - LINES_DIGI_INP + i; 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 - DBG("%s/%s/%d: OFFHOOK\n", xpd->xbus->busname, xpd->xpdname, newchanno); + LINE_DBG(xpd, newchanno, "OFFHOOK\n"); update_line_status(xpd, newchanno, 1); } else if(!offhook && IS_SET(xpd->offhook, newchanno)) { // ONHOOK - DBG("%s/%s/%d: ONHOOK\n", xpd->xbus->busname, xpd->xpdname, newchanno); + LINE_DBG(xpd, newchanno, "ONHOOK\n"); update_line_status(xpd, newchanno, 0); } } @@ -1116,8 +1116,7 @@ void process_dtmf(xpd_t *xpd, const reg_cmd_t *info) val &= 0xF; if(val <= 0) { if(on) - NOTICE("%s/%s: Bad DTMF value %d. Ignored\n", - xpd->xbus->busname, xpd->xpdname, val); + XPD_NOTICE(xpd, "Bad DTMF value %d. Ignored\n", val); return; } val--; @@ -1125,14 +1124,12 @@ void process_dtmf(xpd_t *xpd, const reg_cmd_t *info) for_each_line(xpd, i) { if(IS_SET(lines, i)) { if(on && !IS_SET(priv->dtmf_keypressed, i)) { - DBG("%s/%s/%d: DTMF digit %2d PRESSED (%d)\n", - xpd->xbus->busname, xpd->xpdname, i, digit, val); + LINE_DBG(xpd, i, "DTMF digit %2d PRESSED (%d)\n", digit, val); BIT_SET(priv->dtmf_keypressed, i); if(dtmf_detection) zt_qevent_lock(&xpd->chans[i], ZT_EVENT_DTMFDOWN | digit); } else if(!on && IS_SET(priv->dtmf_keypressed, i)) { - DBG("%s/%s/%d: DTMF digit %2d RELEASED\n", - xpd->xbus->busname, xpd->xpdname, i, digit); + LINE_DBG(xpd, i, "DTMF digit %2d RELEASED\n", digit); BIT_CLR(priv->dtmf_keypressed, i); if(dtmf_detection) zt_qevent_lock(&xpd->chans[i], ZT_EVENT_DTMFUP | digit); @@ -1160,8 +1157,8 @@ HANDLER_DEF(FXS, REGISTER_REPLY) indirect = (REG_FIELD(info, regnum) == 0x1E); regnum = (indirect) ? REG_FIELD(info, subreg) : REG_FIELD(info, regnum); #if 0 - DBG("REGISTER_REPLY: xpd #%d %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n", - xpd->xbus_idx, (indirect)?"I":"D", + XPD_DBG(xpd, "REGISTER_REPLY: %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n", + (indirect)?"I":"D", regnum, REG_FIELD(info, data_low), REG_FIELD(info, data_high)); #endif if(!SPAN_REGISTERED(xpd)) @@ -1402,7 +1399,7 @@ static int handle_register_command(xpd_t *xpd, char *cmdline) BUG_ON(!xpd); xbus = xpd->xbus; if(!down_read_trylock(&xbus->in_use)) { - DBG("Dropped packet. %s is in_use\n", xbus->busname); + XBUS_DBG(xbus, "Dropped packet. Is in_use\n"); return -EBUSY; } xpd->requested_reply = regcmd; @@ -1498,8 +1495,7 @@ static int proc_xpd_metering_write(struct file *file, const char __user *buffer, if(!xpd) return -ENODEV; if(count >= MAX_PROC_WRITE - 1) { - ERR("%s/%s: Metering string too long (%lu)\n", - xpd->xbus->busname, xpd->xpdname, count); + XPD_ERR(xpd, "Metering string too long (%lu)\n", count); return -EINVAL; } if(copy_from_user(&buf, buffer, count)) @@ -1507,19 +1503,16 @@ static int proc_xpd_metering_write(struct file *file, const char __user *buffer, buf[count] = '\0'; ret = sscanf(buf, "%d", &num); if(ret != 1) { - ERR("%s/%s: Metering value should be number. Got '%s'\n", - xpd->xbus->busname, xpd->xpdname, buf); + XPD_ERR(xpd, "Metering value should be number. Got '%s'\n", buf); return -EINVAL; } chan = num; if(chan != ALL_CHANS && chan > xpd->channels) { - ERR("%s/%s: Metering tone: bad channel number %d\n", - xpd->xbus->busname, xpd->xpdname, chan); + XPD_ERR(xpd, "Metering tone: bad channel number %d\n", chan); return -EINVAL; } if((ret = metering_gen(xpd, chan, 1)) < 0) { - ERR("%s/%s: Failed sending metering tone\n", - xpd->xbus->busname, xpd->xpdname); + XPD_ERR(xpd, "Failed sending metering tone\n"); return ret; } return count; @@ -1528,22 +1521,22 @@ static int proc_xpd_metering_write(struct file *file, const char __user *buffer, int __init card_fxs_startup(void) { - INFO("%s revision %s\n", THIS_MODULE->name, XPP_VERSION); + INFO("revision %s\n", XPP_VERSION); #ifdef POLL_DIGITAL_INPUTS - INFO("FEATURE: %s with DIGITAL INPUTS support (polled every %d msec)\n", - THIS_MODULE->name, poll_digital_inputs); + INFO("FEATURE: with DIGITAL INPUTS support (polled every %d msec)\n", + poll_digital_inputs); #else - INFO("FEATURE: %s without DIGITAL INPUTS support\n", THIS_MODULE->name); + INFO("FEATURE: without DIGITAL INPUTS support\n"); #endif #ifdef ZT_VMWI - INFO("FEATURE: %s ZT_VMWI\n", THIS_MODULE->name); + INFO("FEATURE: ZT_VMWI\n"); #else - INFO("FEATURE: %s NO ZT_VMWI\n", THIS_MODULE->name); + INFO("FEATURE: NO ZT_VMWI\n"); #endif #ifdef WITH_METERING - INFO("FEATURE: %s WITH METERING Generation\n", THIS_MODULE->name); + INFO("FEATURE: WITH METERING Generation\n"); #else - INFO("FEATURE: %s NO METERING Generation\n", THIS_MODULE->name); + INFO("FEATURE: NO METERING Generation\n"); #endif xproto_register(&PROTO_TABLE(FXS)); return 0; |