[zaptel-commits] tzafrir: trunk r1394 - in /trunk/xpp: ./ utils/

zaptel-commits at lists.digium.com zaptel-commits at lists.digium.com
Mon Sep 4 16:53:31 MST 2006


Author: tzafrir
Date: Mon Sep  4 18:53:30 2006
New Revision: 1394

URL: http://svn.digium.com/view/zaptel?rev=1394&view=rev
Log:
* Re-add calibrate_slics to the FXS initialization process
* xpp/utils: Build and install init_fxo_modes . Data is based on data from
  wctdm.c . TODO: a separate daa.h?
* Fail the script if automatic calibration has failed.

Added:
    trunk/xpp/calibrate_slics   (with props)
    trunk/xpp/utils/print_modes.c   (with props)
Modified:
    trunk/xpp/initialize_registers
    trunk/xpp/utils/   (props changed)
    trunk/xpp/utils/Makefile
    trunk/xpp/xbus-core.c

Added: trunk/xpp/calibrate_slics
URL: http://svn.digium.com/view/zaptel/trunk/xpp/calibrate_slics?rev=1394&view=auto
==============================================================================
--- trunk/xpp/calibrate_slics (added)
+++ trunk/xpp/calibrate_slics Mon Sep  4 18:53:30 2006
@@ -1,0 +1,314 @@
+#!/usr/bin/perl -w
+
+#
+# $Id:$
+#
+
+use strict;
+use Time::HiRes qw (time alarm sleep);
+
+my $SlicsFile = "$ENV{XPP_BASE}/$ENV{XPD_BUS}/$ENV{XPD_NAME}/slics";
+
+my @SlicNums = (0 .. 7);
+
+if ( ! -f $SlicsFile ) {
+	exit 1
+}
+
+sub logger($) {
+	print STDERR "LOG: @_\n";
+	system("logger @_");
+}
+
+sub write_to_slic_file($) {
+	my $write_str = shift;
+	#print STDERR "[Writing string]\n".$write_str."[End String]\n";
+
+	open(SLICS,">$SlicsFile") or 
+		die("Failed writing to slics file $SlicsFile");
+	print SLICS $write_str;
+	close(SLICS);
+	sleep(0.001);
+	
+}
+
+sub read_reg($$$) {
+	my $read_slic = shift;
+	my $read_reg = shift;
+	my $direct = shift;
+	
+	write_to_slic_file(
+		sprintf("%02x 00 00 00 R%s %02X", 
+			1<<$read_slic, $direct, $read_reg));
+	sleep(0.001);
+	open(SLICS,$SlicsFile) or 
+		die("Failed reading from slics file $SlicsFile");
+	my @reply = ();
+	while(<SLICS>){
+		#if (/^[^#]/) {
+		#	print STDERR "answer line: $_";
+		#}
+		if (/^SLIC_REPLY:\s+[DI]\s+reg_num=0x[[:xdigit:]]+,\s+dataH=0x([[:xdigit:]]+)\s+dataL=0x([[:xdigit:]]+)/){
+			@reply = (hex($1), hex($2)); 
+			#print STDERR "got [@reply]\n";
+			last;
+		}
+	}
+	close(SLICS);
+	if ($direct eq 'I') {
+		return @reply;
+	} else {
+		return $reply[1];
+	}
+}
+
+# TODO: rearange arguments
+sub write_reg{#($$$$$) {
+	my $read_slic = shift;
+	my $read_reg = shift;
+	my $direct = shift;
+	my $reg_val_low = shift;
+	my $reg_val_hi = shift;
+	
+	my $str  = sprintf "%02x 00 00 00 W%s %02X %02X", 
+		1<<$read_slic, $direct, $read_reg, $reg_val_low;
+	if ($direct eq 'I') {
+		$str .= sprintf " %02X", $reg_val_hi;
+	}
+	#printf STDERR "Writing: $str\n";
+	write_to_slic_file($str);
+}
+
+# TODO: rearange arguments
+sub write_reg_all_slics{#($$$$) {
+	my $read_reg = shift;
+	my $direct = shift;
+	my $reg_val_low = shift;
+	my $reg_val_hi = shift;
+	
+	my $str  = sprintf "FF FF 00 00 W%s %02X %02X", 
+		$direct, $read_reg, $reg_val_low;
+	if ($direct eq 'I') {
+		$str .= sprintf " %02X", $reg_val_hi;
+	}
+	printf STDERR "Writing: $str\n";
+	write_to_slic_file($str);
+}
+
+sub log_calib_params() {
+	for my $i (100 .. 107) {
+		my $line="Calib Reg $i:  ";
+		for my $slic (@SlicNums) {
+			$line .= " ".read_reg($slic, $i, 'D');
+		}
+		logger($line);
+	}
+}
+
+sub init_indirect_registers() {
+	return write_to_slic_file("#
+FF FF 00 00	WI	00	C2	55
+FF FF 00 00	WI	01	E6	51
+FF FF 00 00	WI	02	85	4B
+FF FF 00 00	WI	03	37	49
+                          
+FF FF 00 00	WI	04	33	33
+FF FF 00 00	WI	05	02	02
+FF FF 00 00	WI	06	02	02
+FF FF 00 00	WI	07	98	01
+                          
+FF FF 00 00	WI	08	98	01
+FF FF 00 00	WI	09	11	06
+FF FF 00 00	WI	0A	02	02
+FF FF 00 00	WI	0B	E5	00
+                          
+FF FF 00 00	WI	0C	1C	0A
+FF FF 00 00	WI	0D	30	7B
+FF FF 00 00	WI	0E	63	00
+FF FF 00 00	WI	0F	00	00
+                          
+FF FF 00 00	WI	10	70	78
+FF FF 00 00	WI	11	7D	00
+FF FF 00 00	WI	12	00	00
+FF FF 00 00	WI	13	00	00
+                          
+FF FF 00 00	WI	14	F0	7E
+FF FF 00 00	WI	15	60	01
+FF FF 00 00	WI	16	00	00
+FF FF 00 00	WI	17	00	20
+                          
+FF FF 00 00	WI	18	00	20
+FF FF 00 00	WI	19	00	00
+FF FF 00 00	WI	1A	00	20
+FF FF 00 00	WI	1B	00	40
+                          
+FF FF 00 00	WI	1C	00	10
+FF FF 00 00	WI	1D	00	36
+FF FF 00 00	WI	1E	00	10
+FF FF 00 00	WI	1F	00	02
+                          
+FF FF 00 00	WI	20	C0	07
+FF FF 00 00	WI	21	00	26
+FF FF 00 00	WI	22	F4	0F
+FF FF 00 00	WI	23	00	80
+
+#FF FF 00 00	WI	24	20	03
+#FF FF 00 00	WI	25	8C	08
+#FF FF 00 00	WI	26	00	01
+#FF FF 00 00	WI	27	10	00
+                          
+FF FF 00 00	WI	24	00	08
+FF FF 00 00	WI	25	00	08
+FF FF 00 00	WI	26	00	08
+FF FF 00 00	WI	27	00	08
+                          
+FF FF 00 00	WI	28	00	0C
+FF FF 00 00	WI	29	00	0C
+FF FF 00 00	WI	2B	00	01
+                          
+FF FF 00 00	WI	63	DA	00
+FF FF 00 00	WI	64	60	6B
+FF FF 00 00	WI	65	74	00
+FF FF 00 00	WI	66	C0	79
+                          
+FF FF 00 00	WI	67	20	11
+FF FF 00 00	WI	68	E0	3B	
+#");
+}
+
+sub init_early_direct_regs() {
+	return write_to_slic_file("#
+FF FF 00 00	WD	08 00
+FF FF 00 00	WD	4A 34
+FF FF 00 00	WD	4B 10
+FF FF 00 00	WD	40 00
+#")
+}
+
+my @FilterParams = ();
+
+sub save_indirect_filter_params() {
+	for my $slic (@SlicNums) {
+		for my $reg (35 .. 39) {
+			$FilterParams[$slic][$reg] = 
+				[read_reg($slic, $reg, 'I')];
+			write_reg($slic, $reg, 'I', 0, 0x80);
+		}
+	}
+	
+}
+
+sub restore_indirect_filter_params() {
+	for my $slic (@SlicNums) {
+		for my $reg (35 .. 39) {
+			write_reg($slic, $reg, 'I', 
+				@{$FilterParams[$slic][$reg]});
+		}
+	}
+}
+
+my $ManualCalibrationSleepTime = 0.04; # 40ms
+
+sub manual_calibrate_loop($$) {
+	my $write_reg = shift;
+	my $read_reg = shift;
+	
+	# counters to count down to (at most) 0
+	my @slic_counters = ();
+	for my $i (0 .. $#SlicNums) {
+		$slic_counters[$i] = 0x1F;
+	}
+	
+	# start calibration:
+	my $calibration_in_progress = 1;
+	write_reg_all_slics($write_reg, 'D', 0x1F);
+	sleep $ManualCalibrationSleepTime;
+	
+	# wait until all slics have finished calibration, or for timeout
+	while ($calibration_in_progress) {
+		$calibration_in_progress = 0; # until proven otherwise
+		print STDERR "ManualCalib:: ";
+		for my $slic(@SlicNums) {
+			my $value = read_reg($slic, $read_reg, 'D');
+			print STDERR " [$slic_counters[$slic]:$value]";
+			if ($value != 0 && $slic_counters[$slic] >= 0) {
+				$calibration_in_progress = 1;
+				$slic_counters[$slic]--;
+				write_reg($slic,$write_reg,'D',$slic_counters[$slic]);
+			}
+		}
+		print STDERR "\n";
+		# TODO: unnecessary sleep in the last round:
+		sleep $ManualCalibrationSleepTime;
+	}
+}
+
+sub manual_calibrate() {
+	manual_calibrate_loop(98, 88);
+	manual_calibrate_loop(99, 89);
+}
+
+sub auto_calibrate($$) {
+	my $calib_96 = shift;
+	my $calib_97 = shift;
+
+	#log_calib_params();
+	# start calibration:
+	write_to_slic_file(
+		sprintf
+			"FF FF 00 00	WD 61 %02X\n".
+			"FF FF 00 00	WD 60 %02X\n".
+			"", $calib_97, $calib_96
+			
+	);
+	# wait until all slics have finished calibration, or for timeout
+	my $end_time=time() + 2;
+	my $timeout=0;
+	CALIB_LOOP: for my $slic (@SlicNums) {
+		logger("checking slic $slic");
+		while(1) {
+			my $reply;
+			if (($reply=read_reg($slic, 96, 'D')) == 0) {
+				# move to next register
+				logger("slic $slic calibrated");
+				last;
+			}
+			print STDERR "reply: $reply\n";
+			my $time=time();
+			if ( $time > $end_time) {
+				$timeout=1;
+				logger("Exiting on timeout: $time is after timeout $end_time .");
+				exit 1;
+				#last CALIB_LOOP;
+			}
+			logger("auto_calibrate not done yet: slic #$slic\n");
+			sleep(0.1);
+		}
+	}
+	#log_calib_params();
+}
+
+###########################################################
+#
+# main
+#
+
+# TODO: for all slics check the following reads to check communication
+#read_reg($slic, 0x08, 'D'): 0x02
+#read_reg($slic, 0x0B, 'D'): 0x33
+#read_reg($slic, 0x40, 'D'): 0x00 (?)
+
+print STDERR "starting\n";
+
+init_indirect_registers();
+print STDERR "after init_indirect_registers\n";
+init_early_direct_regs();
+print STDERR "after init_early_direct_regs\n";
+auto_calibrate(0x47, 0x1E);
+print STDERR "after auto_calibrate\n";
+manual_calibrate();
+print STDERR "after manul_calibrate\n";
+auto_calibrate(0x40, 0x01);
+print STDERR "after auto_calibrate 2\n";
+
+

Propchange: trunk/xpp/calibrate_slics
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: trunk/xpp/calibrate_slics
------------------------------------------------------------------------------
    svn:executable = *

Propchange: trunk/xpp/calibrate_slics
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: trunk/xpp/calibrate_slics
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: trunk/xpp/initialize_registers
URL: http://svn.digium.com/view/zaptel/trunk/xpp/initialize_registers?rev=1394&r1=1393&r2=1394&view=diff
==============================================================================
--- trunk/xpp/initialize_registers (original)
+++ trunk/xpp/initialize_registers Mon Sep  4 18:53:30 2006
@@ -1,23 +1,59 @@
 #! /bin/sh
-# XPD_BUS	- bus name
-# XPD_NAME	- xpd name
-# XPD_TYPE	- xpd type number (from protocol reply):
+#
+# $Id$
+#
+# This script is run from the xpp kernel module upon detection
+# of a new XPD.
+#
+# Expects the following environment variables to be set:
+#	XPD_BUS	- bus name
+#	XPD_NAME	- xpd name
+#	XPD_TYPE	- xpd type number (from protocol reply):
 #			3 - FXS
 #			4 - FXO
-# XPD_REVISION	- xpd revision number
+#	XPD_REVISION	- xpd revision number
 
 set -e
 
 LOGGER="logger -i -t `basename $0`"
+opermode='FCC'
+INIT_DIR=`dirname $0`
+XPP_BASE=/proc/xpp
 
-INIT_DIR=`dirname $0`
-BASE=/proc/xpp
+if [ -r /etc/default/zaptel ]
+then . /etc/default/zaptel
+fi
 
-SLICS="$BASE/$XPD_BUS/$XPD_NAME/slics"
+export XPP_BASE
+
+SLICS="$XPP_BASE/$XPD_BUS/$XPD_NAME/slics"
 FILE="$INIT_DIR/init_data_${XPD_TYPE}_${XPD_REVISION}.cmd"
+set_daa_country_params() {
+	# based on fxo_modes from wctdm.c . TODO: more decent calculation?
+	reg16=00; reg26=00; reg30=00; reg31=A3; ring_osc=; ring_x=;
+	mode="$1"
+	# TODO: a saner fall-back in case of an unknown mode
+	if [ "$mode" = '' ]; then mode='FCC'; fi
+	if [ -r $INIT_DIR/init_fxo_modes ]; then
+	. $INIT_DIR/init_fxo_modes
+	fi
+	cat <<EOF >$SLICS
+FF FF 00 00	WD 10 $reg16
+FF FF 00 00	WD 1A $reg26
+FF FF 00 00	WD 1E $reg30
+FF FF 00 00	WD 1F $reg31
+EOF
+	# for the FXS:
+	#if [ "$ring_osc" != '' ]; then
+	#	/bin/echo "31 WI __ $ring_osc" >$SLICS
+	#fi
+	#if [ "$ring_x" != '' ]; then
+	#	/bin/echo "31 WI __ $ring_x" >$SLICS
+	#fi
+}
 
 if [ ! -f "$SLICS" ]; then
-	$LOGGER "missing slics file '$SLICS'"
+	$LOGGER "missing register file '$SLICS'"
 	exit 1
 fi
 
@@ -28,7 +64,9 @@
 
 case "$XPD_TYPE" in
 3|4)
+	if [ "$XPD_TYPE" = 3 ]; then "$INIT_DIR/calibrate_slics"; fi
 	cat "$FILE" > "$SLICS" 
+	if [ "$XPD_TYPE" = 4 ]; then set_daa_country_params "$opermode"; fi
 	;;
 *)
 	$LOGGER "Unknown type '$XPD_TYPE'"

