[svn-commits] tzafrir: branch 1.4 r3020 - in /branches/1.4: ./ xpp/ xpp/firmwares/ xpp/util...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Sep 14 19:07:20 CDT 2007


Author: tzafrir
Date: Fri Sep 14 19:07:19 2007
New Revision: 3020

URL: http://svn.digium.com/view/zaptel?view=rev&rev=3020
Log:
New xpp release (Xorcom rev 4648):
* New firmware protocol version: 2.8 .
* New firmwares fix input ports offhook.
* Cleanup INFO() messages during module loading.

* USB: Receive queue with TASKLETS [r4600].  Controlled by rx_tasklet
  parameter to xpp_usb module (can be changed in runtime).
* The pcm_tasklet parameter in xpp module is deprecated:
  - Does not actually do anything.
  - If set during module loading, shows an ERR() message.
  - Also appears in /proc/xpp/sync

* FXS: Hardware DTMF detection by default, can be disabled
  by setting dtmf_detection=0 parameter to xpd_fxs.
  PCM is muted when DTMF key is pressed.

* zapconf:
  - Can now generate users.conf compatible with asterisk-gui.
  - Optional command-line arguments denoting which files to generate.
    Possible values are 'zaptel', 'zapata' and 'users'.
  - Defaults to creating zaptel and zapata.

Merged revisions 3019 via svnmerge from 
http://svn.digium.com/svn/zaptel/branches/1.2

Added:
    branches/1.4/xpp/init_card_3_28
      - copied unchanged from r3019, branches/1.2/xpp/init_card_3_28
    branches/1.4/xpp/init_card_4_28
      - copied unchanged from r3019, branches/1.2/xpp/init_card_4_28
    branches/1.4/xpp/init_card_6_28
      - copied unchanged from r3019, branches/1.2/xpp/init_card_6_28
    branches/1.4/xpp/init_card_7_28
      - copied unchanged from r3019, branches/1.2/xpp/init_card_7_28
    branches/1.4/xpp/init_card_9_28
      - copied unchanged from r3019, branches/1.2/xpp/init_card_9_28
    branches/1.4/xpp/param_doc
      - copied unchanged from r3019, branches/1.2/xpp/param_doc
Removed:
    branches/1.4/xpp/init_card_3_26
    branches/1.4/xpp/init_card_4_26
    branches/1.4/xpp/init_card_6_26
    branches/1.4/xpp/init_card_7_26
    branches/1.4/xpp/init_card_9_26
Modified:
    branches/1.4/   (props changed)
    branches/1.4/xpp/.version
    branches/1.4/xpp/ChangeLog
    branches/1.4/xpp/README.Astribank
    branches/1.4/xpp/card_bri.c
    branches/1.4/xpp/card_bri.h
    branches/1.4/xpp/card_fxo.c
    branches/1.4/xpp/card_fxo.h
    branches/1.4/xpp/card_fxs.c
    branches/1.4/xpp/card_fxs.h
    branches/1.4/xpp/card_global.c
    branches/1.4/xpp/card_global.h
    branches/1.4/xpp/card_pri.c
    branches/1.4/xpp/card_pri.h
    branches/1.4/xpp/firmwares/FPGA_1141.hex
    branches/1.4/xpp/firmwares/FPGA_1151.hex
    branches/1.4/xpp/firmwares/FPGA_FXS.hex
    branches/1.4/xpp/utils/Makefile
    branches/1.4/xpp/utils/zapconf
    branches/1.4/xpp/utils/zconf/Zaptel/Chans.pm
    branches/1.4/xpp/xbus-core.c
    branches/1.4/xpp/xbus-core.h
    branches/1.4/xpp/xpd.h
    branches/1.4/xpp/xpp_usb.c
    branches/1.4/xpp/xpp_zap.c
    branches/1.4/xpp/xpp_zap.h
    branches/1.4/xpp/xproto.c
    branches/1.4/xpp/xproto.h
    branches/1.4/xpp/zap_debug.h

Propchange: branches/1.4/
------------------------------------------------------------------------------
Binary property 'branch-1.2-merged' - no diff available.

Modified: branches/1.4/xpp/.version
URL: http://svn.digium.com/view/zaptel/branches/1.4/xpp/.version?view=diff&rev=3020&r1=3019&r2=3020
==============================================================================
--- branches/1.4/xpp/.version (original)
+++ branches/1.4/xpp/.version Fri Sep 14 19:07:19 2007
@@ -1,1 +1,1 @@
-branch-hotfix-4569-r4584
+trunk-r4648

Modified: branches/1.4/xpp/ChangeLog
URL: http://svn.digium.com/view/zaptel/branches/1.4/xpp/ChangeLog?view=diff&rev=3020&r1=3019&r2=3020
==============================================================================
--- branches/1.4/xpp/ChangeLog (original)
+++ branches/1.4/xpp/ChangeLog Fri Sep 14 19:07:19 2007
@@ -1,3 +1,25 @@
+Tue Sep 11 2007 Oron Peled <oron at actcom.co.il> - xpp.r4648
+  * New firmware protocol version: 2.8 .
+  * New firmwares fix input ports offhook.
+  * Cleanup INFO() messages during module loading.
+
+  * USB: Receive queue with TASKLETS [r4600].  Controlled by rx_tasklet
+    parameter to xpp_usb module (can be changed in runtime).
+  * The pcm_tasklet parameter in xpp module is deprecated:
+    - Does not actually do anything.
+    - If set during module loading, shows an ERR() message.
+    - Also appears in /proc/xpp/sync
+
+  * FXS: Hardware DTMF detection by default, can be disabled
+    by setting dtmf_detection=0 parameter to xpd_fxs.
+    PCM is muted when DTMF key is pressed.
+
+  * zapconf:
+    - Can now generate users.conf compatible with asterisk-gui.
+    - Optional command-line arguments denoting which files to generate.
+      Possible values are 'zaptel', 'zapata' and 'users'.
+    - Defaults to creating zaptel and zapata.
+
 Mon Sep  3 2007 Tzafrir Cohen <tzafrir.cohen at xorcom.com> - xpp.r4584
   * New firmware to fix FXS leds irregularities.
   * Less noise at build time - don't echo version, test compile only once.

Modified: branches/1.4/xpp/README.Astribank
URL: http://svn.digium.com/view/zaptel/branches/1.4/xpp/README.Astribank?view=diff&rev=3020&r1=3019&r2=3020
==============================================================================
--- branches/1.4/xpp/README.Astribank (original)
+++ branches/1.4/xpp/README.Astribank Fri Sep 14 19:07:19 2007
@@ -780,9 +780,13 @@
   with those parameters.
 
 dtmf_detection (xpd_fxs)::
-  enable (1) or disable (0) support of hardware DTMF detection by the Astribank.
-  Disabled by default and currently buggy. On some earlier versions (4372 -
-  4415) it was enabled by default, and disabling it there may help.
+  Enable (1) or disable (0) support of hardware DTMF detection by the 
+  Astribank.
+
+rx_tasklet (xpp_usb)::
+  Enable (1) or disable (0) doing most of the packets processing in
+  separate tasklets. This should probably help on higher-end systes with
+  multiple Astribanks.
 
 
 TROUBLESHOOTING

