From 878abc56f013a9bd94a46bf1a009407e6c8ecceb Mon Sep 17 00:00:00 2001 From: tzafrir Date: Sun, 29 Apr 2007 20:19:13 +0000 Subject: xpp rev. 3814: * Protocol no. 2.6: syncing improvements. * Support for 8-port Astribank BRI. * Firmware unloading now works: rmmod xpp_usb; /etc/hotplug/usb/xpp_fxloader reset * Defaults of kernel parameters are now part of parameter description. * World-readable kernel parameters. * No need for extra patch beyond bristuff for Astribank BRI. * Default poll intervals changed: 500 in BRI and FXO. * Allow changing FXS polls interval at run time. * BRI initalization fixed on SUSE (path to logger). * When using the SUSE zaptel rpm package, set modules_var=ZAPTEL_MODULES in /etc/sysconfig/zaptel . * zt_registration not verbose by default. * xpp_sync warns if FXO is sync slave. * Fixed genzaptelconf -z (zapscan output emulation). * PCM fixes. * Solves "multiple ticks" bug. No need for pcm_tasklets workaround. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@2475 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- xpp/card_bri.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 14 deletions(-) (limited to 'xpp/card_bri.c') diff --git a/xpp/card_bri.c b/xpp/card_bri.c index fecaee9..ad10aed 100644 --- a/xpp/card_bri.c +++ b/xpp/card_bri.c @@ -40,8 +40,8 @@ static const char rcsid[] = "$Id$"; #error CONFIG_ZAPATA_BRI_DCHANS is not defined #endif -DEF_PARM(int, print_dbg, 0, 0600, "Print DBG statements"); /* must be before zap_debug.h */ -DEF_PARM(uint, poll_interval, 100, 0600, "Poll channel state interval in milliseconds (0 - disable)"); +DEF_PARM(int, print_dbg, 0, 0644, "Print DBG statements"); /* must be before zap_debug.h */ +DEF_PARM(uint, poll_interval, 500, 0644, "Poll channel state interval in milliseconds (0 - disable)"); enum xhfc_states { ST_RESET = 0, /* G/F0 */ @@ -129,6 +129,8 @@ typedef union { byte reg; } su_rd_sta_t; +#define REG30_LOST 3 /* in polls */ + #define BRI_DCHAN_SIGCAP ( \ ZT_SIG_EM | \ ZT_SIG_CLEAR | \ @@ -165,6 +167,15 @@ enum led_state { BRI_LED_BLINK_FAST = 0x3 /* 1/4 a second blink cycle */ }; +#define LED_STATE_NAME(x) [ BRI_ ## x ] = #x +static const char *led_state_names[] = { + LED_STATE_NAME(LED_OFF), + LED_STATE_NAME(LED_ON), + LED_STATE_NAME(LED_BLINK_SLOW), + LED_STATE_NAME(LED_BLINK_FAST), +}; +#undef LED_STATE_NAME + enum bri_led_names { GREEN_LED = 0, RED_LED = 1 @@ -194,7 +205,7 @@ struct BRI_priv_data { int t4; /* timer 4 for deactivation */ ulong l1_flags; bool reg30_good; - ulong last_reg30_reply; + uint reg30_ticks; /* * D-Chan: buffers + extra state info. @@ -225,7 +236,7 @@ static /* 0x33 */ DECLARE_CMD(BRI, SET_LED, bool red_led, enum led_state to_led_ static /* 0x0F */ DECLARE_CMD(BRI, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high); #define DEBUG_BUF_SIZE (100) -static void dump_hex_buf(xpd_t *xpd, char *msg, byte *buf, int len) +static void dump_hex_buf(xpd_t *xpd, char *msg, byte *buf, size_t len) { char debug_buf[DEBUG_BUF_SIZE + 1]; int i; @@ -372,6 +383,7 @@ static int send_bri_multibyte(xpd_t *xpd, byte *buf, int len, bool eoftx) xframe_t *xframe; xpacket_t *pack; reg_cmd_t *reg_cmd; + int ret; BUG_ON(len < 0); /* @@ -400,7 +412,10 @@ static int send_bri_multibyte(xpd_t *xpd, byte *buf, int len, bool eoftx) if(print_dbg) dump_xframe("SEND_BRI_MULTI", xbus, xframe); #endif - return xframe_send(xbus, xframe); + ret = xframe_send(xbus, xframe); + if(ret < 0) + NOTICE("%s: %s: failed sending xframe\n", __FUNCTION__, xbus->busname); + return ret; } /* @@ -412,6 +427,7 @@ static int tx_dchan(xpd_t *xpd) struct zt_chan *dchan; int len; int eoframe; + int ret; priv = xpd->priv; BUG_ON(!priv); @@ -463,7 +479,11 @@ static int tx_dchan(xpd_t *xpd) priv->txframe_begin = 1; else priv->txframe_begin = 0; - return send_bri_multibyte(xpd, priv->dchan_tbuf, len, eoframe); + ret = send_bri_multibyte(xpd, priv->dchan_tbuf, len, eoframe); + if(ret < 0) + NOTICE("%s/%s: %s: failed sending xframe\n", + __FUNCTION__, xpd->xbus->busname, xpd->xpdname); + return ret; } /*---------------- BRI: Methods -------------------------------------------*/ @@ -539,7 +559,7 @@ static int BRI_card_init(xbus_t *xbus, xpd_t *xpd) * FPGA firmware limitation: * Force HOST sync *before* sending PCM */ - CALL_PROTO(GLOBAL, SYNC_SOURCE, xbus, NULL, 1, 0); + CALL_PROTO(GLOBAL, SYNC_SOURCE, xbus, NULL, SYNC_MODE_HOST, 0); DBG("done: %s/%s\n", xbus->busname, xpd->xpdname); priv->initialized = 1; CALL_PROTO(BRI, SET_LED, xbus, xpd, GREEN_LED, BRI_LED_ON); @@ -656,9 +676,10 @@ static int BRI_card_tick(xbus_t *xbus, xpd_t *xpd) if((priv->tick_counter % LED_TICKS) == 0) { int i; - if(priv->reg30_good && time_before(priv->last_reg30_reply + HZ/2, jiffies)) { + if(priv->reg30_good && priv->reg30_ticks > poll_interval * REG30_LOST) { /* No reply for 1/2 a second */ - ERR("%s/%s: Lost state tracking\n", xbus->busname, xpd->xpdname); + ERR("%s/%s: Lost state tracking for %d ticks\n", + xbus->busname, xpd->xpdname, priv->reg30_ticks); priv->reg30_good = 0; } if(!priv->reg30_good) { @@ -676,6 +697,7 @@ static int BRI_card_tick(xbus_t *xbus, xpd_t *xpd) } tx_dchan(xpd); priv->tick_counter++; + priv->reg30_ticks++; return 0; } @@ -694,6 +716,7 @@ static int BRI_card_close(xpd_t *xpd, lineno_t pos) static int BRI_span_startup(xpd_t *xpd) { struct BRI_priv_data *priv; + struct zt_chan *dchan; BUG_ON(!xpd); priv = xpd->priv; @@ -701,8 +724,18 @@ static int BRI_span_startup(xpd_t *xpd) DBG("%s/%s: STARTUP\n", xpd->xbus->busname, xpd->xpdname); write_state_register(xpd, 0); /* Enable L1 state machine */ CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 1); - if(SPAN_REGISTERED(xpd)) + if(SPAN_REGISTERED(xpd)) { + dchan = &xpd->span.chans[2]; xpd->span.flags |= ZT_FLAG_RUNNING; + /* + * Zaptel (wrongly) assume that D-Channel need HDLC decoding + * and during zaptel registration override our flags. + * + * Don't Get Mad, Get Even: Now we override zaptel :-) + */ + dchan->flags |= ZT_FLAG_BRIDCHAN; + dchan->flags &= ~ZT_FLAG_HDLC; + } return 0; } @@ -817,8 +850,9 @@ static int BRI_span_shutdown(xpd_t *xpd) BUG_ON(!priv); XFRAME_NEW(xframe, pack, xbus, BRI, SET_LED, xpd->id); #if 1 - DBG("%s/%s: %s %d\n", xbus->busname, xpd->xpdname, - (red_led)?"RED":"GREEN", to_led_state); + DBG("%s/%s: %s %s (%d)\n", xbus->busname, xpd->xpdname, + (red_led)?"RED":"GREEN", + led_state_names[to_led_state], to_led_state); #endif bri_leds = &RPACKET_FIELD(pack, BRI, SET_LED, bri_leds); bri_leds->state = to_led_state; @@ -860,7 +894,7 @@ static void su_new_state(xpd_t *xpd, byte reg_x30) BUG_ON(!priv); xbus = xpd->xbus; new_state.reg = reg_x30; - priv->last_reg30_reply = jiffies; + priv->reg30_ticks = 0; priv->reg30_good = 1; if((xpd->type == XPD_TYPE_BRI_TE && new_state.bits.v_su_sta == ST_TE_ACTIVATED) || (xpd->type == XPD_TYPE_BRI_NT && new_state.bits.v_su_sta == ST_NT_ACTIVATED)) { @@ -868,7 +902,17 @@ static void su_new_state(xpd_t *xpd, byte reg_x30) update_xpd_status(xpd, ZT_ALARM_NONE); } else { priv->ledcontrol[which_led] = BRI_LED_OFF; + /* + * Do NOT notify Zaptel about the disconnection. + * If we do, Asterisk stops transmitting on the D-channel and + * we can't reactivate layer-1. + * Without the notification, Asterisk thinks that we are active + * (although the PSTN stopped layer-1) and on call setup, sends + * us D-channel data, which triggers the layer-1 activation. + */ +#if 0 update_xpd_status(xpd, ZT_ALARM_RED); +#endif } if (priv->state_register.bits.v_su_sta == new_state.bits.v_su_sta) return; /* same same */ @@ -1098,7 +1142,7 @@ static int proc_bri_info_read(char *page, char **start, off_t off, int count, in } else len += sprintf(page + len, "Unkown\n"); len += sprintf(page + len, "Tick Counter: %d\n", priv->tick_counter); - len += sprintf(page + len, "Last Poll Reply at: %ld\n", priv->last_reg30_reply); + len += sprintf(page + len, "Last Poll Reply: %d ticks ago\n", priv->reg30_ticks); len += sprintf(page + len, "reg30_good=%d\n", priv->reg30_good); len += sprintf(page + len, "Drop Counter: %d\n", priv->drop_counter); for(led = 0; led < NUM_LEDS; led++) { -- cgit v1.2.3