Propchange: trunk/xpp/utils/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Sep  4 18:53:30 2006
@@ -1,0 +1,7 @@
+fpga_load
+test_parse
+libhexfile.*
+.*.swp
+print_modes
+init_fxo_modes
+wctdm_fxomodes.h

Modified: trunk/xpp/utils/Makefile
URL: http://svn.digium.com/view/zaptel/trunk/xpp/utils/Makefile?rev=1394&r1=1393&r2=1394&view=diff
==============================================================================
--- trunk/xpp/utils/Makefile (original)
+++ trunk/xpp/utils/Makefile Mon Sep  4 18:53:30 2006
@@ -10,11 +10,13 @@
 MANDIR    = /usr/share/man/man8
 HOTPLUG_USB_DIR = /etc/hotplug/usb
 
-DATA_FILES = $(wildcard ../init_data_*.cmd *.hex) 
+DATA_FILES = $(wildcard ../init_data_*.cmd *.hex) init_fxo_modes
+
+WCTDM=../../wctdm.c
 
 CFLAGS		= -g -Wall $(EXTRA_CFLAGS)
 
-TARGETS	= libhexfile.a fpga_load test_parse
+TARGETS	= libhexfile.a fpga_load test_parse init_fxo_modes
 
 all: $(TARGETS)
 