Modified: branches/1.4/xpp/card_bri.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/xpp/card_bri.c?view=diff&rev=3020&r1=3019&r2=3020
==============================================================================
--- branches/1.4/xpp/card_bri.c (original)
+++ branches/1.4/xpp/card_bri.c Fri Sep 14 19:07:19 2007
@@ -248,7 +248,6 @@
 	);
 
 static /* 0x33 */ DECLARE_CMD(BRI, SET_LED, enum bri_led_names which_led, enum led_state to_led_state);
-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	DO_LED(xpd, which, tostate)	\
 			CALL_PROTO(BRI, SET_LED, (xpd)->xbus, (xpd), (which), (tostate))
@@ -263,7 +262,7 @@
 	debug_buf[0] = '\0';
 	for(i = 0; i < len && n < DEBUG_BUF_SIZE; i++)
 		n += snprintf(&debug_buf[n], DEBUG_BUF_SIZE - n, "%02X ", buf[i]);
-	XPD_DBG(GENERAL, xpd, "%s[0..%d]: %s%s\n", msg, len-1, debug_buf,
+	XPD_DBG(GENERAL, xpd, "%s[0..%zd]: %s%s\n", msg, len-1, debug_buf,
 			(n >= DEBUG_BUF_SIZE)?"...":"");
 }
 
@@ -482,8 +481,8 @@
 		XPD_ERR(xpd, "%s: len=%d is too long. dropping.\n", __FUNCTION__, len);
 		return -EINVAL;
 	}
-	XFRAME_NEW(xframe, pack, xbus, BRI, REGISTER_REQUEST, xpd->xbus_idx);
-	reg_cmd = &RPACKET_FIELD(pack, BRI, REGISTER_REQUEST, reg_cmd);
+	XFRAME_NEW(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx);
+	reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
 	reg_cmd->bytes = len;
 	reg_cmd->eoframe = eoftx;
 	reg_cmd->multibyte = 1;
@@ -644,11 +643,15 @@
 	ret = run_initialize_registers(xpd);
 	if(ret < 0)
 		goto err;
+#if 1
+#warning "Test BRI! (removed old SYNC_SOURCE manipulation)"
+#else
 	/*
 	 * FPGA firmware limitation:
 	 *     Force HOST sync *before* sending PCM
 	 */
 	CALL_PROTO(GLOBAL, SYNC_SOURCE, xbus, NULL, SYNC_MODE_HOST, 0);
+#endif
 	XPD_DBG(PROC, xpd, "done\n");
 	priv->initialized = 1;
 	return 0;
@@ -761,7 +764,7 @@
 	return(0);
 }
 