@@ -23,7 +25,7 @@
 	$(INSTALL) genzaptelconf fpga_load $(DESTDIR)$(BINDIR)/
 	$(INSTALL) -d $(DESTDIR)$(DATADIR)
 	$(INSTALL_DATA) $(DATA_FILES) $(DESTDIR)$(DATADIR)/
-	$(INSTALL) ../initialize_registers  $(DESTDIR)$(DATADIR)/
+	$(INSTALL) ../initialize_registers ../calibrate_slics $(DESTDIR)$(DATADIR)/
 	$(INSTALL) -d $(DESTDIR)$(MANDIR)
 	$(INSTALL_DATA) fpga_load.8 genzaptelconf.8 $(DESTDIR)$(MANDIR)/
 	$(INSTALL) -d $(DESTDIR)$(HOTPLUG_USB_DIR)
@@ -46,5 +48,13 @@
 test_parse: test_parse.o libhexfile.a
 	$(CC) -L. -o $@ $@.o $(EXTRA_LIBS) -lhexfile -lusb
 
+print_modes.o: wctdm_fxomodes.h
+
+wctdm_fxomodes.h: $(WCTDM)
+	perl -n -e 'print if (/^static struct fxo_mode {$$/ .. /};$$/)' $(WCTDM) >$@
+
+init_fxo_modes: print_modes
+	./$^ >$@
+
 clean:
 	$(RM) *.o $(TARGETS)

Added: trunk/xpp/utils/print_modes.c
URL: http://svn.digium.com/view/zaptel/trunk/xpp/utils/print_modes.c?rev=1394&view=auto
==============================================================================
--- trunk/xpp/utils/print_modes.c (added)
+++ trunk/xpp/utils/print_modes.c Mon Sep  4 18:53:30 2006
@@ -1,0 +1,44 @@
+#include <stdio.h>
+
+#include "wctdm_fxomodes.h"
+
+int main() {
+	size_t i;
+	
+	printf("case \"$mode\" in\n");
+	for (i=0; i<(sizeof(fxo_modes)/sizeof(struct fxo_mode)); i++) {
+		if (fxo_modes[i].name == NULL) break;
+		int reg16=0, reg26=0, reg30=0, reg31=0x3a;
+		char ring_osc[BUFSIZ]="", ring_x[BUFSIZ] = "";
+		
+		reg16 |= (fxo_modes[i].ohs << 6);
+		reg16 |= (fxo_modes[i].rz << 1);
+		reg16 |= (fxo_modes[i].rt);
+		
+		reg26 |= (fxo_modes[i].dcv << 6);
+		reg26 |= (fxo_modes[i].mini << 4);
+		reg26 |= (fxo_modes[i].ilim << 1);
+		
+		reg30 = (fxo_modes[i].acim);
+		
+		reg31 |= (fxo_modes[i].ohs2 << 3);
+
+		if (fxo_modes[i].ring_osc !=0 ) {
+			snprintf(ring_osc, BUFSIZ, "; ring_osc=\"%02X %02X\"",
+				(fxo_modes[i].ring_osc)>>8,
+				(fxo_modes[i].ring_osc)&&0xFF
+			);
+		}
+		if (fxo_modes[i].ring_x !=0 ) {
+			snprintf(ring_x, BUFSIZ, "; ring_x=\"%02X %02X\"",
+				(fxo_modes[i].ring_x)>>8,
+				(fxo_modes[i].ring_x)&&0xFF
+			);
+		}
+		
+		printf("%s)\treg16=%02X; reg26=%02X; reg30=%02X; reg31=%02X%s%s;;\n",
+		       fxo_modes[i].name, reg16, reg26, reg30, reg31, ring_osc, ring_x);
+	}
+	printf("esac\n");
+	return 0;
+}