-int BRI_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
+static int BRI_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
 {
 	LINE_DBG(SIGNAL, xpd, pos, "%s\n", txsig2str(txsig));
 	return 0;
@@ -850,7 +853,7 @@
 	if(poll_interval != 0 && (priv->tick_counter % poll_interval) == 0) {
 		// XPD_DBG(GENERAL, xpd, "%d\n", priv->tick_counter);
 		priv->poll_counter++;
-		CALL_PROTO(BRI, REGISTER_REQUEST, xbus, xpd, 0, 0, 0, A_SU_RD_STA, 0, 0, 0);
+		xpp_register_request(xbus, xpd, 0, 0, 0, A_SU_RD_STA, 0, 0, 0);
 
 		if(IS_NT(xpd) && nt_keepalive &&
 			!test_bit(HFC_L1_ACTIVATED, &priv->l1_flags) &&
@@ -1118,36 +1121,7 @@
 
 /*---------------- BRI: HOST COMMANDS -------------------------------------*/
 
-/* 0x0F */ HOSTCMD(BRI, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high)
-{
-	int		ret = 0;
-	xframe_t	*xframe;
-	xpacket_t	*pack;
-	reg_cmd_t	*reg_cmd;
-
-	if(!xbus) {
-		DBG(GENERAL, "NO XBUS\n");
-		return -EINVAL;
-	}
-	XFRAME_NEW(xframe, pack, xbus, BRI, REGISTER_REQUEST, xpd->xbus_idx);
-	LINE_DBG(REGS, xpd, chipsel, "%c%c R%02X S%02X %02X %02X\n",
-			(writing)?'W':'R',
-			(do_subreg)?'S':'D',
-			regnum, subreg, data_low, data_high);
-	reg_cmd = &RPACKET_FIELD(pack, BRI, REGISTER_REQUEST, reg_cmd);
-	reg_cmd->bytes = sizeof(*reg_cmd) - 1;	// do not count the 'bytes' field
-	REG_FIELD(reg_cmd, chipsel) = chipsel;
-	REG_FIELD(reg_cmd, read_request) = (writing) ? 0 : 1;
-	REG_FIELD(reg_cmd, do_subreg) = do_subreg;
-	REG_FIELD(reg_cmd, regnum) = regnum;
-	REG_FIELD(reg_cmd, subreg) = subreg;
-	REG_FIELD(reg_cmd, data_low) = data_low;
-	REG_FIELD(reg_cmd, data_high) = data_high;
-	ret = send_cmd_frame(xbus, xframe);
-	return ret;
-}
-
-/* 0x0F */ HOSTCMD(BRI, XPD_STATE, bool on)
+static /* 0x0F */ HOSTCMD(BRI, XPD_STATE, bool on)
 {
 	BUG_ON(!xpd);
 	XPD_DBG(GENERAL, xpd, "%s\n", (on)?"ON":"OFF");
@@ -1155,19 +1129,19 @@
 	return 0;
 }
 
-/* 0x0F */ HOSTCMD(BRI, RING, lineno_t chan, bool on)
+static /* 0x0F */ HOSTCMD(BRI, RING, lineno_t chan, bool on)
 {
 	XPD_ERR(xpd, "%s: Unsupported\n", __FUNCTION__);
 	return -ENOSYS;
 }
 
-/* 0x0F */ HOSTCMD(BRI, RELAY_OUT, byte which, bool on)
+static /* 0x0F */ HOSTCMD(BRI, RELAY_OUT, byte which, bool on)
 {
 	XPD_ERR(xpd, "%s: Unsupported\n", __FUNCTION__);
 	return -ENOSYS;
 }
 
-/* 0x33 */ HOSTCMD(BRI, SET_LED, enum bri_led_names which_led, enum led_state to_led_state)
+static /* 0x33 */ HOSTCMD(BRI, SET_LED, enum bri_led_names which_led, enum led_state to_led_state)
 {
 	int			ret = 0;
 	xframe_t		*xframe;
@@ -1185,7 +1159,7 @@
 	bri_leds = &RPACKET_FIELD(pack, BRI, SET_LED, bri_leds);
 	bri_leds->state = to_led_state;
 	bri_leds->led_sel = which_led;
-	pack->datalen = RPACKET_SIZE(BRI, SET_LED);
+	XPACKET_LEN(pack) = RPACKET_SIZE(BRI, SET_LED);
 	ret = send_cmd_frame(xbus, xframe);
 	priv->ledstate[which_led] = to_led_state;
 	return ret;
@@ -1196,7 +1170,7 @@
 	int	ret;
 
 	XPD_DBG(REGS, xpd, "value = 0x%02X\n", value);
-	ret = CALL_PROTO(BRI, REGISTER_REQUEST, xpd->xbus, xpd,
+	ret = xpp_register_request(xpd->xbus, xpd,
 			0,		/* chipsel	*/
 			1,		/* writing	*/
 			0,		/* do_subreg	*/
@@ -1326,28 +1300,21 @@
 	priv->state_register.reg = new_state.reg;
 }
 
-HANDLER_DEF(BRI, REGISTER_REPLY)
-{
-	reg_cmd_t		*info = &RPACKET_FIELD(pack, BRI, REGISTER_REPLY, regcmd);
+static int BRI_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
+{
 	unsigned long		flags;
 	struct BRI_priv_data	*priv;
 	int			ret;
 
-	if(!xpd) {
-		XBUS_NOTICE(xbus, "%s: received %s for non-existing unit (%1d%1d)\n",
-				__FUNCTION__, cmd->name,
-				pack->addr.unit, pack->addr.subunit);
-		return -EPROTO;
-	}
 	spin_lock_irqsave(&xpd->lock, flags);
 	priv = xpd->priv;
 	BUG_ON(!priv);
 	if(REG_FIELD(info, do_subreg)) {
-		XPD_DBG(REGS, xpd, "REGISTER_REPLY: RS %02X %02X %02X\n",
+		XPD_DBG(REGS, xpd, "RS %02X %02X %02X\n",
 				REG_FIELD(info, regnum), REG_FIELD(info, subreg), REG_FIELD(info, data_low));
 	} else {
 		if (REG_FIELD(info, regnum) != A_SU_RD_STA)
-			XPD_DBG(REGS, xpd, "REGISTER_REPLY: RD %02X %02X\n",
+			XPD_DBG(REGS, xpd, "RD %02X %02X\n",
 					REG_FIELD(info, regnum), REG_FIELD(info, data_low));
 	}
 	if(info->multibyte) {
@@ -1382,7 +1349,6 @@
 	.owner = THIS_MODULE,
 	.entries = {
 		/*	Table	Card	Opcode		*/
-		XENTRY(	BRI_NT,	BRI,	REGISTER_REPLY		),
 	},
 	.name = "BRI_NT",
 	.type = XPD_TYPE_BRI_NT,
@@ -1397,6 +1363,7 @@
 		.card_pcm_fromspan	= BRI_card_pcm_fromspan,
 		.card_pcm_tospan	= BRI_card_pcm_tospan,
 		.card_close	= BRI_card_close,
+		.card_register_reply	= BRI_card_register_reply,
 
 		.RING		= XPROTO_CALLER(BRI, RING),
 		.RELAY_OUT	= XPROTO_CALLER(BRI, RELAY_OUT),
@@ -1410,7 +1377,6 @@
 	.owner = THIS_MODULE,
 	.entries = {
 		/*	Table	Card	Opcode		*/
-		XENTRY(	BRI_TE,	BRI,	REGISTER_REPLY		),
 	},
 	.name = "BRI_TE",
 	.type = XPD_TYPE_BRI_TE,
@@ -1424,6 +1390,8 @@
 		.card_tick	= BRI_card_tick,
 		.card_pcm_fromspan	= BRI_card_pcm_fromspan,
 		.card_pcm_tospan	= BRI_card_pcm_tospan,
+		.card_close	= BRI_card_close,
+		.card_register_reply	= BRI_card_register_reply,
 
 		.RING		= XPROTO_CALLER(BRI, RING),
 		.RELAY_OUT	= XPROTO_CALLER(BRI, RELAY_OUT),
@@ -1438,8 +1406,8 @@
 	const xproto_entry_t	*xe_nt = NULL;
 	const xproto_entry_t	*xe_te = NULL;
 	// DBG(GENERAL, "\n");
-	xe_nt = xproto_card_entry(&PROTO_TABLE(BRI_NT), pack->opcode);
-	xe_te = xproto_card_entry(&PROTO_TABLE(BRI_TE), pack->opcode);
+	xe_nt = xproto_card_entry(&PROTO_TABLE(BRI_NT), XPACKET_OP(pack));
+	xe_te = xproto_card_entry(&PROTO_TABLE(BRI_TE), XPACKET_OP(pack));
 	return xe_nt != NULL || xe_te != NULL;
 }
 
@@ -1634,7 +1602,7 @@
 	priv->requested_reply = regcmd;
 	if(print_dbg)
 		dump_reg_cmd("BRI", &regcmd, 1);
-	ret = CALL_PROTO(BRI, REGISTER_REQUEST, xpd->xbus, xpd,
+	ret = xpp_register_request(xpd->xbus, xpd,
 			REG_FIELD(&regcmd, chipsel),
 			writing,
 			REG_FIELD(&regcmd, do_subreg),

Modified: branches/1.4/xpp/card_bri.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/xpp/card_bri.h?view=diff&rev=3020&r1=3019&r2=3020
==============================================================================
--- branches/1.4/xpp/card_bri.h (original)
+++ branches/1.4/xpp/card_bri.h Fri Sep 14 19:07:19 2007
@@ -25,16 +25,7 @@
 #include "xpd.h"
 
 enum bri_opcodes {
-	XPROTO_NAME(BRI, REGISTER_REQUEST)		= 0x0F,
-	XPROTO_NAME(BRI, REGISTER_REPLY)		= 0x10,
 	XPROTO_NAME(BRI, SET_LED)			= 0x33,
 };
 
-DEF_RPACKET_DATA(BRI, REGISTER_REPLY,	/* Get status of a single register (for debugging) */
-	reg_cmd_t	regcmd;
-	);
-DEF_RPACKET_DATA(BRI, REGISTER_REQUEST,
-	reg_cmd_t	reg_cmd;
-	);
-
 #endif	/* CARD_BRI_H */

Modified: branches/1.4/xpp/card_fxo.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/xpp/card_fxo.c?view=diff&rev=3020&r1=3019&r2=3020
==============================================================================
--- branches/1.4/xpp/card_fxo.c (original)
+++ branches/1.4/xpp/card_fxo.c Fri Sep 14 19:07:19 2007
@@ -57,12 +57,11 @@
 #define	BAT_THRESHOLD		3
 #define	BAT_DEBOUNCE		3	/* compensate for battery voltage fluctuation (in poll_battery_interval's) */
 
-static /* 0x0F */ DECLARE_CMD(FXO, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high);
 /* Shortcuts */
 #define	DAA_WRITE	1
 #define	DAA_READ	0
 #define	DAA_DIRECT_REQUEST(xbus,xpd,chipsel,writing,reg,dL)	\
-	CALL_PROTO(FXO, REGISTER_REQUEST, (xbus), (xpd), (chipsel), (writing), 0, (reg), 0, (dL), 0)
+	xpp_register_request((xbus), (xpd), (chipsel), (writing), 0, (reg), 0, (dL), 0)
 
 #define	VALID_CHIPSEL(x)	(((chipsel) >= 0 && (chipsel) <= 7) || (chipsel) == ALL_CHANS)
 
@@ -200,7 +199,7 @@
 	spin_unlock_irqrestore(&xpd->lock, flags);
 }
 
-void update_zap_ring(xpd_t *xpd, int pos, bool on)
+static void update_zap_ring(xpd_t *xpd, int pos, bool on)
 {
 	zt_rxsig_t	rxsig;
 
@@ -463,7 +462,7 @@
 	return 0;
 }
 
-int FXO_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
+static int FXO_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
 {
 	struct FXO_priv_data	*priv;
 
@@ -622,36 +621,7 @@
 
 /*---------------- FXO: HOST COMMANDS -------------------------------------*/
 
-/* 0x0F */ HOSTCMD(FXO, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high)
-{
-	int		ret = 0;
-	xframe_t	*xframe;
-	xpacket_t	*pack;
-	reg_cmd_t	*reg_cmd;
-
-	if(!xbus) {
-		DBG(REGS, "NO XBUS\n");
-		return -EINVAL;
-	}
-	XFRAME_NEW(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx);
-	LINE_DBG(REGS, xpd, chipsel, "%c%c R%02X S%02X %02X %02X\n",
-			(writing)?'W':'R',
-			(do_subreg)?'S':'D',
-			regnum, subreg, data_low, data_high);
-	reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
-	reg_cmd->bytes = sizeof(*reg_cmd) - 1;	// do not count the 'bytes' field
-	REG_FIELD(reg_cmd, chipsel) = chipsel;
-	REG_FIELD(reg_cmd, read_request) = (writing) ? 0 : 1;
-	REG_FIELD(reg_cmd, do_subreg) = do_subreg;
-	REG_FIELD(reg_cmd, regnum) = regnum;
-	REG_FIELD(reg_cmd, subreg) = subreg;
-	REG_FIELD(reg_cmd, data_low) = data_low;
-	REG_FIELD(reg_cmd, data_high) = data_high;
-	ret = send_cmd_frame(xbus, xframe);
-	return ret;
-}
-
-static /* 0x0F */ HOSTCMD(FXO, XPD_STATE, bool on)
+/* 0x0F */ HOSTCMD(FXO, XPD_STATE, bool on)
 {
 	int			ret = 0;
 	struct FXO_priv_data	*priv;
@@ -664,7 +634,7 @@
 	return ret;
 }
 
-static /* 0x0F */ HOSTCMD(FXO, RING, lineno_t chan, bool on)
+/* 0x0F */ HOSTCMD(FXO, RING, lineno_t chan, bool on)
 {
 	BUG_ON(!xbus);
 	BUG_ON(!xpd);
@@ -672,7 +642,7 @@
 	return DAA_DIRECT_REQUEST(xbus, xpd, chan, DAA_WRITE, 0x40, (on)?0x04:0x01);
 }
 
-static /* 0x0F */ HOSTCMD(FXO, RELAY_OUT, byte which, bool on)
+/* 0x0F */ HOSTCMD(FXO, RELAY_OUT, byte which, bool on)
 {
 	return -ENOSYS;
 }
@@ -688,7 +658,7 @@
 	struct FXO_priv_data	*priv;
 
 	if(!xpd) {
-		notify_bad_xpd(__FUNCTION__, xbus, pack->addr, cmd->name);
+		notify_bad_xpd(__FUNCTION__, xbus, XPACKET_ADDR(pack), cmd->name);
 		return -EPROTO;
 	}
 	priv = xpd->priv;
@@ -707,7 +677,7 @@
 			/* First report false ring alarms */
 			debounce = atomic_read(&priv->ring_debounce[i]);
 			if(debounce)
-				LINE_NOTICE(xpd, i, "debounced %d ticks\n", debounce);
+				LINE_NOTICE(xpd, i, "debounced false ring (only %d ticks)\n", debounce);
 			/*
 			 * Now set a new ring alarm.
 			 * It will be checked in handle_fxo_ring()
@@ -836,16 +806,11 @@
 }
 #endif
 
-HANDLER_DEF(FXO, DAA_REPLY)
-{
-	reg_cmd_t		*info = &RPACKET_FIELD(pack, FXO, DAA_REPLY, regcmd);
+static int FXO_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
+{
 	struct FXO_priv_data	*priv;
 	lineno_t		chipsel;
 
-	if(!xpd) {
-		notify_bad_xpd(__FUNCTION__, xbus, pack->addr, cmd->name);
-		return -EPROTO;
-	}
 	priv = xpd->priv;
 	BUG_ON(!priv);
 	chipsel = REG_FIELD(info, chipsel);
@@ -862,7 +827,7 @@
 			break;
 #endif
 	}
-	LINE_DBG(REGS, xpd, chipsel, "DAA_REPLY: %c reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
+	LINE_DBG(REGS, xpd, chipsel, "%c reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
 			((info->bytes == 3)?'I':'D'),
 			REG_FIELD(info, regnum),
 			REG_FIELD(info, data_low),
@@ -878,12 +843,11 @@
 }
 
 
-xproto_table_t PROTO_TABLE(FXO) = {
+static xproto_table_t PROTO_TABLE(FXO) = {
 	.owner = THIS_MODULE,
 	.entries = {
 		/*	Prototable	Card	Opcode		*/
 		XENTRY(	FXO,		FXO,	SIG_CHANGED	),
-		XENTRY(	FXO,		FXO,	DAA_REPLY	),
 	},
 	.name = "FXO",
 	.type = XPD_TYPE_FXO,
@@ -899,6 +863,7 @@
 		.card_pcm_tospan	= generic_card_pcm_tospan,
 		.card_ioctl	= FXO_card_ioctl,
 		.card_open	= FXO_card_open,
+		.card_register_reply	= FXO_card_register_reply,
 
 		.RING		= XPROTO_CALLER(FXO, RING),
 		.RELAY_OUT	= XPROTO_CALLER(FXO, RELAY_OUT),
@@ -913,7 +878,7 @@
 	const xproto_entry_t	*xe;
 
 	//DBG(GENERAL, "\n");
-	xe = xproto_card_entry(&PROTO_TABLE(FXO), pack->opcode);
+	xe = xproto_card_entry(&PROTO_TABLE(FXO), XPACKET_OP(pack));
 	return xe != NULL;
 }
 

Modified: branches/1.4/xpp/card_fxo.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/xpp/card_fxo.h?view=diff&rev=3020&r1=3019&r2=3020
==============================================================================
--- branches/1.4/xpp/card_fxo.h (original)
+++ branches/1.4/xpp/card_fxo.h Fri Sep 14 19:07:19 2007
@@ -33,8 +33,6 @@
 	XPROTO_NAME(FXO, RING)			= 0x0F,	/* Write to DAA */
 	XPROTO_NAME(FXO, LED)			= 0x0F,	/* Write to DAA */
 	XPROTO_NAME(FXO, RELAY_OUT)		= 0x0F,	/* Write to DAA */
-/**/
-	XPROTO_NAME(FXO, DAA_REPLY)		= 0x10,
 };
 
 
@@ -43,9 +41,6 @@
 	xpp_line_t	sig_status;	/* channels: lsb=1, msb=8 */
 	xpp_line_t	sig_toggles;	/* channels: lsb=1, msb=8 */
 	);
-DEF_RPACKET_DATA(FXO, DAA_REPLY,	/* Get status of a single DAA (for debugging) */
-	reg_cmd_t	regcmd;
-	);
 
 #define	DAA_VBAT_REGISTER	29
 

Modified: branches/1.4/xpp/card_fxs.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/xpp/card_fxs.c?view=diff&rev=3020&r1=3019&r2=3020
==============================================================================
--- branches/1.4/xpp/card_fxs.c (original)
+++ branches/1.4/xpp/card_fxs.c Fri Sep 14 19:07:19 2007
@@ -37,7 +37,7 @@
 DEF_PARM(uint, poll_digital_inputs, 1000, 0644, "Poll Digital Inputs");
 DEF_PARM_BOOL(reversepolarity, 0, 0644, "Reverse Line Polarity");
 DEF_PARM_BOOL(vmwineon, 0, 0644, "Indicate voicemail to a neon lamp");
-DEF_PARM_BOOL(dtmf_detection, 0, 0644, "Do DTMF detection in hardware");
+DEF_PARM_BOOL(dtmf_detection, 1, 0644, "Do DTMF detection in hardware");
 
 #ifdef	ZT_VMWI
 DEF_PARM_BOOL(vmwi_ioctl, 0, 0644, "Asterisk support VMWI notification via ioctl");
@@ -63,14 +63,13 @@
 
 #define	NUM_LEDS	2
 
-static /* 0x0F */ DECLARE_CMD(FXS, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high);
 /* Shortcuts */
 #define	SLIC_WRITE	1
 #define	SLIC_READ	0
 #define	SLIC_DIRECT_REQUEST(xbus,xpd,chipsel,writing,reg,dL)	\
-	CALL_PROTO(FXS, REGISTER_REQUEST, (xbus), (xpd), (chipsel), (writing), 0, (reg), 0, (dL), 0)
+	xpp_register_request((xbus), (xpd), (chipsel), (writing), 0, (reg), 0, (dL), 0)
 #define	SLIC_INDIRECT_REQUEST(xbus,xpd,chipsel,writing,reg,dL,dH)	\
-	CALL_PROTO(FXS, REGISTER_REQUEST, (xbus), (xpd), (chipsel), (writing), 1, 0x1E, (reg), (dL), (dH))
+	xpp_register_request((xbus), (xpd), (chipsel), (writing), 1, 0x1E, (reg), (dL), (dH))
 
 #define	VALID_CHIPSEL(x)	(((chipsel) >= 0 && (chipsel) <= 7) || (chipsel) == ALL_CHANS)
 
@@ -89,9 +88,10 @@
 #define	FXS_LINE_POL_ACTIVE	((reversepolarity) ? FXS_LINE_REV_ACTIVE : FXS_LINE_ACTIVE)
 #define	FXS_LINE_POL_OHTRANS	((reversepolarity) ? FXS_LINE_REV_OHTRANS : FXS_LINE_OHTRANS)
 
+/*
+ * DTMF detection
+ */
 #define DTMF_REGISTER		0x18	/* 24 */
-#define POLL_DTMF_INTERVAL	20	/* ticks */
-
 
 /*---------------- FXS Protocol Commands ----------------------------------*/
 
@@ -126,7 +126,6 @@
 	xpp_line_t		search_fsk_pattern;
 	xpp_line_t		found_fsk_pattern;
 	xpp_line_t		update_offhook_state;
-	xpp_line_t		dtmf_keypressed;
 	int			led_counter[NUM_LEDS][CHANNELS_PERXPD];
 	int			ohttimer[CHANNELS_PERXPD];
 #define OHT_TIMER		6000	/* How long after RING to retain OHT */
@@ -500,7 +499,7 @@
 	return 0;
 }
 
-int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
+static int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
 {
 	struct FXS_priv_data	*priv;
 	int			ret = 0;
@@ -630,8 +629,12 @@
 			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(priv->lasttxhook[pos] == FXS_LINE_POL_ACTIVE) {
+				priv->ohttimer[pos] = OHT_TIMER;
+				priv->idletxhookstate[pos] = FXS_LINE_POL_OHTRANS;
+				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;
@@ -642,7 +645,30 @@
 				(val & ZT_TONEDETECT_ON) ? "ON" : "OFF",
 				(val & ZT_TONEDETECT_MUTE) ? "MUTE" : "NO-MUTE",
 				(dtmf_detection ? "YES" : "NO"));
-			return (dtmf_detection) ? 0 : -ENOTTY;
+			if(!dtmf_detection) {
+				SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x17, 0);
+				return -ENOTTY;
+			} else {
+				/* Enable DTMF interrupts (XPD will notify when DTMF will be detected) */
+				SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x17, 1);
+				return 0;
+			}
+		case ZT_SETPOLARITY:
+			if (get_user(val, (int __user *)arg))
+				return -EFAULT;
+			/* Can't change polarity while ringing or when open */
+			if (priv->lasttxhook[pos] == FXS_LINE_RING || priv->lasttxhook[pos] == FXS_LINE_OPEN) {
+				LINE_ERR(xpd, pos, "ZT_SETPOLARITY: %s Cannot change when lasttxhook=0x%X\n",
+					(val)?"ON":"OFF", priv->lasttxhook[pos]);
+				return -EINVAL;
+			}
+			LINE_DBG(SIGNAL, xpd, pos, "ZT_SETPOLARITY: %s\n", (val)?"ON":"OFF");
+			if ((val && !reversepolarity) || (!val && reversepolarity))
+				priv->lasttxhook[pos] |= FXS_LINE_RING;
+			else
+				priv->lasttxhook[pos] &= ~FXS_LINE_RING;
+			linefeed_control(xbus, xpd, pos, priv->lasttxhook[pos]);
+			return 0;
 #ifdef	ZT_VMWI
 		case ZT_VMWI:		/* message-waiting led control */
 			if (get_user(val, (int __user *)arg))
@@ -770,17 +796,7 @@
 	}
 }
 
-static void poll_dtmf(xpd_t *xpd)
-{
-	int			i;
-
-	for_each_line(xpd, i) {
-		if(IS_SET(xpd->offhook, i))
-			SLIC_DIRECT_REQUEST(xpd->xbus, xpd, i, SLIC_READ, DTMF_REGISTER, 0);
-	}
-}
-
-void handle_linefeed(xpd_t *xpd)
+static void handle_linefeed(xpd_t *xpd)
 {
 	struct FXS_priv_data	*priv;
 	int			i;
@@ -802,6 +818,7 @@
 						enum fxs_state	txhook = FXS_LINE_POL_ACTIVE;
 						/* Apply the change if appropriate */
 						BIT_CLR(xpd->cid_on, i);
+						BIT_CLR(priv->search_fsk_pattern, i);
 						pcm_recompute(xpd, xpd->offhook | xpd->cid_on);
 						linefeed_control(xpd->xbus, xpd, i, txhook);
 					}
@@ -923,45 +940,13 @@
 	if(SPAN_REGISTERED(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);
 	}
 	return 0;
 }
 
 /*---------------- FXS: HOST COMMANDS -------------------------------------*/
 
-/* 0x0F */ HOSTCMD(FXS, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high)
-{
-	int		ret = 0;
-	xframe_t	*xframe;
-	xpacket_t	*pack;
-	reg_cmd_t	*reg_cmd;
-
-	if(!xbus) {
-		DBG(GENERAL, "NO XBUS\n");
-		return -EINVAL;
-	}
-	XFRAME_NEW(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx);
-	LINE_DBG(REGS, xpd, chipsel, "%c%c R%02X S%02X %02X %02X\n",
-			(writing)?'W':'R',
-			(do_subreg)?'S':'D',
-			regnum, subreg, data_low, data_high);
-	reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
-	reg_cmd->bytes = sizeof(*reg_cmd) - 1;	// do not count the 'bytes' field
-	REG_FIELD(reg_cmd, chipsel) = chipsel;
-	REG_FIELD(reg_cmd, read_request) = (writing) ? 0 : 1;
-	REG_FIELD(reg_cmd, do_subreg) = do_subreg;
-	REG_FIELD(reg_cmd, regnum) = regnum;
-	REG_FIELD(reg_cmd, subreg) = subreg;
-	REG_FIELD(reg_cmd, data_low) = data_low;
-	REG_FIELD(reg_cmd, data_high) = data_high;
-	ret = send_cmd_frame(xbus, xframe);
-	return ret;
-}
-
-static /* 0x0F */ HOSTCMD(FXS, XPD_STATE, bool on)
+/* 0x0F */ HOSTCMD(FXS, XPD_STATE, bool on)
 {
 	int		i;
 	enum fxs_state	value = (on) ? FXS_LINE_POL_ACTIVE : FXS_LINE_OPEN;
@@ -984,7 +969,7 @@
 	return 0;
 }
 
-static /* 0x0F */ HOSTCMD(FXS, RING, lineno_t chan, bool on)
+/* 0x0F */ HOSTCMD(FXS, RING, lineno_t chan, bool on)
 {
 	int			ret = 0;
 	struct FXS_priv_data	*priv;
@@ -1006,7 +991,7 @@
 	return ret;
 }
 
-static /* 0x0F */ HOSTCMD(FXS, RELAY_OUT, byte which, bool on)
+/* 0x0F */ HOSTCMD(FXS, RELAY_OUT, byte which, bool on)
 {
 	int		value;
 	int		relay_channels[] = { 0, 4 };
@@ -1047,7 +1032,6 @@
 	for_each_line(xpd, i) {
 		if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i))
 			continue;
-		BIT_CLR(priv->dtmf_keypressed, i);	/* no dtmf history */
 		if(IS_SET(sig_toggles, i)) {
 			xpd->ringing[i] = 0;		/* No more ringing... */
 #ifdef	WITH_METERING
@@ -1101,19 +1085,19 @@
 	'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '*', '#', 'A', 'B', 'C', 'D'
 };
 
-void process_dtmf(xpd_t *xpd, const reg_cmd_t *info)
+static void process_dtmf(xpd_t *xpd, const reg_cmd_t *info)
 {
 	int		i;
 	byte		val = REG_FIELD(info, data_low);
 	xpp_line_t	lines = BIT(REG_FIELD(info, chipsel));
 	byte		digit;
-	bool		on = val & 0x10;
+	bool		is_down = val & 0x10;
 	struct FXS_priv_data	*priv;
 
 	priv = xpd->priv;
 	val &= 0xF;
 	if(val <= 0) {
-		if(on)
+		if(is_down)
 			XPD_NOTICE(xpd, "Bad DTMF value %d. Ignored\n", val);
 		return;
 	}
@@ -1121,40 +1105,35 @@
 	digit = dtmf_digits[val];
 	for_each_line(xpd, i) {
 		if(IS_SET(lines, i)) {
-			if(on && !IS_SET(priv->dtmf_keypressed, i)) {
-				LINE_DBG(SIGNAL, xpd, i, "DTMF digit %2d PRESSED (%d)\n", digit, val);
-				BIT_SET(priv->dtmf_keypressed, i);
-				if(dtmf_detection)
+			if(dtmf_detection) {
+				LINE_DBG(SIGNAL, xpd, i, "DTMF digit %s (val=%d) '%c'\n",
+						(is_down)?"DOWN":"UP", val, digit);
+				if(is_down) {
+					BIT_SET(xpd->mute_dtmf, i);
 					zt_qevent_lock(&xpd->chans[i], ZT_EVENT_DTMFDOWN | digit);
-			} else if(!on && IS_SET(priv->dtmf_keypressed, i)) {
-				LINE_DBG(SIGNAL, xpd, i, "DTMF digit %2d RELEASED\n", digit);
-				BIT_CLR(priv->dtmf_keypressed, i);
-				if(dtmf_detection)
+				} else {
 					zt_qevent_lock(&xpd->chans[i], ZT_EVENT_DTMFUP | digit);
+					BIT_CLR(xpd->mute_dtmf, i);
+				}
 			}
 			break;
 		}
 	}
 }
 
-HANDLER_DEF(FXS, REGISTER_REPLY)
-{
-	reg_cmd_t		*info = &RPACKET_FIELD(pack, FXS, REGISTER_REPLY, reg_cmd);
+static int FXS_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
+{
 	unsigned long		flags;
 	struct FXS_priv_data	*priv;
 	byte			regnum;
 	bool			indirect;
 
-	if(!xpd) {
-		notify_bad_xpd(__FUNCTION__, xbus, pack->addr, cmd->name);
-		return -EPROTO;
-	}
 	spin_lock_irqsave(&xpd->lock, flags);
 	priv = xpd->priv;
 	BUG_ON(!priv);
 	indirect = (REG_FIELD(info, regnum) == 0x1E);
 	regnum = (indirect) ? REG_FIELD(info, subreg) : REG_FIELD(info, regnum);
-	XPD_DBG(REGS, xpd, "REGISTER_REPLY: %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
+	XPD_DBG(REGS, xpd, "%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));
 	if(!SPAN_REGISTERED(xpd))
@@ -1178,12 +1157,11 @@
 	return 0;
 }
 
-xproto_table_t PROTO_TABLE(FXS) = {
+static xproto_table_t PROTO_TABLE(FXS) = {
 	.owner = THIS_MODULE,
 	.entries = {
 		/*	Prototable	Card	Opcode		*/
 		XENTRY(	FXS,		FXS,	SIG_CHANGED	),
-		XENTRY(	FXS,		FXS,	REGISTER_REPLY	),
 	},
 	.name = "FXS",
 	.type = XPD_TYPE_FXS,
@@ -1200,6 +1178,7 @@
 		.card_open	= FXS_card_open,
 		.card_close	= FXS_card_close,
 		.card_ioctl	= FXS_card_ioctl,
+		.card_register_reply	= FXS_card_register_reply,
 
 		.RING		= XPROTO_CALLER(FXS, RING),
 		.RELAY_OUT	= XPROTO_CALLER(FXS, RELAY_OUT),
@@ -1214,7 +1193,7 @@
 	const xproto_entry_t	*xe;
 
 	// DBG(GENERAL, "\n");
-	xe = xproto_card_entry(&PROTO_TABLE(FXS), pack->opcode);
+	xe = xproto_card_entry(&PROTO_TABLE(FXS), XPACKET_OP(pack));
 	return xe != NULL;
 }
 
@@ -1401,7 +1380,7 @@
 	xpd->requested_reply = regcmd;
 	if(print_dbg)
 		dump_reg_cmd("FXS", &regcmd, 1);
-	ret = CALL_PROTO(FXS, REGISTER_REQUEST, xpd->xbus, xpd,
+	ret = xpp_register_request(xpd->xbus, xpd,
 			REG_FIELD(&regcmd, chipsel),
 			writing,
 			REG_FIELD(&regcmd, do_subreg),

Modified: branches/1.4/xpp/card_fxs.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/xpp/card_fxs.h?view=diff&rev=3020&r1=3019&r2=3020
==============================================================================
--- branches/1.4/xpp/card_fxs.h (original)
+++ branches/1.4/xpp/card_fxs.h Fri Sep 14 19:07:19 2007
@@ -33,8 +33,6 @@
 	XPROTO_NAME(FXS, RING)			= 0x0F,	/* Write to SLIC */
 	XPROTO_NAME(FXS, LED)			= 0x0F,	/* Write to SLIC */
 	XPROTO_NAME(FXS, RELAY_OUT)		= 0x0F,	/* Write to SLIC */
-/**/
-	XPROTO_NAME(FXS, REGISTER_REPLY)	= 0x10,
 };
 
 
@@ -43,8 +41,5 @@
 	xpp_line_t	sig_status;	/* channels: lsb=1, msb=8 */
 	xpp_line_t	sig_toggles;	/* channels: lsb=1, msb=8 */
 	);
-DEF_RPACKET_DATA(FXS, REGISTER_REPLY,	/* Get status of a single SLIC (for debugging) */
-	reg_cmd_t	reg_cmd;
-	);
 
 #endif	/* CARD_FXS_H */

Modified: branches/1.4/xpp/card_global.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/xpp/card_global.c?view=diff&rev=3020&r1=3019&r2=3020
==============================================================================
--- branches/1.4/xpp/card_global.c (original)
+++ branches/1.4/xpp/card_global.c Fri Sep 14 19:07:19 2007
@@ -60,6 +60,36 @@
 	return ret;
 }
 
+int xpp_register_request(xbus_t *xbus, xpd_t *xpd,
+	byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high)
+{
+	int		ret = 0;
+	xframe_t	*xframe;
+	xpacket_t	*pack;
+	reg_cmd_t	*reg_cmd;
+
+	if(!xbus) {
+		DBG(REGS, "NO XBUS\n");
+		return -EINVAL;
+	}
+	XFRAME_NEW(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx);
+	LINE_DBG(REGS, xpd, chipsel, "%c%c R%02X S%02X %02X %02X\n",
+			(writing)?'W':'R',
+			(do_subreg)?'S':'D',
+			regnum, subreg, data_low, data_high);
+	reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
+	reg_cmd->bytes = sizeof(*reg_cmd) - 1;	// do not count the 'bytes' field
+	REG_FIELD(reg_cmd, chipsel) = chipsel;
+	REG_FIELD(reg_cmd, read_request) = (writing) ? 0 : 1;
+	REG_FIELD(reg_cmd, do_subreg) = do_subreg;
+	REG_FIELD(reg_cmd, regnum) = regnum;
+	REG_FIELD(reg_cmd, subreg) = subreg;
+	REG_FIELD(reg_cmd, data_low) = data_low;
+	REG_FIELD(reg_cmd, data_high) = data_high;
+	ret = send_cmd_frame(xbus, xframe);
+	return ret;
+}
+
 /*
  * The XPD parameter is totaly ignored by the driver and firmware as well.
  */
@@ -94,7 +124,7 @@
 
 HANDLER_DEF(GLOBAL, NULL_REPLY)
 {
-	XBUS_DBG(GENERAL, xbus, "got len=%d\n", pack->datalen);
+	XBUS_DBG(GENERAL, xbus, "got len=%d\n", XPACKET_LEN(pack));
 	return 0;
 }
 
@@ -114,7 +144,7 @@
 	card_desc->type = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, type);
 	card_desc->subtype = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, subtype);
 	card_desc->rev = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, rev);
-	card_desc->xpd_addr = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, addr);
+	card_desc->xpd_addr = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, head.addr);
 	card_desc->line_status = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, line_status);
 	XBUS_DBG(GENERAL, xbus, "XPD=%d%d type=%d.%d rev=%d line_status=0x%04X\n",
 			card_desc->xpd_addr.unit,
@@ -127,9 +157,22 @@
 	return 0;
 }
 
+HANDLER_DEF(GLOBAL, REGISTER_REPLY)
+{
+	reg_cmd_t		*reg = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REPLY, regcmd);
+
+	if(!xpd) {
+		XBUS_NOTICE(xbus, "%s: received %s for non-existing unit (%1d%1d)\n",
+				__FUNCTION__, cmd->name,
+				XPACKET_ADDR(pack).unit, XPACKET_ADDR(pack).subunit);
+		return -EPROTO;
+	}
+	return CALL_XMETHOD(card_register_reply, xbus, xpd, reg);
+}
+
 HANDLER_DEF(GLOBAL, PCM_READ)
 {
-	xpd_addr_t	addr = RPACKET_FIELD(pack, GLOBAL, PCM_READ, addr);
+	struct xpd_addr	addr = RPACKET_FIELD(pack, GLOBAL, PCM_READ, head.addr);
 	struct timeval	now;
 	unsigned long	sec_diff;
 	unsigned long	usec_diff;
@@ -196,7 +239,7 @@
 
 	BUG_ON(!xbus);
 	if(!xpd) {
-		notify_bad_xpd(__FUNCTION__, xbus, pack->addr, cmd->name);
+		notify_bad_xpd(__FUNCTION__, xbus, XPACKET_ADDR(pack), cmd->name);
 		return -EPROTO;
 	}
 	XPD_DBG(GENERAL, xpd, "mode=0x%X drift=%d\n", mode, drift);
@@ -219,7 +262,7 @@
 		return 0;
 	if(!xpd) {
 		snprintf(tmp_name, TMP_NAME_LEN, "%s(%1d%1d)", xbus->busname,
-			pack->addr.unit, pack->addr.subunit);
+			XPACKET_ADDR(pack).unit, XPACKET_ADDR(pack).subunit);
 	} else {
 		snprintf(tmp_name, TMP_NAME_LEN, "%s/%s", xbus->busname, xpd->xpdname);
 	}