Propchange: trunk/xpp/utils/print_modes.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: trunk/xpp/utils/print_modes.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: trunk/xpp/utils/print_modes.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: trunk/xpp/xbus-core.c
URL: http://svn.digium.com/view/zaptel/trunk/xpp/xbus-core.c?rev=1394&r1=1393&r2=1394&view=diff
==============================================================================
--- trunk/xpp/xbus-core.c (original)
+++ trunk/xpp/xbus-core.c Mon Sep  4 18:53:30 2006
@@ -29,6 +29,9 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/proc_fs.h>
+#ifdef	PROTOCOL_DEBUG
+#include <linux/ctype.h>
+#endif
 #include <linux/device.h>
 #include <linux/delay.h>	/* for mdelay() to debug */
 #include "xpd.h"
@@ -43,6 +46,11 @@
 #define	PROC_XBUSES		"xbuses"
 #define	PROC_XBUS_SUMMARY	"summary"
 #define	PROC_XBUS_WAITFOR_XPDS	"waitfor_xpds"
+
+#ifdef	PROTOCOL_DEBUG
+#define	PROC_XBUS_COMMAND	"command"
+static int proc_xbus_command_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
+#endif
 
 /* Command line parameters */
 extern int print_dbg;
@@ -504,6 +512,13 @@
 			remove_proc_entry(PROC_XBUS_WAITFOR_XPDS, xbus->proc_xbus_dir);
 			xbus->proc_xbus_waitfor_xpds = NULL;
 		}