@@ -252,6 +295,7 @@
 		XENTRY(	GLOBAL,		GLOBAL,	PCM_READ	),
 		XENTRY(	GLOBAL,		GLOBAL,	SYNC_REPLY	),
 		XENTRY(	GLOBAL,		GLOBAL, ERROR_CODE	),
+		XENTRY(	GLOBAL,		GLOBAL, REGISTER_REPLY	),
 	},
 	.name = "GLOBAL",
 	.packet_is_valid = global_packet_is_valid,
@@ -263,7 +307,7 @@
 	const xproto_entry_t	*xe;
 
 	//DBG(GENERAL, "\n");
-	xe = xproto_global_entry(pack->opcode);
+	xe = xproto_global_entry(XPACKET_OP(pack));
 	return xe != NULL;
 }
 
@@ -280,7 +324,7 @@
 	uint16_t	good_len;
 
 	BUG_ON(!pack);
-	BUG_ON(pack->opcode != XPROTO_NAME(GLOBAL, PCM_READ));
+	BUG_ON(XPACKET_OP(pack) != XPROTO_NAME(GLOBAL, PCM_READ));
 /*
  * Don't use for_each_line(xpd, i) here because for BRI it will ignore the channels of the other
  * xpd's in the same unit.
@@ -290,13 +334,13 @@
 			count++;
 	/* FRAMES: include opcode in calculation */
 	good_len = RPACKET_HEADERSIZE + sizeof(xpp_line_t) + count * 8;