+#ifdef	PROTOCOL_DEBUG
+		if(xbus->proc_xbus_command) {
+			DBG("Removing proc '%s' for %s\n", PROC_XBUS_COMMAND, xbus->busname);
+			remove_proc_entry(PROC_XBUS_COMMAND, xbus->proc_xbus_dir);
+			xbus->proc_xbus_command = NULL;
+		}
+#endif
 		DBG("Removing proc directory %s\n", xbus->busname);
 		remove_proc_entry(xbus->busname, xpp_proc_toplevel);
 		xbus->proc_xbus_dir = NULL;
@@ -594,6 +609,17 @@
 		goto nobus;
 	}
 	xbus->proc_xbus_waitfor_xpds->owner = THIS_MODULE;
+#ifdef	PROTOCOL_DEBUG
+	xbus->proc_xbus_command = create_proc_entry(PROC_XBUS_COMMAND, 0200, xbus->proc_xbus_dir);
+	if (!xbus->proc_xbus_command) {
+		ERR("Failed to create '%s' proc file for xbus %s\n", PROC_XBUS_COMMAND, xbus->busname);
+		err = -EIO;
+		goto nobus;
+	}
+	xbus->proc_xbus_command->write_proc = proc_xbus_command_write;
+	xbus->proc_xbus_command->data = xbus;
+	xbus->proc_xbus_command->owner = THIS_MODULE;
+#endif
 #endif
 	/* Sanity checks */
 	if(!ops->packet_send) {
@@ -733,6 +759,65 @@
 
 }
 
+#ifdef	PROTOCOL_DEBUG
+static int proc_xbus_command_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
+{
+	const int		NUM_SIZE = 100;
+	char			buf[NUM_SIZE];
+	xbus_t			*xbus = data;
+	xpacket_t		*pack;
+	char			*p;
+	byte			*pack_contents;
+	byte			*q;
+
+	if(count >= NUM_SIZE) {
+		ERR("%s: line too long\n", __FUNCTION__);
+		return -EFBIG;
+	}
+	if(copy_from_user(buf, buffer, count))
+		return -EINVAL;
+	buf[count] = '\0';
+	pack = xbus->ops->packet_new(xbus, GFP_KERNEL);
+	if(!pack)
+		return -ENOMEM;
+	q = pack_contents = (byte *)&pack->content;
+	for(p = buf; *p;) {
+		int	val;
+		char	hexdigit[3];
+
+		while(*p && isspace(*p))	// skip whitespace
+			p++;
+		if(!(*p))
+			break;
+		if(!isxdigit(*p)) {
+			ERR("%s: %s: bad hex value ASCII='0x%X' at position %d\n",
+					__FUNCTION__, xbus->busname, *p, p - buf);
+			goto err;
+		}
+		hexdigit[0] = *p++;
+		hexdigit[1] = '\0';
+		hexdigit[2] = '\0';
+		if(isxdigit(*p))
+			hexdigit[1] = *p++;
+		if(sscanf(hexdigit, "%2X", &val) != 1) {
+			ERR("%s: %s: bad hex value '%s' at position %d\n",
+					__FUNCTION__, xbus->busname, hexdigit, p - buf);
+			goto err;
+		}
+		*q++ = val;
+		// DBG("%s: %s: '%s' val=%d\n", __FUNCTION__, xbus->busname, hexdigit, val);
+	}
+	pack->datalen = q - pack_contents -
+			sizeof(pack->content.opcode) - sizeof(pack->content.addr);
+	packet_send(xbus, pack);
+	return count;
+err:
+	xbus->ops->packet_free(xbus, pack);
+	return -EINVAL;
+}
+#endif
+
+
 static int read_proc_xbuses(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
 	int len = 0;
@@ -840,6 +925,9 @@
 {
 	int	ret;
 
+#ifdef PROTOCOL_DEBUG
+	INFO("FEATURE: %s with PROTOCOL_DEBUG\n", THIS_MODULE->name);
+#endif
 	packet_cache = kmem_cache_create("xpp_packets",
 			sizeof(xpacket_t),
 			0, 0,



More information about the zaptel-commits mailing list