-	if(pack->datalen != good_len) {
+	if(XPACKET_LEN(pack) != good_len) {
 		static int rate_limit = 0;
 
 		XPD_COUNTER(xpd, RECV_ERRORS)++;
 		if((rate_limit++ % 1000) <= 10) {
-			XPD_ERR(xpd, "BAD PCM REPLY: pack->datalen=%d (should be %d), count=%d\n",
-					pack->datalen, good_len, count);
+			XPD_ERR(xpd, "BAD PCM REPLY: packet_len=%d (should be %d), count=%d\n",
+					XPACKET_LEN(pack), good_len, count);
 			dump_packet("BAD PCM REPLY", pack, 1);
 		}
 		return 0;
@@ -382,3 +426,4 @@
 }
 
 EXPORT_SYMBOL(run_initialize_registers);
+EXPORT_SYMBOL(xpp_register_request);

Modified: branches/1.4/xpp/card_global.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/xpp/card_global.h?view=diff&rev=3020&r1=3019&r2=3020
==============================================================================
--- branches/1.4/xpp/card_global.h (original)
+++ branches/1.4/xpp/card_global.h Fri Sep 14 19:07:19 2007
@@ -23,6 +23,23 @@
  */
 
 #include "xdefs.h"
+
+enum global_opcodes {
+	XPROTO_NAME(GLOBAL, DESC_REQ)		= 0x04,
+	XPROTO_NAME(GLOBAL, DEV_DESC)		= 0x05,
+	XPROTO_NAME(GLOBAL, REGISTER_REQUEST)	= 0x0F,
+	XPROTO_NAME(GLOBAL, REGISTER_REPLY)	= 0x10,
+/**/
+	XPROTO_NAME(GLOBAL, PCM_WRITE)		= 0x11,
+	XPROTO_NAME(GLOBAL, PCM_READ)		= 0x12,
+/**/
+	XPROTO_NAME(GLOBAL, SYNC_SOURCE)	= 0x19,
+	XPROTO_NAME(GLOBAL, SYNC_REPLY)		= 0x1A,
+/**/
+	XPROTO_NAME(GLOBAL, ERROR_CODE)		= 0x22,
+	XPROTO_NAME(GLOBAL, RESET_SYNC_COUNTERS)	= 0x23,
+	XPROTO_NAME(GLOBAL, NULL_REPLY)		= 0xFE,
+};
 
 DEF_RPACKET_DATA(GLOBAL, NULL_REPLY);
 DEF_RPACKET_DATA(GLOBAL, DESC_REQ);
@@ -51,6 +68,9 @@
 	byte		sync_mode;
 	byte		drift;
 	);
+DEF_RPACKET_DATA(GLOBAL, REGISTER_REPLY,
+	reg_cmd_t	regcmd;
+	);
 DEF_RPACKET_DATA(GLOBAL, RESET_SYNC_COUNTERS,
 	byte		mask;
 	);
@@ -71,8 +91,9 @@
 /* 0x04 */ DECLARE_CMD(GLOBAL, DESC_REQ, int xpd_num);
 /* 0x19 */ DECLARE_CMD(GLOBAL, SYNC_SOURCE, enum sync_mode mode, int drift);
 /* 0x23 */ DECLARE_CMD(GLOBAL, RESET_SYNC_COUNTERS);
-/* 0x11 */ DECLARE_CMD(GLOBAL, PCM_WRITE, xpp_line_t lines, volatile byte *buf);
 
+int xpp_register_request(xbus_t *xbus, xpd_t *xpd,
+	byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high);
 extern xproto_table_t PROTO_TABLE(GLOBAL);
 int run_initialize_registers(xpd_t *xpd);
 

Modified: branches/1.4/xpp/card_pri.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/xpp/card_pri.c?view=diff&rev=3020&r1=3019&r2=3020
==============================================================================
--- branches/1.4/xpp/card_pri.c (original)
+++ branches/1.4/xpp/card_pri.c Fri Sep 14 19:07:19 2007
@@ -174,7 +174,7 @@
 	enum pri_led_state		ledstate[NUM_LEDS];
 };
 
-xproto_table_t	PROTO_TABLE(PRI);
+static xproto_table_t	PROTO_TABLE(PRI);
 
 DEF_RPACKET_DATA(PRI, SET_LED,	/* Set one of the LED's */
 	struct pri_leds		pri_leds;
@@ -182,7 +182,6 @@
 
 
 static /* 0x33 */ DECLARE_CMD(PRI, SET_LED, enum pri_led_selectors led_sel, enum pri_led_state to_led_state);
-static /* 0x0F */ DECLARE_CMD(PRI, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high);
 
 #define	DO_LED(xpd, which, tostate)	\
 		CALL_PROTO(PRI, SET_LED, (xpd)->xbus, (xpd), (which), (tostate))
@@ -196,7 +195,7 @@

[... 5720 lines stripped ...]



More information about the svn-commits mailing list