diff -Nru dahdi-linux-2.2.1-rc2/build_tools/builder dahdi-cnet-linux-2.2.1-rc2/build_tools/builder --- dahdi-linux-2.2.1-rc2/build_tools/builder 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/build_tools/builder 2008-06-28 17:02:27.000000000 -0500 @@ -0,0 +1,168 @@ +#!/bin/sh + +# build_test - a build testing script +# +# Copyright (C) 2008 by Xorcom +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Setup: +# +# 0. Copy this script under build_tools/ and +# +# chmod +x build_tools/builder +# +# 1. Make sure you have git and sqlite3 installed. If the sqlite3 binary +# is called differently, fix the line "SQLITE=" in the script or in +# build_tools/test_build.conf . +# +# 2. Run: +# +# ./build_tools/test_kernel_git init /path/to/some/dir +# +# /path/to/some/dir must exist . This will download a recent kernel +# git repository to /path/to/some/dir/linux-2.6 . Use +# './build_tools/test_kernel_git update' to pull a fresh update there. +# +# 3. Run: +# +# ./build_tools/builder init +# +# +# Usage: +# +# ./build_tools build +# +# The past results are in a sqlite database in the logs subdirectory. For +# a simple list of results: +# +# ./build_tools report +# +# You can also look at the build log for a specific build in the logs +# directory. + +BIN_DIR=`dirname $0` +BASE_DIR=`dirname $BIN_DIR` +SQLITE=sqlite3 +HOSTS="localhost" +LOGS_DIR="$BASE_DIR/logs" +DB=$LOGS_DIR/builds.db +BUILD_SCRIPT=$BIN_DIR/test_kernel_git +KERNELS_localhost="2.6.12 2.6.18 2.6.25" + +usage() { + me=`basename $0` + echo "$me: test building Zaptel/DAHDI with various kernels" + echo "" + echo "Usage: $0 command " + echo " init Create results directory and database." + echo " build [] Run the test builds. The default list: " + echo " $KERNELS_localhost" + echo " report [] Print all results [matching ]" + echo " Default is to print all the resaults." + echo "" + echo "Filters:" + echo " failed: Only failed tests." + echo " fail_type Where fail_type matches ." + echo " 2.6* Only builds for a matching kernel version." + echo " Else: Match a string from the build name, which " + echo " is essentially the time it started." + echo "" +} + +set -e + +if [ -r $BIN_DIR/test_build.conf ]; then . $BIN_DIR/test_build.conf; fi + +# Runs the test script, logs the result, and fails if the test command +# has failed. +build_and_check() { + test_name="$1" + test_cmd="$2" + log_file="$3" + results_str="$4" + fail_type='' + + set +e + $BUILD_SCRIPT $test_cmd >$log_file 2>&1 + rc=$? + set -e + if [ $rc != 0 ]; then + fail_type="$test_name" + echo "$results_str, $rc, '$fail_type', '$log_file');" | $SQLITE $DB + fi + return $rc +} + +build_zaptel() { + build_name="$1" + host="$2" + kvers="$3" + log_base="build__${build_name}__${host}__${kvers}" + log_base_full="$LOGS_DIR/$log_base" + log_file="$log_base_full.log" + results_str="INSERT INTO results VALUES ('$build_name', '$host', '$kvers'" + # Due to 'set -e' a failed test exists the script. + build_and_check setver "setver $kvers" "$log_file" "$results_str" + build_and_check clean "test clean" "$log_file" "$results_str" + build_and_check build "build" "$log_file" "$results_str" + + # If we got here, all was well. + echo "$results_str, 0, 'complete', '$log_file');" | $SQLITE $DB +} + +case "$1" in +init) + mkdir -p $LOGS_DIR + cat <&2 "$0: Unknown command '$1'. Aborting." + exit 1 +esac diff -Nru dahdi-linux-2.2.1-rc2/build_tools/genmodconf dahdi-cnet-linux-2.2.1-rc2/build_tools/genmodconf --- dahdi-linux-2.2.1-rc2/build_tools/genmodconf 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/build_tools/genmodconf 2008-07-01 15:55:52.000000000 -0500 @@ -0,0 +1,80 @@ +#!/bin/sh + +# this script makes an attempt to build a proper set of rules +# for loading the DAHDI modules and automatically running dahdi_xcfg +# +# it accepts two parameters: +# the root prefix to be used for finding/creating the files +# the list of module names being installed +# +# the process is as follows: +# +# the file can be located at /etc/modprobe.conf (combined with all +# other rules), /etc/modprobe.d/dahdi (DAHDI only) or /etc/modules.d/dahdi +# (DAHDI only) +# +# when the file is DAHDI rules only, then we don't preserve the existing +# contents of the file; the system administrator can put desired options and +# overrides in a separate file with a name that appears earlier in the sort +# order, so there is no need to edit the file produced by this script +# +# when the file is combined with all other rules, then we make a backup +# of it and remove all the old DAHDI rules we can find, replacing them with +# new ones +# +# in addition, versions of module-init-tools 3.2.0 and later +# have the ability to pass module parameters specified on the modprobe command +# line to commands in 'install' rules, thus keeping them from being lost, so +# we try to determine what version is installed and take advantage of that + +toolver=`/sbin/modprobe --version 2>/dev/null| awk '{print $3}' | cut -d. -f2 | cut -d- -f1` +if [ ${toolver} -ge 2 ]; then + cmdopts=\$CMDLINE_OPTS +fi +if [ -d ${1}/etc/modprobe.d ]; then + target=${1}/etc/modprobe.d/dahdi +elif [ -d ${1}/etc/modules.d ]; then + target=${1}/etc/modules.d/dahdi +elif [ -f ${1}/etc/modprobe.conf ]; then + target=${1}/etc/modprobe.conf + combined=1 +elif [ -f ${1}/etc/conf.modules ]; then + target=${1}/etc/conf.modules + combined=1 +else + echo No suitable location for module rules can be found... exiting. + exit 1 +fi + +if [ -n "${combined}" ]; then + if [ -f ${target} ]; then + mv ${target} ${target}.bak + cat ${target}.bak | grep -v "alias char-major-250" | grep -v "alias char-major-196" > ${target} + fi +else + if [ -f ${target} ]; then + mv ${target} ${target}.bak + fi + echo "# automatically generated file; do not edit" > ${target} +fi + +echo Building ${target}... + +for mod in ${2}; do + if ! grep -q "install ${mod} " ${target}; then + echo "install ${mod} /sbin/modprobe --ignore-install ${mod} ${cmdopts} && /sbin/ztcfg" >> ${target} + fi +done + +if [ -z "${combined}" ]; then + echo "***" + echo "*** WARNING:" + echo "*** If you had custom settings in ${target}," + echo "*** they have been moved to ${target}.bak." + echo "***" + echo "*** In the future, do not edit ${target}, but" + echo "*** instead put your changes in another file" + echo "*** in the same directory so that they will not" + echo "*** be overwritten by future DAHDI updates." + echo "***" +fi diff -Nru dahdi-linux-2.2.1-rc2/build_tools/genudevrules dahdi-cnet-linux-2.2.1-rc2/build_tools/genudevrules --- dahdi-linux-2.2.1-rc2/build_tools/genudevrules 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/build_tools/genudevrules 2008-10-22 13:49:41.000000000 -0500 @@ -0,0 +1,40 @@ +#!/bin/sh + +ver=`udevinfo -V | cut -f3 -d" "` + +if [ -z "${ver}" ]; then + # Not found - try udevadm + ver=`udevadm info -V | cut -f3 -d" "` + + if [ -z "${ver}" ]; then + # nobody has that old version, anyway. + ver=54 + fi +fi + +# udev versions prior to 055 use a single '=' for matching key values +# udev versions 055 and later support '==' for that purpose, and versions +# beyond 092 will probably make it mandatory +# +# very old versions of udev required naming rules and permissions rules to be +# in separate files, but it's not clear at what version number that changed + +if [ ${ver} -gt 54 ]; then + match="==" +else + match="=" +fi + +cat <drivers; + print join(" ", @drivers); + ' +} + +# Add modules for existing hardware on the system for the list of +# modules to load. +# +# As module loading is manual with insmod, some manual fixes are needed. +set_modules_to_load() { + for mod in `dahdi_drivers`; do + case "$mod" in + xpp_usb) + MODULES_LOAD="$MODULES_LOAD xpp/xpp xpp/xpd_fxs" + MODULES_LOAD="$MODULES_LOAD xpp/xpd_fxo xpp/xpd_pri" + if [ -r "$MODULES_DIR/xpp/xpd_bri.ko" ]; then + MODULES_LOAD="$MODULES_LOAD xpp/xpd_bri" + fi + MODULES_LOAD="$MODULES_LOAD xpp/xpp_usb" + ;; + wctdm24xxp | wct4xxp | wcte12xp | wctc4xp) + MODULES_LOAD="$MODULES_LOAD $mod/$mod" + ;; + wanpipe) + : # requires different handling + ;; + *) + MODULES_LOAD="$MODULES_LOAD $mod" + ;; + esac + done +} + +# Initialize the Xorcom Astribank (xpp/) using perl utiliites: +# intended to replace all the the three functions below if user has +# installed the dahdi-perl utilities. +xpp_startup() { + # do nothing if there are no astribank devices: + if ! grep -q connected /proc/xpp/xbuses 2>/dev/null; then return 0; fi + + echo "Waiting for Astribank devices to initialize:" + $TOOLS_DIR/xpp/waitfor_xpds # Asusmes a recent dahdi-tools + + # overriding locales for the above two, as perl can be noisy + # when locales are missing. + # No register all the devices if they didn't auto-register: + LC_ALL=C dahdi_registration on + + # this one could actually be run after dahdi_cfg: + LC_ALL=C xpp_sync "$XPP_SYNC" +} + +# recursively unload a module and its dependencies, if possible. +# where's modprobe -r when you need it? +# inputs: module to unload. +# returns: the result from +unload_module() { + module="$1" + line=`lsmod 2>/dev/null | grep "^$1 " || :` + if [ "$line" = '' ]; then return; fi # module was not loaded + + set -- $line + # $1: the original module, $2: size, $3: refcount, $4: deps list + mods=`echo $4 | tr , ' '` + # xpp_usb keeps the xpds below busy if an xpp hardware is + # connected. Hence must be removed before them: + case "$module" in xpd_*) mods="xpp_usb $mods";; esac + for mod in $mods; do + # run in a subshell, so it won't step over our vars: + (unload_module $mod) + # TODO: the following is probably the error handling we want: + # if [ $? != 0 ]; then return 1; fi + done + rmmod $module +} + +usage() { + me=`basename $0` + echo "$me: Run DAHDI in a test environment" + echo 'Version: $Id: live_dahdi 6487 2009-04-25 16:35:33Z tzafrir $' + echo '' + echo "Usage: equivalent of:" + echo "$me configure ./configure" + echo "$me install make install" + echo "$me config make config" + echo "$me unload /etc/init.d/dahdi stop" + echo "$me load /etc/init.d/dahdi start" + echo "$me reload /etc/init.d/dahdi restart" + echo "$me xpp-firm (Reset and load xpp firmware)" + echo "$me rsync TARGET (copy filea to /tmp/live in host TARGET)" + echo "$me exec COMMAND (Run COMMAND in 'live' environment)" + echo "" + echo "dahdi-linux: $LINUX_DIR" + echo "dahdi-tools: $TOOLS_DIR" +} + +case "$1" in +configure) + shift + cd "$TOOLS_DIR"; ./configure --with-dahdi="$LINUX_DIR_FULL" "$@" + ;; +install) + shift + cd "$LINUX_DIR"; make install DESTDIR=$DESTDIR "$@" + cd "$TOOLS_DIR"; make install DESTDIR=$DESTDIR DYNFS=yes "$@" + ;; +config) + shift + cd "$TOOLS_DIR"; make config DESTDIR=$DESTDIR "$@" + mkdir -p $DESTDIR/etc/asterisk + ;; +rsync) + if [ $# -ne 2 ]; then + echo >&2 "$0: Error: rsync requires a target parameter". + exit 1 + fi + # copy the script itself and the installed directory to the + # target host: + rsync -ai "$0" $DESTDIR "$2:/tmp/" + ;; +unload) + # OK for Asterisk not to be running. TODO: a better test? + $AST_SCRIPT stop || : + for mod in $REMOVE_MODULES; do + unload_module $mod + done + ;; +load) + # TODO: Find a way to use modprobe. + # Or implement a way to pass arguments to modules here (yuck) + set_modules_to_load + for module in $MODULES_LOAD; do + eval module_args="\$`basename ${module}`_ARGS" + insmod $MODULES_DIR/$module.ko $module_args + done + xpp_startup + GENCONF_PARAMETERS=$DESTDIR/etc/dahdi/genconf_parameters \ + DAHDI_CONF_FILE=$DESTDIR/etc/dahdi/system.conf \ + DAHDI_MODS_FILE=$DESTDIR/etc/dahdi/modules \ + CHAN_DAHDI_CHANNELS_FILE=$DESTDIR/etc/asterisk/dahdi-channels.conf \ + dahdi_genconf + dahdi_cfg -c $DESTDIR/etc/dahdi/system.conf + # TODO: fxotune, hpec + # or find a way to reuse init.d start sequence. + + # TODO: A local copy of Asterisk, configured with dahdi_gnconf. + # doable, but trickier. + $AST_SCRIPT start + ;; +reload) + $0 unload + $0 load + ;; +exec) + if [ $# -lt 2 ]; then + # No command given: start a subshell in the environemnt + # of the "live" system: + echo >&2 "$0: Error: exec requires a command to run" + exit 1 + fi + + # Command given: run it: + shift + "$@" + ;; +xpp-firm) + # Still broken. Needs to be run several times. + # set XPP_HOTPLUG_DISABLED=yes in /etc/dahdi/init.conf + XPP_FIRMWARE_DIR=$FIRMWARE_DIR \ + sh "$TOOLS_DIR"/xpp/xpp_fxloader reset + sleep 5 + XPP_FIRMWARE_DIR=$FIRMWARE_DIR \ + sh "$TOOLS_DIR"/xpp/xpp_fxloader load + ;; +help) + usage + ;; +*) + echo >&2 "$0: Error: incorrect command \"$1\". Aborting" + usage + exit 1 +esac diff -Nru dahdi-linux-2.2.1-rc2/build_tools/make_version dahdi-cnet-linux-2.2.1-rc2/build_tools/make_version --- dahdi-linux-2.2.1-rc2/build_tools/make_version 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/build_tools/make_version 2008-05-23 10:32:46.000000000 -0500 @@ -0,0 +1,56 @@ +#!/bin/sh + +if [ -f ${1}/.version ]; then + cat ${1}.version +elif [ -f ${1}/.svnrevision ]; then + echo SVN-`cat ${1}/.svnbranch`-r`cat ${1}/.svnrevision` +elif [ -d .svn ]; then + PARTS=`LANG=C svn info ${1} | grep URL | awk '{print $2;}' | sed -e s:^.*/svn/${2}/:: | sed -e 's:/: :g'` + BRANCH=0 + TEAM=0 + + REV=`svnversion -c ${1} | cut -d: -f2` + + if [ "${PARTS}" = "trunk" ] + then + echo SVN-'trunk'-r${REV} + exit 0 + fi + + for PART in $PARTS + do + if [ ${BRANCH} != 0 ] + then + RESULT="${RESULT}-${PART}" + break + fi + + if [ ${TEAM} != 0 ] + then + RESULT="${RESULT}-${PART}" + continue + fi + + if [ "${PART}" = "branches" ] + then + BRANCH=1 + RESULT="branch" + continue + fi + + if [ "${PART}" = "tags" ] + then + BRANCH=1 + RESULT="tag" + continue + fi + + if [ "${PART}" = "team" ] + then + TEAM=1 + continue + fi + done + + echo SVN-${RESULT##-}-r${REV} +fi diff -Nru dahdi-linux-2.2.1-rc2/build_tools/make_version_h dahdi-cnet-linux-2.2.1-rc2/build_tools/make_version_h --- dahdi-linux-2.2.1-rc2/build_tools/make_version_h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/build_tools/make_version_h 2008-05-21 11:59:46.000000000 -0500 @@ -0,0 +1,9 @@ +#!/bin/sh +cat << END +/* + * version.h + * Automatically generated + */ +#define DAHDI_VERSION "${DAHDIVERSION}" + +END diff -Nru dahdi-linux-2.2.1-rc2/build_tools/test_kernel_git dahdi-cnet-linux-2.2.1-rc2/build_tools/test_kernel_git --- dahdi-linux-2.2.1-rc2/build_tools/test_kernel_git 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/build_tools/test_kernel_git 2008-06-28 17:02:27.000000000 -0500 @@ -0,0 +1,101 @@ +#!/bin/sh + +set -e + +GIT_URL=git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git +CONF_FILE=build_tools/git_test.conf + +usage() { + me=`basename $0` + echo "$me: test building DAHDI vs. kernel from git" + echo "Usage:" + echo " $me checkout Pull a kernel version into " + echo " $me update Update (pull) the kernel tree." + echo " $me setver Set the kernel version" + echo " $me versions Print available versions" + echo " $me version Print current (kernel) version" + echo " $me version_driver Print the version of DAHDI" + echo " $me build Test-build" + echo " $me git Run " + echo "" + echo " $me versions [pattern] List available versions." +} + +# Set a variable in $CONF_FILE +# The format of CONF_FILE is assumed to be: +# VAR=value +# in shell syntax. "value" may be quoted. +# "value should not contain a '|' character. +set_var() { + var="$1" + val="$2" + if grep -q "^$var=" $CONF_FILE 2>/dev/null; then + sed -i -e "s|^$var=.*|$var=\"$val\"|" $CONF_FILE + else + echo "$var=\"$val\"" >>$CONF_FILE + fi +} + +if [ -r "$CONF_FILE" ]; then . "$CONF_FILE"; fi + +if echo "$CONF_FILE" | grep -qv '^/'; then + # make CONF_FILE an absolute path: + CONF_FILE="$PWD/$CONF_FILE" +fi + +command="$1" + +case "$command" in + checkout) + kernel_dir="$2" + cd "$kernel_dir" + git clone $GIT_URL + set_var kernel_dir "$kernel_dir/linux-2.6" + ;; + update) + cd "$kernel_dir" + git pull + ;; + git) + cd "$kernel_dir" + shift + git "$@" + ;; + versions) + cd "$kernel_dir" + git tag -l $2 | cut -c2- + ;; + version) + cd "$kernel_dir" + echo "Configured: $kernel_ver" + echo -n "Actual: " + git describe | cut -c2- + ;; + version_driver) + version_h=include/dahdi/version.h + make $version_h >/dev/null + awk -F'"' '/DAHDI_VERSION/{print $2}' $version_h + ;; + setver) + kernel_ver="$2" + tag="v$kernel_ver" + cd "$kernel_dir" + git-reset --hard "$tag" + make distclean + make defconfig modules_prepare + set_var kernel_ver "$kernel_ver" + ;; + test|build) + # you can pass extra parameters to the make command in + # two ways: + # 1. Set the value of MAKE_PARAMS in git_test.conf . + # 2. Any extra command-line parameter. + shift + make KSRC="$kernel_dir" KVERS=$kernel_ver $MAKE_PARAMS "$@" + ;; + *) + echo "$0: no such command $command. Aborting." + usage + exit 1 + ;; +esac diff -Nru dahdi-linux-2.2.1-rc2/build_tools/uninstall-modules dahdi-cnet-linux-2.2.1-rc2/build_tools/uninstall-modules --- dahdi-linux-2.2.1-rc2/build_tools/uninstall-modules 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/build_tools/uninstall-modules 2008-07-08 15:18:38.000000000 -0500 @@ -0,0 +1,64 @@ +#!/bin/sh + +# This script takes two arguments: a top-level module name, and a kernel version string +# +# It will search the entire /lib/modules directory tree for the given kernel version, +# and find all modules that are dependent (even indirectly) on the specified module. +# After producing that list, it will remove all those modules. + +base="${1}" +deptree="${base}" +rmlist="" +founddep=1 + +checkmod() { + SAVEIFS="${IFS}" + IFS="," + modname=`basename ${1}` + modname=${modname%.ko} + if test "${modname}" = "${base}"; then + rmlist="${rmlist} ${1}" + IFS="${SAVEIFS}" + return + fi + for dep in `modinfo -F depends ${1}`; do + for mod in ${deptree}; do + if test "${dep}" = "${mod}"; then + addit=1 + for checkmod in ${deptree}; do + if test "${checkmod}" = "${modname}"; then + addit=0 + break + fi + done + if test "${addit}" = "1"; then + deptree="${deptree},${modname%.ko}" + rmlist="${rmlist} ${1}" + founddep=1 + fi + fi + done + done + IFS="${SAVEIFS}" +} + + +while test "${founddep}" = "1"; do + founddep=0 + find /lib/modules/${2}/misc -name \*.ko -print > /tmp/modlist.$$ 2> /dev/null + find /lib/modules/${2}/extra -name \*.ko -print >> /tmp/modlist.$$ 2> /dev/null + find /lib/modules/${2}/zaptel -name \*.ko -print >> /tmp/modlist.$$ 2> /dev/null + find /lib/modules/${2}/dahdi -name \*.ko -print >> /tmp/modlist.$$ 2> /dev/null + exec 9<&0 < /tmp/modlist.$$ + while read mod; do + checkmod ${mod} + done + exec 0<&9 9<&- + rm /tmp/modlist.$$ +done + +if test -n "${rmlist}"; then + for mod in ${rmlist}; do + rm -f ${mod} + done +fi diff -Nru dahdi-linux-2.2.1-rc2/ChangeLog dahdi-cnet-linux-2.2.1-rc2/ChangeLog --- dahdi-linux-2.2.1-rc2/ChangeLog 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/ChangeLog 2009-12-15 15:48:28.000000000 -0600 @@ -0,0 +1,2259 @@ +2009-12-11 23:22 +0000 [r7683-7684] Shaun Ruffell + + * dahdi-linux version 2.2.1-rc2 released. + + * /, drivers/dahdi/dahdi-base.c: Merged revisions 7682 via svnmerge + from https://origsvn.digium.com/svn/dahdi/linux/trunk ........ + r7682 | sruffell | 2009-12-11 17:20:03 -0600 (Fri, 11 Dec 2009) | + 5 lines dahdi-base: Do not wait for impulse when echotraining. + Waiting here for the impulse on the transmit can cause the + echotraining logic to stick the channel into muted state. This is + especially apparent on systems that regularly do not service the + interrupts every millisecond. DAHDI-387. ........ + + * /, drivers/dahdi/dahdi-base.c: Merged revisions 7681 via svnmerge + from https://origsvn.digium.com/svn/dahdi/linux/trunk ........ + r7681 | sruffell | 2009-12-11 17:20:02 -0600 (Fri, 11 Dec 2009) | + 6 lines dahdi-base: Reduce the max allocation size in + dahdi_reallocbufs. Lower the maximum contiguous chunk that DAHDI + asks for from DAHDI_MAX_BUFFER_SIZE*2 to DAHDI_MAX_BUFFER_SIZE. + With 4K pages, this can allow the kernel to try a little harder + to find the memory it needs since the request goes from order 4 + to order 3. ........ + +2009-11-23 19:20 +0000 [r7636] Shaun Ruffell + + * dahdi-linux version 2.2.1-rc1 released. + + * drivers/dahdi/wcte12xp/base.c, /: Merged revisions 7632 via + svnmerge from https://origsvn.digium.com/svn/dahdi/linux/trunk + ........ r7632 | mspiceland | 2009-11-23 13:13:17 -0600 (Mon, 23 + Nov 2009) | 4 lines Even if we are debouncing the LOS + declaration, we still expect the LED to turn red as soon as we + unplug the physical cable. This impliments this on the wcte12xp + just as it already does on the wct4xxp. ........ + +2009-11-22 11:43 +0000 [r7616-7620] Tzafrir Cohen + + * /, drivers/dahdi/xpp/firmwares/USB_FW.hex: xpp firmware: USB + firmware with support of MPP 1.4 xpp rev: 7419 Merged revisions + 7615 via svnmerge from + http://svn.digium.com/svn/dahdi/linux/trunk + + * drivers/dahdi/xpp/firmwares/PIC_TYPE_1.hex, /: xpp firmware: fix + FXS indirect register reading. xpp rev: 7498 Merged revisions + 7614 via svnmerge from + http://svn.digium.com/svn/dahdi/linux/trunk + +2009-11-19 22:52 +0000 [r7610] Tzafrir Cohen + + * drivers/dahdi/xpp/xpp.rules, /: xpp: rules for loading USB + firmware into 1163 devices as well Merged revisions 7595 via + svnmerge from http://svn.digium.com/svn/dahdi/linux/trunk + +2009-11-19 19:15 +0000 [r7604] Shaun Ruffell + + * /, drivers/dahdi/wctdm24xxp/base.c: Merged revisions 7601 via + svnmerge from https://origsvn.digium.com/svn/dahdi/linux/trunk + ........ r7601 | sruffell | 2009-11-19 10:11:20 -0600 (Thu, 19 + Nov 2009) | 1 line wctdm24xxp: Honor the alawoverride parameter + when using the VPMADT032. ........ + +2009-11-12 23:45 +0000 [r7572-7584] Shaun Ruffell + + * drivers/dahdi/wcte12xp/base.c, /, + drivers/dahdi/voicebus/GpakCust.c: Merged revisions 7582 via + svnmerge from https://origsvn.digium.com/svn/dahdi/linux/trunk + ........ r7582 | sruffell | 2009-11-12 17:19:13 -0600 (Thu, 12 + Nov 2009) | 1 line wcte12xp, voicebus: Set the companding mode + correctly on E1. ........ + + * drivers/dahdi/voicebus/GpakCust.h, drivers/dahdi/wcte12xp/base.c, + /, include/dahdi/kernel.h, drivers/dahdi/adt_lec.c, + drivers/dahdi/wctdm24xxp/base.c, drivers/dahdi/adt_lec.h, + drivers/dahdi/voicebus/GpakCust.c: Merged revisions + 7309,7348,7565-7571 via svnmerge from + https://origsvn.digium.com/svn/dahdi/linux/trunk ........ r7309 | + mattf | 2009-10-02 11:31:58 -0500 (Fri, 02 Oct 2009) | 1 line + Implement API update to do per-channel companding selection for + VPMADT032 ........ r7348 | mattf | 2009-10-07 16:26:08 -0500 + (Wed, 07 Oct 2009) | 1 line Fix a logic error in the companding + check. Duh.... ........ r7565 | sruffell | 2009-11-12 13:22:06 + -0600 (Thu, 12 Nov 2009) | 7 lines voicebus: Fix race when + enabling/disabling hardware echocan. This closes a race condition + where it was possible for the driver to believe it has enabled + the VPMADT032 when in fact, it really has not. This fixes a + regression introduced in dahdi-linux 2.2.0. (issue #15724) + ........ r7566 | sruffell | 2009-11-12 13:22:06 -0600 (Thu, 12 + Nov 2009) | 1 line wctdm24xxp, wcte12xp: We no longer have any + DTMF events to check for. ........ r7567 | sruffell | 2009-11-12 + 13:22:07 -0600 (Thu, 12 Nov 2009) | 1 line voicebus: Remove + unused curtone from 'struct vpmadt032' ........ r7568 | sruffell + | 2009-11-12 13:22:07 -0600 (Thu, 12 Nov 2009) | 1 line voicebus: + Remove redundant MAX_CHANNELS_FROM_SPAN ........ r7569 | sruffell + | 2009-11-12 13:22:08 -0600 (Thu, 12 Nov 2009) | 3 lines + voicebus: Use dev_xxx macro when printing vpm messages. We also + do not need the unused context member of the vpmadt032 structure. + ........ r7570 | sruffell | 2009-11-12 13:22:08 -0600 (Thu, 12 + Nov 2009) | 4 lines wcte12xp: Change serial port configuration + setting for hw echocan. The wcte12xp, like the wctdm24xpp, should + have the PcmOutPortA set to SerialPortNull. ........ r7571 | + sruffell | 2009-11-12 13:56:49 -0600 (Thu, 12 Nov 2009) | 1 line + kernel.h: Define 'list_replace' for kernels < 2.6.18 ........ + +2009-11-10 15:47 +0000 [r7539-7550] Shaun Ruffell + + * drivers/dahdi/wcte12xp/base.c, /: Merged revisions 7549 via + svnmerge from https://origsvn.digium.com/svn/dahdi/linux/trunk + ........ r7549 | sruffell | 2009-11-10 09:46:18 -0600 (Tue, 10 + Nov 2009) | 9 lines wcte12xp: Export features and operations for + VPMADT032. Fixes a regression in dahdi-linux 2.2.0 where it was + impossible for userspace to reset the state of a channel in the + VPM. (issue #15724) Patches: mantis-15724-2.patch uploaded by + sruffell (license 456) Tested by: alecdavis ........ + + * drivers/dahdi/wcte12xp/base.c, drivers/dahdi/wct4xxp/base.c: + wct4xxp, wcte12xp: Don't export new module parms by default on + the 2.2 branch Most people are going to use the defaults, and + this eliminates a potential interface change that would cause + problems if someone wants to go between 2.2.1 and 2.2.0.4. + + * drivers/dahdi/voicebus/voicebus.h, + drivers/dahdi/wcb4xxp/wcb4xxp.h, + drivers/dahdi/wct4xxp/wct4xxp-diag.c, Makefile, + drivers/dahdi/voicebus/GpakCust.h, + drivers/dahdi/hpec/dahdi_echocan_hpec.c, + drivers/dahdi/firmware/Makefile, drivers/dahdi/wcb4xxp/base.c, + drivers/dahdi/dahdi_dynamic.c, + drivers/dahdi/wctdm24xxp/wctdm24xxp.h, drivers/dahdi/wctdm.c, + drivers/dahdi/proslic.h, drivers/dahdi/dahdi-base.c, + drivers/dahdi/dahdi_dummy.c, README, drivers/dahdi/xpp/xdefs.h, + drivers/dahdi/wcfxo.c, drivers/dahdi/wcte12xp/base.c, + include/dahdi/user.h, /, include/dahdi/kernel.h, + drivers/dahdi/wct4xxp/base.c, drivers/dahdi/voicebus/voicebus.c, + drivers/dahdi/wctc4xxp/base.c, drivers/dahdi/wctdm24xxp/base.c, + drivers/dahdi/wcte12xp/wcte12xp.h, + drivers/dahdi/voicebus/GpakCust.c: Merged revisions + 6699,6706,6714,6768,6771,6785,6812-6818,6821,6838,6928-6929,6941,6945-6946,6952,6981-6982,7003-7004,7008,7023,7027,7094-7097,7110,7117-7118,7125,7140,7147,7155,7194,7284,7293,7319,7437-7438,7445,7480,7486-7487,7512-7524,7527-7528,7534-7536 + via svnmerge from + https://origsvn.digium.com/svn/dahdi/linux/trunk ........ r6699 | + kpfleming | 2009-06-23 15:32:01 -0500 (Tue, 23 Jun 2009) | 3 + lines Use the same mutex lock for channel allocation and license + checking in dahdi_echocan_hpec, so that channel allocation won't + happen while the license is being checked (or rechecked) ........ + r6706 | sruffell | 2009-06-23 18:21:25 -0500 (Tue, 23 Jun 2009) | + 1 line README: Minor corrections to the README. ........ r6714 | + twilson | 2009-06-24 15:23:07 -0500 (Wed, 24 Jun 2009) | 1 line + Remove unused torisa code from header ........ r6768 | sruffell | + 2009-06-26 12:07:39 -0500 (Fri, 26 Jun 2009) | 1 line wct4xxp: + Unmap the same size DMA window that was mapped. ........ r6771 | + sruffell | 2009-06-26 12:22:45 -0500 (Fri, 26 Jun 2009) | 6 lines + dahdi_dynamic: Release the dlock before calling accross modules. + Resolves a hard lock due to a recursive spinlock grab at startup. + Reported by: mapacheco (closes issue #15210) ........ r6785 | + sruffell | 2009-06-28 23:47:26 -0500 (Sun, 28 Jun 2009) | 5 lines + echocan: Properly keep the reference counts for the echocan + modules. (closes issue #13504) (closes issue #15327) Reported by: + sruffell, tzafrir ........ r6812 | tzafrir | 2009-07-02 14:25:54 + -0500 (Thu, 02 Jul 2009) | 5 lines wcb4xxp: Don't assume we have + 4 spans (ports). First part of extra hfcmulti drivers: the number + of ports is still hardwired to 4, but just in a single place. + ........ r6813 | tzafrir | 2009-07-02 14:34:05 -0500 (Thu, 02 Jul + 2009) | 4 lines wcb4xxp: Extra bit macros that a needed for + kernels < 2.6.24 Macros borrowed from xpp/ . ........ r6814 | + tzafrir | 2009-07-02 14:42:25 -0500 (Thu, 02 Jul 2009) | 2 lines + wcb4xxp: Adjust debug filter code to number of ports. ........ + r6815 | tzafrir | 2009-07-02 14:52:14 -0500 (Thu, 02 Jul 2009) | + 6 lines wcb4xxp: support for other HFC-xS cards (info, not code) + This commit includes skeleton for the support of other + HFC-[248]S-based cards. It still does not include all the + different cases for different cards. ........ r6816 | tzafrir | + 2009-07-02 14:59:44 -0500 (Thu, 02 Jul 2009) | 2 lines The B410P + differs from other HFC-xS cards with respect to the EC unit + ........ r6817 | tzafrir | 2009-07-02 15:07:36 -0500 (Thu, 02 Jul + 2009) | 7 lines More B410P differences: Clock and NT/TE. * The + B410P reads the NT/TE switches the other way around from other + cards. * Its clock is also 1/2 of that of other cards, which + causes wierd PCM on an unmodified driver. ........ r6818 | + tzafrir | 2009-07-02 15:14:39 -0500 (Thu, 02 Jul 2009) | 4 lines + wcb4xxp: Fix PCM handling for various cards. HFC-8S cards behave + quite differently than HFC-4S cards here. ........ r6821 | + tzafrir | 2009-07-02 15:18:59 -0500 (Thu, 02 Jul 2009) | 6 lines + wcb4xxp: Fix LED handling in OpenVox cards (maybe also others) + This commit adds extra functions to handle LEDs in the non-B410P + cards. Only tested on OpenVox cards. OpenVox cards are known to + have slightly different LEDs so this is likely to be slightly + broken for others. ........ r6838 | sruffell | 2009-07-13 + 09:33:39 -0500 (Mon, 13 Jul 2009) | 1 line wctc4xxp: Remove + deprecated DMA_xxBIT_MASK usage. ........ r6928 | sruffell | + 2009-08-04 11:22:23 -0500 (Tue, 04 Aug 2009) | 1 line wcte12xp: + Remove unused 'schluffen' declaration in wcte12xp.h ........ + r6929 | sruffell | 2009-08-04 11:22:26 -0500 (Tue, 04 Aug 2009) | + 4 lines wctdm24xxp: Eliminate 'variety' and 'type' members from + 'struct wctdm'. struct wctdm can hold a pointer to struct + wctdm_desc directly, and eliminate the need to copy members of + wctdm_desc into wctdm. ........ r6941 | dbailey | 2009-08-05 + 09:40:45 -0500 (Wed, 05 Aug 2009) | 14 lines Change proslic + linefeed register setting Insure that proslic linefeed register + is not transitioned from Active to On-Hook Transmission while the + channel is off-hook. Replaced magic numbers assigned to linefeed + associated variables with more descriptive constants. (issue + #15352) Reported by: alecdavis Patches: + wctdm_prevent_ohttimer_click.diff3.txt uploaded by dbailey + (license 819) Tested by: alecdavis, dbailey, vmikhelson ........ + r6945 | sruffell | 2009-08-05 14:39:10 -0500 (Wed, 05 Aug 2009) | + 6 lines wctdm24xxp, wctdm: Formatting changes. Update the lines + affected by revision 6941. I'm taking every opportunity to move + DAHDI closer to the kernel coding conventions short of just + reformatting for the sake of reformatting. The majority of these + changes are to bring the line lengths under 80 chars. ........ + r6946 | sruffell | 2009-08-05 14:39:13 -0500 (Wed, 05 Aug 2009) | + 1 line dahdi_dummy: Remove some trailing whitespace. ........ + r6952 | sruffell | 2009-08-11 13:47:21 -0500 (Tue, 11 Aug 2009) | + 3 lines wctdm24xxp: Remove unused members related to hardware + DTMF detection. Not used anymore, so they are gone. ........ + r6981 | sruffell | 2009-08-13 09:42:05 -0500 (Thu, 13 Aug 2009) | + 1 line wctc4xxp: Remove flag member that is not used. ........ + r6982 | sruffell | 2009-08-13 09:42:08 -0500 (Thu, 13 Aug 2009) | + 1 line wctdm24xxp: Use the ARRAY_SIZE macro where appropriate. + ........ r7003 | sruffell | 2009-08-13 19:46:26 -0500 (Thu, 13 + Aug 2009) | 9 lines wctdm24xxp, wctdm: Detect if our hookstate + has been set back to the initial state. Check if our hookstate + has been set back to the initial state, typically the result of a + chanconfig, and if so, if we're an FXO port, forget our current + battery state. This allows the driver to determine and report + again what the hook state of the port is. (related to issue + #14577) (closes issue #15429) ........ r7004 | sruffell | + 2009-08-13 19:46:28 -0500 (Thu, 13 Aug 2009) | 1 line dahdi-base: + Add comment to explain why rxhooksig is reset on span start. + ........ r7008 | sruffell | 2009-08-14 10:47:39 -0500 (Fri, 14 + Aug 2009) | 11 lines wcfxo: Reset the DAA on module + initialization. The X100p and clones will sometimes work and + sometimes not depending on wether the DAA powers up in running + state- this seems to be related to the power supply. This problem + is caused by the driver not reseting the DAA and may be the + source of a great many intermittent problems with this card. + (closes issue #14232) Reported by: tallen8840 Patch by: + tallen8840 Tested by: explidous, Flavio ........ r7023 | sruffell + | 2009-08-17 09:07:06 -0500 (Mon, 17 Aug 2009) | 4 lines README: + Update known issues section. Remove note about echocanceler + reference counts, since that is fixed, and add a note about issue + with KB1 when configured with more than 128 taps. ........ r7027 + | seanbright | 2009-08-17 14:31:54 -0500 (Mon, 17 Aug 2009) | 7 + lines Silence spurious warnings when trying to remove Zaptel + directories during install. (closes issue #15479) Reported by: + pprindeville Patches: dahdi-linux-rm.patch uploaded by + pprindeville (license 347) ........ r7094 | sruffell | 2009-09-07 + 16:40:19 -0500 (Mon, 07 Sep 2009) | 4 lines wctdm24xxp: Remove a + few more unneeded 'volatile' keywords. The writechunk and + readchunk parameters are never accessed by hardware at the same + time that the software is accessing them anymore. ........ r7095 + | sruffell | 2009-09-07 16:40:22 -0500 (Mon, 07 Sep 2009) | 5 + lines dahdi-base: Reduce the stack usage of dahdi_common_ioctl. + Split the DAHDI_GETGAINS and DAHDI_SETGAINS ioctls into their own + functions and dynamically allocate the 'struct dahdi_gains' + structure to reduce the pressure on the stack. ........ r7096 | + sruffell | 2009-09-07 16:40:25 -0500 (Mon, 07 Sep 2009) | 1 line + dahdi-base: Prevent compilation if both EMPULSE and EMFLASH are + defined. ........ r7097 | sruffell | 2009-09-07 16:40:29 -0500 + (Mon, 07 Sep 2009) | 4 lines dahdi-base: Fix flag check in + dahdi_rbs_sethook. As long as any of the flags were set, this + check would have always passed. ........ r7110 | rmeyerriecks | + 2009-09-14 15:30:24 -0500 (Mon, 14 Sep 2009) | 1 line Fixed issue + where the clear channel flags were not being set at the + appropriate time causing a channel re-configure to mis-set the + last channel in each span ........ r7117 | dbailey | 2009-09-14 + 15:51:56 -0500 (Mon, 14 Sep 2009) | 17 lines Race condition in + handling writes to proslic LINEFEED register (64) The wctdm24xxp + driver has a problem where a VMWI IOCTL call followed immediately + by a ONHOOKTRANSFER IOCTL call will cause the ONHOOK transfer + request to be dropped. This occurs if the write to the proslic's + LINEFEED register for the VMWI ICTL call is not completed when + the ONHOOK transfer request IOCTL is processed. I also cleaned + out some magic numbers used in setting the linefeed register. + (closes issue #15875) Reported by: dbailey Patches: + 15875-wctdm24xxp.diff uploaded by dbailey (license 819) Tested + by: dbailey ........ r7118 | seanbright | 2009-09-14 16:10:38 + -0500 (Mon, 14 Sep 2009) | 1 line Change zap -> dahdi. ........ + r7125 | rmeyerriecks | 2009-09-15 09:59:06 -0500 (Tue, 15 Sep + 2009) | 2 lines dahdi-base: Minor syntax change to meet style + guidelines ........ r7140 | dbailey | 2009-09-15 15:50:45 -0500 + (Tue, 15 Sep 2009) | 12 lines Change WCTDM SPI clock off state + polarity and read timing Change the off state of the SPI clock to + high and provide more time for data to settle out on SPI reads. + (closes issue #15261) Reported by: alecdavis Patches: + wctdm_spi_clocking.diff2.txt uploaded by alecdavis (license 585) + Tested by: alecdavis, dbailey ........ r7147 | sruffell | + 2009-09-16 13:19:00 -0500 (Wed, 16 Sep 2009) | 4 lines wct4xxp: + Check the alarm state if we're debouncing a red alarm. This fixes + a problem where if you set the alarmdebounce module parameter on + gen2+ cards, you never detect when you go into red alarm. + ........ r7155 | sruffell | 2009-09-21 10:24:36 -0500 (Mon, 21 + Sep 2009) | 8 lines dahdi-base: dahdi_ioctl_[get|set]gains should + return the res value. In function dahdi_ioctl_getgains() and + dahdi_ioctl_setgains() return value assigned to res variable, but + these function always return 0 which is an error. (closes issue + #15916.) Patch by: ys ........ r7194 | dbailey | 2009-09-22 + 09:03:53 -0500 (Tue, 22 Sep 2009) | 12 lines wctdm: Add missing + break A break was missing that caused DAHDI_ONHOOKTRANSFER ioctl + call to fall into DAHDI_SETPOLARITY ioctl call. (issue #14261) + Reported by: alecdavis Patches: wctdm_fix_ONHOOKTRANSFER.diff.txt + uploaded by alecdavis (license 585) Tested by: alecdavis ........ + r7284 | mattf | 2009-09-30 11:34:11 -0500 (Wed, 30 Sep 2009) | 1 + line Update echocan API so it only uses channel offset in free + routine ........ r7293 | tzafrir | 2009-09-30 13:09:42 -0500 + (Wed, 30 Sep 2009) | 2 lines move the dev->bus_id fix from xpp to + kernel.h: needed elsewhere ........ r7319 | sruffell | 2009-10-02 + 16:09:01 -0500 (Fri, 02 Oct 2009) | 1 line wcte12xp: The timer is + called every 200ms, not every 100ms. Fix comment. ........ r7437 + | sruffell | 2009-10-29 13:26:16 -0500 (Thu, 29 Oct 2009) | 10 + lines dahdi-base: Do not allow jumps in system time to lock up + the system w/core_timer Since dahdi coretimer uses the number of + milliseconds that has actually passed to determine how many times + to call dahdi_receive, it is possible that if the system time + shifts after dahdi is started, that the system can appear to lock + up while the core timer attempts to catch up. This change + prevents soft lock ups under these conditions. This is brings the + dahdi_dummy changes in r6933 into dahdi-base. (related to issue + #15647) ........ r7438 | sruffell | 2009-10-29 13:26:17 -0500 + (Thu, 29 Oct 2009) | 1 line wcte12xp, wctdm24xxp: VPMADT032 + firmware update to 1.20. ........ r7445 | mspiceland | 2009-10-29 + 16:37:45 -0500 (Thu, 29 Oct 2009) | 3 lines Debounce alarms by + default for wct4xxp per AT&T 54016. Also, the various alarm + conditions can be debounced separately. ........ r7480 | sruffell + | 2009-11-04 14:43:05 -0600 (Wed, 04 Nov 2009) | 4 lines + voicebus: Increase the NLP converged threshold to 18. Brings in + the change from r7065 that was on the + team/sruffell/dahdi-linux-vpm119 branch. ........ r7486 | + mspiceland | 2009-11-04 17:25:32 -0600 (Wed, 04 Nov 2009) | 9 + lines Adding alarm debounce to single span driver (wcte12xp). + Debounce yellow alarm also. In wcte12xp, change check alarm + frequency to 100ms for better debounce granularity. Fix lines + over 80 cols from last alarm debounce commit. ........ r7487 | + mspiceland | 2009-11-04 17:28:21 -0600 (Wed, 04 Nov 2009) | 2 + lines Remove commented out code block that was unintentionally + left in. ........ r7512 | sruffell | 2009-11-06 18:35:38 -0600 + (Fri, 06 Nov 2009) | 1 line wcte12xp: Remove unused flag member + and make const the t1_descs. ........ r7513 | sruffell | + 2009-11-06 18:35:38 -0600 (Fri, 06 Nov 2009) | 4 lines voicebus: + Remove the VB_PRINTK macro. Unnecessarily duplicates the dev_xxx + macros. Also removes the need for the board_name member from + struct voicebus. ........ r7514 | sruffell | 2009-11-06 18:35:39 + -0600 (Fri, 06 Nov 2009) | 4 lines voicebus: Remove sdi member + from 'struct voicebus' This is only used during startup so we + don't need to carry it around in the structure at all times. + ........ r7515 | sruffell | 2009-11-06 18:35:40 -0600 (Fri, 06 + Nov 2009) | 1 line voicebus: Set the DMA_BIT_MASK ........ r7516 + | sruffell | 2009-11-06 18:35:40 -0600 (Fri, 06 Nov 2009) | 1 + line voicebus: Use DAHDI_IRQ_SHARED instead of defining our own. + ........ r7517 | sruffell | 2009-11-06 18:35:40 -0600 (Fri, 06 + Nov 2009) | 24 lines voicebus: Send 'idle' buffers when the + transmit descriptor underruns. Previously, when the host system + fails to service the interrupt in a timely fashion, the transmit + descriptor ring for the voicebus card would "go empty" since the + interface wouldn't have another descriptor to read in. The driver + only knows that it went empty, not how far behind it actually + was. Therefore, the driver could just increase the latency by a + millisecond and keep going waiting for another bump. + Additionally, when the transmit descriptor actually goes empty, + there are some cases where an in process SPI transaction to one + of the modules is interrupted, which may result in corrupted + module register writes on rare occassions. This now makes it + possible for the voicebus drivers to coexist with some devices + that periodically lock interrupts for longer than 25ms. Before + this patch, the latency would constantly increase until either + the modules received a corrupted frame. This patch preconfigures + all the receive descriptors to send an "idle" packet that will be + transmitted to the onboard modules when the host doesn't service + the interrupt within (latency - 2)ms. There are now two kinds of + underruns, softunderuns where the driver can detect that these + idlebuffers have made it to the TX FIFO, and the normal hard + underrun where the part signals a transmit descriptor unavailable + interrupt. DAHDI-278. ........ r7518 | sruffell | 2009-11-06 + 18:35:41 -0600 (Fri, 06 Nov 2009) | 7 lines voicebus: Add + function to lock the latency. Now that increases in the latency + produce less undefined behavior on the SPI busses, provide an + interface for client drivers to inform the voicebus library to + not increase the latency if underruns are detected. This can + speed up loads of the driver since latency bumps do not trigger a + restart of the driver initialization. DAHDI-278. ........ r7519 | + sruffell | 2009-11-06 18:35:42 -0600 (Fri, 06 Nov 2009) | 4 lines + wcte12xp: Lock latency when loading No longer need to restart + board initialization if the latency would have increased during + initialization. DAHDI-278. ........ r7520 | sruffell | 2009-11-06 + 18:35:42 -0600 (Fri, 06 Nov 2009) | 4 lines wctdm24xxp: Lock + latency when loading We no longer need to retry board + initialization if the latency would have increased during the + initialization. DAHDI-278 ........ r7521 | sruffell | 2009-11-06 + 18:35:43 -0600 (Fri, 06 Nov 2009) | 4 lines voicebus, wctdm24xxp, + wcte12xp: Move a print out of the interrupt handler. This can be + handled just as well in process context and printing to a serial + console from the interrupt handler has the potential to cause + long latencies. ........ r7522 | sruffell | 2009-11-06 18:35:44 + -0600 (Fri, 06 Nov 2009) | 5 lines voicebus: Add optional sysfs + entry for reading a boards current latency. This is off by + default since it hasn't been tested on a full range of kernels, + but can be useful for quickly seeing differences for latencies on + different cards installed in the system. ........ r7523 | + sruffell | 2009-11-06 18:35:44 -0600 (Fri, 06 Nov 2009) | 1 line + voicebus: Remove 'assert' macros and use BUG_ON/WARN_ON directly. + ........ r7524 | sruffell | 2009-11-06 18:35:45 -0600 (Fri, 06 + Nov 2009) | 1 line voicebus: Be just a little more graceful if we + cannot grab our interrupt line. ........ r7527 | sruffell | + 2009-11-06 18:58:03 -0600 (Fri, 06 Nov 2009) | 1 line wcte12xp: + Fix up some continued strings. ........ r7528 | sruffell | + 2009-11-06 18:58:03 -0600 (Fri, 06 Nov 2009) | 1 line wct4xxp: + Fix up some continued strings. ........ r7534 | sruffell | + 2009-11-09 12:02:40 -0600 (Mon, 09 Nov 2009) | 1 line wct4xxp: + Only print the new debounce messages when debug is set. ........ + r7535 | sruffell | 2009-11-09 12:02:41 -0600 (Mon, 09 Nov 2009) | + 1 line wcte12xp: Only print the new debounce messages when debug + is set. ........ r7536 | sruffell | 2009-11-09 12:11:06 -0600 + (Mon, 09 Nov 2009) | 4 lines wcte12xp: use the dev_xxx macro for + the debounce messages. We want to know which device is reporting + the debounce when there are more than one card in the system. + ........ + +2009-11-05 12:06 +0000 [r7485-7493] Tzafrir Cohen + + * drivers/dahdi/xpp/xpp_dahdi.c, /, drivers/dahdi/pciradio.c, + drivers/dahdi/xpp/xbus-sysfs.c, drivers/dahdi/wctdm.c, + drivers/dahdi/wctdm24xxp/base.c, drivers/dahdi/xpp/xbus-core.c, + drivers/dahdi/dahdi-base.c: backport a number of build fixes from + trunk to 2.2 Merged revisions 7226,7356,7392 via svnmerge from + http://svn.digium.com/svn/dahdi/linux/trunk ........ r7226 | + tzafrir | 2009-09-28 10:57:07 +0200 (Mon, 28 Sep 2009) | 8 lines + xpp: Use proper get/set for device->driver_data 2.6.32-rc1 broke + direct access to the member 'driver_data' of 'struct device'. + However direct access to wasn't proper in the first place. This + commit replaces direct access to dev->driver_data with + dev_get_drvdata() and dev_set_drvdata(). ........ r7356 | + sruffell | 2009-10-09 07:22:55 +0200 (Fri, 09 Oct 2009) | 6 lines + dahdi-base: Include linux/sched.h Commit a99bba to the mainline + kernel removed sched.h from poll.h. So dahdi-base.c needs to + include sched.h directly now. + http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=a99bba + ........ r7392 | sruffell | 2009-10-12 22:05:35 +0200 (Mon, 12 + Oct 2009) | 4 lines headers: sched.h was also removed from + interrupts.h Commit d43c36 made it necessary to add sched.h to + more of the board drivers. + http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=d43c36 + ........ + + * /, drivers/dahdi/xpp/xbus-sysfs.c: xpp: Add sysfs xpd attribute + 'timing_priority' Merged revisions 7237 via svnmerge from + http://svn.digium.com/svn/dahdi/linux/trunk + + * drivers/dahdi/xpp/xbus-pcm.c, + drivers/dahdi/xpp/firmwares/PIC_TYPE_4.hex, + drivers/dahdi/xpp/init_card_4_30, drivers/dahdi/xpp/xpp_dahdi.c, + /, drivers/dahdi/xpp/card_pri.c, drivers/dahdi/xpp/xbus-pcm.h, + drivers/dahdi/xpp/card_bri.c, drivers/dahdi/xpp/xproto.c: T1 CAS + support in the xpp "pri" module Merged revisions + 7244-7245,7266,7276,7457 via svnmerge from + http://svn.digium.com/svn/dahdi/linux/trunk ........ r7244 | + tzafrir | 2009-09-29 18:23:13 +0200 (Tue, 29 Sep 2009) | 5 lines + xpp: make card_hooksig an optional card method. Done in + preperation for T1 CAS support, as the PRI module will use RBS + instead. ........ r7245 | tzafrir | 2009-09-29 18:45:15 +0200 + (Tue, 29 Sep 2009) | 2 lines xpp: refactor pcm mask handling. + ........ r7266 | tzafrir | 2009-09-30 00:43:05 +0200 (Wed, 30 Sep + 2009) | 2 lines xpp: T1 CAS support ........ r7276 | tzafrir | + 2009-09-30 15:49:48 +0200 (Wed, 30 Sep 2009) | 2 lines xpp: PRI + PIC firmware: T1-CAS fixes ........ r7457 | tzafrir | 2009-11-03 + 22:24:13 +0200 (Tue, 03 Nov 2009) | 4 lines xpp: More E1/T1 CAS + fixes. Mostly connect/disconnect xpp revs: mostly 7458, 7466 + ........ + +2009-08-19 16:44 +0000 [r7039] Kevin P. Fleming + + * drivers/dahdi/wcte12xp/base.c, /, drivers/dahdi/wct4xxp/base.c, + drivers/dahdi/wctdm24xxp/base.c: Merged revisions 7038 via + svnmerge from https://origsvn.digium.com/svn/dahdi/linux/trunk + ........ r7038 | kpfleming | 2009-08-19 11:40:13 -0500 (Wed, 19 + Aug 2009) | 9 lines Ensure that dahdi_scan correctly reports VPM + presence. The wct4xxp driver (for the dual/quad span T1/E1 cards) + and the wcte12xp driver (for the single span VoiceBus-based T1/E1 + cards) did not properly update the 'devicetype' field reported by + dahdi_scan when a VPM was found during the card startup process. + As a result, dahdi_scan did not show that a VPM was present on + the card, even if it was. ........ + +2009-08-13 22:04 +0000 [r7001] Tzafrir Cohen + + * /, drivers/dahdi/xpp/firmwares/FPGA_1161.hex: xpp firmware: Fixes + PCM issue with FXO that is not a timing source Fixes PCM issue + with an Astribank2 (116x) FXO module that is installed alongside + a PRI/BRI module. xpp: FPGA_1161.hex r7276 . Merged revisions + 6938,6966 via svnmerge from + http://svn.digium.com/svn/dahdi/linux/trunk + +2009-08-06 17:35 +0000 [r6950] Shaun Ruffell + + * /, drivers/dahdi/dahdi-base.c: Merged revisions 6890-6891 via + svnmerge from https://origsvn.digium.com/svn/dahdi/linux/trunk + ........ r6890 | sruffell | 2009-07-23 17:01:04 -0500 (Thu, 23 + Jul 2009) | 1 line dahdi-base: Reduce the stack usage of + ioctl_load_zone. ........ r6891 | sruffell | 2009-07-23 17:26:25 + -0500 (Thu, 23 Jul 2009) | 3 lines dahdi-base: Update formatting + in ioctl_load_zone. Fixes checkpatch.pl formatting errors from + the previous commit. ........ + +2009-08-04 16:38 +0000 [r6934-6937] Shaun Ruffell + + * /, drivers/dahdi/wctc4xxp/base.c: Merged revisions 6717,6760 via + svnmerge from https://origsvn.digium.com/svn/dahdi/linux/trunk + ........ r6717 | sruffell | 2009-06-24 21:30:19 -0500 (Wed, 24 + Jun 2009) | 3 lines wctc4xxp: Update to use struct + net_device_ops. Accomodates a change in the linux kernel network + device interface. ........ r6760 | sruffell | 2009-06-25 17:16:34 + -0500 (Thu, 25 Jun 2009) | 1 line wctc4xxp: Make the + wctc4xxp_netdev_ops structure static. ........ + + * drivers/dahdi/dahdi_dummy.c, /: Merged revisions 6933 via + svnmerge from https://origsvn.digium.com/svn/dahdi/linux/trunk + ........ r6933 | sruffell | 2009-08-04 11:22:39 -0500 (Tue, 04 + Aug 2009) | 10 lines dahdi_dummy: Do not allow jumps in system + time to lock up the system. Since dahdi_dummy uses the number of + milliseconds that has actually passed to determine how many times + to call dahdi_receive, it is possible that if the system time + shifts after dahdi is started, that the system can appear to lock + up while dahdi_dummy attempts to catch up. This change prevents + soft lock ups under these conditions. (closes issue #15647) + Reported by: missnebun ........ + +2009-07-21 18:11 +0000 [r6864] Shaun Ruffell + + * drivers/dahdi/tor2.c, drivers/dahdi/wcte12xp/base.c, /, + include/dahdi/dahdi_config.h, drivers/dahdi/wct4xxp/base.c, + drivers/dahdi/wcte11xp.c, drivers/dahdi/dahdi-base.c: Merged + revisions 6844,6852,6862-6863 via svnmerge from + https://origsvn.digium.com/svn/dahdi/linux/trunk ........ r6844 | + sruffell | 2009-07-16 12:29:53 -0500 (Thu, 16 Jul 2009) | 10 + lines wcte12xp: Disable vpmadt032 companding by default. This + fixes a regression in 2.2.0 where certain configurations will + fail patloop test or have repeated HDLC aborts because the + VPMADT032 is modifying the clear channel or d channel data + streams. This restores the behavior to how it was in dahdi-linux + 2.1.0.4. (closes issue #15498) Reported by: alecdavis Tested by: + alecdavis ........ r6852 | tzafrir | 2009-07-19 10:45:40 -0500 + (Sun, 19 Jul 2009) | 12 lines tor2: allow using port4 as timing + source Fix a silly regression introduced when strict check on the + timing parameter was added (sync-1 is the array index, not sync + itself. And 0 is a special case). (closes issue #15408) Reported + by: dferrer Patches: tor2-4th_sync.patch uploaded by dferrer + (license 525) ........ r6862 | sruffell | 2009-07-21 12:52:59 + -0500 (Tue, 21 Jul 2009) | 4 lines Revert "wct4xxp, wcte11xp: Use + the default configuration by default at startup." This reverts + the change introduced by revision 6712. This change can cause + problems when there is a VPM module installed on the quad-span + digital cards. ........ r6863 | sruffell | 2009-07-21 12:53:02 + -0500 (Tue, 21 Jul 2009) | 12 lines dahdi-base: Add support for + core timing. This essentially moves the function of dahdi_dummy + into the core of DAHDI. It ensures that if DAHDI is loaded, it + will always be able to provide timing, regardless of whether + there are board drivers loaded, or if the board drivers are + properly calling dahdi_receive. If there is a master span loaded + which is calling dahdi_receive, then the behavior will be like it + is normally. This functionality is off by default, uncomment + CONFIG_DAHDI_CORE_TIMER in include/dahdi/config_dahdi.h in order + to enable it. ........ + +2009-07-21 18:11 +0000 [r6858-6864] Shaun Ruffell + + * dahdi-linux version 2.2.0.2 released. + + * wcte12xp: Disable vpmadt032 companding by default. This + fixes a regression in 2.2.0 where certain configurations will + fail patloop test or have repeated HDLC aborts because the + VPMADT032 is modifying the clear channel or d channel data + streams. This restores the behavior to how it was in dahdi-linux + 2.1.0.4. (closes issue #15498) Reported by: alecdavis Tested by: + alecdavis + + * tor2: allow using port4 as timing source Fix a silly regression + introduced when strict check on the timing parameter was added + (sync-1 is the array index, not sync itself. And 0 is a special + case). (closes issue #15408) Reported by: dferrer Patches: + tor2-4th_sync.patch uploaded by dferrer (license 525) + + * Revert "wct4xxp, wcte11xp: Use the default configuration by default + at startup." This reverts the change introduced by revision 6712. + This change can cause problems when there is a VPM module installed + on the quad-span digital cards. + + * dahdi-base: Add support for core timing. This essentially moves the + function of dahdi_dummy into the core of DAHDI. It ensures that if + DAHDI is loaded, it will always be able to provide timing, + regardless of whether there are board drivers loaded, or if the + board drivers are properly calling dahdi_receive. If there is a + master span loaded which is calling dahdi_receive, then the behavior + will be like it is normally. This functionality is off by default, + uncomment CONFIG_DAHDI_CORE_TIMER in include/dahdi/config_dahdi.h in + order to enable it. + +2009-06-30 Shaun Ruffell + + * dahdi-linux version 2.2.0.1 released. + + * Fix for kernel panic when echotraining is enabled on echocan that + does not support it. + + * Fix for kernel panic on RHEL4 when using VPMADT032. + + * Fix to allow wct4xxp, wcb4xxp, and wcte11xp to provide early timing. + +2009-06-23 15:44 +0000 [r6695] Shaun Ruffell + + * dahdi-linux version 2.2.0 released. + + * README: Adding a known issues section to the README + files. + +2009-06-18 18:03 +0000 [r6692] Shaun Ruffell + + * drivers/dahdi/wcfxo.c, drivers/dahdi/wctdm.c, + drivers/dahdi/wctdm24xxp/base.c: Fix calls to dahdi_hooksig. When + JAPAN, AUDIO_RINGCHECK, or ZERO_BATT_RING compile time options are + selected it is possible to get a kernel panic due to an invalid + pointer passed to the dahdi_hooksig function. (closes issue #15350) + Patch by: alecdavis + +2009-06-12 22:30 +0000 [r6688] Jason Parker + + * drivers/dahdi/Kbuild: Make complex conditionals work with GNU + make 3.80. Much uglier, but it works on RHEL4. + +2009-06-04 21:14 +0000 [r6675] Shaun Ruffell + + * drivers/dahdi/dahdi-base.c: Fix bug in procfs + handling. Fix bug in procfs handling where it was possible to get + a warning in lib/vsprintf.c when reading from /proc/dahdi/x. + Patch by: biohumanoid (closes issue #15252) + +2009-05-27 Shaun Ruffell + + * dahdi-linux version 2.2.0-rc5 released. + +2009-05-27 12:48 +0000 [r6659] Tzafrir Cohen + + * drivers/dahdi/xpp/card_pri.c, drivers/dahdi/xpp/card_bri.c, + drivers/dahdi/xpp/card_fxo.c, drivers/dahdi/xpp/card_fxs.c, + drivers/dahdi/xpp/card_global.c: Fix more 'owner' for 2.6.30 + to be happy. Finishing the work of r6642. Completely shut issue + #14964. + +2009-05-25 08:23 +0000 [r6651-6653] Tzafrir Cohen + + * drivers/dahdi/xpp/firmwares/PIC_TYPE_3.hex, + drivers/dahdi/xpp/firmwares/PIC_TYPE_4.hex, + drivers/dahdi/xpp/firmwares/FPGA_1161.hex, + drivers/dahdi/xpp/firmwares/PIC_TYPE_1.hex, + drivers/dahdi/xpp/firmwares/PIC_TYPE_2.hex: xpp firmwares: fixes + sync issues of FXO module in a BRI/PRI Astribank * Also fixes LED + blinking issues in PRI modules * Various bugfixes in the PICs. + + * drivers/dahdi/xpp/firmwares/USB_FW.hex: USB_FW.hex: Allow setting + caps. even when FPGA is loaded. Note that They will only take + effect after a reset. Firmware rev. 7071. + +2009-05-19 16:09 +0000 [r6635-6642] Tzafrir Cohen + + * drivers/dahdi/xpp/xpp_dahdi.c, drivers/dahdi/xpp/xpp_usb.c, + drivers/dahdi/xpp/xbus-core.c, drivers/dahdi/xpp/xdefs.h: xpp: + 'owner' property of procfs was dropped in 2.6.30. This adds a + compatibility macro for older versions that is a noop for kernels + >= 2.6.30. (closes issue #14964) + + * drivers/dahdi/xpp/xproto.h, drivers/dahdi/xpp/xbus-sysfs.c, + drivers/dahdi/xpp/xbus-core.c, drivers/dahdi/xpp/card_global.c, + drivers/dahdi/xpp/xproto.c, drivers/dahdi/xpp/xbus-core.h, + drivers/dahdi/xpp/xbus-pcm.c: xpp: fix the Astribank state + machine This generally is a case that would not happen in the + wild, though. + + * drivers/dahdi/xpp/card_bri.c, drivers/dahdi/xpp/xdefs.h: xpp: + report in sysfs if bri module uses hardhdlc support + + * drivers/dahdi/xpp/calibrate_slics (removed): xpp: remove obsolete + script calibrate_slics + + * drivers/dahdi/xpp/card_pri.c, drivers/dahdi/xpp/mmapbus.c, + drivers/dahdi/xpp/card_bri.c, drivers/dahdi/xpp/card_fxo.c, + drivers/dahdi/xpp/mmapdrv.c, drivers/dahdi/xpp/xbus-sysfs.c, + drivers/dahdi/xpp/Kbuild, drivers/dahdi/xpp/card_fxs.c, + drivers/dahdi/xpp/xdefs.h: Replaece member bus_id with dev_name() + and set_dev_name() As of 2.6.26 the macros dev_name() and + set_dev_name() are used to read and set (respectively) the bus_id + member in sysfs. As of 2.6.30 bus_id is gone. This patch provides + comaptiobility macros for older kernel versions and removes + direct usage of bus_id. (closes issue #14965) Patches: + xpp_2630_dev_name.diff uploaded by tzafrir (license 46) + + * drivers/dahdi/voicebus, drivers/dahdi/vpmadt032_loader: ignore + generated files in voicebus and vpmadt032_loader + +2009-05-15 23:37 +0000 [r6625-6628] Shaun Ruffell + + * drivers/dahdi/voicebus/GpakCust.c: voicebus: Use '&' not '|' when + checking for a bit. + + * drivers/dahdi/voicebus/GpakCust.c: voicebus: Make the + enable/disable echocan messages debug again. I accidentally + changed to print everytime. They should only be printed if + DEBUG_ECHOCAN is specified in the debug module parameter. + +2009-05-14 14:49 +0000 [r6621] Shaun Ruffell + + * drivers/dahdi/wcte12xp/base.c: wcte12xp: Set the syncsrc in the + span appropriately. Before this commit, dahdi_tool would report + "Internally clocked" for boards supported by the wcte12xp driver + both when receiving timing from the span and providing it to the + span. Now it reports "Internally clocked" if providing timeing to + the span, and the card if receiving timeing from the span. + DAHDI-65. + +2009-05-12 22:30 +0000 [r6606-6610] Kevin P. Fleming + + * drivers/dahdi/Kbuild: use proper case for variable name :-) + + * drivers/dahdi/Kbuild: Allow VPMADT032 and HPEC binary modules to + be used on platforms where ARCH is set to the new 'generic' x86 + flavor available in recent Linux kernel releases + + * drivers/dahdi/Kbuild: emit warning messages when DAHDI is being + built on a CPU architecture that does not support HPEC or the + VPMADT032 firmware loader, so the user will know why they are not + included clean up the conditional logic for these items in the + Kbuild file + + * Makefile: remove another unused variable + +2009-05-11 17:48 +0000 [r6589-6590] Shaun Ruffell + + * dahdi-linux version 2.2.0-rc4 released. + + * drivers/dahdi/wcte12xp/base.c: wcte12xp: Expose vpm parameters as + module parameters. Expose the vpmnlptype, vpmnlpthresh, and + vpmnlpmaxsupp as module parameters like for the wctdm24xxp. + DAHDI-261 + + * drivers/dahdi/wcte12xp/base.c, drivers/dahdi/wctdm24xxp/base.c, + drivers/dahdi/voicebus/GpakApi.h, + drivers/dahdi/voicebus/GpakCust.c, + drivers/dahdi/voicebus/GpakCust.h: voicebus: Update the default + vpmadt032 parameters. Move the echo can channel parameters into a + common location for both the wcte12xp and wctdm24xxp drivers that + use the voicebus module. This is intended to make it clearer + which differences are required between the clients. Additionally, + update the default parameters to the new recommended values. + VPMADT032-37 + +2009-05-07 19:42 +0000 [r6572] Shaun Ruffell + + * drivers/dahdi/wcte12xp/base.c, drivers/dahdi/wctdm24xxp/base.c, + drivers/dahdi/voicebus/GpakCust.c, + drivers/dahdi/voicebus/GpakCust.h: voicebus: Create workqueue for + each vpmadt032 instance. Depending on the system latency, the + deferred work for the vpmadt032 can take up to 200ms. This change + allows each vpmadt032 to use its own workqueue, and not the + global system workqueue. This prevents vpm operations from + blocking the main system workqueue for extended periods. This + restores the behavior to the way it was before the common + vpmadt032 code was moved out of the wctdm24xxp and wcte12xp + drivers. DAHDI-260 voicebus-squash: Adding the wq name. + +2009-05-07 19:42 +0000 [r6568-6572] Shaun Ruffell + + * dahdi-linux version 2.2.0-rc3 released. + + * drivers/dahdi/wcte12xp/base.c, drivers/dahdi/wctdm24xxp/base.c, + drivers/dahdi/voicebus/GpakCust.c, + drivers/dahdi/voicebus/GpakCust.h: voicebus: Create workqueue for + each vpmadt032 instance. Depending on the system latency, the + deferred work for the vpmadt032 can take up to 200ms. This change + allows each vpmadt032 to use its own workqueue, and not the + global system workqueue. This prevents vpm operations from + blocking the main system workqueue for extended periods. This + restores the behavior to the way it was before the common + vpmadt032 code was moved out of the wctdm24xxp and wcte12xp + drivers. + + * drivers/dahdi/wcte12xp/base.c, drivers/dahdi/wctdm24xxp/base.c, + drivers/dahdi/voicebus/GpakCust.h: voicebus: Changing default NLP + type to 'suppression'. The 'suppression' default for the NLP + provides better echo canceling performance. Also ensures that the + wctdm24xxp and wcte12xp driver use the same default values. + +2009-05-05 17:32 +0000 [r6564] Shaun Ruffell + + * drivers/dahdi/voicebus/GpakCust.c: voicebus: Use the companding + type on the span when enabling echocan. + +2009-05-04 20:36 +0000 [r6562] Doug Bailey + + * drivers/dahdi/voicebus/GpakCust.c: Insure that vpmnlptype, + vpmnlpmaxsupp, and vpmnlpthresh are set back to module level + defaults when echo can is freed. (Previously they were zero'd + out) DAHDI-257 + +2009-05-02 07:53 +0000 [r6556] Kevin P. Fleming + + * Makefile: Remove explicit passing of ARCH to kernel build system + There is no value in setting a value for ARCH and passing it to + the kernel build system; the configured kernel headers/sources + already have an architecture specified and can't be used for any + other architecture anyway. + +2009-05-01 16:43 +0000 [r6549-6554] Shaun Ruffell + + * drivers/dahdi/dahdi-base.c: dahdi-base: define + __RW_LOCK_UNLOCKED() Linux 2.6.9 does not contain that + definition, but the older definition is deprecated since it + defeats lock state checking. DAHDI-253 + + * drivers/dahdi/voicebus/Makefile (added): voicebus: Need Makefile + to build on 2.6.9 DAHDI-253 + + * drivers/dahdi/wcb4xxp/base.c: wcb4xxp: Define mmiowb if not + already defined. Linux kernel 2.6.9 does not define mmiowb. + DAHDI-253 + + * drivers/dahdi/wctc4xxp/base.c: wctc4xxp: spin_trylock_irqsave is + not defined on some kernels. DAHDI-253 + + * drivers/dahdi/wctc4xxp/base.c: wctc4xxp: Defined gfp_t for + earlier kernels. This definition was just copied from the xpp + driver. DAHDI-253 + + * drivers/dahdi/wctc4xxp/base.c: wctc4xxp: Fix inclusion of + linux/io.h on 2.6.9 kernels. DAHDI-253 + +2009-04-30 20:59 +0000 [r6544-6546] Kevin P. Fleming + + * include/dahdi/user.h: Fix compilation of applications that use + DAHDI ioctls Defining ioctl codes in this file requires that + linux/ioctl.h be included first. + + * drivers/dahdi/wcte12xp/base.c, drivers/dahdi/wct4xxp/base.c, + drivers/dahdi/wctdm24xxp/base.c: Ensure that vpmsupport=0 module + parameter takes proper effect For these drivers, when the + vpmsupport module parameter is set to zero, don't even register + the span as supporting echo cancellation. DAHDI-250 + +2009-04-30 13:59 +0000 [r6542] Tzafrir Cohen + + * drivers/dahdi/xpp/firmwares/FPGA_1161.hex: xpp: A new FPGA + firmware to hopefully help with BRI/FXO. + +2009-04-29 18:24 +0000 [r6523-6529] Shaun Ruffell + + * dahdi-linux version 2.2.0-rc2 released. + + * drivers/dahdi/dahdi_echocan_kb1.c, drivers/dahdi/wcte12xp/base.c, + include/dahdi/user.h, include/dahdi/kernel.h, + drivers/dahdi/adt_lec.c, drivers/dahdi/dahdi_echocan_jpah.c, + drivers/dahdi/wct4xxp/base.c, drivers/dahdi/ecdis.h, + drivers/dahdi/wctdm24xxp/base.c, + drivers/dahdi/dahdi_echocan_mg2.c, + drivers/dahdi/wcte12xp/wcte12xp.h, + drivers/dahdi/voicebus/GpakCust.c, drivers/dahdi/hpec/hpec.h, + drivers/dahdi/wcb4xxp/wcb4xxp.h, + drivers/dahdi/dahdi_echocan_sec2.c, + drivers/dahdi/voicebus/GpakCust.h, + drivers/dahdi/hpec/dahdi_echocan_hpec.c, + include/dahdi/dahdi_config.h, drivers/dahdi/wcb4xxp/base.c, + drivers/dahdi/wctdm24xxp/wctdm24xxp.h, + drivers/dahdi/dahdi_echocan_oslec.c, drivers/dahdi/dahdi-base.c, + drivers/dahdi/dahdi_echocan_sec.c: echocan: Improve interface for + echo cancelers. Echo cancelers are now able to report if they are + able to automatically disable their NLP portions in the presence + of tones in the audio stream. Also, the interface is changed to + allow user space to just disable the NLP portion of the echo + canceler. These changes improve fax and modem handling in DAHDI. + This commit merges in the changes on + http://svn.digium.com/svn/dahdi/linux/team/kpfleming/echocan_work + Patch by: kpfleming Also contains improvements to CED tone + detection. (closes issue #13286) Reported by: viniciusfontes + + * drivers/dahdi/wct4xxp/base.c: wct4xxp: Fix problem when timing + source is via external cable. + + * drivers/dahdi/wcte12xp/base.c, drivers/dahdi/wcte12xp/voicebus.c + (removed), drivers/dahdi/wcte12xp/vpmadt032.c (removed), + drivers/dahdi/voicebus (added), drivers/dahdi/voicebus/voicebus.c + (added), drivers/dahdi/wctdm24xxp/base.c, drivers/dahdi/Kconfig, + drivers/dahdi/wcte12xp/wcte12xp.h, + drivers/dahdi/wcte12xp/GpakErrs.h (removed), + drivers/dahdi/wctdm24xxp/GpakApi.c (removed), + drivers/dahdi/wcte12xp/vpmadt032.h (removed), + drivers/dahdi/wctdm24xxp/voicebus.c (removed), + drivers/dahdi/voicebus/voicebus.h (added), Makefile, + drivers/dahdi/wctdm24xxp/GpakApi.h (removed), + drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c (added), + drivers/dahdi/wcte12xp/Kbuild, drivers/dahdi/voicebus/Kbuild + (added), drivers/dahdi/wctdm24xxp/GpakHpi.h (removed), + drivers/dahdi/wctdm24xxp/Kbuild, drivers/dahdi/voicebus.c + (removed), drivers/dahdi/voicebus.h (removed), + drivers/dahdi/vpmadt032_loader (added), + drivers/dahdi/wcte12xp/GpakApi.c (removed), + drivers/dahdi/wcte12xp/gpakenum.h (removed), + drivers/dahdi/Kbuild, drivers/dahdi/voicebus/gpakenum.h (added), + drivers/dahdi/voicebus/GpakApi.c (added), + drivers/dahdi/adt_lec.c, drivers/dahdi/wcte12xp/GpakApi.h + (removed), drivers/dahdi/voicebus/GpakApi.h (added), + drivers/dahdi/voicebus/GpakCust.c (added), + drivers/dahdi/wctdm24xxp/gpakenum.h (removed), + drivers/dahdi/voicebus/gpakErrs.h (added), + drivers/dahdi/wctdm24xxp/GpakCust.c (removed), + drivers/dahdi/voicebus/GpakCust.h (added), + drivers/dahdi/voicebus/GpakHpi.h (added), + drivers/dahdi/wctdm24xxp/gpakErrs.h (removed), + drivers/dahdi/firmware/Makefile, + drivers/dahdi/voicebus/vpmadtreg.c (added), + drivers/dahdi/wctdm24xxp/GpakCust.h (removed), + drivers/dahdi/voicebus/vpmadtreg.h (added), + drivers/dahdi/wctdm24xxp/wctdm24xxp.h: voicebus: Move common + vpmadt032 interface into voicebus module. The voicebus library + was previously linked into both the wcte12xp and wctdm24xxp + drivers. It is now broken out into it's own module and the common + parts of the vpmadt032 interface are now located in that module + to reduce duplication between the wcte12xp and wctdm24xxp + drivers. + + * drivers/dahdi/wctc4xxp/base.c: wctc4xxp: Change netif_rx_xxx to + napi_xxx The netif_rx_xxx functions were dropped from the linux + kernel source on 2009-01-21 in commit + 288379f050284087578b77e04f040b57db3db3f8. (closes issue #14963) + Reported by: tzafrir + + * drivers/dahdi/wcte12xp/base.c, + drivers/dahdi/wcte12xp/vpmadt032.c, + drivers/dahdi/wcte12xp/wcte12xp.h: wcte12xp: Update cmdqueue + processing. The command queue for reading from the registers on + the framer is now stored in a linked_list instead of an array. + Allows for the locks to protect this structure to be held for + shorter periods of time and reduces the need to cycle through all + the elements in the array to decide if there is a command in the + queue to process. Remove the usecount and dead members from + struct t1 since the module reference count will allow us to know + when it's safe to free up the memory. This change also moves + alarm processing out of the interrupt handler and removes the + need for special interrupt handling of commands. + + * drivers/dahdi/dahdi_dummy.c: dahdi_dummy: Remove real-time clock + support. This removes support for using the real-time clock as a + timing source in dahdi_dummy. Instead, the normal kernel timers + method is now more accurate since it keeps track of how much real + time has passed to determine how many times to call dahdi_receive + and dahdi_transmit. This method was originally suggested by bmd. + (closes issue #13930) (closes issue #14884) Reported by: tzafrir + Tested by: dbackeberg, ask + + * drivers/dahdi/voicebus.c: voicebus: Removing unused code blocks + and space in flag definitions. + +2009-04-27 20:03 +0000 [r6513] Tzafrir Cohen + + * drivers/dahdi/xpp/card_bri.c, drivers/dahdi/xpp/Kbuild: xpp: + hard_hdlc support for the BRI module. The BRI module will now use + hardhdlc unless the DAHDI tree has been patched with the + bri_dchan patch, in which case the old "bristuffed" code will be + used. Thus it is now built by default. + +2009-04-25 16:35 +0000 [r6487] Tzafrir Cohen + + * build_tools/live_dahdi: adapt live_dahdi to current xpp tools * + More varibles to set through the environment * Different way to + list drivers + +2009-04-23 15:11 +0000 [r6457-6466] Tzafrir Cohen + + * drivers/dahdi/xpp/firmwares/PIC_TYPE_3.hex, + drivers/dahdi/xpp/firmwares/PIC_TYPE_4.hex, + drivers/dahdi/xpp/firmwares/USB_FW.hex, + drivers/dahdi/xpp/firmwares/FPGA_1161.hex, + drivers/dahdi/xpp/firmwares/PIC_TYPE_1.hex, + drivers/dahdi/xpp/firmwares/PIC_TYPE_2.hex: Don't set the Id + keyword on firmwares; restore original ID The Id SVN keyword is + set locally in Xorcom and used as an identifier. That Id should + not be overriden by this SVN repository. + + * drivers/dahdi/xpp/firmwares/FPGA_1161.hex: xpp: FPGA_1161.hex: + fix FXO PCM issues (new boards only) FPGA_1161.hex rev. 7024. + +2009-04-22 12:53 +0000 [r6444] Kevin P. Fleming + + * drivers/dahdi/dahdi-base.c: don't refer to macros from + dahdi_config.h until after it has been included use the proper + type for the flags variable in dahdi_ppp_xmit() + +2009-04-21 22:16 +0000 [r6430] Tzafrir Cohen + + * include/dahdi/user.h, include/dahdi/kernel.h: Move + DAHDI_DEFAULT_MTU_MRU from kernel.h to user.h The macro + DAHDI_DEFAULT_MTU_MRU needs to be exposed to userspace to build + tools/ppp/dahdi.c . + +2009-04-20 10:49 +0000 [r6407-6409] Tzafrir Cohen + + * drivers/dahdi/xpp/firmwares/PIC_TYPE_3.hex, + drivers/dahdi/xpp/firmwares/PIC_TYPE_4.hex, + drivers/dahdi/xpp/firmwares/FPGA_1161.hex, + drivers/dahdi/xpp/firmwares/PIC_TYPE_1.hex, + drivers/dahdi/xpp/firmwares/PIC_TYPE_2.hex: xpp firmware: + stability fixes for firmwares of new Astribanks FPGA_1161.hex: + xpp rev 7007 PIC_TYPE_*.hex: xpp rev 7000 + + * drivers/dahdi/xpp/xpp_dahdi.c, drivers/dahdi/xpp/xproto.h, + drivers/dahdi/xpp/card_pri.c, drivers/dahdi/xpp/card_bri.c, + drivers/dahdi/xpp/card_fxo.c, drivers/dahdi/xpp/xpp_dahdi.h, + drivers/dahdi/xpp/xbus-core.c, drivers/dahdi/xpp/card_fxs.c: xpp: + Do use information about number of ports the Astribank provides + + * drivers/dahdi/xpp/init_card_1_30: xpp: Fix FXS calibration (dec + rather than hex) + +2009-04-16 19:35 +0000 [r6376-6393] Tzafrir Cohen + + * drivers/dahdi/xpp/card_fxs.c, drivers/dahdi/xpp/init_card_1_30, + drivers/dahdi/xpp/init_card_2_30: xpp fxs/fxo: PCM and DTMF fixes + + * drivers/dahdi/xpp/card_fxs.c: xpp fxs: Notify the user just one + about wrong VMWI config From xpp rev. 6974. + + * drivers/dahdi/xpp/card_fxs.c: xpp fxs: Ignore registers of + disabled SLICs From xpp rev. 6979 + + * drivers/dahdi/xpp/card_bri.c: xpp bri: explicitly turn off leds + on startup If NT/TE was changed (e.g: happened because of + firmware bug) We would be left with a lit led we don't know + about. From xpp rev. 6990 + +2009-04-10 09:53 +0000 [r6344] Tzafrir Cohen + + * drivers/dahdi/xpp/astribank_hook.sample (removed): Move + astribank_hook from linux to tools. Install it by default + +2009-04-04 14:22 +0000 [r6325] Tzafrir Cohen + + * Makefile: Also install dahdi_config.h to /usr/include/dahdi + +2009-04-02 20:34 +0000 [r6301-6312] Tzafrir Cohen + + * drivers/dahdi/xpp/astribank_hook.sample: Update the sample udev + astribank_hook for TwinStar + + * drivers/dahdi/xpp/firmwares/PIC_TYPE_3.hex (added), + drivers/dahdi/xpp/xpp.rules, + drivers/dahdi/xpp/firmwares/PIC_TYPE_4.hex (added), + drivers/dahdi/xpp/.version, + drivers/dahdi/xpp/firmwares/FPGA_1161.hex (added), + drivers/dahdi/xpp/firmwares/USB_FW.hex, + drivers/dahdi/xpp/firmwares/Makefile, + drivers/dahdi/xpp/firmwares/PIC_TYPE_1.hex (added), + drivers/dahdi/xpp/firmwares/PIC_TYPE_2.hex (added): XPP: support + for 116x Astribanks. * New software to load in the udev rules * + New control protocol ("MPP") * More modular FPGA firmware From + Xorcom rev. 6963. + + * drivers/dahdi/xpp/xbus-pcm.c: Reduce the rate for a potentially + annoying message This message is used when an xpp span is a DAHDI + sync master but also set to take timing from the DAHDI master. + This means wrong settings: user is wasting CPU cycles. However + notifying the user about it every second is still too much. + +2009-04-02 17:27 +0000 [r6285-6294] Kevin P. Fleming + + * drivers/dahdi/dahdi-base.c: ensure that the structure being + returned by DAHDI_GET_BUFINFO is completely initialized + +2009-03-26 18:33 +0000 [r6262] Wendell Thompson + + * drivers/dahdi/voicebus.c: Fixes DAHDI-214 crash on driver unload. + Affects wcte12xp and wctdm24xxp modules. + +2009-03-24 19:08 +0000 [r6237-6246] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Eliminate unnecessary checks for + NULL before freeing memory. + + * drivers/dahdi/wctc4xxp/base.c: Do not allocate more memory than + is needed when sending packets. + + * drivers/dahdi/wctc4xxp/base.c: Block runt packets from the + transcoder. Tested by: Walter Klomp + + * drivers/dahdi/wctc4xxp/base.c: Do not define the debug flags if + CONFIG_SLUB is not set. Some versions of the kernel + (2.6.18-92.1.22.el5) have patches in them to panic if a slab + cache is created with unsupported flags. + +2009-03-24 15:59 +0000 [r6236] Tzafrir Cohen + + * drivers/dahdi/dahdi-base.c: Make sure the requested echo + canceller name is NULL-terminated. Make sure that the that the + name of the echo canceller requested in the DAHDI ioctl + DAHDI_ATTACH_ECHOCAN is NULL-terminated. + +2009-03-23 23:49 +0000 [r6217-6228] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Verify checksum on the RTP IP + header before queueing. + + * drivers/dahdi/wctc4xxp/base.c: Poll the card in a kernel timer + when several channels are open. Polling the driver increases + overall system throughput when there are several transcoding + channels open by reducing the number of interrupts the the TC400M + generates. + + * drivers/dahdi/wctc4xxp/base.c: Optionally show total number of + packets dropped when channel is closed. + + * drivers/dahdi/wctc4xxp/base.c: Do not handle duplicate reponses. + It is possible for system activity to prevent the wctc4xxp driver + from responding the the firmware on the TC400M for a period of + time. If this occurs, the TC400M will resend a response to a + command that we sent. This duplicate reponse will then sometimes + confuse the driver. Normally this would manifest as an attempt to + connect the same channel together in a transcoding session. + + * drivers/dahdi/wctc4xxp/base.c: Set TX_COMPLETE atomically with + changes to the waiting_for_response_list. This change is to catch + a condition where it is possible, for whatever reason, for a + response to come in before the request is marked tx complete. If + this happened, it was possible to leak the response packet and + double complete the command. + + * drivers/dahdi/wctc4xxp/base.c: split send_trans_connect into a + connect / disconnect pair. Trivial change that makes the code + read more naturally. Also changes the order of members in the + channel_pvt structure. For more natural alignment. Both + non-functional changes. + + * drivers/dahdi/wctc4xxp/base.c: If the driver fails to register, + make sure we cleanup the command cache. + + * drivers/dahdi/wctc4xxp/base.c: Setup the TC400M to poll the own + bit on the descriptor ring. On certain systems having the + hardware poll the descriptor ring provides more reliable + operation that strobbing the transmit demand poll and receive + demand poll register. + + * drivers/dahdi/wctc4xxp/base.c: Make sure that messages sitting in + the outbound queue cause the timer to reschedule. + + * drivers/dahdi/wctc4xxp/base.c: Refactor channel command handling. + Makes commands and reponses clearer and easier to trouble shoot, + reduces pressure on the stack, and brings driver closer to kernel + coding standards. + +2009-03-18 18:48 +0000 [r6201] Jason Parker + + * drivers/dahdi/dahdi_dynamic_loc.c: Fix a typo + +2009-03-17 17:59 +0000 [r6170-6191] Tzafrir Cohen + + * drivers/dahdi/xpp/firmwares/USB_FW.hex: xpp USB_FW.hex rev 6885: + fixes reading label from USB Previous USB_FW.hex, 6770, has + failed to properly read the USB iSerial field ("Label" in xpp + terms). This is fixed here. + + * include/dahdi/dahdi_config.h (added), include/dahdi/kernel.h, + drivers/dahdi/xpp/Kbuild, drivers/dahdi/dahdi-base.c, + drivers/dahdi/dahdi_config.h (removed): Move dahdi_config.h to be + under include/dahdi/ This makes dahdi_config.h part of the + "offcial" interface to external modules. Practically most of its + configuration items are internal to dahdi-base. But some are + intended for other drivers. + + * drivers/dahdi/biquad.h, include/dahdi/kernel.h, + drivers/dahdi/ecdis.h, drivers/dahdi/dahdi-base.c: Make ecdis.h + used by dahdi-base.h alone ecdis.h is no longer #include-d in + kernel.h . it was there because of decleration of some structs + that are part of struct dahdi_chan. The declerations of those + structs were moved into kernel.h directly. + +2009-03-13 10:21 +0000 [r6134-6147] Tzafrir Cohen + + * drivers/dahdi/dahdi-base.c: Fix handling of 'w' in a pulse dial + string Make the special "digit" 'w' work in pulse dialing as it + works with tone dialing (a delay of 0.5 second till the next + digit). Note that the digit gets uppercased before it gets to + this function. (closes issue #13999) Reported by: IgorG Patches: + dahdi-base.c.pulse2.diff uploaded by tzafrir (license 46) Tested + by: litnimax + + * drivers/dahdi/xpp/xpp.conf: A better sample xpp.conf + + * drivers/dahdi/xpp/init_card_3_30, + drivers/dahdi/xpp/init_card_4_30, + drivers/dahdi/xpp/init_card_1_30, + drivers/dahdi/xpp/init_card_2_30: xpp init_card_* scripts now + less verbose * Demote some messages to be debug messages. * + Rephrase the message about defaults for the PRI module (the + driver's defaults are used, which is OK) + + * drivers/dahdi/dahdi-base.c: Fix handling of DAHDI_GETGAINS_V1 + missing from r6124 . + +2009-03-11 14:51 +0000 [r6113-6126] Shaun Ruffell + + * drivers/dahdi/voicebus.c: Allow 10ms for voicebus hardware to + settle after reset. The voicebus hardware needs more time to + settle after a reset. The short settle time explains why there + was frequently one IRQ miss reported in the proc file for the + spans. Reported by: jsloan + + * drivers/dahdi/wct4xxp/base.c: Relax ident wheel requirements. Do + not require the first card to be set to 0 and allow skips in the + ident wheel numbers. The ident wheel allows a user to determine + the order that cards register there spans with DAHDI. (closes + issue #13078) Reported by: opticron Patch by: opticron + + * include/dahdi/user.h, drivers/dahdi/dahdi-base.c: Fix direction + bits on several ioctls. (related to issue #14499) Reported by: ys + + * include/dahdi/kernel.h, drivers/dahdi/dahdi_transcode.c: Keep + transcoders on a list in registration order. This fixes a bug + where it was possible for there to be a transcoder in position + "1" but not in position "0" if a transcoder hardware driver was + loaded, unloaded, and reloaded again without also reloading + dahdi_transcode. The result is that codec_dahdi fails to + enumerate all the transcoders in the system. (closes issue + #14627) Reported by: xblurone + + * drivers/dahdi/dahdi-base.c: Eliminating an unused parameter to + dahdi_specchan_open. + +2009-03-06 21:43 +0000 [r6096] Wendell Thompson + + * drivers/dahdi/xpp/xpp_usb.c, drivers/dahdi/wctc4xxp/base.c, + drivers/dahdi/voicebus.c: Workarounds for SLUB sysfs problems in + kernel 2.6.22 with CONFIG_SLUB and CONFIG_SLUB_DEBUG, as in + Fedora Core 6. Fixes kernel oops when loading/unloading dahdi + modules. DAHDI-226 + +2009-03-05 18:53 +0000 [r6079] Tzafrir Cohen + + * drivers/dahdi/xpp/firmwares/FPGA_1141.hex, + drivers/dahdi/xpp/firmwares/FPGA_1151.hex, + drivers/dahdi/xpp/firmwares/FPGA_FXS.hex: xpp: FPGA firmwares + 6799 New FPGA firmware with a number of bug fixes. + +2009-03-01 13:56 +0000 [r6046] Tzafrir Cohen + + * drivers/dahdi/xpp/init_card_3_30, drivers/dahdi/xpp/xpp_dahdi.c, + drivers/dahdi/xpp/xproto.h, drivers/dahdi/xpp/.version, + drivers/dahdi/xpp/card_fxo.c, drivers/dahdi/xpp/xpp_dahdi.h, + drivers/dahdi/xpp/firmwares/USB_FW.hex, + drivers/dahdi/xpp/xbus-sysfs.c, drivers/dahdi/xpp/xframe_queue.c, + drivers/dahdi/xpp/xbus-core.c, drivers/dahdi/xpp/card_global.c, + drivers/dahdi/xpp/xbus-core.h, drivers/dahdi/xpp/Changelog_xpp, + drivers/dahdi/xpp/card_global.h, drivers/dahdi/xpp/xbus-pcm.c: + New XPP code: xpp rev 6795: * Fix cases where the command_queue + overflowed during initialization. - Also add a + 'command_queue_length' parameter to xpp.ko * More migrations to + sysfs: - Add a 'transport' attribute to our astribank devices + which points to the usb device we use. E.g: + /sys/bus/astribanks/devices/xbus-00/transport is symlinked to + ../../../../../../devices/pci0000:00/0000:00:10.4/usb5/5-4 - Move + /proc/xpp/XBUS-??/XPD-??/span to + /sys/bus/xpds/devices/??:?:?/span - Migrate from /proc/xpp/sync + to: /sys/bus/astribanks/drivers/xppdrv/sync - New 'offhook' + attribute in: /sys/bus/xpds/devices/??:?:?/offhook * PRI: change + the "timing" priority to match the convention used by other PRI + cards -- I.e: lower numbers (not 0) have higher priority. * FXO: + - Power denial: create two module parameters instead of + hard-coded constants (power_denial_safezone, + power_denial_minlen). For sites that get non-standard + power-denial signals from central office on offhook. - Don't + hangup on power-denial, just notify Dahdi and wait for - Fix + caller-id detection for the case central office sends it before + first ring without any indication before. Asterisk's desicion. * + USB_FW.hex: - Fixes cases where firmware loading would fail. + +2009-02-11 05:41 +0000 [r6005] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Use the proper pci_device when + handling dma buffers. + +2009-02-10 14:07 +0000 [r5997] Matthew Fredrickson + + * drivers/dahdi/wcb4xxp/base.c: Set default alarm debounce time to + 500ms to debounce NT L1 deactivations + +2009-02-09 06:03 +0000 [r5987] Tzafrir Cohen + + * drivers/dahdi/xpp/xproto.c: Fix building DAHDI with module + unloading disabled As moduel_refcount is only used for debugging, + disable it in this non-common case. (Closes issue #14402) + +2009-02-02 14:13 +0000 [r5936] Kevin P. Fleming + + * drivers/dahdi/dahdi_echocan_kb1.c, + drivers/dahdi/hpec/dahdi_echocan_hpec.c, include/dahdi/kernel.h, + drivers/dahdi/dahdi_echocan_jpah.c, + drivers/dahdi/dahdi_echocan_mg2.c, + drivers/dahdi/dahdi_echocan_oslec.c, drivers/dahdi/dahdi-base.c, + drivers/dahdi/dahdi_echocan_sec.c, drivers/dahdi/hpec/hpec.h, + drivers/dahdi/dahdi_echocan_sec2.c: Array-style echo canceller + updates first appeared in Zaptel, because HPEC only supports that + mode. However, when the function for doing array-style updates + was written, the argument names were reversed. In Zaptel this did + no harm, because HPEC was the only module that used array-style + updates. When DAHDI was created, non-array-style updates were + removed, and the existing modules were converted to using + array-style updates. Unfortunately the new code was written based + on the argument names, which were incorrect. This caused all the + echo cancellers to be broken (except HPEC, although we did not + know that at the time), and it was corrected by reversing the + order of the arguments passed when the array-style update + function was called (leading to a confusing mismatch). This fixed + all the non-HPEC modules, but left HPEC broken, which was just + discovered. This commit corrects all these problems, so that the + argument names and the data passed actually make sense, and all + the modules work properly. + +2009-01-30 23:42 +0000 [r5924] Matthew Fredrickson + + * drivers/dahdi/wcb4xxp/base.c: Make sure that we pass alarm + notification up the stack whenever alarms occur on the B410P + +2009-01-30 16:53 +0000 [r5916] Mike Spiceland + + * drivers/dahdi/wctdm24xxp/base.c: Do a stricter test for FXS + modules. FXO modules will be hi-z during this time and the value + will be undefined. This test ensures that FXO modules will not + falsely trigger during FXS probes. The value of 0x88 from + register 1 has been confirmed during this stage on quad and + single port modules. + +2009-01-28 23:17 +0000 [r5895] Richard Mudgett + + * include/dahdi/user.h: Minor comment rearangement to avoid + possible confusion. + +2009-01-28 04:41 +0000 [r5870] Shaun Ruffell + + * drivers/dahdi/wcb4xxp/base.c: Ensure the teignorered parameter is + exposed as a module parameter. Related to issue #14031 . + +2009-01-27 Shaun Ruffell + + * dahdi-linux version 2.1.0.4 released. + + * Fix for a kernel panic regression when heavily using pseudo + channels (issue #14183) (merged r5811 and r5819 from the trunk) + + * Fix the safety check in tor2 to be for SPANS_PER_CARD + (issue #13954) (merged r5590 from the trunk). + +2008-12-17 Shaun Ruffell + + * dahdi-linux version 2.1.0.3 released. + +2008-12-17 15:57 +0000 [r5535-5576] Shaun Ruffell + + * drivers/dahdi/wcb4xxp/base.c: Do not propogate received + HDLC frames on channels that are not configured. Issue: DAHDI-217 + + * drivers/dahdi/wcb4xxp/base.c: Use %p to print out pointer values. + + * drivers/dahdi/wcb4xxp/base.c: Remove an endless while loop. + + * drivers/dahdi/wcte12xp/base.c: Quiet some warnings about + possible use of uninitialized variables. + + * build_tools/live_dahdi: live_dahdi: Use the nonrelative path for + the dahdi-tools folder in live_dahdi. + +2008-12-15 Shaun Ruffell + + * dahdi-linux version 2.1.0.2 released. + +2008-12-15 20:31 +0000 [r5534-5535] Shaun Ruffell + + * build_tools/live_dahdi: live_dahdi: Use the nonrelative path for + the dahdi-tools folder in live_dahdi. + + * drivers/dahdi/wcte12xp/base.c: wcte12xp: do not release a + spinlock that we did not acquire. + +2008-12-12 14:32 +0000 [r5523] Kevin P. Fleming + + * drivers/dahdi/dahdi-base.c: use a format string for + request_module, so the compiler will do the right thing + +2008-12-11 Shaun Ruffell + + * dahdi-linux version 2.1.0.1 released. + +2008-12-11 21:46 +0000 [r5509] Shaun Ruffell + + * include/dahdi/kernel.h: Add definition of dev_notice for kernels + < 2.6.17. + +2008-12-11 21:03 +0000 [r5498-5504] Tzafrir Cohen + + * drivers/dahdi/xpp/xbus-sysfs.c: One more place whe + old-but-not-ancient hotplug is used. + + * drivers/dahdi/dahdi_echocan_oslec.c: Send all samples to OSLEC, + rather than just the first. (closes issue #14036) Reported by: + marcotasto Patches: dahdi_echocan_oslec.patch uploaded by + marcotasto (license 635) + + * drivers/dahdi/xpp/xbus-sysfs.c, drivers/dahdi/xpp/xbus-core.h, + drivers/dahdi/xpp/xdefs.h: Add a separate case for hotplug of + kernels <= 2.6.9 . + +2008-12-11 20:19 +0000 [r5497] Shaun Ruffell + + * drivers/dahdi/dahdi_dummy.c: If we're using the + system tick, don't use the hrtimer interface. + +2008-12-11 18:57 +0000 [r5482-5492] Tzafrir Cohen + + * drivers/dahdi/xpp/xbus-sysfs.c: Fix the xpp OLD_HOTPLUG fix. + + * drivers/dahdi/dahdi_dummy.c: Fix building dahdi_dummy for kernels + 2.6.13, 2.6.14: Those kernels don't have RTC yet. + + * drivers/dahdi/wcb4xxp: Yet Another directory in which to ignore + modules.order + + * drivers/dahdi/wcb4xxp/base.c: Remove an include that is not + available before 2.6.15 and is not needed + + * drivers/dahdi/xpp/xbus-sysfs.c, drivers/dahdi/xpp/xbus-core.h: A + bit less maigc with OLD_HOTPLUG_SUPPORT + + * drivers/dahdi/dahdi-base.c: Fixed a typo that broke building + dahdi-base with kernels < 2.6.13 + +2008-12-11 16:43 +0000 [r5481] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Fix compilation issues + on 2.6.15 and below kernels. Thanks tzafrir. + +2008-12-09 Shaun Ruffell + + * dahdi-linux version 2.1.0 released. + +2008-12-09 18:49 +0000 [r5453] Tzafrir Cohen + + * live_dahdi (added): live_dahdi - test dahdi without fully + installing it. + +2008-12-06 22:23 +0000 [r5444] Tzafrir Cohen + + * drivers/dahdi/xpp, drivers/dahdi/wcte12xp, drivers/dahdi, + drivers/dahdi/wct4xxp, drivers/dahdi/wctc4xxp, + drivers/dahdi/wctdm24xxp: Ignore modules.order in modules + directories. + +2008-12-04 20:57 +0000 [r5433-5434] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Fix an erroneous warning and + ensure that the sample size is set correctly when decoding G723 + packets. Issue: DAHDI-198 + + * drivers/dahdi/dahdi_transcode.c: Do not use an already built + channel if the source and destination formats do not match the + formats we want. This fixes a regression introduced by the new + transcoder interface where a translation path from one complex + codec to another can result in garbled audio. + +2008-12-01 17:58 +0000 [r5413-5420] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Service the transmit descriptor + ring before the receive descriptor ring so that commands that are + still sitting on the transmit descriptor ring are not completed + twice. + +2008-11-27 09:59 +0000 [r5397-5403] Tzafrir Cohen + + * Makefile: dahdi-linux: Remove README.Astribank.html generation. + + * drivers/dahdi/xpp/README.Astribank (removed): Moving + README.Astribank to dahdi-tools . + + * drivers/dahdi/xpp/README.Astribank: Fixes and some work in + progress on DAHDI Astribank README. + +2008-11-25 20:00 +0000 [r5384] Shaun Ruffell + + * drivers/dahdi/wcte11xp.c, drivers/dahdi/wct1xxp.c: Validate the + timing priority on the wcte11xp and wct1xxp driver. + +2008-11-25 Shaun Ruffell + + * dahdi-linux version 2.1.0-rc5 released. + +2008-11-25 20:00 +0000 [r5383-5384] Shaun Ruffell + + * drivers/dahdi/wcte11xp.c, drivers/dahdi/wct1xxp.c: Validate the + timing priority on the wcte11xp and wct1xxp driver. + + * drivers/dahdi/tor2.c: Validate that the span priority is valid in + the tor2 driver. Patch provided by tzafrir. + +2008-11-24 05:32 +0000 [r5367-5374] Shaun Ruffell + + * drivers/dahdi/wcb4xxp/base.c: Additional debugging code. Patch + provided by akohlsmith. Issue DAHDI-173. + + * drivers/dahdi/wcb4xxp/base.c: Add a 'spanfilter' module parameter + in order to isolate debugging information to just the spans of + interest. Patch provided by akohlsmith. Issue DAHDI-173. + + * drivers/dahdi/wcb4xxp/base.c, drivers/dahdi/wcb4xxp/wcb4xxp.h: + Use counter of pending HDLC frames in order to eliminate the need + to send a zero-byte frame to kick start the transmission process. + Patch provided by akohlsmith. Issue DAHDI-173. + + * drivers/dahdi/wcb4xxp/base.c, drivers/dahdi/wcb4xxp/wcb4xxp.h: Do + not make assumptions about the number of ready HDLC frames on + HDLC RX interrupt. This prevents libpri from becoming confused + when many HDLC frames arrive before the driver can service them + or a false RX interrupt is received. Patch provided by akolsmith. + Issue DAHDI-173. + +2008-11-21 20:15 +0000 [r5360] Jason Parker + + * drivers/dahdi/dahdi-base.c: Fix a think-o in numeric comparison. + Swap order to make it more clear. (closes issue #13813) Reported + by: ys + +2008-11-21 04:42 +0000 [r5350-5355] Shaun Ruffell + + * drivers/dahdi/dahdi-base.c: Convert some uses of sprintf to + snprintf in dahdi_proc_read in order to eliminate a buffer + overrun. Issue: DAHDI-209 + + * drivers/dahdi/wcb4xxp/base.c: Force the FIFO to reset when the + file handle is closed. Patch provided by akohlsmith. Issue: + DAHDI-178 + +2008-11-20 12:31 +0000 [r5340-5345] Tzafrir Cohen + + * drivers/dahdi/tor2.c: Make tor2 load properly. Seems to fix + #13487. Thanks to heyuqi for the testing. + + * drivers/dahdi/xpp/README.Astribank: * Some extrra Zap->DAHDI (and + Dahdi->DAHDI) fixes in the Astribank README. * Some extra + asciidoc formatting fixes. + +2008-11-19 21:25 +0000 [r5335] Kevin P. Fleming + + * drivers/dahdi/wcb4xxp/Makefile (added): support wcb4xxp build on + kernels that don't directly use Kbuild + +2008-11-17 18:17 +0000 [r5321] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: - Fix for race condition of + encoder and decoder are allocated at the same time in the driver. + This would result in -EBUSY returns from the DAHDI_TC_ALLOCATE + ioctl. - Increase the length of the receive descriptor ring from + 8 to 32 to reduce the probability of running out of receive + descriptors. + +2008-11-17 Shaun Ruffell + + * dahdi-linux version 2.1.0-rc4 released. + +2008-11-17 18:17 +0000 [r5321] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: - Fix for race condition of + encoder and decoder are allocated at the same time in the driver. + This would result in -EBUSY returns from the DAHDI_TC_ALLOCATE + ioctl. - Increase the length of the receive descriptor ring from + 8 to 32 to reduce the probability of running out of receive + descriptors. + +2008-11-17 18:01 +0000 [r5320] Tzafrir Cohen + + * drivers/dahdi/xpp/init_card_4_30, drivers/dahdi/xpp/card_pri.c: + xpp_pri: Fix T1 CRC initialization Clock synchronization when + sync is not from first port. + +2008-11-17 17:44 +0000 [r5315] Shaun Ruffell + + * drivers/dahdi/wcb4xxp/base.c, drivers/dahdi/wcb4xxp/wcb4xxp.h: A + fix for an issue with corruption on the D-Channels. Patch + provided by akohlsmith. Issue: DAHDI-173. + +2008-11-16 19:30 +0000 [r5310] Tzafrir Cohen + + * drivers/dahdi/xpp/firmwares/USB_FW.hex: Fixed USB firmware that + caused some bad bioses to hang on boot. The BIOSes included in a + number of motherboards could hang from an Astribank firmware + newer than 1.2.20.1 / 1.4.5.1 . This was due to an some incorrect + USB information in the firmware. This firmware fixes it. Merged + Zaptel revisions 4580 via svnmerge from + http://svn.digium.com/svn/zaptel/branches/1.2 + +2008-11-13 22:10 +0000 [r5303] Shaun Ruffell + + * drivers/dahdi/wcte12xp/base.c, drivers/dahdi/wctdm24xxp/base.c, + drivers/dahdi/voicebus.c, drivers/dahdi/voicebus.h: Make a + message about the host cacheline size being unsupported a debug + only message. The voicebus interface still works whether the + cacheline size is supported or not, but the message is confusing + to users. + +2008-11-10 20:37 +0000 [r5288] Tzafrir Cohen + + * drivers/dahdi/xpp/init_card_2_30: xpp init_card_2_30: no need to + check environment in verify mode. Fixes #13832 in Zaptel. + +2008-11-10 Shaun Ruffell + + * dahdi-linux version 2.1.0-rc3 released. + +2008-11-10 19:48 +0000 [r5275] Shaun Ruffell + + * drivers/dahdi/wcte12xp/base.c, drivers/dahdi/dahdi-base.c: - Do + not hold any locks while calling close_channel, which can result + in calls to the echocan modules which do not necesarrily assume + they are being called in atomic context. - Remove the bigzaplock + around calls to psuedo_alloc and pseudo_free. The structures + protected by this lock are already protected by the chan_lock in + these two cases. - Remove calls to in_atomic() that were + previously added to work around this, but did not cover all the + cases. Issue: DAHDI-195, DAHDI-170 + +2008-11-09 00:33 +0000 [r5269-5270] Sean Bright + + * drivers/dahdi/dahdi-base.c: We only use print_debug_writebuf when + CONFIG_DAHDI_NET or CONFIG_DAHDI_PPP are defined, so only define + it in those cases as well. Reported & Tested by: KP7 via + #asterisk-dev + + * drivers/dahdi/dahdi-base.c: Add missing semi-colon. Reported & + Tested by: KP7 via #asterisk-dev + +2008-11-05 23:45 +0000 [r5249-5257] Shaun Ruffell + + * drivers/dahdi/wcb4xxp/base.c: Whitespace changes for the coding + standard. + + * drivers/dahdi/wcb4xxp/base.c: rate limiting a diagnostic printk. + +2008-11-05 Shaun Ruffell + + * dahdi-linux version 2.1.0-rc2 released. + +2008-11-05 20:17 +0000 [r5230-5237] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Fix warning messages in order to + build on 2.6.27. (Closes issue #13757) Patch provided by tzafrir. + + * drivers/dahdi/wcte12xp/vpmadt032.c, + drivers/dahdi/wctdm24xxp/GpakCust.c: Check the return value of + the down_interruptible call in order to quiet a warning. This + semaphore does not protect any host data structures, but only + accesses to the VPMADT032 module. The worse thing that could + happen is that the internal state of the VPM module is corrupted, + and then would only happen on module loading because otherwise + access because that is the only time this function is called in + the context of a user process. In this case, the module would + need to be reloaded again anyway. (Closes issue #13742) Reported + by smurfix + + * drivers/dahdi/wcb4xxp/base.c: Remove the loopback module + parameter since it's not implemented yet. + + * drivers/dahdi/wcb4xxp/base.c: Allow the wcb4xxp to take all the + signalling types. + +2008-11-03 Shaun Ruffell + + * dahdi-linux version 2.1.0-rc1 released. + +2008-11-03 12:01 +0000 [r5203-5211] Tzafrir Cohen + + * drivers/dahdi/dahdi_dummy.c: Adjust DAHDI to the new timers + interface of kernel 2.6.28 + + * drivers/dahdi/dahdi-base.c: dahdi-base: hw_echocancel_off: return + 0 if no hardware EC If the span has no hardware EC, return 0, + rather than a random uninitialized value (which was no harm, as + that return value is always ignored anyway). + + * README: README: no need to generate Kbuild for OSLEC. No need to + create a Kbuild file. staging/echo has a Makefile that works fine + for us. + +2008-10-31 22:23 +0000 [r5196] Shaun Ruffell + + * drivers/dahdi/wcb4xxp/base.c: Changing the spantype to indicate + whether it is a TE or NT BRI port. + +2008-10-31 21:33 +0000 [r5195] Matthew Fredrickson + + * drivers/dahdi/wcb4xxp/base.c: Fix the FIFO configuration to use + the data from the EC correctly + +2008-10-31 21:05 +0000 [r5190-5191] Tzafrir Cohen + + * drivers/dahdi/wcb4xxp/base.c: wcb4xxp: Set the spantype to "BRI" + (to show e.g. in dahdi_scan) + + * drivers/dahdi/wcb4xxp/base.c: wcb4xxp: Claim to provide DACS for + dahdi_scan dahdi_scan can tell that a span is digital if its + first channel has DACS signalling capability. While this is + probably not supported by the current driver, it is also + harmless. Without this, dahdi_scan shows the spans of this card + as analog. (Done after consulting with sruffel) + +2008-10-31 17:11 +0000 [r5186] Shaun Ruffell + + * drivers/dahdi/wcb4xxp/base.c: Fix for a case where a span might + not always come back up after a disconnect. Patch provided by + akohlsmith. Issue: DAHDI-174 + +2008-10-30 19:16 +0000 [r5179-5180] Tzafrir Cohen + + * drivers/dahdi/dahdi-base.c: Use correct length for the, well, + dahdi transcoder device name. + + * drivers/dahdi/dahdi-base.c: Use ! to hint udev about directory + separator. Udev knows how to convert a '!' in the device name to + a directory separator. Thus the name 'dahdi!ctl' will create the + device /dev/dahdi/ctl . We still keep older udev rules in this + release for compatibility, but eventually we'll only need them to + set permissions. + +2008-10-29 16:48 +0000 [r5171-5175] Shaun Ruffell + + * drivers/dahdi/wcb4xxp/base.c: The /proc/wcb4xxp should not be + created once for each card but rather once for all cards. + + * drivers/dahdi/wcb4xxp/base.c: By default, do not create the + procfs entry for the wcb4xxp driver. + +2008-10-29 15:09 +0000 [r5167] Tzafrir Cohen + + * drivers/dahdi/xpp/xbus-core.c: xpp: Increase the maximal size of + the command queue to 500 . Temporarily increase the maximal size + of the command queue from 300 to 500 as a workaround of an issue + at initialization time (mainly of BRI+FXS). + +2008-10-28 21:59 +0000 [r5156-5163] Kevin P. Fleming + + * drivers/dahdi: update to latest octasic_api tag with NULL + definition fix + + * drivers/dahdi/tor2.c, drivers/dahdi/wcfxo.c, + drivers/dahdi/wcte12xp/base.c, drivers/dahdi/wcte12xp/GpakApi.c, + drivers/dahdi/pciradio.c, drivers/dahdi/wct4xxp/base.c, + drivers/dahdi/wcte12xp/vpmadt032.c, + drivers/dahdi/wctc4xxp/base.c, drivers/dahdi/dahdi_echocan_mg2.c, + drivers/dahdi/wctdm24xxp/base.c, + drivers/dahdi/wctdm24xxp/GpakApi.c, + drivers/dahdi/wcte12xp/vpmadt032.h, + drivers/dahdi/wctdm24xxp/GpakCust.c, + drivers/dahdi/wcb4xxp/base.c, drivers/dahdi/dahdi_dynamic_loc.c, + drivers/dahdi/dahdi_transcode.c, drivers/dahdi/wcte11xp.c, + drivers/dahdi/dahdi_dynamic.c, drivers/dahdi/dahdi_dynamic_eth.c, + drivers/dahdi/wct1xxp.c, drivers/dahdi/wctdm.c, + drivers/dahdi/wcb4xxp, drivers/dahdi/voicebus.c, + drivers/dahdi/dahdi-base.c, drivers/dahdi/dahdi_dummy.c: fix a + large number of warnings found by sparse, the kernel code sanity + checking tool. some of these fixes are non-optimal (casting + 'unsigned long' to '__user void *'), but are unavoidable in many + cases. started from tzafrir's patch, did most of the work myself. + (closes issue #13763) Reported by: tzafrir Patches: + sparse_fixes_1.diff uploaded by tzafrir (license 46) + + * README: various cleanups, primarily proper capitalization + +2008-10-28 18:26 +0000 [r5148-5150] Shaun Ruffell + + * drivers/dahdi/wcb4xxp/Kbuild (added), drivers/dahdi/Kbuild, + drivers/dahdi/wcb4xxp/base.c (added), drivers/dahdi/wcb4xxp + (added), drivers/dahdi/wcb4xxp/wcb4xxp.h (added), README: Adding + the wcb4xxp driver, a native dahdi driver for the B410P module. + +2008-10-27 19:27 +0000 [r5127-5138] Tzafrir Cohen + + * README: dahdi linux README: Clarify OSLEC EC build procedure. + + * drivers/dahdi/xpp/card_fxo.c: xpp fxo: Add sysfs battery + attribute. + + * drivers/dahdi/xpp/xpp_dahdi.c, drivers/dahdi/xpp/xbus-core.c, + drivers/dahdi/xpp/xbus-core.h: xpp: remove an unused manual + reference count field. + + * drivers/dahdi/xpp/xpp_dahdi.c, drivers/dahdi/xpp/xbus-sysfs.c: + xpp: Make some definitions static, as per sparse. Fixes the xpp + warnings of #13763 (except some false alarms). + + * drivers/dahdi/xpp/card_pri.c, drivers/dahdi/xpp/card_bri.c, + drivers/dahdi/xpp/card_fxo.c, drivers/dahdi/xpp/xbus-sysfs.c, + drivers/dahdi/xpp/card_fxs.c, drivers/dahdi/xpp/xbus-core.h, + drivers/dahdi/xpp/xdefs.h: Fix xpp compile problems on kernel < + 2.6.16 Support for kernels that use the older hotplug support + rather than the newer uevent. Fixes the xpp issue from #13427. + + * include/dahdi/kernel.h: kernel.h: cleanup DAHDI_FLAG_* defines, + no functional change. Define the DAHDI_FLAG_* using the + DAHDI_FLAGBIT_* enum values. + +2008-10-22 18:49 +0000 [r5121-5124] Jason Parker + + * build_tools/genudevrules: Need to make sure we check for udevadm + in addition to udevinfo. Some silly person (or people) decided + that it wasn't useful to have in their distro... *cough* + + * drivers/dahdi/wctdm.c: Fix building on big endian machines. + (closes issue #13754) Reported by: shrift Patches: + wctdm-powerpc.patch uploaded by irroot (license 52) Tested by: + shrift + +2008-10-22 11:44 +0000 [r5105-5118] Tzafrir Cohen + + * drivers/dahdi/wct1xxp.c: wct1xxp: fix error handling at device + startup. And also give more useful error messages if things go + bad. (closes issue #13607) Patches: wct1xxp_pci.diff uploaded by + tzafrir (license 46) Tested by: klaus3000 + + * drivers/dahdi/xpp/init_card_1_30: xpp FXS init script: Do use + high-pass filter. + + * drivers/dahdi/Kbuild, drivers/dahdi/dahdi_echocan_oslec.c + (added), README: An experimental OSLEC echocan module. + + * /: dahdi-trunk: ignore the generated README.html . + + * README: dahdi-linux README: better place for build requirements. + (We'll have to put a content there one of these days) + + * README: Fix headers numbering. + +2008-10-16 17:40 +0000 [r5097] Tzafrir Cohen + + * drivers/dahdi/xpp/xpp.rules, drivers/dahdi/xpp/xpp_usb.c, + drivers/dahdi/xpp/card_pri.c, drivers/dahdi/xpp/card_fxo.c, + drivers/dahdi/xpp/xframe_queue.c, drivers/dahdi/xpp/xbus-sysfs.c, + drivers/dahdi/xpp/Kbuild, drivers/dahdi/xpp/card_fxs.c, + drivers/dahdi/xpp/card_global.c, drivers/dahdi/xpp/xproto.c, + drivers/dahdi/xpp/xframe_queue.h, + drivers/dahdi/xpp/astribank_hook.sample (added), + drivers/dahdi/xpp/init_card_1_30, drivers/dahdi/xpp/xbus-pcm.c, + drivers/dahdi/xpp/init_card_2_30, + drivers/dahdi/xpp/card_global.h, + drivers/dahdi/xpp/init_card_3_30, drivers/dahdi/xpp/xproto.h, + drivers/dahdi/xpp/xpp_dahdi.c, drivers/dahdi/xpp/xpd.h, + drivers/dahdi/xpp/init_card_4_30, drivers/dahdi/xpp/xpp_dahdi.h, + drivers/dahdi/xpp/card_bri.c, drivers/dahdi/xpp/mmapdrv.c, + drivers/dahdi/xpp/xbus-core.c, drivers/dahdi/xpp/xbus-core.h, + drivers/dahdi/xpp/xdefs.h: xpp: start migration from procfs to + sysfs. * Sysfs representation for XPDs: + /sys/bus/xpds/devices/:: * Astribanks sysfs + directories now include the XPDs as subdirectories: e.g. + /sys/bus/astribanks/devices/xbus-00/00:3:0 * procfs control + interface deprecated: conditioned by OLD_PROC (defaults to off). + Control functionality moved to sysfs: * xbus attributes: cls + connector label status timing waitfor_xpds xbus_state * XPDs can + have driver-specific attributes. Common attriubtes: blink + chipregs span * PRI-specific attributes: pri_clocking pri_dchan + pri_cas pri_alarms pri_layer1 pri_localloop pri_protocol * The + Astribank attribute "xbus_state" is read/write. Reading it shows + the current state of the Astribank. Writing "start" or "stop" + allows a software equivalent of connect or disconnect + respectively. * When an Astribank is ready it sends an "online" + event. Whenever its not ready (e.g. at the time of disconnect) it + sends an "offline" event. Use astribank_hook.sample to handle + those. + +2008-10-14 22:11 +0000 [r5090] Shaun Ruffell + + * drivers/dahdi/wcte12xp/base.c: If the vpmadt032 firmware needs to + be reloaded, make sure we use the same slot in the ifaces array. + +2008-10-10 22:38 +0000 [r5084] Shaun Ruffell + + * drivers/dahdi/dahdi_transcode.c, drivers/dahdi/wctc4xxp/base.c: - + Ensure that the source format is considered when selecting a + transcoder. - When a command is to be retried, turn off the + TX_COMPLETE flag before resubmitting it to the hardware. This + should elimate some of the warnings printed to the kernel log in + the wctc4xxp_transmit_cmd function. + +2008-10-09 02:54 +0000 [r5068] Kevin P. Fleming + + * drivers/dahdi/dahdi-base.c: a micro-optimization found while + creslin and i spent four or five hours tracking down a very + complex problem + +2008-10-06 20:52 +0000 [r5064] Kevin P. Fleming + + * drivers/dahdi/dahdi-base.c: use the same logic here as elsewhere + for releasing echocan module references + +2008-10-06 17:48 +0000 [r5060] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Embed room for the complete packet + to the DTE in the transcoder buffer structure. Simplifies + alignment management at the cost of a little wasted memory, but + the end results is that operation is more reliable on more + systems. + +2008-10-06 16:55 +0000 [r5056] Sean Bright + + * drivers/dahdi/dahdi-base.c: Fix a few compile errors that only + show up when CONFIG_DAHDI_PPP is defined. (closes issue #13608) + Reported by: Nik Soggia Fix suggested by: Nik Soggia Tested by: + seanbright + +2008-10-03 20:32 +0000 [r5046-5051] Tzafrir Cohen + + * drivers/dahdi/dahdi-base.c: Fix building with CONFIG_DAHDI_NET in + kernel 2.6.22 The leftovers of issues #13542 (which was mostly + resolved in previous committ. This closes it. + + * drivers/dahdi/dahdi-base.c: Fix building with CONFIG_DAHDI_NET . + It builds, but will it run? Patch dahdi-base.c.hdlc.patch by + biohumanoid that fixes some aparant copy&paste errors. + +2008-10-03 20:09 +0000 [r5045] Sean Bright + + * drivers/dahdi/dahdi-base.c, drivers/dahdi/dahdi_config.h: Fix + some compilation problems that show up when CONFIG_DAHDI_DEBUG is + defined. + +2008-10-03 15:39 +0000 [r5021-5034] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: There are two possible valid + statues when booting the TC400M. + + * drivers/dahdi/wctc4xxp/base.c: Keep hold of the channel lock when + setting the data_ready flag for the channel after writing to the + receive queue. Prevents a warning that data was on the recieve + queue but the data ready flag was not set. Issue: DAHDI-42 + + * drivers/dahdi/wctc4xxp/base.c: wctc4xxp_cleanup_channel_private + needs a pointer to the zt_transcoder_channel and not just the + private portion now in order to manage the data ready flag state. + + * drivers/dahdi/wctc4xxp/base.c: Mark that there is not any data + waiting whenever we cleanup the private channel structures. + Issue: DAHDI-42 + + * drivers/dahdi/dahdi-base.c: DAHDI should always make data + received from the PSTN available to user mode immediately. Only + allow the transmit buffering policy to be changed in order to + reduce the chance of underruns to the PSTN. + +2008-09-30 20:29 +0000 [r5017] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Removing references to setup_timer + in pre 2.6.18 kernels. + +2008-09-29 Shaun Ruffell + + * dahdi-linux 2.0.0 released. + +2008-09-28 17:29 +0000 [r5002-5007] Shaun Ruffell + + * drivers/dahdi/wctdm.c: Improve reliablity of UK caller ID for the + TDM400P by not allowing the ringdebounce to be decremented when + it is at 0 already. Related to issue #12531. Reported mattbrown, + fix suggested by benbrown. + + * drivers/dahdi/wcte12xp/base.c: Fixed type of flags parameter to + spin_lock_irqsave functions. Fixes compilation issues on + platforms where int and long do not have the same size. Closes + Issues #0013575. Reported by Ulmo. + + * drivers/dahdi/dahdi_echocan_kb1.c, + drivers/dahdi/dahdi_echocan_mg2.c, drivers/dahdi/dahdi-base.c, + drivers/dahdi/dahdi_echocan_sec.c, + drivers/dahdi/dahdi_echocan_sec2.c: Fixes failure of modular echo + cancelers in DAHDI. Reported by lots of people, fix suggested by + mattf. + +2008-09-26 03:20 +0000 [r4990] Shaun Ruffell + + * drivers/dahdi/dahdi-base.c: The channel master should not be set + to 0, but rather should be 'cleared' by setting the channel to be + it's own master. (related to issue 11611) + +2008-09-25 16:50 +0000 [r4979-4986] Tzafrir Cohen + + * drivers/dahdi/xpp/firmwares/FPGA_1151.hex: XPP firmware: Only + send out CAS D-channel messages when in CAS mode. + + * drivers/dahdi/xpp/init_card_3_30, + drivers/dahdi/xpp/card_global.c, + drivers/dahdi/xpp/init_card_1_30, + drivers/dahdi/xpp/init_card_2_30: Fix display of indirect + registers and streamline their setting. * This commit fixes + display of indirect registers through the chipregs (formly + "slics") procfs file. Only the low byte was displayed. * It also + deprecates previous {RW}S in favour of {RW}I. The prevois style + is still allowed but deprecated, and thus previous scripts will + still work. + + * drivers/dahdi/xpp/card_fxo.c: XPP FXO: Add caller-id workaround + for ESTI-DTMF (for #9096) * Also rename the CID_STYLE_* constants + to formal names. + +2008-09-24 06:15 +0000 [r4971] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Adding back in the mode module + parameter for the wctc4xxp driver. This is primarily used to + increase the number of channels available when only transcoding + to/from g729 by setting it to 'g729'. + +2008-09-18 21:23 +0000 [r4957] Shaun Ruffell + + * drivers/dahdi/wcte12xp/base.c: Adding a needed header for the + in_atomic call. + +2008-09-18 21:23 +0000 [r4956-4957] Shaun Ruffell + + * drivers/dahdi/wcte12xp/base.c, drivers/dahdi/dahdi-base.c: + close_channel is called with a spin_lock held, which means that + GFP_KERNEL can not be used for the memory allocations down that + call path. Have allocations in this call path check if they are + in atomic context and use the appropriate flags. Issue: DAHDI-195 + +2008-09-17 19:07 +0000 [r4917-4930] Shaun Ruffell + + * README: Just moved a note into it's own paragraph so that + asciidoc can make the appropriate callout. + + * README: Added a note about installing support for the B410P in + the installation section of the README file. + + * drivers/dahdi/dahdi-base.c: Turn off reference counting on the + echo canceller modules in order to prevent misconfigurations from + preventing the drivers from unloading. NOTE: This is only a + temporary workaround, since it also means that the echocanceller + can be unloaded by an administrator while in use, which would + most likely result in a kernel oops. Related to issue #13504. + +2008-09-15 20:49 +0000 [r4905-4909] Shaun Ruffell + + * drivers/dahdi/wctdm.c, drivers/dahdi/dahdi-base.c: Edit some + comments and error strings. Issue: DAHDI-13 + + * drivers/dahdi/wcte12xp/vpmadt032.c, + drivers/dahdi/wctdm24xxp/base.c: Fixed two typos. + +2008-09-11 23:00 +0000 [r4894-4900] Tzafrir Cohen + + * drivers/dahdi/dahdi-base.c: Fix a type used in nethdlc mode, as + pointed out in #13427 . + + * drivers/dahdi/xpp/xpp.rules (added), Makefile: Move udev rules + xpp.rules from dahdi-tools to dahdi-linux . + +2008-09-08 Russell Bryant + + * dahdi-linux version 2.0.0-rc4 released. + +2008-09-06 20:27 +0000 [r4868-4870] Matthew Fredrickson + + * drivers/dahdi/dahdi-base.c: Fix buglet in #define for 2.6.9 + + * drivers/dahdi/wct4xxp/base.c: Revert unnecessary default hardhdlc + mode from 56K to 64K + + * drivers/dahdi/wct4xxp/base.c, drivers/dahdi/dahdi-base.c: Fix + class_simple on old 2.6.9 kernels + +2008-09-04 21:42 +0000 [r4865] Matthew Fredrickson + + * include/dahdi/fasthdlc.h: Some picky switches require the LSB to + be 1 for 56k links + +2008-09-04 21:29 +0000 [r4861-4864] Shaun Ruffell + + * drivers/dahdi/wct4xxp/base.c: Remove a couple of 'magic numbers' + to make it clear all the ports of the framer should be + configured. + + * drivers/dahdi/wct4xxp/base.c: Fixes an issue where the dual-span + cards are not properly configured which can cause data loss. Fix + provided by opticron and possibly related to issue #0013393. + +2008-08-29 21:46 +0000 [r4856] Matthew Fredrickson + + * drivers/dahdi/dahdi-base.c: Remove useless kzalloc + +2008-08-27 17:12 +0000 [r4848-4849] Kevin P. Fleming + + * drivers/dahdi/dahdi_dummy.c: remove some more ztdummy references + + * drivers/dahdi/wcfxo.c, drivers/dahdi/wcte12xp/base.c, + drivers/dahdi/wct4xxp/base.c, drivers/dahdi/wcte11xp.c, + drivers/dahdi/wct1xxp.c, drivers/dahdi/wctc4xxp/base.c, + drivers/dahdi/wctdm.c, drivers/dahdi/wctdm24xxp/base.c, README: a + bit of attribution cleanup + +2008-08-27 16:48 +0000 [r4847] Jason Parker + + * Makefile: Set a list of headers to install/uninstall, so the + lists don't get out of sync (note the previously missing + fasthdlc.h in the uninstall-include target) + +2008-08-26 13:04 +0000 [r4829-4841] Tzafrir Cohen + + * Makefile: "docs" target to generate documentation. Generate docs + with asciidoc. + + * drivers/dahdi/xpp/README.Astribank: Fix asciidoc. + + * Makefile: Don't try to clean modules if there's no kernel source + available (like in Zaptel). + + * README: Reverting unwanted changes in the README (from r4830) + Also fixed ZT references in the ABI compatibility section. The + numerical ioctl values need to be recalculated, though. + + * README: Make the README file more relevant to modules. + + * drivers/dahdi/Kbuild, Makefile: Support MODULES_EXTRA and + SUBDIRS_EXTRA to add extra modules from the make command line. + +2008-08-25 17:50 +0000 [r4828] Jason Parker + + * Makefile: Make sure we remove headers that we installed in + install-include + +2008-08-25 14:54 +0000 [r4823] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Remove this warning, which could + occur if the driver is loaded on a system without a wctc4xxp, and + then subsequently unloaded. + +2008-08-24 05:53 +0000 [r4817] Matthew Fredrickson + + * include/dahdi/user.h, include/dahdi/kernel.h, + drivers/dahdi/dahdi-base.c, include/dahdi/fasthdlc.h: Add support + for 56 KB HDLC as well as selectable rate via ioctl + +2008-08-20 22:20 +0000 [r4805] Kevin P. Fleming + + * drivers/dahdi/dahdi_dynamic.c: use the new separate allocation + method for channel structures here too replace "ZTD" references + in channel/span names with "DYN" (closes issue #13302) Reported + by: KNK + +2008-08-20 Kevin P. Fleming + + * dahdi-linux version 2.0.0-rc3 released. + +2008-08-20 22:20 +0000 [r4801-4805] Kevin P. Fleming + + * drivers/dahdi/dahdi_dynamic.c: use the new separate allocation + method for channel structures here too replace "ZTD" references + in channel/span names with "DYN" (closes issue #13302) Reported + by: KNK + + * drivers/dahdi/dahdi_dynamic.c: update code to match version in + Zaptel + + * drivers/dahdi/xpp/xpd.h, drivers/dahdi/wctdm24xxp/wctdm24xxp.h, + drivers/dahdi/wcte12xp/vpmadt032.c, + drivers/dahdi/wctdm24xxp/base.c, + drivers/dahdi/wctdm24xxp/GpakApi.c, drivers/dahdi/dahdi-base.c, + drivers/dahdi/wctdm24xxp/GpakCust.c: improve compatibility with + 2.6.26 and 2.6.27 kernels (closes issue #13253) Reported by: + raiden Patches: zap-dev.patch uploaded by smurfix on issue #13277 + (license 547) zap-sema.patch uploaded by smurfix on issue #13277 + (license 547) + +2008-08-20 19:31 +0000 [r4798] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Change to support both 5.3kbps and + 6.3kbps bit rates when using the G723.1 codec. + +2008-08-19 20:49 +0000 [r4795] Kevin P. Fleming + + * drivers/dahdi/firmware/Makefile: port over improvements to + firmware Makefile from Zaptel + +2008-08-19 20:25 +0000 [r4791-4794] Shaun Ruffell + + * drivers/dahdi/wctc4xxp/base.c: Fixed calculation of the + timestamp. + + * include/dahdi/kernel.h, drivers/dahdi/dahdi_transcode.c, + drivers/dahdi/wctc4xxp/base.c: Couple of fixes for the + transcoder: - In dahdi_transcode.c, Embed the identifiation + number, assigned sequentially when the transcoders are + registered, in the transcoder structure. This allows + DAHDI_TC_GETINFO to work as expected even though the transcoders + are rotated on the list in order to spread the load. - In + wctc4xxp, fix bug where all transcoders are named tc400b0. + +2008-08-18 23:24 +0000 [r4788] Kevin P. Fleming + + * Makefile: minor cleanups, and allow DAHDI_BUILD_ALL to be + overriden on the command line + +2008-08-14 21:37 +0000 [r4776-4784] Tzafrir Cohen + + * drivers/dahdi/xpp/.version, drivers/dahdi/xpp/Changelog_xpp: Set + xpp version to 6056 and reset XPP changelog. + + * drivers/dahdi/xpp/firmwares/Makefile (added), Makefile: Also + install Astribank firmwares and init scripts to /usr/share/dahdi + . + + * drivers/dahdi/xpp/card_fxo.c: xpp: FXO: display signed voltage + values (from xpp r6055) This is only an issue with the displayed + value. In case you wondered why you have battery voltage of more + than 220V. + +2008-08-14 01:09 +0000 [r4773] Kevin P. Fleming + + * drivers/dahdi/dahdi_transcode.c: remove devfs support, and use + consistent include file path + +2008-08-13 21:04 +0000 [r4770] Doug Bailey + + * drivers/dahdi/wctdm24xxp/wctdm24xxp.h, + drivers/dahdi/wctdm24xxp/base.c: import the neon mwi detection + +2008-08-11 16:22 +0000 [r4758-4761] Tzafrir Cohen + + * drivers/dahdi/xpp/card_pri.c, drivers/dahdi/xpp/card_bri.c, + drivers/dahdi/xpp/firmwares/FPGA_1151.hex, + drivers/dahdi/xpp/xbus-core.c, drivers/dahdi/xpp/card_global.c, + drivers/dahdi/xpp/xbus-pcm.c: xpp: CAS/E1 support in the PRI + module, and minor fixes. * Add support for CAS in the PRI module. + Use firmware rev. 5975. * Debugging parameter pcmtx_chan now + accepts a dahdi channel number. * Do initialize a reserved + protocol field (card_global). * The name DAHDI as used in + proc/xpp/sync has 5 (not 6) letters. * Fix DTMF "channel leak" + regression in the FXS module. + + * drivers/dahdi/xpp/card_fxo.c: xpp: fxo: Fix support for + CID_STYLE_PASS_ALWAYS + + * drivers/dahdi/xpp/Kbuild: A more robust test for bri_dchan + support. + + * drivers/dahdi/xpp/xpd.h, drivers/dahdi/xpp/xpp_dahdi.c: xpp_blink + is a bit mask of ports, and not boolean anymore. + +2008-08-08 Kevin P. Fleming + + * dahdi-linux version 2.0.0-rc2 released. + +2008-08-07 20:21 +0000 [r4742] Shaun Ruffell : + + * drivers/dahdi/dahdi_transcode.c: Make sure types are same size on + 64-bit machines. + +2008-08-06 Kevin P. Fleming + + * dahdi-linux version 2.0.0-rc1 released. diff -Nru dahdi-linux-2.2.1-rc2/dkms.conf dahdi-cnet-linux-2.2.1-rc2/dkms.conf --- dahdi-linux-2.2.1-rc2/dkms.conf 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/dkms.conf 2010-01-09 21:29:01.955618012 -0600 @@ -0,0 +1,108 @@ +# dkms.conf for dahdi-cnet-linux +PACKAGE_VERSION="2.2.1-rc2" +PACKAGE_NAME="dahdi-cnet-linux" +AUTOINSTALL="yes" +MAKE[0]="KVERS=$kernelver make" +CLEAN="make clean" + +BUILT_MODULE_NAME[0]="dahdi_dynamic_loc" +BUILT_MODULE_NAME[1]="wct1xxp" +BUILT_MODULE_NAME[2]="tor2" +BUILT_MODULE_NAME[3]="dahdi_dummy" +BUILT_MODULE_NAME[4]="wcb4xxp" +BUILT_MODULE_NAME[5]="dahdi_transcode" +BUILT_MODULE_NAME[6]="wcfxo" +BUILT_MODULE_NAME[7]="wctdm24xxp" +BUILT_MODULE_NAME[8]="wcte11xp" +BUILT_MODULE_NAME[9]="dahdi_echocan_jpah" +BUILT_MODULE_NAME[10]="dahdi" +BUILT_MODULE_NAME[11]="dahdi_echocan_oslec" +BUILT_MODULE_NAME[12]="dahdi_voicebus" +BUILT_MODULE_NAME[13]="xpp" +BUILT_MODULE_NAME[14]="xpd_bri" +BUILT_MODULE_NAME[15]="xpd_fxo" +BUILT_MODULE_NAME[16]="xpp_usb" +BUILT_MODULE_NAME[17]="xpd_pri" +BUILT_MODULE_NAME[18]="xpd_fxs" +BUILT_MODULE_NAME[19]="dahdi_echocan_sec" +BUILT_MODULE_NAME[20]="dahdi_echocan_mg2" +BUILT_MODULE_NAME[21]="pciradio" +BUILT_MODULE_NAME[22]="dahdi_echocan_kb1" +BUILT_MODULE_NAME[23]="dahdi_dynamic_eth" +BUILT_MODULE_NAME[24]="dahdi_echocan_sec2" +BUILT_MODULE_NAME[25]="dahdi_dynamic" +BUILT_MODULE_NAME[26]="wctc4xxp" +BUILT_MODULE_NAME[27]="wcte12xp" +BUILT_MODULE_NAME[28]="dahdi_vpmadt032_loader" +BUILT_MODULE_NAME[29]="wct4xxp" +BUILT_MODULE_NAME[30]="wctdm" +BUILT_MODULE_NAME[31]="echo" + +BUILT_MODULE_LOCATION[0]="drivers/dahdi/" +BUILT_MODULE_LOCATION[1]="drivers/dahdi/" +BUILT_MODULE_LOCATION[2]="drivers/dahdi/" +BUILT_MODULE_LOCATION[3]="drivers/dahdi/" +BUILT_MODULE_LOCATION[4]="drivers/dahdi/wcb4xxp/" +BUILT_MODULE_LOCATION[5]="drivers/dahdi/" +BUILT_MODULE_LOCATION[6]="drivers/dahdi/" +BUILT_MODULE_LOCATION[7]="drivers/dahdi/wctdm24xxp/" +BUILT_MODULE_LOCATION[8]="drivers/dahdi/" +BUILT_MODULE_LOCATION[9]="drivers/dahdi/" +BUILT_MODULE_LOCATION[10]="drivers/dahdi/" +BUILT_MODULE_LOCATION[11]="drivers/dahdi/" +BUILT_MODULE_LOCATION[12]="drivers/dahdi/voicebus/" +BUILT_MODULE_LOCATION[13]="drivers/dahdi/xpp/" +BUILT_MODULE_LOCATION[14]="drivers/dahdi/xpp/" +BUILT_MODULE_LOCATION[15]="drivers/dahdi/xpp/" +BUILT_MODULE_LOCATION[16]="drivers/dahdi/xpp/" +BUILT_MODULE_LOCATION[17]="drivers/dahdi/xpp/" +BUILT_MODULE_LOCATION[18]="drivers/dahdi/xpp/" +BUILT_MODULE_LOCATION[19]="drivers/dahdi/" +BUILT_MODULE_LOCATION[20]="drivers/dahdi/" +BUILT_MODULE_LOCATION[21]="drivers/dahdi/" +BUILT_MODULE_LOCATION[22]="drivers/dahdi/" +BUILT_MODULE_LOCATION[23]="drivers/dahdi/" +BUILT_MODULE_LOCATION[24]="drivers/dahdi/" +BUILT_MODULE_LOCATION[25]="drivers/dahdi/" +BUILT_MODULE_LOCATION[26]="drivers/dahdi/wctc4xxp/" +BUILT_MODULE_LOCATION[27]="drivers/dahdi/wcte12xp/" +BUILT_MODULE_LOCATION[28]="drivers/dahdi/" +BUILT_MODULE_LOCATION[29]="drivers/dahdi/wct4xxp/" +BUILT_MODULE_LOCATION[30]="drivers/dahdi/" +BUILT_MODULE_LOCATION[31]="drivers/staging/echo" + +DEST_MODULE_LOCATION[0]="/extra/" +DEST_MODULE_LOCATION[1]="/extra/" +DEST_MODULE_LOCATION[2]="/extra/" +DEST_MODULE_LOCATION[3]="/extra/" +DEST_MODULE_LOCATION[4]="/extra/wcb4xxp/" +DEST_MODULE_LOCATION[5]="/extra/" +DEST_MODULE_LOCATION[6]="/extra/" +DEST_MODULE_LOCATION[7]="/extra/wctdm24xxp/" +DEST_MODULE_LOCATION[8]="/extra/" +DEST_MODULE_LOCATION[9]="/extra/" +DEST_MODULE_LOCATION[10]="/extra/" +DEST_MODULE_LOCATION[11]="/extra/" +DEST_MODULE_LOCATION[12]="/extra/voicebus/" +DEST_MODULE_LOCATION[13]="/extra/xpp/" +DEST_MODULE_LOCATION[14]="/extra/xpp/" +DEST_MODULE_LOCATION[15]="/extra/xpp/" +DEST_MODULE_LOCATION[16]="/extra/xpp/" +DEST_MODULE_LOCATION[17]="/extra/xpp/" +DEST_MODULE_LOCATION[18]="/extra/xpp/" +DEST_MODULE_LOCATION[19]="/extra/" +DEST_MODULE_LOCATION[20]="/extra/" +DEST_MODULE_LOCATION[21]="/extra/" +DEST_MODULE_LOCATION[22]="/extra/" +DEST_MODULE_LOCATION[23]="/extra/" +DEST_MODULE_LOCATION[24]="/extra/" +DEST_MODULE_LOCATION[25]="/extra/" +DEST_MODULE_LOCATION[26]="/extra/wctc4xxp/" +DEST_MODULE_LOCATION[27]="/extra/wcte12xp/" +DEST_MODULE_LOCATION[28]="/extra/" +DEST_MODULE_LOCATION[29]="/extra/wct4xxp/" +DEST_MODULE_LOCATION[30]="/extra/" +DEST_MODULE_LOCATION[31]="/extra/" + +POST_INSTALL="dkms-post-install ${source_tree}/$PACKAGE_NAME-$PACKAGE_VERSION" +POST_REMOVE="dkms-post-remove ${source_tree}/$PACKAGE_NAME-$PACKAGE_VERSION $PACKAGE_NAME $kernelver" diff -Nru dahdi-linux-2.2.1-rc2/dkms-post-install dahdi-cnet-linux-2.2.1-rc2/dkms-post-install --- dahdi-linux-2.2.1-rc2/dkms-post-install 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/dkms-post-install 2010-01-09 21:29:01.955618012 -0600 @@ -0,0 +1,6 @@ +#!/bin/bash +echo Running post-install... +make -C $1 install-devices +make -C $1 install-include +make -C $1 install-firmware +make -C $1 install-xpp-firm diff -Nru dahdi-linux-2.2.1-rc2/dkms-post-remove dahdi-cnet-linux-2.2.1-rc2/dkms-post-remove --- dahdi-linux-2.2.1-rc2/dkms-post-remove 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/dkms-post-remove 2010-01-09 21:29:01.955618012 -0600 @@ -0,0 +1,11 @@ +#!/bin/bash +modtest=`dkms status -m $2 | grep -v $3` +if [ -z "$modtest" ] +then + echo Completing dahdi-cnet uninstall. + make -C $1 uninstall-firmware + make -C $1 uninstall-include + make -C $1 uninstall-devices +else + echo "$2 still installed for other kernel versions." +fi diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/adt_lec.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/adt_lec.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/adt_lec.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/adt_lec.c 2009-11-12 14:02:24.000000000 -0600 @@ -0,0 +1,73 @@ +/* + * ADT Line Echo Canceller Parameter Parsing + * + * Copyright (C) 2008-2009 Digium, Inc. + * + * Kevin P. Fleming + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#ifndef _ADT_LEC_C +#define _ADT_LEC_C + +#include + +static inline void adt_lec_init_defaults(struct adt_lec_params *params, __u32 tap_length) +{ + params->tap_length = tap_length; + params->nlp_type = 0; + params->nlp_max_suppress = 0; + params->nlp_threshold = 0; +} + +static int adt_lec_parse_params(struct adt_lec_params *params, + struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p) +{ + unsigned int x; + char *c; + + params->tap_length = ecp->tap_length; + + for (x = 0; x < ecp->param_count; x++) { + for (c = p[x].name; *c; c++) + *c = tolower(*c); + if (!strcmp(p[x].name, "nlp_type")) { + switch (p[x].value) { + case ADT_LEC_NLP_OFF: + case ADT_LEC_NLP_MUTE: + case ADT_LEC_RANDOM_NOISE: + case ADT_LEC_HOTH_NOISE: + case ADT_LEC_SUPPRESS: + params->nlp_type = p[x].value; + break; + default: + return -EINVAL; + } + } else if (!strcmp(p[x].name, "nlp_thresh")) { + params->nlp_threshold = p[x].value; + } else if (!strcmp(p[x].name, "nlp_suppress")) { + params->nlp_max_suppress = p[x].value; + } else { + return -EINVAL; + } + } + + return 0; +} + +#endif /* _ADT_LEC_C */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/adt_lec.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/adt_lec.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/adt_lec.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/adt_lec.h 2009-11-12 14:02:24.000000000 -0600 @@ -0,0 +1,48 @@ +/* + * ADT Line Echo Canceller Parameter Parsing + * + * Copyright (C) 2008 Digium, Inc. + * + * Kevin P. Fleming + * + * All rights reserved. + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#ifndef _ADT_LEC_H +#define _ADT_LEC_H + +enum adt_lec_nlp_type { + ADT_LEC_NLP_OFF = 0, + ADT_LEC_NLP_MUTE, + ADT_LEC_RANDOM_NOISE, + ADT_LEC_HOTH_NOISE, + ADT_LEC_SUPPRESS, +}; + +enum adt_companding { + ADT_COMP_ULAW = 0, + ADT_COMP_ALAW, +}; + +struct adt_lec_params { + __u32 tap_length; + enum adt_lec_nlp_type nlp_type; + __u32 nlp_threshold; + __u32 nlp_max_suppress; + enum adt_companding companding; +}; + +#endif /* _ADT_LEC_H */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/arith.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/arith.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/arith.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/arith.h 2008-08-05 18:56:00.000000000 -0500 @@ -0,0 +1,378 @@ +/* + * Handy add/subtract functions to operate on chunks of shorts. + * Feel free to add customizations for additional architectures + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#ifndef _DAHDI_ARITH_H +#define _DAHDI_ARITH_H + +#ifdef CONFIG_DAHDI_MMX +#ifdef DAHDI_CHUNKSIZE +static inline void __ACSS(volatile short *dst, const short *src) +{ + __asm__ __volatile__ ( + "movq 0(%0), %%mm0;\n" + "movq 0(%1), %%mm1;\n" + "movq 8(%0), %%mm2;\n" + "movq 8(%1), %%mm3;\n" + "paddsw %%mm1, %%mm0;\n" + "paddsw %%mm3, %%mm2;\n" + "movq %%mm0, 0(%0);\n" + "movq %%mm2, 8(%0);\n" + : "=r" (dst) + : "r" (src), "0" (dst) + : "memory" +#ifdef CLOBBERMMX + , "%mm0", "%mm1", "%mm2", "%mm3" +#endif + ); + +} +static inline void __SCSS(volatile short *dst, const short *src) +{ + __asm__ __volatile__ ( + "movq 0(%0), %%mm0;\n" + "movq 0(%1), %%mm1;\n" + "movq 8(%0), %%mm2;\n" + "movq 8(%1), %%mm3;\n" + "psubsw %%mm1, %%mm0;\n" + "psubsw %%mm3, %%mm2;\n" + "movq %%mm0, 0(%0);\n" + "movq %%mm2, 8(%0);\n" + : "=r" (dst) + : "r" (src), "0" (dst) + : "memory" +#ifdef CLOBBERMMX + , "%mm0", "%mm1", "%mm2", "%mm3" +#endif + ); + +} + +#if (DAHDI_CHUNKSIZE == 8) +#define ACSS(a,b) __ACSS(a,b) +#define SCSS(a,b) __SCSS(a,b) +#elif (DAHDI_CHUNKSIZE > 8) +static inline void ACSS(volatile short *dst, const short *src) +{ + int x; + for (x=0;x>= 4; + + /* Clear our accumulator, mm4 */ + + /* + + For every set of eight... + + Load 16 coefficients into four registers... + Shift each word right 16 to make them shorts... + Pack the resulting shorts into two registers... + With the coefficients now in mm0 and mm2, load the + history into mm1 and mm3... + Multiply/add mm1 into mm0, and mm3 into mm2... + Add mm2 into mm0 (without saturation, alas). Now we have two half-results. + Accumulate in mm4 (again, without saturation, alas) + */ + __asm__ ( + "pxor %%mm4, %%mm4;\n" + "mov %1, %%edi;\n" + "mov %2, %%esi;\n" + "mov %3, %%ecx;\n" + "1:" + "movq 0(%%edi), %%mm0;\n" + "movq 8(%%edi), %%mm1;\n" + "movq 16(%%edi), %%mm2;\n" + "movq 24(%%edi), %%mm3;\n" + /* can't use 4/5 since 4 is the accumulator for us */ + "movq 32(%%edi), %%mm6;\n" + "movq 40(%%edi), %%mm7;\n" + "psrad $16, %%mm0;\n" + "psrad $16, %%mm1;\n" + "psrad $16, %%mm2;\n" + "psrad $16, %%mm3;\n" + "psrad $16, %%mm6;\n" + "psrad $16, %%mm7;\n" + "packssdw %%mm1, %%mm0;\n" + "packssdw %%mm3, %%mm2;\n" + "packssdw %%mm7, %%mm6;\n" + "movq 0(%%esi), %%mm1;\n" + "movq 8(%%esi), %%mm3;\n" + "movq 16(%%esi), %%mm7;\n" + "pmaddwd %%mm1, %%mm0;\n" + "pmaddwd %%mm3, %%mm2;\n" + "pmaddwd %%mm7, %%mm6;\n" + "paddd %%mm6, %%mm4;\n" + "paddd %%mm2, %%mm4;\n" + "paddd %%mm0, %%mm4;\n" + /* Come back and do for the last few bytes */ + "movq 48(%%edi), %%mm6;\n" + "movq 56(%%edi), %%mm7;\n" + "psrad $16, %%mm6;\n" + "psrad $16, %%mm7;\n" + "packssdw %%mm7, %%mm6;\n" + "movq 24(%%esi), %%mm7;\n" + "pmaddwd %%mm7, %%mm6;\n" + "paddd %%mm6, %%mm4;\n" + "add $64, %%edi;\n" + "add $32, %%esi;\n" + "dec %%ecx;\n" + "jnz 1b;\n" + "movq %%mm4, %%mm0;\n" + "psrlq $32, %%mm0;\n" + "paddd %%mm0, %%mm4;\n" + "movd %%mm4, %0;\n" + : "=r" (sum) + : "r" (coeffs), "r" (hist), "r" (len) + : "%ecx", "%edi", "%esi" + ); + + return sum; +} + +static inline void UPDATE(volatile int *taps, const short *history, const int nsuppr, const int ntaps) +{ + int i; + int correction; + for (i=0;i>= 4; + /* First, load up taps, */ + __asm__ ( + "pxor %%mm4, %%mm4;\n" + "mov %0, %%edi;\n" + "mov %1, %%esi;\n" + "mov %3, %%ecx;\n" + "1:" + "jnz 1b;\n" + "movq %%mm4, %%mm0;\n" + "psrlq $32, %%mm0;\n" + "paddd %%mm0, %%mm4;\n" + "movd %%mm4, %0;\n" + : "=r" (taps), "=r" (taps_short) + : "r" (history), "r" (nsuppr), "r" (ntaps), "0" (taps) + : "%ecx", "%edi", "%esi" + ); +#endif +#if 1 + for (i=0;i> 16; + } +#endif +} + +static inline int CONVOLVE2(const short *coeffs, const short *hist, int len) +{ + int sum; + /* Divide length by 16 */ + len >>= 4; + + /* Clear our accumulator, mm4 */ + + /* + + For every set of eight... + Load in eight coefficients and eight historic samples, multliply add and + accumulate the result + */ + __asm__ ( + "pxor %%mm4, %%mm4;\n" + "mov %1, %%edi;\n" + "mov %2, %%esi;\n" + "mov %3, %%ecx;\n" + "1:" + "movq 0(%%edi), %%mm0;\n" + "movq 8(%%edi), %%mm2;\n" + "movq 0(%%esi), %%mm1;\n" + "movq 8(%%esi), %%mm3;\n" + "pmaddwd %%mm1, %%mm0;\n" + "pmaddwd %%mm3, %%mm2;\n" + "paddd %%mm2, %%mm4;\n" + "paddd %%mm0, %%mm4;\n" + "movq 16(%%edi), %%mm0;\n" + "movq 24(%%edi), %%mm2;\n" + "movq 16(%%esi), %%mm1;\n" + "movq 24(%%esi), %%mm3;\n" + "pmaddwd %%mm1, %%mm0;\n" + "pmaddwd %%mm3, %%mm2;\n" + "paddd %%mm2, %%mm4;\n" + "paddd %%mm0, %%mm4;\n" + "add $32, %%edi;\n" + "add $32, %%esi;\n" + "dec %%ecx;\n" + "jnz 1b;\n" + "movq %%mm4, %%mm0;\n" + "psrlq $32, %%mm0;\n" + "paddd %%mm0, %%mm4;\n" + "movd %%mm4, %0;\n" + : "=r" (sum) + : "r" (coeffs), "r" (hist), "r" (len) + : "%ecx", "%edi", "%esi" + ); + + return sum; +} +static inline short MAX16(const short *y, int len, int *pos) +{ + int k; + short max = 0; + int bestpos = 0; + for (k=0;k 32767) + sum = 32767; + else if (sum < -32768) + sum = -32768; + dst[x] = sum; + } +#endif +} + +static inline void SCSS(short *dst, short *src) +{ + int x; + + /* Subtract src from dst with saturation, storing in dst */ +#ifdef BFIN + for (x = 0; x < DAHDI_CHUNKSIZE; x++) + dst[x] = __builtin_bfin_sub_fr1x16(dst[x], src[x]); +#else + int sum; + + for (x = 0; x < DAHDI_CHUNKSIZE; x++) { + sum = dst[x] - src[x]; + if (sum > 32767) + sum = 32767; + else if (sum < -32768) + sum = -32768; + dst[x] = sum; + } +#endif +} + +#endif /* DAHDI_CHUNKSIZE */ + +static inline int CONVOLVE(const int *coeffs, const short *hist, int len) +{ + int x; + int sum = 0; + for (x=0;x> 16) * hist[x]; + return sum; +} + +static inline int CONVOLVE2(const short *coeffs, const short *hist, int len) +{ + int x; + int sum = 0; + for (x=0;x> 16; + } +} + +static inline short MAX16(const short *y, int len, int *pos) +{ + int k; + short max = 0; + int bestpos = 0; + for (k=0;k + * + * Copyright (C) 2001 Steve Underwood + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +static inline void biquad2_init (biquad2_state_t *bq, + int32_t gain, + int32_t a1, + int32_t a2, + int32_t b1, + int32_t b2) +{ + bq->gain = gain; + bq->a1 = a1; + bq->a2 = a2; + bq->b1 = b1; + bq->b2 = b2; + + bq->z1 = 0; + bq->z2 = 0; +} +/*- End of function --------------------------------------------------------*/ + +static inline int16_t biquad2 (biquad2_state_t *bq, int16_t sample) +{ + int32_t y; + int32_t z0; + + z0 = sample*bq->gain + bq->z1*bq->a1 + bq->z2*bq->a2; + y = z0 + bq->z1*bq->b1 + bq->z2*bq->b2; + + bq->z2 = bq->z1; + bq->z1 = z0 >> 15; + y >>= 15; + return y; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi-base.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi-base.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi-base.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi-base.c 2010-01-09 21:29:01.959619081 -0600 @@ -0,0 +1,8370 @@ +/* + * DAHDI Telephony Interface Driver + * + * Written by Mark Spencer + * Based on previous works, designs, and architectures conceived and + * written by Jim Dixon . + * + * Special thanks to Steve Underwood + * for substantial contributions to signal processing functions + * in DAHDI and the Zapata library. + * + * Yury Bokhoncovich + * Adaptation for 2.4.20+ kernels (HDLC API was changed) + * The work has been performed as a part of our move + * from Cisco 3620 to IBM x305 here in F1 Group + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001 - 2008 Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args) + +/* #define BUF_MUNGE */ + +#include +/* Grab fasthdlc with tables */ +#define FAST_HDLC_NEED_TABLES +#include +#include "ecdis.h" + +#ifndef CONFIG_OLD_HDLC_API +#define NEW_HDLC_INTERFACE +#endif + +#ifdef CONFIG_DAHDI_PPP +#include +#include +#include +#endif + +#ifdef CONFIG_DAHDI_NET +#include +#endif + +#include "hpec/hpec_user.h" + +#if defined(EMPULSE) && defined(EMFLASH) +#error "You cannot define both EMPULSE and EMFLASH" +#endif + +/* Get helper arithmetic */ +#include "arith.h" +#if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP) +#include +#endif + +#define hdlc_to_ztchan(h) (((struct dahdi_hdlc *)(h))->chan) +#define dev_to_ztchan(h) (((struct dahdi_hdlc *)(dev_to_hdlc(h)->priv))->chan) +#define ztchan_to_dev(h) ((h)->hdlcnetdev->netdev) + +/* macro-oni for determining a unit (channel) number */ +#define UNIT(file) MINOR(file->f_dentry->d_inode->i_rdev) + +/* names of tx level settings */ +static char *dahdi_txlevelnames[] = { +"0 db (CSU)/0-133 feet (DSX-1)", +"133-266 feet (DSX-1)", +"266-399 feet (DSX-1)", +"399-533 feet (DSX-1)", +"533-655 feet (DSX-1)", +"-7.5db (CSU)", +"-15db (CSU)", +"-22.5db (CSU)" +} ; + +EXPORT_SYMBOL(dahdi_transcode_fops); +EXPORT_SYMBOL(dahdi_init_tone_state); +EXPORT_SYMBOL(dahdi_mf_tone); +EXPORT_SYMBOL(dahdi_register); +EXPORT_SYMBOL(dahdi_unregister); +EXPORT_SYMBOL(__dahdi_mulaw); +EXPORT_SYMBOL(__dahdi_alaw); +#ifdef CONFIG_CALC_XLAW +EXPORT_SYMBOL(__dahdi_lineartoulaw); +EXPORT_SYMBOL(__dahdi_lineartoalaw); +#else +EXPORT_SYMBOL(__dahdi_lin2mu); +EXPORT_SYMBOL(__dahdi_lin2a); +#endif +EXPORT_SYMBOL(dahdi_lboname); +EXPORT_SYMBOL(dahdi_transmit); +EXPORT_SYMBOL(dahdi_receive); +EXPORT_SYMBOL(dahdi_rbsbits); +EXPORT_SYMBOL(dahdi_qevent_nolock); +EXPORT_SYMBOL(dahdi_qevent_lock); +EXPORT_SYMBOL(dahdi_hooksig); +EXPORT_SYMBOL(dahdi_alarm_notify); +EXPORT_SYMBOL(dahdi_set_dynamic_ioctl); +EXPORT_SYMBOL(dahdi_ec_chunk); +EXPORT_SYMBOL(dahdi_ec_span); +EXPORT_SYMBOL(dahdi_hdlc_abort); +EXPORT_SYMBOL(dahdi_hdlc_finish); +EXPORT_SYMBOL(dahdi_hdlc_getbuf); +EXPORT_SYMBOL(dahdi_hdlc_putbuf); +EXPORT_SYMBOL(dahdi_alarm_channel); +EXPORT_SYMBOL(dahdi_register_chardev); +EXPORT_SYMBOL(dahdi_unregister_chardev); + +EXPORT_SYMBOL(dahdi_register_echocan_factory); +EXPORT_SYMBOL(dahdi_unregister_echocan_factory); + +EXPORT_SYMBOL(dahdi_set_hpec_ioctl); + +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry *proc_entries[DAHDI_MAX_SPANS]; +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +#define CLASS_DEV_CREATE(class, devt, device, name) \ + device_create(class, device, devt, NULL, "%s", name) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#define CLASS_DEV_CREATE(class, devt, device, name) \ + device_create(class, device, devt, name) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) +#define CLASS_DEV_CREATE(class, devt, device, name) \ + class_device_create(class, NULL, devt, device, name) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) +#define CLASS_DEV_CREATE(class, devt, device, name) \ + class_device_create(class, devt, device, name) +#else +#define CLASS_DEV_CREATE(class, devt, device, name) \ + class_simple_device_add(class, devt, device, name) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#define CLASS_DEV_DESTROY(class, devt) \ + device_destroy(class, devt) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) +#define CLASS_DEV_DESTROY(class, devt) \ + class_device_destroy(class, devt) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9) +#define CLASS_DEV_DESTROY(class, devt) \ + class_simple_device_remove(devt) +#else +#define CLASS_DEV_DESTROY(class, devt) \ + class_simple_device_remove(class, devt) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) +static struct class *dahdi_class = NULL; +#else +static struct class_simple *dahdi_class = NULL; +#define class_create class_simple_create +#define class_destroy class_simple_destroy +#endif + +static int deftaps = 64; + +static int debug; + +/*! + * \brief states for transmit signalling + */ +enum dahdi_txstate { + DAHDI_TXSTATE_ONHOOK, + DAHDI_TXSTATE_OFFHOOK, + DAHDI_TXSTATE_START, + DAHDI_TXSTATE_PREWINK, + DAHDI_TXSTATE_WINK, + DAHDI_TXSTATE_PREFLASH, + DAHDI_TXSTATE_FLASH, + DAHDI_TXSTATE_DEBOUNCE, + DAHDI_TXSTATE_AFTERSTART, + DAHDI_TXSTATE_RINGON, + DAHDI_TXSTATE_RINGOFF, + DAHDI_TXSTATE_KEWL, + DAHDI_TXSTATE_AFTERKEWL, + DAHDI_TXSTATE_PULSEBREAK, + DAHDI_TXSTATE_PULSEMAKE, + DAHDI_TXSTATE_PULSEAFTER, +}; + +typedef short sumtype[DAHDI_MAX_CHUNKSIZE]; + +static sumtype sums[(DAHDI_MAX_CONF + 1) * 3]; + +/* Translate conference aliases into actual conferences + and vice-versa */ +static short confalias[DAHDI_MAX_CONF + 1]; +static short confrev[DAHDI_MAX_CONF + 1]; + +static sumtype *conf_sums_next; +static sumtype *conf_sums; +static sumtype *conf_sums_prev; + +static struct dahdi_span *master; +static struct file_operations dahdi_fops; +struct file_operations *dahdi_transcode_fops = NULL; + +static struct { + int src; /* source conf number */ + int dst; /* dst conf number */ +} conf_links[DAHDI_MAX_CONF + 1]; + +#ifdef CONFIG_DAHDI_CORE_TIMER + +static struct core_timer { + struct timer_list timer; + struct timespec start_interval; + atomic_t count; + atomic_t shutdown; + atomic_t last_count; +} core_timer; + +#endif /* CONFIG_DAHDI_CORE_TIMER */ + + + +/* There are three sets of conference sum accumulators. One for the current +sample chunk (conf_sums), one for the next sample chunk (conf_sums_next), and +one for the previous sample chunk (conf_sums_prev). The following routine +(rotate_sums) "rotates" the pointers to these accululator arrays as part +of the events of sample chink processing as follows: + +The following sequence is designed to be looked at from the reference point +of the receive routine of the master span. + +1. All (real span) receive chunks are processed (with putbuf). The last one +to be processed is the master span. The data received is loaded into the +accumulators for the next chunk (conf_sums_next), to be in alignment with +current data after rotate_sums() is called (which immediately follows). +Keep in mind that putbuf is *also* a transmit routine for the pseudo parts +of channels that are in the REALANDPSEUDO conference mode. These channels +are processed from data in the current sample chunk (conf_sums), being +that this is a "transmit" function (for the pseudo part). + +2. rotate_sums() is called. + +3. All pseudo channel receive chunks are processed. This data is loaded into +the current sample chunk accumulators (conf_sums). + +4. All conference links are processed (being that all receive data for this +chunk has already been processed by now). + +5. All pseudo channel transmit chunks are processed. This data is loaded from +the current sample chunk accumulators (conf_sums). + +6. All (real span) transmit chunks are processed (with getbuf). This data is +loaded from the current sample chunk accumulators (conf_sums). Keep in mind +that getbuf is *also* a receive routine for the pseudo part of channels that +are in the REALANDPSEUDO conference mode. These samples are loaded into +the next sample chunk accumulators (conf_sums_next) to be processed as part +of the next sample chunk's data (next time around the world). + +*/ + +enum dahdi_digit_mode { + DIGIT_MODE_DTMF, + DIGIT_MODE_MFR1, + DIGIT_MODE_PULSE, + DIGIT_MODE_MFR2_FWD, + DIGIT_MODE_MFR2_REV, +}; + +#include "digits.h" + +static struct dahdi_dialparams global_dialparams = { + .dtmf_tonelen = DEFAULT_DTMF_LENGTH, + .mfv1_tonelen = DEFAULT_MFR1_LENGTH, + .mfr2_tonelen = DEFAULT_MFR2_LENGTH, +}; + +static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit); + +#if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP) +#define dahdi_kernel_fpu_begin kernel_fpu_begin +#endif + +struct dahdi_timer { + int ms; /* Countdown */ + int pos; /* Position */ + int ping; /* Whether we've been ping'd */ + int tripped; /* Whether we're tripped */ + struct list_head list; + wait_queue_head_t sel; +}; + +static LIST_HEAD(zaptimers); + +#ifdef DEFINE_SPINLOCK +static DEFINE_SPINLOCK(zaptimerlock); +static DEFINE_SPINLOCK(bigzaplock); +#else +static spinlock_t zaptimerlock = SPIN_LOCK_UNLOCKED; +static spinlock_t bigzaplock = SPIN_LOCK_UNLOCKED; +#endif + +struct dahdi_zone { + atomic_t refcount; + char name[40]; /* Informational, only */ + int ringcadence[DAHDI_MAX_CADENCE]; + struct dahdi_tone *tones[DAHDI_TONE_MAX]; + /* Each of these is a circular list + of dahdi_tones to generate what we + want. Use NULL if the tone is + unavailable */ + struct dahdi_tone dtmf[16]; /* DTMF tones for this zone, with desired length */ + struct dahdi_tone dtmf_continuous[16]; /* DTMF tones for this zone, continuous play */ + struct dahdi_tone mfr1[15]; /* MFR1 tones for this zone, with desired length */ + struct dahdi_tone mfr2_fwd[15]; /* MFR2 FWD tones for this zone, with desired length */ + struct dahdi_tone mfr2_rev[15]; /* MFR2 REV tones for this zone, with desired length */ + struct dahdi_tone mfr2_fwd_continuous[16]; /* MFR2 FWD tones for this zone, continuous play */ + struct dahdi_tone mfr2_rev_continuous[16]; /* MFR2 REV tones for this zone, continuous play */ +}; + +static struct dahdi_span *spans[DAHDI_MAX_SPANS]; +static struct dahdi_chan *chans[DAHDI_MAX_CHANNELS]; + +static int maxspans = 0; +static int maxchans = 0; +static int maxconfs = 0; +static int maxlinks = 0; + +static int default_zone = -1; + +short __dahdi_mulaw[256]; +short __dahdi_alaw[256]; + +#ifndef CONFIG_CALC_XLAW +u_char __dahdi_lin2mu[16384]; + +u_char __dahdi_lin2a[16384]; +#endif + +static u_char defgain[256]; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) +#define __RW_LOCK_UNLOCKED() RW_LOCK_UNLOCKED +#endif + +#ifdef DEFINE_RWLOCK +static DEFINE_RWLOCK(zone_lock); +static DEFINE_RWLOCK(chan_lock); +#else +static rwlock_t zone_lock = RW_LOCK_UNLOCKED; +static rwlock_t chan_lock = RW_LOCK_UNLOCKED; +#endif + +static struct dahdi_zone *tone_zones[DAHDI_TONE_ZONE_MAX]; + +#define NUM_SIGS 10 + +#ifdef DEFINE_RWLOCK +static DEFINE_RWLOCK(ecfactory_list_lock); +#else +static rwlock_t ecfactory_list_lock = __RW_LOCK_UNLOCKED(); +#endif + +static LIST_HEAD(ecfactory_list); + +struct ecfactory { + const struct dahdi_echocan_factory *ec; + struct list_head list; +}; + +int dahdi_register_echocan_factory(const struct dahdi_echocan_factory *ec) +{ + struct ecfactory *cur; + + WARN_ON(!ec->owner); + + write_lock(&ecfactory_list_lock); + + /* make sure it isn't already registered */ + list_for_each_entry(cur, &ecfactory_list, list) { + if (cur->ec == ec) { + write_unlock(&ecfactory_list_lock); + return -EPERM; + } + } + + if (!(cur = kzalloc(sizeof(*cur), GFP_KERNEL))) { + write_unlock(&ecfactory_list_lock); + return -ENOMEM; + } + + cur->ec = ec; + INIT_LIST_HEAD(&cur->list); + + list_add_tail(&cur->list, &ecfactory_list); + + write_unlock(&ecfactory_list_lock); + + return 0; +} + +void dahdi_unregister_echocan_factory(const struct dahdi_echocan_factory *ec) +{ + struct ecfactory *cur, *next; + + write_lock(&ecfactory_list_lock); + + list_for_each_entry_safe(cur, next, &ecfactory_list, list) { + if (cur->ec == ec) { + list_del(&cur->list); + break; + } + } + + write_unlock(&ecfactory_list_lock); +} + +static inline void rotate_sums(void) +{ + /* Rotate where we sum and so forth */ + static int pos = 0; + conf_sums_prev = sums + (DAHDI_MAX_CONF + 1) * pos; + conf_sums = sums + (DAHDI_MAX_CONF + 1) * ((pos + 1) % 3); + conf_sums_next = sums + (DAHDI_MAX_CONF + 1) * ((pos + 2) % 3); + pos = (pos + 1) % 3; + memset(conf_sums_next, 0, maxconfs * sizeof(sumtype)); +} + +/*! + * \return quiescent (idle) signalling states, for the various signalling types + */ +static int dahdi_q_sig(struct dahdi_chan *chan) +{ + int x; + static const unsigned int in_sig[NUM_SIGS][2] = { + { DAHDI_SIG_NONE, 0 }, + { DAHDI_SIG_EM, (DAHDI_ABIT << 8) }, + { DAHDI_SIG_FXSLS, DAHDI_BBIT | (DAHDI_BBIT << 8) }, + { DAHDI_SIG_FXSGS, DAHDI_ABIT | DAHDI_BBIT | ((DAHDI_ABIT | DAHDI_BBIT) << 8) }, + { DAHDI_SIG_FXSKS, DAHDI_BBIT | DAHDI_BBIT | ((DAHDI_ABIT | DAHDI_BBIT) << 8) }, + { DAHDI_SIG_FXOLS, (DAHDI_ABIT << 8) }, + { DAHDI_SIG_FXOGS, DAHDI_BBIT | ((DAHDI_ABIT | DAHDI_BBIT) << 8) }, + { DAHDI_SIG_FXOKS, (DAHDI_ABIT << 8) }, + { DAHDI_SIG_SF, 0 }, + { DAHDI_SIG_EM_E1, DAHDI_DBIT | ((DAHDI_ABIT | DAHDI_DBIT) << 8) }, + }; + + /* must have span to begin with */ + if (!chan->span) + return -1; + + /* if RBS does not apply, return error */ + if (!(chan->span->flags & DAHDI_FLAG_RBS) || !chan->span->rbsbits) + return -1; + + if (chan->sig == DAHDI_SIG_CAS) + return chan->idlebits; + + for (x = 0; x < NUM_SIGS; x++) { + if (in_sig[x][0] == chan->sig) + return in_sig[x][1]; + } + + return -1; /* not found -- error */ +} + +#ifdef CONFIG_PROC_FS +static const char *sigstr(int sig) +{ + switch (sig) { + case DAHDI_SIG_FXSLS: + return "FXSLS"; + case DAHDI_SIG_FXSKS: + return "FXSKS"; + case DAHDI_SIG_FXSGS: + return "FXSGS"; + case DAHDI_SIG_FXOLS: + return "FXOLS"; + case DAHDI_SIG_FXOKS: + return "FXOKS"; + case DAHDI_SIG_FXOGS: + return "FXOGS"; + case DAHDI_SIG_EM: + return "E&M"; + case DAHDI_SIG_EM_E1: + return "E&M-E1"; + case DAHDI_SIG_CLEAR: + return "Clear"; + case DAHDI_SIG_HDLCRAW: + return "HDLCRAW"; + case DAHDI_SIG_HDLCFCS: + return "HDLCFCS"; + case DAHDI_SIG_HDLCNET: + return "HDLCNET"; + case DAHDI_SIG_HARDHDLC: + return "Hardware-assisted HDLC"; + case DAHDI_SIG_MTP2: + return "MTP2"; + case DAHDI_SIG_SLAVE: + return "Slave"; + case DAHDI_SIG_CAS: + return "CAS"; + case DAHDI_SIG_DACS: + return "DACS"; + case DAHDI_SIG_DACS_RBS: + return "DACS+RBS"; + case DAHDI_SIG_SF: + return "SF (ToneOnly)"; + case DAHDI_SIG_NONE: + default: + return "Unconfigured"; + } +} + +static int fill_alarm_string(char *buf, int count, int alarms) +{ + int len; + + if (alarms <= 0) + return 0; + + len = snprintf(buf, count, "%s%s%s%s%s%s", + (alarms & DAHDI_ALARM_BLUE) ? "BLUE " : "", + (alarms & DAHDI_ALARM_YELLOW) ? "YELLOW " : "", + (alarms & DAHDI_ALARM_RED) ? "RED " : "", + (alarms & DAHDI_ALARM_LOOPBACK) ? "LOOP " : "", + (alarms & DAHDI_ALARM_RECOVER) ? "RECOVERING " : "", + (alarms & DAHDI_ALARM_NOTOPEN) ? "NOTOPEN " : ""); + + if (len > 0) + buf[--len] = '\0'; /* strip last space */ + + return len; +} + +static int dahdi_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int x, len = 0, real_count; + long span; + + /* In Linux 2.6, page is always PROC_BLOCK_SIZE=(PAGE_SIZE-1024) bytes. + * 0name) + len += snprintf(page + len, count - len, "Span %ld: %s ", + span, spans[span]->name); + if (spans[span]->desc) + len += snprintf(page + len, count - len, "\"%s\"", + spans[span]->desc); + else + len += snprintf(page + len, count - len, "\"\""); + + if (spans[span] == master) + len += snprintf(page + len, count - len, " (MASTER)"); + + if (spans[span]->lineconfig) { + /* framing first */ + if (spans[span]->lineconfig & DAHDI_CONFIG_B8ZS) + len += snprintf(page + len, count - len, " B8ZS/"); + else if (spans[span]->lineconfig & DAHDI_CONFIG_AMI) + len += snprintf(page + len, count - len, " AMI/"); + else if (spans[span]->lineconfig & DAHDI_CONFIG_HDB3) + len += snprintf(page + len, count - len, " HDB3/"); + /* then coding */ + if (spans[span]->lineconfig & DAHDI_CONFIG_ESF) + len += snprintf(page + len, count - len, "ESF"); + else if (spans[span]->lineconfig & DAHDI_CONFIG_D4) + len += snprintf(page + len, count - len, "D4"); + else if (spans[span]->lineconfig & DAHDI_CONFIG_CCS) + len += snprintf(page + len, count - len, "CCS"); + /* E1's can enable CRC checking */ + if (spans[span]->lineconfig & DAHDI_CONFIG_CRC4) + len += snprintf(page + len, count - len, "/CRC4"); + } + + len += snprintf(page + len, count - len, " "); + + /* list alarms */ + len += fill_alarm_string(page + len, count - len, spans[span]->alarms); + if (spans[span]->syncsrc && + (spans[span]->syncsrc == spans[span]->spanno)) + len += snprintf(page + len, count - len, "ClockSource "); + len += snprintf(page + len, count - len, "\n"); + if (spans[span]->bpvcount) + len += snprintf(page + len, count - len, "\tBPV count: %d\n", + spans[span]->bpvcount); + if (spans[span]->crc4count) + len += snprintf(page + len, count - len, + "\tCRC4 error count: %d\n", + spans[span]->crc4count); + if (spans[span]->ebitcount) + len += snprintf(page + len, count - len, + "\tE-bit error count: %d\n", + spans[span]->ebitcount); + if (spans[span]->fascount) + len += snprintf(page + len, count - len, + "\tFAS error count: %d\n", + spans[span]->fascount); + if (spans[span]->irqmisses) + len += snprintf(page + len, count - len, + "\tIRQ misses: %d\n", + spans[span]->irqmisses); + if (spans[span]->timingslips) + len += snprintf(page + len, count - len, + "\tTiming slips: %d\n", + spans[span]->timingslips); + len += snprintf(page + len, count - len, "\n"); + + for (x = 0; x < spans[span]->channels; x++) { + struct dahdi_chan *chan = spans[span]->chans[x]; + + if (chan->name) + len += snprintf(page + len, count - len, + "\t%4d %s ", chan->channo, chan->name); + + if (chan->sig) { + if (chan->sig == DAHDI_SIG_SLAVE) + len += snprintf(page+len, count-len, "%s ", + sigstr(chan->master->sig)); + else { + len += snprintf(page+len, count-len, "%s ", + sigstr(chan->sig)); + if (chan->nextslave && + (chan->master->channo == chan->channo)) + len += snprintf(page+len, count-len, + "Master "); + } + } + + if (test_bit(DAHDI_FLAGBIT_OPEN, &chan->flags)) + len += snprintf(page + len, count - len, "(In use) "); + +#ifdef OPTIMIZE_CHANMUTE + if (chan->chanmute) + len += snprintf(page+len, count-len, "(no pcm) "); +#endif + + len += fill_alarm_string(page+len, count-len, + chan->chan_alarms); + + if (chan->ec_factory) + len += snprintf(page+len, count-len, "(SWEC: %s) ", + chan->ec_factory->name); + + if (chan->ec_state) + len += snprintf(page+len, count-len, "(EC: %s) ", + chan->ec_state->ops->name); + + len += snprintf(page+len, count-len, "\n"); + + /* If everything printed so far is before beginning + * of request */ + if (len <= off) { + off -= len; + len = 0; + } + + /* stop if we've already generated enough */ + if (len > off + count) + break; + /* stop if we're NEAR danger limit. let it be -128 bytes. */ + if (len > count-128) + break; + } + count = real_count; + /* If everything printed so far is before beginning of request */ + if (len <= off) { + off = 0; + len = 0; + } + *start = page + off; + len -= off; /* un-count any remaining offset */ + *eof = 1; + if (len > count) + len = count; /* don't return bytes not asked for */ + return len; +} +#endif + +static int dahdi_first_empty_alias(void) +{ + /* Find the first conference which has no alias pointing to it */ + int x; + for (x=1;x 0; x--) { + if (confrev[x]) { + maxconfs = x + 1; + return; + } + } + + maxconfs = 0; +} + +static void recalc_maxlinks(void) +{ + int x; + + for (x = DAHDI_MAX_CONF - 1; x > 0; x--) { + if (conf_links[x].src || conf_links[x].dst) { + maxlinks = x + 1; + return; + } + } + + maxlinks = 0; +} + +static int dahdi_first_empty_conference(void) +{ + /* Find the first conference which has no alias */ + int x; + + for (x = DAHDI_MAX_CONF - 1; x > 0; x--) { + if (!confalias[x]) + return x; + } + + return -1; +} + +static int dahdi_get_conf_alias(int x) +{ + int a; + + if (confalias[x]) + return confalias[x]; + + /* Allocate an alias */ + a = dahdi_first_empty_alias(); + confalias[x] = a; + confrev[a] = x; + + /* Highest conference may have changed */ + recalc_maxconfs(); + + return a; +} + +static void dahdi_check_conf(int x) +{ + int y; + + /* return if no valid conf number */ + if (x <= 0) + return; + + /* Return if there is no alias */ + if (!confalias[x]) + return; + + for (y = 0; y < maxchans; y++) { + if (chans[y] && (chans[y]->confna == x) && + ((chans[y]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONF || + (chans[y]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONFANN || + (chans[y]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONFMON || + (chans[y]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONFANNMON || + (chans[y]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_REALANDPSEUDO)) { + return; + } + } + + /* If we get here, nobody is in the conference anymore. Clear it out + both forward and reverse */ + confrev[confalias[x]] = 0; + confalias[x] = 0; + + /* Highest conference may have changed */ + recalc_maxconfs(); +} + +/* enqueue an event on a channel */ +static void __qevent(struct dahdi_chan *chan, int event) +{ + /* if full, ignore */ + if ((chan->eventoutidx == 0) && (chan->eventinidx == (DAHDI_MAX_EVENTSIZE - 1))) + return; + + /* if full, ignore */ + if (chan->eventinidx == (chan->eventoutidx - 1)) + return; + + /* save the event */ + chan->eventbuf[chan->eventinidx++] = event; + + /* wrap the index, if necessary */ + if (chan->eventinidx >= DAHDI_MAX_EVENTSIZE) + chan->eventinidx = 0; + + /* wake em all up */ + if (chan->iomask & DAHDI_IOMUX_SIGEVENT) + wake_up_interruptible(&chan->eventbufq); + + wake_up_interruptible(&chan->readbufq); + wake_up_interruptible(&chan->writebufq); + wake_up_interruptible(&chan->sel); + + return; +} + +void dahdi_qevent_nolock(struct dahdi_chan *chan, int event) +{ + __qevent(chan, event); +} + +void dahdi_qevent_lock(struct dahdi_chan *chan, int event) +{ + unsigned long flags; + spin_lock_irqsave(&chan->lock, flags); + __qevent(chan, event); + spin_unlock_irqrestore(&chan->lock, flags); +} + +/* sleep in user space until woken up. Equivilant of tsleep() in BSD */ +static int schluffen(wait_queue_head_t *q) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(q, &wait); + current->state = TASK_INTERRUPTIBLE; + + if (!signal_pending(current)) + schedule(); + + current->state = TASK_RUNNING; + remove_wait_queue(q, &wait); + + if (signal_pending(current)) + return -ERESTARTSYS; + + return 0; +} + +static inline void calc_fcs(struct dahdi_chan *ss, int inwritebuf) +{ + int x; + unsigned int fcs = PPP_INITFCS; + unsigned char *data = ss->writebuf[inwritebuf]; + int len = ss->writen[inwritebuf]; + + /* Not enough space to do FCS calculation */ + if (len < 2) + return; + + for (x = 0; x < len - 2; x++) + fcs = PPP_FCS(fcs, data[x]); + + fcs ^= 0xffff; + /* Send out the FCS */ + data[len - 2] = (fcs & 0xff); + data[len - 1] = (fcs >> 8) & 0xff; +} + +static int dahdi_reallocbufs(struct dahdi_chan *ss, int blocksize, int numbufs) +{ + unsigned char *newtxbuf = NULL; + unsigned char *newrxbuf = NULL; + unsigned char *oldtxbuf = NULL; + unsigned char *oldrxbuf = NULL; + unsigned long flags; + int x; + + /* Check numbufs */ + if (numbufs < 2) + numbufs = 2; + + if (numbufs > DAHDI_MAX_NUM_BUFS) + numbufs = DAHDI_MAX_NUM_BUFS; + + /* We need to allocate our buffers now */ + if (blocksize) { + newtxbuf = kzalloc(blocksize * numbufs, GFP_KERNEL); + if (NULL == newtxbuf) + return -ENOMEM; + newrxbuf = kzalloc(blocksize * numbufs, GFP_KERNEL); + if (NULL == newrxbuf) { + kfree(newtxbuf); + return -ENOMEM; + } + } + + /* Now that we've allocated our new buffers, we can safely + move things around... */ + + spin_lock_irqsave(&ss->lock, flags); + + ss->blocksize = blocksize; /* set the blocksize */ + oldrxbuf = ss->readbuf[0]; /* Keep track of the old buffer */ + oldtxbuf = ss->writebuf[0]; + ss->readbuf[0] = NULL; + + if (newrxbuf) { + BUG_ON(NULL == newtxbuf); + for (x = 0; x < numbufs; x++) { + ss->readbuf[x] = newrxbuf + x * blocksize; + ss->writebuf[x] = newtxbuf + x * blocksize; + } + } else { + for (x = 0; x < numbufs; x++) { + ss->readbuf[x] = NULL; + ss->writebuf[x] = NULL; + } + } + + /* Mark all buffers as empty */ + for (x = 0; x < numbufs; x++) { + ss->writen[x] = + ss->writeidx[x]= + ss->readn[x]= + ss->readidx[x] = 0; + } + + /* Keep track of where our data goes (if it goes + anywhere at all) */ + if (newrxbuf) { + ss->inreadbuf = 0; + ss->inwritebuf = 0; + } else { + ss->inreadbuf = -1; + ss->inwritebuf = -1; + } + + ss->outreadbuf = -1; + ss->outwritebuf = -1; + ss->numbufs = numbufs; + + if ((ss->txbufpolicy == DAHDI_POLICY_WHEN_FULL) || (ss->txbufpolicy == DAHDI_POLICY_HALF_FULL)) + ss->txdisable = 1; + else + ss->txdisable = 0; + + if (ss->rxbufpolicy == DAHDI_POLICY_WHEN_FULL) + ss->rxdisable = 1; + else + ss->rxdisable = 0; + + spin_unlock_irqrestore(&ss->lock, flags); + + kfree(oldtxbuf); + kfree(oldrxbuf); + + return 0; +} + +static int dahdi_hangup(struct dahdi_chan *chan); +static void dahdi_set_law(struct dahdi_chan *chan, int law); + +/* Pull a DAHDI_CHUNKSIZE piece off the queue. Returns + 0 on success or -1 on failure. If failed, provides + silence */ +static int __buf_pull(struct confq *q, u_char *data, struct dahdi_chan *c, char *label) +{ + int oldoutbuf = q->outbuf; + /* Ain't nuffin to read */ + if (q->outbuf < 0) { + if (data) + memset(data, DAHDI_LIN2X(0,c), DAHDI_CHUNKSIZE); + return -1; + } + if (data) + memcpy(data, q->buf[q->outbuf], DAHDI_CHUNKSIZE); + q->outbuf = (q->outbuf + 1) % DAHDI_CB_SIZE; + + /* Won't be nuffin next time */ + if (q->outbuf == q->inbuf) { + q->outbuf = -1; + } + + /* If they thought there was no space then + there is now where we just read */ + if (q->inbuf < 0) + q->inbuf = oldoutbuf; + return 0; +} + +/* Returns a place to put stuff, or NULL if there is + no room */ + +static u_char *__buf_pushpeek(struct confq *q) +{ + if (q->inbuf < 0) + return NULL; + return q->buf[q->inbuf]; +} + +static u_char *__buf_peek(struct confq *q) +{ + if (q->outbuf < 0) + return NULL; + return q->buf[q->outbuf]; +} + +#ifdef BUF_MUNGE +static u_char *__buf_cpush(struct confq *q) +{ + int pos; + /* If we have no space, return where the + last space that we *did* have was */ + if (q->inbuf > -1) + return NULL; + pos = q->outbuf - 1; + if (pos < 0) + pos += DAHDI_CB_SIZE; + return q->buf[pos]; +} + +static void __buf_munge(struct dahdi_chan *chan, u_char *old, u_char *new) +{ + /* Run a weighted average of the old and new, in order to + mask a missing sample */ + int x; + int val; + for (x=0;xinbuf; + if (q->inbuf < 0) { + return -1; + } + if (data) + /* Copy in the data */ + memcpy(q->buf[q->inbuf], data, DAHDI_CHUNKSIZE); + + /* Advance the inbuf pointer */ + q->inbuf = (q->inbuf + 1) % DAHDI_CB_SIZE; + + if (q->inbuf == q->outbuf) { + /* No space anymore... */ + q->inbuf = -1; + } + /* If they don't think data is ready, let + them know it is now */ + if (q->outbuf < 0) { + q->outbuf = oldinbuf; + } + return 0; +} + +static void reset_conf(struct dahdi_chan *chan) +{ + int x; + + /* Empty out buffers and reset to initialization */ + + for (x = 0; x < DAHDI_CB_SIZE; x++) + chan->confin.buf[x] = chan->confin.buffer + DAHDI_CHUNKSIZE * x; + + chan->confin.inbuf = 0; + chan->confin.outbuf = -1; + + for (x = 0; x < DAHDI_CB_SIZE; x++) + chan->confout.buf[x] = chan->confout.buffer + DAHDI_CHUNKSIZE * x; + + chan->confout.inbuf = 0; + chan->confout.outbuf = -1; +} + + +static const struct dahdi_echocan_factory *find_echocan(const char *name) +{ + struct ecfactory *cur; + char name_upper[strlen(name) + 1]; + char *c; + const char *d; + char modname_buf[128] = "dahdi_echocan_"; + unsigned int tried_once = 0; + + for (c = name_upper, d = name; *d; c++, d++) { + *c = toupper(*d); + } + + *c = '\0'; + +retry: + read_lock(&ecfactory_list_lock); + + list_for_each_entry(cur, &ecfactory_list, list) { + if (!strcmp(name_upper, cur->ec->name)) { + if (try_module_get(cur->ec->owner)) { + read_unlock(&ecfactory_list_lock); + return cur->ec; + } else { + read_unlock(&ecfactory_list_lock); + return NULL; + } + } + } + + read_unlock(&ecfactory_list_lock); + + if (tried_once) { + return NULL; + } + + /* couldn't find it, let's try to load it */ + + for (c = &modname_buf[strlen(modname_buf)], d = name; *d; c++, d++) { + *c = tolower(*d); + } + + request_module("%s", modname_buf); + + tried_once = 1; + + /* and try one more time */ + goto retry; +} + +static void release_echocan(const struct dahdi_echocan_factory *ec) +{ + if (ec) + module_put(ec->owner); +} + +/** + * close_channel - close the channel, resetting any channel variables + * @chan: the dahdi_chan to close + * + * This function might be called before the channel is placed on the global + * array of channels, (chans), and therefore, neither this function nor it's + * children should depend on the dahdi_chan.channo member which is not set yet. + */ +static void close_channel(struct dahdi_chan *chan) +{ + unsigned long flags; + void *rxgain = NULL; + struct dahdi_echocan_state *ec_state; + const struct dahdi_echocan_factory *ec_current; + int oldconf; + short *readchunkpreec; +#ifdef CONFIG_DAHDI_PPP + struct ppp_channel *ppp; +#endif + + might_sleep(); + + /* XXX Buffers should be send out before reallocation!!! XXX */ + if (!(chan->flags & DAHDI_FLAG_NOSTDTXRX)) + dahdi_reallocbufs(chan, 0, 0); + spin_lock_irqsave(&chan->lock, flags); +#ifdef CONFIG_DAHDI_PPP + ppp = chan->ppp; + chan->ppp = NULL; +#endif + ec_state = chan->ec_state; + chan->ec_state = NULL; + ec_current = chan->ec_current; + chan->ec_current = NULL; + readchunkpreec = chan->readchunkpreec; + chan->readchunkpreec = NULL; + chan->curtone = NULL; + if (chan->curzone) + atomic_dec(&chan->curzone->refcount); + chan->curzone = NULL; + chan->cadencepos = 0; + chan->pdialcount = 0; + dahdi_hangup(chan); + chan->itimerset = chan->itimer = 0; + chan->pulsecount = 0; + chan->pulsetimer = 0; + chan->ringdebtimer = 0; + init_waitqueue_head(&chan->sel); + init_waitqueue_head(&chan->readbufq); + init_waitqueue_head(&chan->writebufq); + init_waitqueue_head(&chan->eventbufq); + init_waitqueue_head(&chan->txstateq); + chan->txdialbuf[0] = '\0'; + chan->digitmode = DIGIT_MODE_DTMF; + chan->dialing = 0; + chan->afterdialingtimer = 0; + /* initialize IO MUX mask */ + chan->iomask = 0; + /* save old conf number, if any */ + oldconf = chan->confna; + /* initialize conference variables */ + chan->_confn = 0; + if ((chan->sig & __DAHDI_SIG_DACS) != __DAHDI_SIG_DACS) { + chan->confna = 0; + chan->confmode = 0; + } + chan->confmute = 0; + /* release conference resource, if any to release */ + if (oldconf) dahdi_check_conf(oldconf); + chan->gotgs = 0; + reset_conf(chan); + + if (chan->gainalloc && chan->rxgain) + rxgain = chan->rxgain; + + chan->rxgain = defgain; + chan->txgain = defgain; + chan->gainalloc = 0; + chan->eventinidx = chan->eventoutidx = 0; + chan->flags &= ~(DAHDI_FLAG_LOOPED | DAHDI_FLAG_LINEAR | DAHDI_FLAG_PPP | DAHDI_FLAG_SIGFREEZE); + + dahdi_set_law(chan,0); + + memset(chan->conflast, 0, sizeof(chan->conflast)); + memset(chan->conflast1, 0, sizeof(chan->conflast1)); + memset(chan->conflast2, 0, sizeof(chan->conflast2)); + + if (chan->span && chan->span->dacs && oldconf) + chan->span->dacs(chan, NULL); + + if (ec_state) { + ec_state->ops->echocan_free(chan, ec_state); + release_echocan(ec_current); + } + + spin_unlock_irqrestore(&chan->lock, flags); + + if (rxgain) + kfree(rxgain); + if (readchunkpreec) + kfree(readchunkpreec); + +#ifdef CONFIG_DAHDI_PPP + if (ppp) { + tasklet_kill(&chan->ppp_calls); + skb_queue_purge(&chan->ppp_rq); + ppp_unregister_channel(ppp); + kfree(ppp); + } +#endif + +} + +static int free_tone_zone(int num) +{ + struct dahdi_zone *z = NULL; + int res = 0; + + if ((num >= DAHDI_TONE_ZONE_MAX) || (num < 0)) + return -EINVAL; + + write_lock(&zone_lock); + if (tone_zones[num]) { + if (!atomic_read(&tone_zones[num]->refcount)) { + z = tone_zones[num]; + tone_zones[num] = NULL; + } else { + res = -EBUSY; + } + } + write_unlock(&zone_lock); + + if (z) + kfree(z); + + return res; +} + +static int dahdi_register_tone_zone(int num, struct dahdi_zone *zone) +{ + int res = 0; + + if ((num >= DAHDI_TONE_ZONE_MAX) || (num < 0)) + return -EINVAL; + + write_lock(&zone_lock); + if (tone_zones[num]) { + res = -EINVAL; + } else { + res = 0; + tone_zones[num] = zone; + } + write_unlock(&zone_lock); + + if (!res) + module_printk(KERN_INFO, "Registered tone zone %d (%s)\n", num, zone->name); + + return res; +} + +static int start_tone_digit(struct dahdi_chan *chan, int tone) +{ + struct dahdi_tone *playtone = NULL; + int base, max; + + if (!chan->curzone) + return -ENODATA; + + switch (chan->digitmode) { + case DIGIT_MODE_DTMF: + /* Set dialing so that a dial operation doesn't interrupt this tone */ + chan->dialing = 1; + base = DAHDI_TONE_DTMF_BASE; + max = DAHDI_TONE_DTMF_MAX; + break; + case DIGIT_MODE_MFR2_FWD: + base = DAHDI_TONE_MFR2_FWD_BASE; + max = DAHDI_TONE_MFR2_FWD_MAX; + break; + case DIGIT_MODE_MFR2_REV: + base = DAHDI_TONE_MFR2_REV_BASE; + max = DAHDI_TONE_MFR2_REV_MAX; + break; + default: + return -EINVAL; + } + + if ((tone < base) || (tone > max)) + return -EINVAL; + + switch (chan->digitmode) { + case DIGIT_MODE_DTMF: + playtone = &chan->curzone->dtmf_continuous[tone - base]; + break; + case DIGIT_MODE_MFR2_FWD: + playtone = &chan->curzone->mfr2_fwd_continuous[tone - base]; + break; + case DIGIT_MODE_MFR2_REV: + playtone = &chan->curzone->mfr2_rev_continuous[tone - base]; + break; + } + + if (!playtone || !playtone->tonesamples) + return -ENOSYS; + + chan->curtone = playtone; + + return 0; +} + +static int start_tone(struct dahdi_chan *chan, int tone) +{ + int res = -EINVAL; + + /* Stop the current tone, no matter what */ + chan->tonep = 0; + chan->curtone = NULL; + chan->pdialcount = 0; + chan->txdialbuf[0] = '\0'; + chan->dialing = 0; + + if (tone == -1) { + /* Just stop the current tone */ + res = 0; + } else if (!chan->curzone) { + static int __warnonce = 1; + if (__warnonce) { + __warnonce = 0; + /* The tonezones are loaded by dahdi_cfg based on /etc/dahdi/system.conf. */ + module_printk(KERN_WARNING, "DAHDI: Cannot start tones until tone zone is loaded.\n"); + } + /* Note that no tone zone exists at the moment */ + res = -ENODATA; + } else if ((tone >= 0 && tone <= DAHDI_TONE_MAX)) { + /* Have a tone zone */ + if (chan->curzone->tones[tone]) { + chan->curtone = chan->curzone->tones[tone]; + res = 0; + } else { /* Indicate that zone is loaded but no such tone exists */ + res = -ENOSYS; + } + } else if (chan->digitmode == DIGIT_MODE_DTMF || + chan->digitmode == DIGIT_MODE_MFR2_FWD || + chan->digitmode == DIGIT_MODE_MFR2_REV) { + res = start_tone_digit(chan, tone); + } else { + chan->dialing = 0; + res = -EINVAL; + } + + if (chan->curtone) + dahdi_init_tone_state(&chan->ts, chan->curtone); + + return res; +} + +static int set_tone_zone(struct dahdi_chan *chan, int zone) +{ + int res = 0; + struct dahdi_zone *z; + + /* Do not call with the channel locked. */ + + if (zone == -1) + zone = default_zone; + + if ((zone >= DAHDI_TONE_ZONE_MAX) || (zone < 0)) + return -EINVAL; + + read_lock(&zone_lock); + + if ((z = tone_zones[zone])) { + unsigned long flags; + + spin_lock_irqsave(&chan->lock, flags); + + if (chan->curzone) + atomic_dec(&chan->curzone->refcount); + + atomic_inc(&z->refcount); + chan->curzone = z; + chan->tonezone = zone; + memcpy(chan->ringcadence, z->ringcadence, sizeof(chan->ringcadence)); + + spin_unlock_irqrestore(&chan->lock, flags); + } else { + res = -ENODATA; + } + + read_unlock(&zone_lock); + + return res; +} + +static void dahdi_set_law(struct dahdi_chan *chan, int law) +{ + if (!law) { + if (chan->deflaw) + law = chan->deflaw; + else + if (chan->span) law = chan->span->deflaw; + else law = DAHDI_LAW_MULAW; + } + if (law == DAHDI_LAW_ALAW) { + chan->xlaw = __dahdi_alaw; +#ifdef CONFIG_CALC_XLAW + chan->lineartoxlaw = __dahdi_lineartoalaw; +#else + chan->lin2x = __dahdi_lin2a; +#endif + } else { + chan->xlaw = __dahdi_mulaw; +#ifdef CONFIG_CALC_XLAW + chan->lineartoxlaw = __dahdi_lineartoulaw; +#else + chan->lin2x = __dahdi_lin2mu; +#endif + } +} + +static int dahdi_chan_reg(struct dahdi_chan *chan) +{ + int x; + unsigned long flags; + + might_sleep(); + + spin_lock_init(&chan->lock); + if (!chan->master) + chan->master = chan; + if (!chan->readchunk) + chan->readchunk = chan->sreadchunk; + if (!chan->writechunk) + chan->writechunk = chan->swritechunk; + dahdi_set_law(chan, 0); + close_channel(chan); + + write_lock_irqsave(&chan_lock, flags); + for (x = 1; x < DAHDI_MAX_CHANNELS; x++) { + if (chans[x]) + continue; + + chans[x] = chan; + if (maxchans < x + 1) + maxchans = x + 1; + chan->channo = x; + write_unlock_irqrestore(&chan_lock, flags); + /* set this AFTER running close_channel() so that + HDLC channels wont cause hangage */ + set_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags); + break; + } + + if (DAHDI_MAX_CHANNELS == x) { + write_unlock_irqrestore(&chan_lock, flags); + module_printk(KERN_ERR, "No more channels available\n"); + return -ENOMEM; + } + + return 0; +} + +char *dahdi_lboname(int x) +{ + if ((x < 0) || (x > 7)) + return "Unknown"; + return dahdi_txlevelnames[x]; +} + +#if defined(CONFIG_DAHDI_NET) || defined(CONFIG_DAHDI_PPP) +static inline void print_debug_writebuf(struct dahdi_chan* ss, struct sk_buff *skb, int oldbuf) +{ +#ifdef CONFIG_DAHDI_DEBUG + int x; + + module_printk(KERN_NOTICE, "Buffered %d bytes to go out in buffer %d\n", ss->writen[oldbuf], oldbuf); + module_printk(KERN_DEBUG ""); + for (x=0;xwriten[oldbuf];x++) + printk("%02x ", ss->writebuf[oldbuf][x]); + printk("\n"); +#endif +} +#endif + +#ifdef CONFIG_DAHDI_NET +#ifdef NEW_HDLC_INTERFACE +static int dahdi_net_open(struct net_device *dev) +{ + int res = hdlc_open(dev); + struct dahdi_chan *ms = dev_to_ztchan(dev); + +/* if (!dev->hard_start_xmit) return res; is this really necessary? --byg */ + if (res) /* this is necessary to avoid kernel panic when UNSPEC link encap, proven --byg */ + return res; +#else +static int dahdi_net_open(hdlc_device *hdlc) +{ + struct dahdi_chan *ms = hdlc_to_ztchan(hdlc); + int res; +#endif + if (!ms) { + module_printk(KERN_NOTICE, "dahdi_net_open: nothing??\n"); + return -EINVAL; + } + if (test_bit(DAHDI_FLAGBIT_OPEN, &ms->flags)) { + module_printk(KERN_NOTICE, "%s is already open!\n", ms->name); + return -EBUSY; + } + if (!(ms->flags & DAHDI_FLAG_NETDEV)) { + module_printk(KERN_NOTICE, "%s is not a net device!\n", ms->name); + return -EINVAL; + } + ms->txbufpolicy = DAHDI_POLICY_IMMEDIATE; + ms->rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + + res = dahdi_reallocbufs(ms, DAHDI_DEFAULT_MTU_MRU, DAHDI_DEFAULT_NUM_BUFS); + if (res) + return res; + + fasthdlc_init(&ms->rxhdlc, (ms->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64); + fasthdlc_init(&ms->txhdlc, (ms->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64); + ms->infcs = PPP_INITFCS; + + netif_start_queue(ztchan_to_dev(ms)); + +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "DAHDINET: Opened channel %d name %s\n", ms->channo, ms->name); +#endif + return 0; +} + +static int dahdi_register_hdlc_device(struct net_device *dev, const char *dev_name) +{ + int result; + + if (dev_name && *dev_name) { + if ((result = dev_alloc_name(dev, dev_name)) < 0) + return result; + } + result = register_netdev(dev); + if (result != 0) + return -EIO; +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,14) + if (netif_carrier_ok(dev)) + netif_carrier_off(dev); /* no carrier until DCD goes up */ +#endif + return 0; +} + +#ifdef NEW_HDLC_INTERFACE +static int dahdi_net_stop(struct net_device *dev) +{ + hdlc_device *h = dev_to_hdlc(dev); + struct dahdi_hdlc *hdlc = h->priv; + +#else +static void dahdi_net_close(hdlc_device *hdlc) +{ +#endif + struct dahdi_chan *ms = hdlc_to_ztchan(hdlc); + if (!ms) { +#ifdef NEW_HDLC_INTERFACE + module_printk(KERN_NOTICE, "dahdi_net_stop: nothing??\n"); + return 0; +#else + module_printk(KERN_NOTICE, "dahdi_net_close: nothing??\n"); + return; +#endif + } + if (!(ms->flags & DAHDI_FLAG_NETDEV)) { +#ifdef NEW_HDLC_INTERFACE + module_printk(KERN_NOTICE, "dahdi_net_stop: %s is not a net device!\n", ms->name); + return 0; +#else + module_printk(KERN_NOTICE, "dahdi_net_close: %s is not a net device!\n", ms->name); + return; +#endif + } + /* Not much to do here. Just deallocate the buffers */ + netif_stop_queue(ztchan_to_dev(ms)); + dahdi_reallocbufs(ms, 0, 0); + hdlc_close(dev); +#ifdef NEW_HDLC_INTERFACE + return 0; +#else + return; +#endif +} + +#ifdef NEW_HDLC_INTERFACE +/* kernel 2.4.20+ has introduced attach function, dunno what to do, + just copy sources from dscc4 to be sure and ready for further mastering, + NOOP right now (i.e. really a stub) --byg */ +static int dahdi_net_attach(struct net_device *dev, unsigned short encoding, + unsigned short parity) +{ +/* struct net_device *dev = hdlc_to_dev(hdlc); + struct dscc4_dev_priv *dpriv = dscc4_priv(dev); + + if (encoding != ENCODING_NRZ && + encoding != ENCODING_NRZI && + encoding != ENCODING_FM_MARK && + encoding != ENCODING_FM_SPACE && + encoding != ENCODING_MANCHESTER) + return -EINVAL; + + if (parity != PARITY_NONE && + parity != PARITY_CRC16_PR0_CCITT && + parity != PARITY_CRC16_PR1_CCITT && + parity != PARITY_CRC32_PR0_CCITT && + parity != PARITY_CRC32_PR1_CCITT) + return -EINVAL; + + dpriv->encoding = encoding; + dpriv->parity = parity;*/ + return 0; +} +#endif + +static struct dahdi_hdlc *dahdi_hdlc_alloc(void) +{ + return kzalloc(sizeof(struct dahdi_hdlc), GFP_KERNEL); +} + +#ifdef NEW_HDLC_INTERFACE +static int dahdi_xmit(struct sk_buff *skb, struct net_device *dev) +{ + /* FIXME: this construction seems to be not very optimal for me but I could find nothing better at the moment (Friday, 10PM :( ) --byg */ +/* struct dahdi_chan *ss = hdlc_to_ztchan(list_entry(dev, struct dahdi_hdlc, netdev.netdev));*/ + struct dahdi_chan *ss = dev_to_ztchan(dev); + struct net_device_stats *stats = hdlc_stats(dev); + +#else +static int dahdi_xmit(hdlc_device *hdlc, struct sk_buff *skb) +{ + struct dahdi_chan *ss = hdlc_to_ztchan(hdlc); + struct net_device *dev = &ss->hdlcnetdev->netdev.netdev; + struct net_device_stats *stats = &ss->hdlcnetdev->netdev.stats; +#endif + int retval = 1; + int x,oldbuf; + unsigned int fcs; + unsigned char *data; + unsigned long flags; + /* See if we have any buffers */ + spin_lock_irqsave(&ss->lock, flags); + if (skb->len > ss->blocksize - 2) { + module_printk(KERN_ERR, "dahdi_xmit(%s): skb is too large (%d > %d)\n", dev->name, skb->len, ss->blocksize -2); + stats->tx_dropped++; + retval = 0; + } else if (ss->inwritebuf >= 0) { + /* We have a place to put this packet */ + /* XXX We should keep the SKB and avoid the memcpy XXX */ + data = ss->writebuf[ss->inwritebuf]; + memcpy(data, skb->data, skb->len); + ss->writen[ss->inwritebuf] = skb->len; + ss->writeidx[ss->inwritebuf] = 0; + /* Calculate the FCS */ + fcs = PPP_INITFCS; + for (x=0;xlen;x++) + fcs = PPP_FCS(fcs, data[x]); + /* Invert it */ + fcs ^= 0xffff; + /* Send it out LSB first */ + data[ss->writen[ss->inwritebuf]++] = (fcs & 0xff); + data[ss->writen[ss->inwritebuf]++] = (fcs >> 8) & 0xff; + /* Advance to next window */ + oldbuf = ss->inwritebuf; + ss->inwritebuf = (ss->inwritebuf + 1) % ss->numbufs; + + if (ss->inwritebuf == ss->outwritebuf) { + /* Whoops, no more space. */ + ss->inwritebuf = -1; + + netif_stop_queue(ztchan_to_dev(ss)); + } + if (ss->outwritebuf < 0) { + /* Let the interrupt handler know there's + some space for us */ + ss->outwritebuf = oldbuf; + } + dev->trans_start = jiffies; + stats->tx_packets++; + stats->tx_bytes += ss->writen[oldbuf]; + print_debug_writebuf(ss, skb, oldbuf); + retval = 0; + /* Free the SKB */ + dev_kfree_skb_any(skb); + } + spin_unlock_irqrestore(&ss->lock, flags); + return retval; +} + +#ifdef NEW_HDLC_INTERFACE +static int dahdi_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + return hdlc_ioctl(dev, ifr, cmd); +} +#else +static int dahdi_net_ioctl(hdlc_device *hdlc, struct ifreq *ifr, int cmd) +{ + return -EIO; +} +#endif + +#endif + +#ifdef CONFIG_DAHDI_PPP + +static int dahdi_ppp_xmit(struct ppp_channel *ppp, struct sk_buff *skb) +{ + + /* + * If we can't handle the packet right now, return 0. If we + * we handle or drop it, return 1. Always free if we return + * 1 and never if we return 0 + */ + struct dahdi_chan *ss = ppp->private; + int x,oldbuf; + unsigned int fcs; + unsigned char *data; + unsigned long flags; + int retval = 0; + + /* See if we have any buffers */ + spin_lock_irqsave(&ss->lock, flags); + if (!(test_bit(DAHDI_FLAGBIT_OPEN, &ss->flags))) { + module_printk(KERN_ERR, "Can't transmit on closed channel\n"); + retval = 1; + } else if (skb->len > ss->blocksize - 4) { + module_printk(KERN_ERR, "dahdi_ppp_xmit(%s): skb is too large (%d > %d)\n", ss->name, skb->len, ss->blocksize -2); + retval = 1; + } else if (ss->inwritebuf >= 0) { + /* We have a place to put this packet */ + /* XXX We should keep the SKB and avoid the memcpy XXX */ + data = ss->writebuf[ss->inwritebuf]; + /* Start with header of two bytes */ + /* Add "ALL STATIONS" and "UNNUMBERED" */ + data[0] = 0xff; + data[1] = 0x03; + ss->writen[ss->inwritebuf] = 2; + + /* Copy real data and increment amount written */ + memcpy(data + 2, skb->data, skb->len); + + ss->writen[ss->inwritebuf] += skb->len; + + /* Re-set index back to zero */ + ss->writeidx[ss->inwritebuf] = 0; + + /* Calculate the FCS */ + fcs = PPP_INITFCS; + for (x=0;xlen + 2;x++) + fcs = PPP_FCS(fcs, data[x]); + /* Invert it */ + fcs ^= 0xffff; + + /* Point past the real data now */ + data += (skb->len + 2); + + /* Send FCS out LSB first */ + data[0] = (fcs & 0xff); + data[1] = (fcs >> 8) & 0xff; + + /* Account for FCS length */ + ss->writen[ss->inwritebuf]+=2; + + /* Advance to next window */ + oldbuf = ss->inwritebuf; + ss->inwritebuf = (ss->inwritebuf + 1) % ss->numbufs; + + if (ss->inwritebuf == ss->outwritebuf) { + /* Whoops, no more space. */ + ss->inwritebuf = -1; + } + if (ss->outwritebuf < 0) { + /* Let the interrupt handler know there's + some space for us */ + ss->outwritebuf = oldbuf; + } + print_debug_writebuf(ss, skb, oldbuf); + retval = 1; + } + spin_unlock_irqrestore(&ss->lock, flags); + if (retval) { + /* Get rid of the SKB if we're returning non-zero */ + /* N.B. this is called in process or BH context so + dev_kfree_skb is OK. */ + dev_kfree_skb(skb); + } + return retval; +} + +static int dahdi_ppp_ioctl(struct ppp_channel *ppp, unsigned int cmd, unsigned long flags) +{ + return -EIO; +} + +static struct ppp_channel_ops ztppp_ops = +{ + .start_xmit = dahdi_ppp_xmit, + .ioctl = dahdi_ppp_ioctl, +}; + +#endif + +static void dahdi_chan_unreg(struct dahdi_chan *chan) +{ + int x; + unsigned long flags; + + might_sleep(); + + release_echocan(chan->ec_factory); + +#ifdef CONFIG_DAHDI_NET + if (chan->flags & DAHDI_FLAG_NETDEV) { + unregister_hdlc_device(chan->hdlcnetdev->netdev); + free_netdev(chan->hdlcnetdev->netdev); + kfree(chan->hdlcnetdev); + chan->hdlcnetdev = NULL; + } +#endif + write_lock_irqsave(&chan_lock, flags); + if (test_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags)) { + chans[chan->channo] = NULL; + clear_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags); + } +#ifdef CONFIG_DAHDI_PPP + if (chan->ppp) { + module_printk(KERN_NOTICE, "HUH??? PPP still attached??\n"); + } +#endif + maxchans = 0; + for (x=1;xmaster == chan) { + chans[x]->master = chans[x]; + } + if ((chans[x]->confna == chan->channo) && + ((chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR || + (chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORTX || + (chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORBOTH || + (chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR_RX_PREECHO || + (chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR_TX_PREECHO || + (chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORBOTH_PREECHO || + (chans[x]->confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_DIGITALMON)) { + /* Take them out of conference with us */ + /* release conference resource if any */ + if (chans[x]->confna) { + dahdi_check_conf(chans[x]->confna); + if (chans[x]->span && chans[x]->span->dacs) + chans[x]->span->dacs(chans[x], NULL); + } + chans[x]->confna = 0; + chans[x]->_confn = 0; + chans[x]->confmode = 0; + } + } + chan->channo = -1; + write_unlock_irqrestore(&chan_lock, flags); +} + +static ssize_t dahdi_chan_read(struct file *file, char *usrbuf, size_t count, int unit) +{ + struct dahdi_chan *chan = chans[unit]; + int amnt; + int res, rv; + int oldbuf,x; + unsigned long flags; + + /* Make sure count never exceeds 65k, and make sure it's unsigned */ + count &= 0xffff; + + if (!chan) + return -EINVAL; + + if (count < 1) + return -EINVAL; + + for (;;) { + spin_lock_irqsave(&chan->lock, flags); + if (chan->eventinidx != chan->eventoutidx) { + spin_unlock_irqrestore(&chan->lock, flags); + return -ELAST /* - chan->eventbuf[chan->eventoutidx]*/; + } + res = chan->outreadbuf; + if (chan->rxdisable) + res = -1; + spin_unlock_irqrestore(&chan->lock, flags); + if (res >= 0) + break; + if (file->f_flags & O_NONBLOCK) + return -EAGAIN; + rv = schluffen(&chan->readbufq); + if (rv) + return rv; + } + amnt = count; +/* added */ +#if 0 + if ((unit == 24) || (unit == 48) || (unit == 16) || (unit == 47)) { + int myamnt = amnt; + int x; + if (amnt > chan->readn[res]) + myamnt = chan->readn[res]; + module_printk(KERN_NOTICE, "dahdi_chan_read(unit: %d, inwritebuf: %d, outwritebuf: %d amnt: %d\n", + unit, chan->inwritebuf, chan->outwritebuf, myamnt); + + module_printk(KERN_DEBUG, "\t("); + for (x = 0; x < myamnt; x++) + printk((x ? " %02x" : "%02x"), (unsigned char)usrbuf[x]); + printk(")\n"); + } +#endif +/* end addition */ + if (chan->flags & DAHDI_FLAG_LINEAR) { + if (amnt > (chan->readn[res] << 1)) + amnt = chan->readn[res] << 1; + if (amnt) { + /* There seems to be a max stack size, so we have + to do this in smaller pieces */ + short lindata[128]; + int left = amnt >> 1; /* amnt is in bytes */ + int pos = 0; + int pass; + while (left) { + pass = left; + if (pass > 128) + pass = 128; + for (x = 0; x < pass; x++) + lindata[x] = DAHDI_XLAW(chan->readbuf[res][x + pos], chan); + if (copy_to_user(usrbuf + (pos << 1), lindata, pass << 1)) + return -EFAULT; + left -= pass; + pos += pass; + } + } + } else { + if (amnt > chan->readn[res]) + amnt = chan->readn[res]; + if (amnt) { + if (copy_to_user(usrbuf, chan->readbuf[res], amnt)) + return -EFAULT; + } + } + spin_lock_irqsave(&chan->lock, flags); + chan->readidx[res] = 0; + chan->readn[res] = 0; + oldbuf = res; + chan->outreadbuf = (res + 1) % chan->numbufs; + if (chan->outreadbuf == chan->inreadbuf) { + /* Out of stuff */ + chan->outreadbuf = -1; + if (chan->rxbufpolicy == DAHDI_POLICY_WHEN_FULL) + chan->rxdisable = 1; + } + if (chan->inreadbuf < 0) { + /* Notify interrupt handler that we have some space now */ + chan->inreadbuf = oldbuf; + } + spin_unlock_irqrestore(&chan->lock, flags); + + return amnt; +} + +static int num_filled_bufs(struct dahdi_chan *chan) +{ + int range1, range2; + + if (chan->inwritebuf < 0) { + return chan->numbufs; + } + + if (chan->outwritebuf < 0) { + return 0; + } + + if (chan->outwritebuf <= chan->inwritebuf) { + return chan->inwritebuf - chan->outwritebuf; + } + + /* This means (in > out) and we have wrap around */ + range1 = chan->numbufs - chan->outwritebuf; + range2 = chan->inwritebuf; + + return range1 + range2; +} + +static ssize_t dahdi_chan_write(struct file *file, const char *usrbuf, size_t count, int unit) +{ + unsigned long flags; + struct dahdi_chan *chan = chans[unit]; + int res, amnt, oldbuf, rv, x; + + /* Make sure count never exceeds 65k, and make sure it's unsigned */ + count &= 0xffff; + + if (!chan) + return -EINVAL; + + if (count < 1) { + return -EINVAL; + } + + for (;;) { + spin_lock_irqsave(&chan->lock, flags); + if ((chan->curtone || chan->pdialcount) && !(chan->flags & DAHDI_FLAG_PSEUDO)) { + chan->curtone = NULL; + chan->tonep = 0; + chan->dialing = 0; + chan->txdialbuf[0] = '\0'; + chan->pdialcount = 0; + } + if (chan->eventinidx != chan->eventoutidx) { + spin_unlock_irqrestore(&chan->lock, flags); + return -ELAST; + } + res = chan->inwritebuf; + spin_unlock_irqrestore(&chan->lock, flags); + if (res >= 0) + break; + if (file->f_flags & O_NONBLOCK) { +#ifdef BUFFER_DEBUG + printk("Error: Nonblock\n"); +#endif + return -EAGAIN; + } + /* Wait for something to be available */ + rv = schluffen(&chan->writebufq); + if (rv) { + return rv; + } + } + + amnt = count; + if (chan->flags & DAHDI_FLAG_LINEAR) { + if (amnt > (chan->blocksize << 1)) + amnt = chan->blocksize << 1; + } else { + if (amnt > chan->blocksize) + amnt = chan->blocksize; + } + +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "dahdi_chan_write(unit: %d, res: %d, outwritebuf: %d amnt: %d\n", + unit, res, chan->outwritebuf, amnt); +#endif +#if 0 + if ((unit == 24) || (unit == 48) || (unit == 16) || (unit == 47)) { + int x; + module_printk(KERN_NOTICE, "dahdi_chan_write/in(unit: %d, res: %d, outwritebuf: %d amnt: %d, txdisable: %d)\n", + unit, res, chan->outwritebuf, amnt, chan->txdisable); + module_printk(KERN_DEBUG, "\t("); for (x = 0; x < amnt; x++) module_printk(KERN_DEBUG, (x ? " %02x" : "%02x"), (unsigned char)usrbuf[x]); + module_printk(KERN_DEBUG, ")\n"); + } +#endif + + if (amnt) { + if (chan->flags & DAHDI_FLAG_LINEAR) { + /* There seems to be a max stack size, so we have + to do this in smaller pieces */ + short lindata[128]; + int left = amnt >> 1; /* amnt is in bytes */ + int pos = 0; + int pass; + while (left) { + pass = left; + if (pass > 128) + pass = 128; + if (copy_from_user(lindata, usrbuf + (pos << 1), pass << 1)) { + return -EFAULT; + } + left -= pass; + for (x = 0; x < pass; x++) + chan->writebuf[res][x + pos] = DAHDI_LIN2X(lindata[x], chan); + pos += pass; + } + chan->writen[res] = amnt >> 1; + } else { + if (copy_from_user(chan->writebuf[res], usrbuf, amnt)) { + return -EFAULT; + } + chan->writen[res] = amnt; + } + chan->writeidx[res] = 0; + if (chan->flags & DAHDI_FLAG_FCS) + calc_fcs(chan, res); + oldbuf = res; + spin_lock_irqsave(&chan->lock, flags); + chan->inwritebuf = (res + 1) % chan->numbufs; + + if (chan->inwritebuf == chan->outwritebuf) { + /* Don't stomp on the transmitter, just wait for them to + wake us up */ + chan->inwritebuf = -1; + /* Make sure the transmitter is transmitting in case of POLICY_WHEN_FULL */ + chan->txdisable = 0; + } + + if (chan->outwritebuf < 0) { + /* Okay, the interrupt handler has been waiting for us. Give them a buffer */ + chan->outwritebuf = oldbuf; + } + + if ((chan->txbufpolicy == DAHDI_POLICY_HALF_FULL) && (chan->txdisable)) { + if (num_filled_bufs(chan) >= (chan->numbufs >> 1)) { +#ifdef BUFFER_DEBUG + printk("Reached buffer fill mark of %d\n", num_filled_bufs(chan)); +#endif + chan->txdisable = 0; + } + } + +#ifdef BUFFER_DEBUG + if ((chan->statcount <= 0) || (amnt != 128) || (num_filled_bufs(chan) != chan->lastnumbufs)) { + printk("amnt: %d Number of filled buffers: %d\n", amnt, num_filled_bufs(chan)); + chan->statcount = 32000; + chan->lastnumbufs = num_filled_bufs(chan); + } +#endif + + spin_unlock_irqrestore(&chan->lock, flags); + + if (chan->flags & DAHDI_FLAG_NOSTDTXRX && chan->span->hdlc_hard_xmit) + chan->span->hdlc_hard_xmit(chan); + } + return amnt; +} + +static int dahdi_ctl_open(struct inode *inode, struct file *file) +{ + /* Nothing to do, really */ + return 0; +} + +static int dahdi_chan_open(struct inode *inode, struct file *file) +{ + /* Nothing to do here for now either */ + return 0; +} + +static int dahdi_ctl_release(struct inode *inode, struct file *file) +{ + /* Nothing to do */ + return 0; +} + +static int dahdi_chan_release(struct inode *inode, struct file *file) +{ + /* Nothing to do for now */ + return 0; +} + +static void set_txtone(struct dahdi_chan *ss, int fac, int init_v2, int init_v3) +{ + if (fac == 0) { + ss->v2_1 = 0; + ss->v3_1 = 0; + return; + } + ss->txtone = fac; + ss->v1_1 = 0; + ss->v2_1 = init_v2; + ss->v3_1 = init_v3; + return; +} + +static void dahdi_rbs_sethook(struct dahdi_chan *chan, int txsig, int txstate, + int timeout) +{ + static const struct { + unsigned int sig_type; + /* Index is dahdi_txsig enum */ + unsigned int bits[DAHDI_TXSIG_TOTAL]; + } outs[NUM_SIGS] = { + { + /* + * We set the idle case of the DAHDI_SIG_NONE to this pattern to make idle E1 CAS + * channels happy. Should not matter with T1, since on an un-configured channel, + * who cares what the sig bits are as long as they are stable + */ + .sig_type = DAHDI_SIG_NONE, + .bits[DAHDI_TXSIG_ONHOOK] = DAHDI_BITS_ACD, + }, { + .sig_type = DAHDI_SIG_EM, + .bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_ABCD, + .bits[DAHDI_TXSIG_START] = DAHDI_BITS_ABCD, + }, { + .sig_type = DAHDI_SIG_FXSLS, + .bits[DAHDI_TXSIG_ONHOOK] = DAHDI_BITS_BD, + .bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_ABCD, + .bits[DAHDI_TXSIG_START] = DAHDI_BITS_ABCD, + }, { + .sig_type = DAHDI_SIG_FXSGS, + .bits[DAHDI_TXSIG_ONHOOK] = DAHDI_BITS_BD, + .bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_ABCD, +#ifndef CONFIG_CAC_GROUNDSTART + .bits[DAHDI_TXSIG_START] = DAHDI_BITS_AC, +#endif + }, { + .sig_type = DAHDI_SIG_FXSKS, + .bits[DAHDI_TXSIG_ONHOOK] = DAHDI_BITS_BD, + .bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_ABCD, + .bits[DAHDI_TXSIG_START] = DAHDI_BITS_ABCD, + }, { + .sig_type = DAHDI_SIG_FXOLS, + .bits[DAHDI_TXSIG_ONHOOK] = DAHDI_BITS_BD, + .bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_BD, + }, { + .sig_type = DAHDI_SIG_FXOGS, + .bits[DAHDI_TXSIG_ONHOOK] = DAHDI_BITS_ABCD, + .bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_BD, + }, { + .sig_type = DAHDI_SIG_FXOKS, + .bits[DAHDI_TXSIG_ONHOOK] = DAHDI_BITS_BD, + .bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_BD, + .bits[DAHDI_TXSIG_KEWL] = DAHDI_BITS_ABCD, + }, { + .sig_type = DAHDI_SIG_SF, + .bits[DAHDI_TXSIG_ONHOOK] = DAHDI_BITS_BCD, + .bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_ABCD, + .bits[DAHDI_TXSIG_START] = DAHDI_BITS_ABCD, + .bits[DAHDI_TXSIG_KEWL] = DAHDI_BITS_BCD, + }, { + .sig_type = DAHDI_SIG_EM_E1, + .bits[DAHDI_TXSIG_ONHOOK] = DAHDI_DBIT, + .bits[DAHDI_TXSIG_OFFHOOK] = DAHDI_BITS_ABD, + .bits[DAHDI_TXSIG_START] = DAHDI_BITS_ABD, + .bits[DAHDI_TXSIG_KEWL] = DAHDI_DBIT, + } + }; + int x; + + /* if no span, return doing nothing */ + if (!chan->span) + return; + + if (!(chan->span->flags & DAHDI_FLAG_RBS)) { + module_printk(KERN_NOTICE, "dahdi_rbs: Tried to set RBS hook state on non-RBS channel %s\n", chan->name); + return; + } + if ((txsig > 3) || (txsig < 0)) { + module_printk(KERN_NOTICE, "dahdi_rbs: Tried to set RBS hook state %d (> 3) on channel %s\n", txsig, chan->name); + return; + } + if (!chan->span->rbsbits && !chan->span->hooksig) { + module_printk(KERN_NOTICE, "dahdi_rbs: Tried to set RBS hook state %d on channel %s while span %s lacks rbsbits or hooksig function\n", + txsig, chan->name, chan->span->name); + return; + } + /* Don't do anything for RBS */ + if (chan->sig == DAHDI_SIG_DACS_RBS) + return; + chan->txstate = txstate; + + /* if tone signalling */ + if (chan->sig == DAHDI_SIG_SF) { + chan->txhooksig = txsig; + if (chan->txtone) { /* if set to make tone for tx */ + if ((txsig && !(chan->toneflags & DAHDI_REVERSE_TXTONE)) || + ((!txsig) && (chan->toneflags & DAHDI_REVERSE_TXTONE))) { + set_txtone(chan,chan->txtone,chan->tx_v2,chan->tx_v3); + } else { + set_txtone(chan,0,0,0); + } + } + chan->otimer = timeout * DAHDI_CHUNKSIZE; /* Otimer is timer in samples */ + return; + } + if (chan->span->hooksig) { + if (chan->txhooksig != txsig) { + chan->txhooksig = txsig; + chan->span->hooksig(chan, txsig); + } + chan->otimer = timeout * DAHDI_CHUNKSIZE; /* Otimer is timer in samples */ + return; + } else { + for (x = 0; x < NUM_SIGS; x++) { + if (outs[x].sig_type == chan->sig) { +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "Setting bits to %d for channel %s state %d in %d signalling\n", outs[x].bits[txsig], chan->name, txsig, chan->sig); +#endif + chan->txhooksig = txsig; + chan->txsig = outs[x].bits[txsig]; + chan->span->rbsbits(chan, chan->txsig); + chan->otimer = timeout * DAHDI_CHUNKSIZE; /* Otimer is timer in samples */ + return; + } + } + } + module_printk(KERN_NOTICE, "dahdi_rbs: Don't know RBS signalling type %d on channel %s\n", chan->sig, chan->name); +} + +static int dahdi_cas_setbits(struct dahdi_chan *chan, int bits) +{ + /* if no span, return as error */ + if (!chan->span) + return -1; + if (chan->span->rbsbits) { + chan->txsig = bits; + chan->span->rbsbits(chan, bits); + } else { + module_printk(KERN_NOTICE, "Huh? CAS setbits, but no RBS bits function\n"); + } + + return 0; +} + +static int dahdi_hangup(struct dahdi_chan *chan) +{ + int x, res = 0; + + /* Can't hangup pseudo channels */ + if (!chan->span) + return 0; + + /* Can't hang up a clear channel */ + if (chan->flags & (DAHDI_FLAG_CLEAR | DAHDI_FLAG_NOSTDTXRX)) + return -EINVAL; + + chan->kewlonhook = 0; + + if ((chan->sig == DAHDI_SIG_FXSLS) || (chan->sig == DAHDI_SIG_FXSKS) || + (chan->sig == DAHDI_SIG_FXSGS)) { + chan->ringdebtimer = RING_DEBOUNCE_TIME; + } + + if (chan->span->flags & DAHDI_FLAG_RBS) { + if (chan->sig == DAHDI_SIG_CAS) { + dahdi_cas_setbits(chan, chan->idlebits); + } else if ((chan->sig == DAHDI_SIG_FXOKS) && (chan->txstate != DAHDI_TXSTATE_ONHOOK) + /* if other party is already on-hook we shouldn't do any battery drop */ + && !((chan->rxhooksig == DAHDI_RXSIG_ONHOOK) && (chan->itimer <= 0))) { + /* Do RBS signalling on the channel's behalf */ + dahdi_rbs_sethook(chan, DAHDI_TXSIG_KEWL, DAHDI_TXSTATE_KEWL, DAHDI_KEWLTIME); + } else + dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_ONHOOK, 0); + } else { + /* Let the driver hang up the line if it wants to */ + if (chan->span->sethook) { + if (chan->txhooksig != DAHDI_ONHOOK) { + chan->txhooksig = DAHDI_ONHOOK; + res = chan->span->sethook(chan, DAHDI_ONHOOK); + } else + res = 0; + } + } + + /* if not registered yet, just return here */ + if (!test_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags)) + return res; + + /* Mark all buffers as empty */ + for (x = 0; x < chan->numbufs; x++) { + chan->writen[x] = + chan->writeidx[x]= + chan->readn[x]= + chan->readidx[x] = 0; + } + + if (chan->readbuf[0]) { + chan->inreadbuf = 0; + chan->inwritebuf = 0; + } else { + chan->inreadbuf = -1; + chan->inwritebuf = -1; + } + chan->outreadbuf = -1; + chan->outwritebuf = -1; + chan->dialing = 0; + chan->afterdialingtimer = 0; + chan->curtone = NULL; + chan->pdialcount = 0; + chan->cadencepos = 0; + chan->txdialbuf[0] = 0; + + return res; +} + +static int initialize_channel(struct dahdi_chan *chan) +{ + int res; + unsigned long flags; + void *rxgain=NULL; + struct dahdi_echocan_state *ec_state; + const struct dahdi_echocan_factory *ec_current; + + if ((res = dahdi_reallocbufs(chan, DAHDI_DEFAULT_BLOCKSIZE, DAHDI_DEFAULT_NUM_BUFS))) + return res; + + spin_lock_irqsave(&chan->lock, flags); + + chan->rxbufpolicy = DAHDI_POLICY_IMMEDIATE; + chan->txbufpolicy = DAHDI_POLICY_IMMEDIATE; + + ec_state = chan->ec_state; + chan->ec_state = NULL; + ec_current = chan->ec_current; + chan->ec_current = NULL; + + chan->txdisable = 0; + chan->rxdisable = 0; + + chan->digitmode = DIGIT_MODE_DTMF; + chan->dialing = 0; + chan->afterdialingtimer = 0; + + chan->cadencepos = 0; + chan->firstcadencepos = 0; /* By default loop back to first cadence position */ + + /* HDLC & FCS stuff */ + fasthdlc_init(&chan->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64); + fasthdlc_init(&chan->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64); + chan->infcs = PPP_INITFCS; + + /* Timings for RBS */ + chan->prewinktime = DAHDI_DEFAULT_PREWINKTIME; + chan->preflashtime = DAHDI_DEFAULT_PREFLASHTIME; + chan->winktime = DAHDI_DEFAULT_WINKTIME; + chan->flashtime = DAHDI_DEFAULT_FLASHTIME; + + if (chan->sig & __DAHDI_SIG_FXO) + chan->starttime = DAHDI_DEFAULT_RINGTIME; + else + chan->starttime = DAHDI_DEFAULT_STARTTIME; + chan->rxwinktime = DAHDI_DEFAULT_RXWINKTIME; + chan->rxflashtime = DAHDI_DEFAULT_RXFLASHTIME; + chan->debouncetime = DAHDI_DEFAULT_DEBOUNCETIME; + chan->pulsemaketime = DAHDI_DEFAULT_PULSEMAKETIME; + chan->pulsebreaktime = DAHDI_DEFAULT_PULSEBREAKTIME; + chan->pulseaftertime = DAHDI_DEFAULT_PULSEAFTERTIME; + + /* Initialize RBS timers */ + chan->itimerset = chan->itimer = chan->otimer = 0; + chan->ringdebtimer = 0; + + init_waitqueue_head(&chan->sel); + init_waitqueue_head(&chan->readbufq); + init_waitqueue_head(&chan->writebufq); + init_waitqueue_head(&chan->eventbufq); + init_waitqueue_head(&chan->txstateq); + + /* Reset conferences */ + reset_conf(chan); + + /* I/O Mask, etc */ + chan->iomask = 0; + /* release conference resource if any */ + if (chan->confna) + dahdi_check_conf(chan->confna); + if ((chan->sig & __DAHDI_SIG_DACS) != __DAHDI_SIG_DACS) { + chan->confna = 0; + chan->confmode = 0; + if (chan->span && chan->span->dacs) + chan->span->dacs(chan, NULL); + } + chan->_confn = 0; + memset(chan->conflast, 0, sizeof(chan->conflast)); + memset(chan->conflast1, 0, sizeof(chan->conflast1)); + memset(chan->conflast2, 0, sizeof(chan->conflast2)); + chan->confmute = 0; + chan->gotgs = 0; + chan->curtone = NULL; + chan->tonep = 0; + chan->pdialcount = 0; + if (chan->gainalloc && chan->rxgain) + rxgain = chan->rxgain; + chan->rxgain = defgain; + chan->txgain = defgain; + chan->gainalloc = 0; + chan->eventinidx = chan->eventoutidx = 0; + dahdi_set_law(chan,0); + dahdi_hangup(chan); + + /* Make sure that the audio flag is cleared on a clear channel */ + if ((chan->sig & DAHDI_SIG_CLEAR) || (chan->sig & DAHDI_SIG_HARDHDLC)) + chan->flags &= ~DAHDI_FLAG_AUDIO; + + if ((chan->sig == DAHDI_SIG_CLEAR) || (chan->sig == DAHDI_SIG_HARDHDLC)) + chan->flags &= ~(DAHDI_FLAG_PPP | DAHDI_FLAG_FCS | DAHDI_FLAG_HDLC); + + chan->flags &= ~DAHDI_FLAG_LINEAR; + if (chan->curzone) { + /* Take cadence from tone zone */ + memcpy(chan->ringcadence, chan->curzone->ringcadence, sizeof(chan->ringcadence)); + } else { + /* Do a default */ + memset(chan->ringcadence, 0, sizeof(chan->ringcadence)); + chan->ringcadence[0] = chan->starttime; + chan->ringcadence[1] = DAHDI_RINGOFFTIME; + } + + if (ec_state) { + ec_state->ops->echocan_free(chan, ec_state); + release_echocan(ec_current); + } + + spin_unlock_irqrestore(&chan->lock, flags); + + set_tone_zone(chan, -1); + + if (rxgain) + kfree(rxgain); + + return 0; +} + +static int dahdi_timing_open(struct inode *inode, struct file *file) +{ + struct dahdi_timer *t; + unsigned long flags; + + if (!(t = kzalloc(sizeof(*t), GFP_KERNEL))) + return -ENOMEM; + + init_waitqueue_head(&t->sel); + INIT_LIST_HEAD(&t->list); + file->private_data = t; + + spin_lock_irqsave(&zaptimerlock, flags); + list_add(&t->list, &zaptimers); + spin_unlock_irqrestore(&zaptimerlock, flags); + + return 0; +} + +static int dahdi_timer_release(struct inode *inode, struct file *file) +{ + struct dahdi_timer *t, *cur, *next; + unsigned long flags; + + if (!(t = file->private_data)) + return 0; + + spin_lock_irqsave(&zaptimerlock, flags); + + list_for_each_entry_safe(cur, next, &zaptimers, list) { + if (t == cur) { + list_del(&cur->list); + break; + } + } + + spin_unlock_irqrestore(&zaptimerlock, flags); + + if (!cur) { + module_printk(KERN_NOTICE, "Timer: Not on list??\n"); + return 0; + } + + kfree(cur); + + return 0; +} + +static int dahdi_specchan_open(struct inode *inode, struct file *file, int unit) +{ + int res = 0; + + if (chans[unit] && chans[unit]->sig) { + /* Make sure we're not already open, a net device, or a slave device */ + if (chans[unit]->flags & DAHDI_FLAG_NETDEV) + res = -EBUSY; + else if (chans[unit]->master != chans[unit]) + res = -EBUSY; + else if ((chans[unit]->sig & __DAHDI_SIG_DACS) == __DAHDI_SIG_DACS) + res = -EBUSY; + else if (!test_and_set_bit(DAHDI_FLAGBIT_OPEN, &chans[unit]->flags)) { + unsigned long flags; + res = initialize_channel(chans[unit]); + if (res) { + /* Reallocbufs must have failed */ + clear_bit(DAHDI_FLAGBIT_OPEN, &chans[unit]->flags); + return res; + } + spin_lock_irqsave(&chans[unit]->lock, flags); + if (chans[unit]->flags & DAHDI_FLAG_PSEUDO) + chans[unit]->flags |= DAHDI_FLAG_AUDIO; + if (chans[unit]->span && chans[unit]->span->open) { + res = chans[unit]->span->open(chans[unit]); + } + if (!res) { + chans[unit]->file = file; + spin_unlock_irqrestore(&chans[unit]->lock, flags); + } else { + spin_unlock_irqrestore(&chans[unit]->lock, flags); + close_channel(chans[unit]); + clear_bit(DAHDI_FLAGBIT_OPEN, &chans[unit]->flags); + } + } else + res = -EBUSY; + } else + res = -ENXIO; + return res; +} + +static int dahdi_specchan_release(struct inode *node, struct file *file, int unit) +{ + int res=0; + unsigned long flags; + + if (chans[unit]) { + /* Chan lock protects contents against potentially non atomic accesses. + * So if the pointer setting is not atomic, we should protect */ + spin_lock_irqsave(&chans[unit]->lock, flags); + chans[unit]->file = NULL; + spin_unlock_irqrestore(&chans[unit]->lock, flags); + close_channel(chans[unit]); + if (chans[unit]->span && chans[unit]->span->close) + res = chans[unit]->span->close(chans[unit]); + /* The channel might be destroyed by low-level driver span->close() */ + if(chans[unit]) + clear_bit(DAHDI_FLAGBIT_OPEN, &chans[unit]->flags); + } else + res = -ENXIO; + return res; +} + +static int can_open_timer(void) +{ +#ifdef CONFIG_DAHDI_CORE_TIMER + return 1; +#else + return maxspans > 0; +#endif +} + +static struct dahdi_chan *dahdi_alloc_pseudo(void) +{ + struct dahdi_chan *pseudo; + + /* Don't allow /dev/dahdi/pseudo to open if there is not a timing + * source. */ + if (!can_open_timer()) + return NULL; + + if (!(pseudo = kzalloc(sizeof(*pseudo), GFP_KERNEL))) + return NULL; + + pseudo->sig = DAHDI_SIG_CLEAR; + pseudo->sigcap = DAHDI_SIG_CLEAR; + pseudo->flags = DAHDI_FLAG_PSEUDO | DAHDI_FLAG_AUDIO; + + if (dahdi_chan_reg(pseudo)) { + kfree(pseudo); + pseudo = NULL; + } else { + snprintf(pseudo->name, sizeof(pseudo->name)-1,"Pseudo/%d", pseudo->channo); + } + + return pseudo; +} + +static void dahdi_free_pseudo(struct dahdi_chan *pseudo) +{ + if (pseudo) { + dahdi_chan_unreg(pseudo); + kfree(pseudo); + } +} + +static int dahdi_open(struct inode *inode, struct file *file) +{ + int unit = UNIT(file); + struct dahdi_chan *chan; + /* Minor 0: Special "control" descriptor */ + if (!unit) + return dahdi_ctl_open(inode, file); + if (unit == 250) { + if (!dahdi_transcode_fops) { + if (request_module("dahdi_transcode")) { + return -ENXIO; + } + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + __MOD_INC_USE_COUNT (dahdi_transcode_fops->owner); +#else + if (!try_module_get(dahdi_transcode_fops->owner)) { + return -ENXIO; + } +#endif + if (dahdi_transcode_fops && dahdi_transcode_fops->open) { + return dahdi_transcode_fops->open(inode, file); + } else { + /* dahdi_transcode module should have exported a + * file_operations table. */ + WARN_ON(1); + } + return -ENXIO; + } + if (unit == 253) { + if (can_open_timer()) { + return dahdi_timing_open(inode, file); + } else { + return -ENXIO; + } + } + if (unit == 254) + return dahdi_chan_open(inode, file); + if (unit == 255) { + chan = dahdi_alloc_pseudo(); + if (chan) { + file->private_data = chan; + return dahdi_specchan_open(inode, file, chan->channo); + } else { + return -ENXIO; + } + } + return dahdi_specchan_open(inode, file, unit); +} + +#if 0 +static int dahdi_open(struct inode *inode, struct file *file) +{ + int res; + unsigned long flags; + spin_lock_irqsave(&bigzaplock, flags); + res = __dahdi_open(inode, file); + spin_unlock_irqrestore(&bigzaplock, flags); + return res; +} +#endif + +static ssize_t dahdi_read(struct file *file, char *usrbuf, size_t count, loff_t *ppos) +{ + int unit = UNIT(file); + struct dahdi_chan *chan; + + /* Can't read from control */ + if (!unit) { + return -EINVAL; + } + + if (unit == 253) + return -EINVAL; + + if (unit == 254) { + chan = file->private_data; + if (!chan) + return -EINVAL; + return dahdi_chan_read(file, usrbuf, count, chan->channo); + } + + if (unit == 255) { + chan = file->private_data; + if (!chan) { + module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n"); + return -EINVAL; + } + return dahdi_chan_read(file, usrbuf, count, chan->channo); + } + if (count < 0) + return -EINVAL; + + return dahdi_chan_read(file, usrbuf, count, unit); +} + +static ssize_t dahdi_write(struct file *file, const char *usrbuf, size_t count, loff_t *ppos) +{ + int unit = UNIT(file); + struct dahdi_chan *chan; + /* Can't read from control */ + if (!unit) + return -EINVAL; + if (count < 0) + return -EINVAL; + if (unit == 253) + return -EINVAL; + if (unit == 254) { + chan = file->private_data; + if (!chan) + return -EINVAL; + return dahdi_chan_write(file, usrbuf, count, chan->channo); + } + if (unit == 255) { + chan = file->private_data; + if (!chan) { + module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n"); + return -EINVAL; + } + return dahdi_chan_write(file, usrbuf, count, chan->channo); + } + return dahdi_chan_write(file, usrbuf, count, unit); + +} + +static int dahdi_set_default_zone(int defzone) +{ + if ((defzone < 0) || (defzone >= DAHDI_TONE_ZONE_MAX)) + return -EINVAL; + write_lock(&zone_lock); + if (!tone_zones[defzone]) { + write_unlock(&zone_lock); + return -EINVAL; + } + if ((default_zone != -1) && tone_zones[default_zone]) + atomic_dec(&tone_zones[default_zone]->refcount); + atomic_inc(&tone_zones[defzone]->refcount); + default_zone = defzone; + write_unlock(&zone_lock); + return 0; +} + +/* No bigger than 32k for everything per tone zone */ +#define MAX_SIZE 32768 +/* No more than 128 subtones */ +#define MAX_TONES 128 + +/* The tones to be loaded can (will) be a mix of regular tones, + DTMF tones and MF tones. We need to load DTMF and MF tones + a bit differently than regular tones because their storage + format is much simpler (an array structure field of the zone + structure, rather an array of pointers). +*/ +static int ioctl_load_zone(unsigned long data) +{ + struct load_zone_workarea { + struct dahdi_tone *samples[MAX_TONES]; + short next[MAX_TONES]; + struct dahdi_tone_def_header th; + struct dahdi_tone_def td; + } *work; + + size_t space; + size_t size; + int res; + int x; + void *slab, *ptr; + struct dahdi_zone *z; + struct dahdi_tone *t; + + work = kzalloc(sizeof(*work), GFP_KERNEL); + if (!work) + return -ENOMEM; + + if (copy_from_user(&work->th, (struct dahdi_tone_def_header *)data, + sizeof(work->th))) { + kfree(work); + return -EFAULT; + } + + data += sizeof(work->th); + + if ((work->th.count < 0) || (work->th.count > MAX_TONES)) { + module_printk(KERN_NOTICE, "Too many tones included\n"); + kfree(work); + return -EINVAL; + } + + space = size = sizeof(*z) + work->th.count * sizeof(*t); + + if (size > MAX_SIZE) { + kfree(work); + return -E2BIG; + } + + z = ptr = slab = kzalloc(size, GFP_KERNEL); + if (!z) { + kfree(work); + return -ENOMEM; + } + + ptr += sizeof(*z); + space -= sizeof(*z); + + dahdi_copy_string(z->name, work->th.name, sizeof(z->name)); + + for (x = 0; x < DAHDI_MAX_CADENCE; x++) + z->ringcadence[x] = work->th.ringcadence[x]; + + atomic_set(&z->refcount, 0); + + for (x = 0; x < work->th.count; x++) { + enum { + REGULAR_TONE, + DTMF_TONE, + MFR1_TONE, + MFR2_FWD_TONE, + MFR2_REV_TONE, + } tone_type; + + if (space < sizeof(*t)) { + kfree(slab); + kfree(work); + module_printk(KERN_NOTICE, "Insufficient tone zone space\n"); + return -EINVAL; + } + + res = copy_from_user(&work->td, (struct dahdi_tone_def *)data, + sizeof(work->td)); + if (res) { + kfree(slab); + kfree(work); + return -EFAULT; + } + + data += sizeof(work->td); + + if ((work->td.tone >= 0) && (work->td.tone < DAHDI_TONE_MAX)) { + tone_type = REGULAR_TONE; + + t = work->samples[x] = ptr; + + space -= sizeof(*t); + ptr += sizeof(*t); + + /* Remember which sample is work->next */ + work->next[x] = work->td.next; + + /* Make sure the "next" one is sane */ + if ((work->next[x] >= work->th.count) || + (work->next[x] < 0)) { + module_printk(KERN_NOTICE, + "Invalid 'next' pointer: %d\n", + work->next[x]); + kfree(slab); + kfree(work); + return -EINVAL; + } + } else if ((work->td.tone >= DAHDI_TONE_DTMF_BASE) && + (work->td.tone <= DAHDI_TONE_DTMF_MAX)) { + tone_type = DTMF_TONE; + work->td.tone -= DAHDI_TONE_DTMF_BASE; + t = &z->dtmf[work->td.tone]; + } else if ((work->td.tone >= DAHDI_TONE_MFR1_BASE) && + (work->td.tone <= DAHDI_TONE_MFR1_MAX)) { + tone_type = MFR1_TONE; + work->td.tone -= DAHDI_TONE_MFR1_BASE; + t = &z->mfr1[work->td.tone]; + } else if ((work->td.tone >= DAHDI_TONE_MFR2_FWD_BASE) && + (work->td.tone <= DAHDI_TONE_MFR2_FWD_MAX)) { + tone_type = MFR2_FWD_TONE; + work->td.tone -= DAHDI_TONE_MFR2_FWD_BASE; + t = &z->mfr2_fwd[work->td.tone]; + } else if ((work->td.tone >= DAHDI_TONE_MFR2_REV_BASE) && + (work->td.tone <= DAHDI_TONE_MFR2_REV_MAX)) { + tone_type = MFR2_REV_TONE; + work->td.tone -= DAHDI_TONE_MFR2_REV_BASE; + t = &z->mfr2_rev[work->td.tone]; + } else { + module_printk(KERN_NOTICE, + "Invalid tone (%d) defined\n", + work->td.tone); + kfree(slab); + kfree(work); + return -EINVAL; + } + + t->fac1 = work->td.fac1; + t->init_v2_1 = work->td.init_v2_1; + t->init_v3_1 = work->td.init_v3_1; + t->fac2 = work->td.fac2; + t->init_v2_2 = work->td.init_v2_2; + t->init_v3_2 = work->td.init_v3_2; + t->modulate = work->td.modulate; + + switch (tone_type) { + case REGULAR_TONE: + t->tonesamples = work->td.samples; + if (!z->tones[work->td.tone]) + z->tones[work->td.tone] = t; + break; + case DTMF_TONE: + t->tonesamples = global_dialparams.dtmf_tonelen; + t->next = &dtmf_silence; + z->dtmf_continuous[work->td.tone] = *t; + z->dtmf_continuous[work->td.tone].next = + &z->dtmf_continuous[work->td.tone]; + break; + case MFR1_TONE: + switch (work->td.tone + DAHDI_TONE_MFR1_BASE) { + case DAHDI_TONE_MFR1_KP: + case DAHDI_TONE_MFR1_ST: + case DAHDI_TONE_MFR1_STP: + case DAHDI_TONE_MFR1_ST2P: + case DAHDI_TONE_MFR1_ST3P: + /* signaling control tones are always 100ms */ + t->tonesamples = 100 * DAHDI_CHUNKSIZE; + break; + default: + t->tonesamples = global_dialparams.mfv1_tonelen; + break; + } + t->next = &mfr1_silence; + break; + case MFR2_FWD_TONE: + t->tonesamples = global_dialparams.mfr2_tonelen; + t->next = &dtmf_silence; + z->mfr2_fwd_continuous[work->td.tone] = *t; + z->mfr2_fwd_continuous[work->td.tone].next = + &z->mfr2_fwd_continuous[work->td.tone]; + break; + case MFR2_REV_TONE: + t->tonesamples = global_dialparams.mfr2_tonelen; + t->next = &dtmf_silence; + z->mfr2_rev_continuous[work->td.tone] = *t; + z->mfr2_rev_continuous[work->td.tone].next = + &z->mfr2_rev_continuous[work->td.tone]; + break; + } + } + + for (x = 0; x < work->th.count; x++) { + if (work->samples[x]) + work->samples[x]->next = work->samples[work->next[x]]; + } + + res = dahdi_register_tone_zone(work->th.zone, z); + if (res) { + kfree(slab); + } else { + if ( -1 == default_zone ) { + dahdi_set_default_zone(work->th.zone); + } + } + + kfree(work); + return res; +} + +void dahdi_init_tone_state(struct dahdi_tone_state *ts, struct dahdi_tone *zt) +{ + ts->v1_1 = 0; + ts->v2_1 = zt->init_v2_1; + ts->v3_1 = zt->init_v3_1; + ts->v1_2 = 0; + ts->v2_2 = zt->init_v2_2; + ts->v3_2 = zt->init_v3_2; + ts->modulate = zt->modulate; +} + +struct dahdi_tone *dahdi_mf_tone(const struct dahdi_chan *chan, char digit, int digitmode) +{ + unsigned int tone_index; + + if (!chan->curzone) { + static int __warnonce = 1; + if (__warnonce) { + __warnonce = 0; + /* The tonezones are loaded by dahdi_cfg based on /etc/dahdi/system.conf. */ + module_printk(KERN_WARNING, "Cannot get dtmf tone until tone zone is loaded.\n"); + } + return NULL; + } + + switch (digitmode) { + case DIGIT_MODE_PULSE: + /* We should only get here with a pulse digit if we need + * to "dial" 'W' (wait 0.5 second) + */ + if (digit == 'W') + return &tone_pause; + + return NULL; + /* You should not get here */ + case DIGIT_MODE_DTMF: + switch (digit) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + tone_index = DAHDI_TONE_DTMF_0 + (digit - '0'); + break; + case '*': + tone_index = DAHDI_TONE_DTMF_s; + break; + case '#': + tone_index = DAHDI_TONE_DTMF_p; + break; + case 'A': + case 'B': + case 'C': + case 'D': + tone_index = DAHDI_TONE_DTMF_A + (digit - 'A'); + case 'W': + return &tone_pause; + default: + return NULL; + } + return &chan->curzone->dtmf[tone_index - DAHDI_TONE_DTMF_BASE]; + case DIGIT_MODE_MFR1: + switch (digit) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + tone_index = DAHDI_TONE_MFR1_0 + (digit - '0'); + break; + case '*': + tone_index = DAHDI_TONE_MFR1_KP; + break; + case '#': + tone_index = DAHDI_TONE_MFR1_ST; + break; + case 'A': + tone_index = DAHDI_TONE_MFR1_STP; + break; + case 'B': + tone_index = DAHDI_TONE_MFR1_ST2P; + break; + case 'C': + tone_index = DAHDI_TONE_MFR1_ST3P; + break; + case 'W': + return &tone_pause; + default: + return NULL; + } + return &chan->curzone->mfr1[tone_index - DAHDI_TONE_MFR1_BASE]; + case DIGIT_MODE_MFR2_FWD: + switch (digit) { + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + tone_index = DAHDI_TONE_MFR2_FWD_1 + (digit - '1'); + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + tone_index = DAHDI_TONE_MFR2_FWD_10 + (digit - 'A'); + break; + case 'W': + return &tone_pause; + default: + return NULL; + } + return &chan->curzone->mfr2_fwd[tone_index - DAHDI_TONE_MFR2_FWD_BASE]; + case DIGIT_MODE_MFR2_REV: + switch (digit) { + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + tone_index = DAHDI_TONE_MFR2_REV_1 + (digit - '1'); + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + tone_index = DAHDI_TONE_MFR2_REV_10 + (digit - 'A'); + break; + case 'W': + return &tone_pause; + default: + return NULL; + } + return &chan->curzone->mfr2_rev[tone_index - DAHDI_TONE_MFR2_REV_BASE]; + default: + return NULL; + } +} + +static void __do_dtmf(struct dahdi_chan *chan) +{ + char c; + + /* Called with chan->lock held */ + while ((c = chan->txdialbuf[0])) { + memmove(chan->txdialbuf, chan->txdialbuf + 1, sizeof(chan->txdialbuf) - 1); + switch (c) { + case 'T': + chan->digitmode = DIGIT_MODE_DTMF; + chan->tonep = 0; + break; + case 'M': + chan->digitmode = DIGIT_MODE_MFR1; + chan->tonep = 0; + break; + case 'O': + chan->digitmode = DIGIT_MODE_MFR2_FWD; + chan->tonep = 0; + break; + case 'R': + chan->digitmode = DIGIT_MODE_MFR2_REV; + chan->tonep = 0; + break; + case 'P': + chan->digitmode = DIGIT_MODE_PULSE; + chan->tonep = 0; + break; + default: + if ((c != 'W') && (chan->digitmode == DIGIT_MODE_PULSE)) { + if ((c >= '0') && (c <= '9') && (chan->txhooksig == DAHDI_TXSIG_OFFHOOK)) { + /* (CNET) Dial pulse mappings for FXO ports */ + switch(chan->map_pulse) + { + case MAP_PULSE_NZ_OSLO: /* 0=10 pulses, 1=9 pulses, ... 9=1 pulse */ + chan->pdialcount = 10 - (c - '0'); break; + case MAP_PULSE_SWEDEN: /* 0=1 pulse, 1=2 pulses, ... 9=10 pulses */ + chan->pdialcount = (c - '0') + 1; break; + default: /* standard dial pulse mapping */ + chan->pdialcount = (c == '0') ? 10 : c - '0'; break; + } + dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_PULSEBREAK, + chan->pulsebreaktime); + return; + } + } else { + chan->curtone = dahdi_mf_tone(chan, c, chan->digitmode); + chan->tonep = 0; + if (chan->curtone) { + dahdi_init_tone_state(&chan->ts, chan->curtone); + return; + } + } + } + } + + /* Notify userspace process if there is nothing left */ + chan->dialing = 0; + __qevent(chan, DAHDI_EVENT_DIALCOMPLETE); +} + +static int dahdi_release(struct inode *inode, struct file *file) +{ + int unit = UNIT(file); + int res; + struct dahdi_chan *chan; + + if (!unit) + return dahdi_ctl_release(inode, file); + if (unit == 253) { + return dahdi_timer_release(inode, file); + } + if (unit == 250) { + /* We should not be here because the dahdi_transcode.ko module + * should have updated the file_operations for this file + * handle when the file was opened. */ + WARN_ON(1); + return -EFAULT; + } + if (unit == 254) { + chan = file->private_data; + if (!chan) + return dahdi_chan_release(inode, file); + else + return dahdi_specchan_release(inode, file, chan->channo); + } + if (unit == 255) { + chan = file->private_data; + if (chan) { + res = dahdi_specchan_release(inode, file, chan->channo); + dahdi_free_pseudo(chan); + } else { + module_printk(KERN_NOTICE, "Pseudo release and no private data??\n"); + res = 0; + } + return res; + } + return dahdi_specchan_release(inode, file, unit); +} + +#if 0 +static int dahdi_release(struct inode *inode, struct file *file) +{ + /* Lock the big zap lock when handling a release */ + unsigned long flags; + int res; + spin_lock_irqsave(&bigzaplock, flags); + res = __dahdi_release(inode, file); + spin_unlock_irqrestore(&bigzaplock, flags); + return res; +} +#endif + + +void dahdi_alarm_channel(struct dahdi_chan *chan, int alarms) +{ + unsigned long flags; + + spin_lock_irqsave(&chan->lock, flags); + if (chan->chan_alarms != alarms) { + chan->chan_alarms = alarms; + dahdi_qevent_nolock(chan, alarms ? DAHDI_EVENT_ALARM : DAHDI_EVENT_NOALARM); + } + spin_unlock_irqrestore(&chan->lock, flags); +} + +void dahdi_alarm_notify(struct dahdi_span *span) +{ + int x; + + span->alarms &= ~DAHDI_ALARM_LOOPBACK; + /* Determine maint status */ + if (span->maintstat || span->mainttimer) + span->alarms |= DAHDI_ALARM_LOOPBACK; + /* DON'T CHANGE THIS AGAIN. THIS WAS DONE FOR A REASON. + The expression (a != b) does *NOT* do the same thing + as ((!a) != (!b)) */ + /* if change in general state */ + if ((!span->alarms) != (!span->lastalarms)) { + span->lastalarms = span->alarms; + for (x = 0; x < span->channels; x++) + dahdi_alarm_channel(span->chans[x], span->alarms); + /* Switch to other master if current master in alarm */ + for (x=1; xalarms && (spans[x]->flags & DAHDI_FLAG_RUNNING)) { + if(master != spans[x]) + module_printk(KERN_NOTICE, "Master changed to %s\n", spans[x]->name); + master = spans[x]; + break; + } + } + } +} + +#define VALID_SPAN(j) do { \ + if ((j >= DAHDI_MAX_SPANS) || (j < 1)) \ + return -EINVAL; \ + if (!spans[j]) \ + return -ENXIO; \ +} while(0) + +#define CHECK_VALID_SPAN(j) do { \ + /* Start a given span */ \ + if (get_user(j, (int *)data)) \ + return -EFAULT; \ + VALID_SPAN(j); \ +} while(0) + +#define VALID_CHANNEL(j) do { \ + if ((j >= DAHDI_MAX_CHANNELS) || (j < 1)) \ + return -EINVAL; \ + if (!chans[j]) \ + return -ENXIO; \ +} while(0) + +static int dahdi_timer_ioctl(struct inode *node, struct file *file, unsigned int cmd, unsigned long data, struct dahdi_timer *timer) +{ + int j; + unsigned long flags; + switch(cmd) { + case DAHDI_TIMERCONFIG: + get_user(j, (int *)data); + if (j < 0) + j = 0; + spin_lock_irqsave(&zaptimerlock, flags); + timer->ms = timer->pos = j; + spin_unlock_irqrestore(&zaptimerlock, flags); + break; + case DAHDI_TIMERACK: + get_user(j, (int *)data); + spin_lock_irqsave(&zaptimerlock, flags); + if ((j < 1) || (j > timer->tripped)) + j = timer->tripped; + timer->tripped -= j; + spin_unlock_irqrestore(&zaptimerlock, flags); + break; + case DAHDI_GETEVENT: /* Get event on queue */ + j = DAHDI_EVENT_NONE; + spin_lock_irqsave(&zaptimerlock, flags); + /* set up for no event */ + if (timer->tripped) + j = DAHDI_EVENT_TIMER_EXPIRED; + if (timer->ping) + j = DAHDI_EVENT_TIMER_PING; + spin_unlock_irqrestore(&zaptimerlock, flags); + put_user(j,(int *)data); + break; + case DAHDI_TIMERPING: + spin_lock_irqsave(&zaptimerlock, flags); + timer->ping = 1; + wake_up_interruptible(&timer->sel); + spin_unlock_irqrestore(&zaptimerlock, flags); + break; + case DAHDI_TIMERPONG: + spin_lock_irqsave(&zaptimerlock, flags); + timer->ping = 0; + spin_unlock_irqrestore(&zaptimerlock, flags); + break; + default: + return -ENOTTY; + } + return 0; +} + +static int dahdi_ioctl_getgains(struct inode *node, struct file *file, + unsigned int cmd, unsigned long data, int unit) +{ + int res = 0; + struct dahdi_gains *gain; + int i, j; + + gain = kzalloc(sizeof(*gain), GFP_KERNEL); + if (!gain) + return -ENOMEM; + + if (copy_from_user(gain, (struct dahdi_gains *)data, sizeof(*gain))) { + res = -EFAULT; + goto cleanup; + } + i = gain->chan; /* get channel no */ + /* if zero, use current channel no */ + if (!i) + i = unit; + + /* make sure channel number makes sense */ + if ((i < 0) || (i > DAHDI_MAX_CHANNELS) || !chans[i]) { + res = -EINVAL; + goto cleanup; + } + + if (!(chans[i]->flags & DAHDI_FLAG_AUDIO)) { + res = -EINVAL; + goto cleanup; + } + gain->chan = i; /* put the span # in here */ + for (j = 0; j < 256; ++j) { + gain->txgain[j] = chans[i]->txgain[j]; + gain->rxgain[j] = chans[i]->rxgain[j]; + } + if (copy_to_user((struct dahdi_gains *)data, gain, sizeof(*gain))) { + res = -EFAULT; + goto cleanup; + } +cleanup: + + kfree(gain); + return res; +} + +static int dahdi_ioctl_setgains(struct inode *node, struct file *file, + unsigned int cmd, unsigned long data, int unit) +{ + int res = 0; + struct dahdi_gains *gain; + unsigned char *txgain, *rxgain; + int i, j; + unsigned long flags; + const int GAIN_TABLE_SIZE = sizeof(defgain); + + gain = kzalloc(sizeof(*gain), GFP_KERNEL); + if (!gain) + return -ENOMEM; + + if (copy_from_user(gain, (struct dahdi_gains *)data, sizeof(*gain))) { + res = -EFAULT; + goto cleanup; + } + i = gain->chan; /* get channel no */ + /* if zero, use current channel no */ + if (!i) + i = unit; + /* make sure channel number makes sense */ + if ((i < 0) || (i > DAHDI_MAX_CHANNELS) || !chans[i]) { + res = -EINVAL; + goto cleanup; + } + if (!(chans[i]->flags & DAHDI_FLAG_AUDIO)) { + res = -EINVAL; + goto cleanup; + } + + rxgain = kzalloc(GAIN_TABLE_SIZE*2, GFP_KERNEL); + if (!rxgain) { + res = -ENOMEM; + goto cleanup; + } + + gain->chan = i; /* put the span # in here */ + txgain = rxgain + GAIN_TABLE_SIZE; + + for (j = 0; j < GAIN_TABLE_SIZE; ++j) { + rxgain[j] = gain->rxgain[j]; + txgain[j] = gain->txgain[j]; + } + + if (!memcmp(rxgain, defgain, GAIN_TABLE_SIZE) && + !memcmp(txgain, defgain, GAIN_TABLE_SIZE)) { + kfree(rxgain); + spin_lock_irqsave(&chans[i]->lock, flags); + if (chans[i]->gainalloc) + kfree(chans[i]->rxgain); + chans[i]->gainalloc = 0; + chans[i]->rxgain = defgain; + chans[i]->txgain = defgain; + spin_unlock_irqrestore(&chans[i]->lock, flags); + } else { + /* This is a custom gain setting */ + spin_lock_irqsave(&chans[i]->lock, flags); + if (chans[i]->gainalloc) + kfree(chans[i]->rxgain); + chans[i]->gainalloc = 1; + chans[i]->rxgain = rxgain; + chans[i]->txgain = txgain; + spin_unlock_irqrestore(&chans[i]->lock, flags); + } + + if (copy_to_user((struct dahdi_gains *)data, gain, sizeof(*gain))) { + res = -EFAULT; + goto cleanup; + } +cleanup: + + kfree(gain); + return res; +} + +static int dahdi_common_ioctl(struct inode *node, struct file *file, unsigned int cmd, unsigned long data, int unit) +{ + union { + struct dahdi_spaninfo spaninfo; + struct dahdi_params param; + } stack; + struct dahdi_chan *chan; + unsigned long flags; + int i,j; + int return_master = 0; + size_t size_to_copy; + + switch(cmd) { + /* get channel parameters */ + case DAHDI_GET_PARAMS_V1: /* Intentional drop through. */ + case DAHDI_GET_PARAMS: + size_to_copy = sizeof(struct dahdi_params); + if (copy_from_user(&stack.param, (struct dahdi_params *) data, size_to_copy)) + return -EFAULT; + + /* check to see if the caller wants to receive our master channel number */ + if (stack.param.channo & DAHDI_GET_PARAMS_RETURN_MASTER) { + return_master = 1; + stack.param.channo &= ~DAHDI_GET_PARAMS_RETURN_MASTER; + } + + /* Pick the right channo's */ + if (!stack.param.channo || unit) { + stack.param.channo = unit; + } + /* Check validity of channel */ + VALID_CHANNEL(stack.param.channo); + chan = chans[stack.param.channo]; + + /* point to relevant structure */ + stack.param.sigtype = chan->sig; /* get signalling type */ + /* return non-zero if rx not in idle state */ + if (chan->span) { + j = dahdi_q_sig(chan); + if (j >= 0) { /* if returned with success */ + stack.param.rxisoffhook = ((chan->rxsig & (j >> 8)) != (j & 0xff)); + } else { + stack.param.rxisoffhook = ((chan->rxhooksig != DAHDI_RXSIG_ONHOOK) && + (chan->rxhooksig != DAHDI_RXSIG_INITIAL)); + } + } else if ((chan->txstate == DAHDI_TXSTATE_KEWL) || (chan->txstate == DAHDI_TXSTATE_AFTERKEWL)) + stack.param.rxisoffhook = 1; + else + stack.param.rxisoffhook = 0; + if (chan->span && chan->span->rbsbits && !(chan->sig & DAHDI_SIG_CLEAR)) { + stack.param.rxbits = chan->rxsig; + stack.param.txbits = chan->txsig; + stack.param.idlebits = chan->idlebits; + } else { + stack.param.rxbits = -1; + stack.param.txbits = -1; + stack.param.idlebits = 0; + } + if (chan->span && (chan->span->rbsbits || chan->span->hooksig) && + !(chan->sig & DAHDI_SIG_CLEAR)) { + stack.param.rxhooksig = chan->rxhooksig; + stack.param.txhooksig = chan->txhooksig; + } else { + stack.param.rxhooksig = -1; + stack.param.txhooksig = -1; + } + stack.param.prewinktime = chan->prewinktime; + stack.param.preflashtime = chan->preflashtime; + stack.param.winktime = chan->winktime; + stack.param.flashtime = chan->flashtime; + stack.param.starttime = chan->starttime; + stack.param.rxwinktime = chan->rxwinktime; + stack.param.rxflashtime = chan->rxflashtime; + stack.param.debouncetime = chan->debouncetime; + stack.param.channo = chan->channo; + stack.param.chan_alarms = chan->chan_alarms; + + /* if requested, put the master channel number in the top 16 bits of the result */ + if (return_master) + stack.param.channo |= chan->master->channo << 16; + + stack.param.pulsemaketime = chan->pulsemaketime; + stack.param.pulsebreaktime = chan->pulsebreaktime; + stack.param.pulseaftertime = chan->pulseaftertime; + if (chan->span) stack.param.spanno = chan->span->spanno; + else stack.param.spanno = 0; + dahdi_copy_string(stack.param.name, chan->name, sizeof(stack.param.name)); + stack.param.chanpos = chan->chanpos; + stack.param.sigcap = chan->sigcap; + /* Return current law */ + if (chan->xlaw == __dahdi_alaw) + stack.param.curlaw = DAHDI_LAW_ALAW; + else + stack.param.curlaw = DAHDI_LAW_MULAW; + + if (copy_to_user((struct dahdi_params *) data, &stack.param, size_to_copy)) + return -EFAULT; + + break; + /* set channel parameters */ + case DAHDI_SET_PARAMS: + if (copy_from_user(&stack.param, (struct dahdi_params *) data, sizeof(struct dahdi_params))) + return -EFAULT; + + stack.param.chan_alarms = 0; /* be explicit about the above */ + + /* Pick the right channo's */ + if (!stack.param.channo || unit) { + stack.param.channo = unit; + } + /* Check validity of channel */ + VALID_CHANNEL(stack.param.channo); + chan = chans[stack.param.channo]; + /* point to relevant structure */ + /* NOTE: sigtype is *not* included in this */ + /* get timing stack.paramters */ + chan->prewinktime = stack.param.prewinktime; + chan->preflashtime = stack.param.preflashtime; + chan->winktime = stack.param.winktime; + chan->flashtime = stack.param.flashtime; + chan->starttime = stack.param.starttime; + /* Update ringtime if not using a tone zone */ + if (!chan->curzone) + chan->ringcadence[0] = chan->starttime; + chan->rxwinktime = stack.param.rxwinktime; + chan->rxflashtime = stack.param.rxflashtime; + chan->debouncetime = stack.param.debouncetime; + chan->pulsemaketime = stack.param.pulsemaketime; + chan->pulsebreaktime = stack.param.pulsebreaktime; + chan->pulseaftertime = stack.param.pulseaftertime; + break; + case DAHDI_GETGAINS_V1: /* Intentional drop through. */ + case DAHDI_GETGAINS: /* get gain stuff */ + return dahdi_ioctl_getgains(node, file, cmd, data, unit); + case DAHDI_SETGAINS: /* set gain stuff */ + return dahdi_ioctl_setgains(node, file, cmd, data, unit); + case DAHDI_SPANSTAT: + size_to_copy = sizeof(struct dahdi_spaninfo); + if (copy_from_user(&stack.spaninfo, (struct dahdi_spaninfo *) data, size_to_copy)) + return -EFAULT; + i = stack.spaninfo.spanno; /* get specified span number */ + if ((i < 0) || (i >= maxspans)) return(-EINVAL); /* if bad span no */ + if (i == 0) { + /* if to figure it out for this chan */ + if (!chans[unit]) + return -EINVAL; + i = chans[unit]->span->spanno; + } + if (!spans[i]) + return -EINVAL; + stack.spaninfo.spanno = i; /* put the span # in here */ + stack.spaninfo.totalspans = 0; + if (maxspans) stack.spaninfo.totalspans = maxspans - 1; /* put total number of spans here */ + dahdi_copy_string(stack.spaninfo.desc, spans[i]->desc, sizeof(stack.spaninfo.desc)); + dahdi_copy_string(stack.spaninfo.name, spans[i]->name, sizeof(stack.spaninfo.name)); + stack.spaninfo.alarms = spans[i]->alarms; /* get alarm status */ + stack.spaninfo.bpvcount = spans[i]->bpvcount; /* get BPV count */ + stack.spaninfo.rxlevel = spans[i]->rxlevel; /* get rx level */ + stack.spaninfo.txlevel = spans[i]->txlevel; /* get tx level */ + stack.spaninfo.crc4count = spans[i]->crc4count; /* get CRC4 error count */ + stack.spaninfo.ebitcount = spans[i]->ebitcount; /* get E-bit error count */ + stack.spaninfo.fascount = spans[i]->fascount; /* get FAS error count */ + stack.spaninfo.irqmisses = spans[i]->irqmisses; /* get IRQ miss count */ + stack.spaninfo.syncsrc = spans[i]->syncsrc; /* get active sync source */ + stack.spaninfo.totalchans = spans[i]->channels; + stack.spaninfo.numchans = 0; + for (j = 0; j < spans[i]->channels; j++) { + if (spans[i]->chans[j]->sig) + stack.spaninfo.numchans++; + } + stack.spaninfo.lbo = spans[i]->lbo; + stack.spaninfo.lineconfig = spans[i]->lineconfig; + stack.spaninfo.irq = spans[i]->irq; + stack.spaninfo.linecompat = spans[i]->linecompat; + dahdi_copy_string(stack.spaninfo.lboname, dahdi_lboname(spans[i]->lbo), sizeof(stack.spaninfo.lboname)); + if (spans[i]->manufacturer) + dahdi_copy_string(stack.spaninfo.manufacturer, spans[i]->manufacturer, + sizeof(stack.spaninfo.manufacturer)); + if (spans[i]->devicetype) + dahdi_copy_string(stack.spaninfo.devicetype, spans[i]->devicetype, sizeof(stack.spaninfo.devicetype)); + dahdi_copy_string(stack.spaninfo.location, spans[i]->location, sizeof(stack.spaninfo.location)); + if (spans[i]->spantype) + dahdi_copy_string(stack.spaninfo.spantype, spans[i]->spantype, sizeof(stack.spaninfo.spantype)); + + if (copy_to_user((struct dahdi_spaninfo *) data, &stack.spaninfo, size_to_copy)) + return -EFAULT; + break; + case DAHDI_CHANDIAG_V1: /* Intentional drop through. */ + case DAHDI_CHANDIAG: + { + /* there really is no need to initialize this structure because when it is used it has + * already been completely overwritten, but apparently the compiler cannot figure that + * out and warns about uninitialized usage... so initialize it. + */ + struct dahdi_echocan_state ec_state = { .ops = NULL, }; + + get_user(j, (int *) data); /* get channel number from user */ + /* make sure its a valid channel number */ + if ((j < 1) || (j >= maxchans)) + return -EINVAL; + /* if channel not mapped, not there */ + if (!chans[j]) + return -EINVAL; + + chan = kmalloc(sizeof(*chan), GFP_KERNEL); + if (!chan) + return -ENOMEM; + + /* lock channel */ + spin_lock_irqsave(&chans[j]->lock, flags); + /* make static copy of channel */ + *chan = *chans[j]; + if (chan->ec_state) { + ec_state = *chan->ec_state; + } + /* release it. */ + spin_unlock_irqrestore(&chans[j]->lock, flags); + + module_printk(KERN_INFO, "Dump of DAHDI Channel %d (%s,%d,%d):\n\n",j, + chan->name, chan->channo, chan->chanpos); + module_printk(KERN_INFO, "flags: %x hex, writechunk: %p, readchunk: %p\n", + (unsigned int) chan->flags, chan->writechunk, chan->readchunk); + module_printk(KERN_INFO, "rxgain: %p, txgain: %p, gainalloc: %d\n", + chan->rxgain, chan->txgain, chan->gainalloc); + module_printk(KERN_INFO, "span: %p, sig: %x hex, sigcap: %x hex\n", + chan->span, chan->sig, chan->sigcap); + module_printk(KERN_INFO, "inreadbuf: %d, outreadbuf: %d, inwritebuf: %d, outwritebuf: %d\n", + chan->inreadbuf, chan->outreadbuf, chan->inwritebuf, chan->outwritebuf); + module_printk(KERN_INFO, "blocksize: %d, numbufs: %d, txbufpolicy: %d, txbufpolicy: %d\n", + chan->blocksize, chan->numbufs, chan->txbufpolicy, chan->rxbufpolicy); + module_printk(KERN_INFO, "txdisable: %d, rxdisable: %d, iomask: %d\n", + chan->txdisable, chan->rxdisable, chan->iomask); + module_printk(KERN_INFO, "curzone: %p, tonezone: %d, curtone: %p, tonep: %d\n", + chan->curzone, chan->tonezone, chan->curtone, chan->tonep); + module_printk(KERN_INFO, "digitmode: %d, txdialbuf: %s, dialing: %d, aftdialtimer: %d, cadpos. %d\n", + chan->digitmode, chan->txdialbuf, chan->dialing, + chan->afterdialingtimer, chan->cadencepos); + module_printk(KERN_INFO, "confna: %d, confn: %d, confmode: %d, confmute: %d\n", + chan->confna, chan->_confn, chan->confmode, chan->confmute); + module_printk(KERN_INFO, "ec: %p, deflaw: %d, xlaw: %p\n", + chan->ec_state, chan->deflaw, chan->xlaw); + if (chan->ec_state) { + module_printk(KERN_INFO, "echostate: %02x, echotimer: %d, echolastupdate: %d\n", + ec_state.status.mode, ec_state.status.pretrain_timer, ec_state.status.last_train_tap); + } + module_printk(KERN_INFO, "itimer: %d, otimer: %d, ringdebtimer: %d\n\n", + chan->itimer, chan->otimer, chan->ringdebtimer); + kfree(chan); + break; + } + default: + return -ENOTTY; + } + return 0; +} + +static int (*dahdi_dynamic_ioctl)(unsigned int cmd, unsigned long data); + +void dahdi_set_dynamic_ioctl(int (*func)(unsigned int cmd, unsigned long data)) +{ + dahdi_dynamic_ioctl = func; +} + +static int (*dahdi_hpec_ioctl)(unsigned int cmd, unsigned long data); + +void dahdi_set_hpec_ioctl(int (*func)(unsigned int cmd, unsigned long data)) +{ + dahdi_hpec_ioctl = func; +} + +static void recalc_slaves(struct dahdi_chan *chan) +{ + int x; + struct dahdi_chan *last = chan; + + /* Makes no sense if you don't have a span */ + if (!chan->span) + return; + +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "Recalculating slaves on %s\n", chan->name); +#endif + + /* Link all slaves appropriately */ + for (x=chan->chanpos;xspan->channels;x++) + if (chan->span->chans[x]->master == chan) { +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "Channel %s, slave to %s, last is %s, its next will be %d\n", + chan->span->chans[x]->name, chan->name, last->name, x); +#endif + last->nextslave = x; + last = chan->span->chans[x]; + } + /* Terminate list */ + last->nextslave = 0; +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "Done Recalculating slaves on %s (last is %s)\n", chan->name, last->name); +#endif +} + +static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data) +{ + /* I/O CTL's for control interface */ + int i,j; + int sigcap; + int res = 0; + int x,y; + struct dahdi_chan *newmaster; + unsigned long flags; + int rv; + switch(cmd) { + case DAHDI_INDIRECT: + { + struct dahdi_indirect_data ind; + + if (copy_from_user(&ind, (struct dahdi_indirect_data *)data, sizeof(ind))) + return -EFAULT; + VALID_CHANNEL(ind.chan); + return dahdi_chan_ioctl(inode, file, ind.op, (unsigned long) ind.data, ind.chan); + } + case DAHDI_SPANCONFIG: + { + struct dahdi_lineconfig lc; + + if (copy_from_user(&lc, (struct dahdi_lineconfig *)data, sizeof(lc))) + return -EFAULT; + VALID_SPAN(lc.span); + if ((lc.lineconfig & 0x07f0 & spans[lc.span]->linecompat) != (lc.lineconfig & 0x07f0)) + return -EINVAL; + if (spans[lc.span]->spanconfig) { + spans[lc.span]->lineconfig = lc.lineconfig; + spans[lc.span]->lbo = lc.lbo; + spans[lc.span]->txlevel = lc.lbo; + spans[lc.span]->rxlevel = 0; + + return spans[lc.span]->spanconfig(spans[lc.span], &lc); + } + return 0; + } + case DAHDI_STARTUP: + CHECK_VALID_SPAN(j); + if (spans[j]->flags & DAHDI_FLAG_RUNNING) + return 0; + if (spans[j]->startup) + res = spans[j]->startup(spans[j]); + if (!res) { + /* Mark as running and hangup any channels */ + spans[j]->flags |= DAHDI_FLAG_RUNNING; + for (x=0;xchannels;x++) { + y = dahdi_q_sig(spans[j]->chans[x]) & 0xff; + if (y >= 0) spans[j]->chans[x]->rxsig = (unsigned char)y; + spin_lock_irqsave(&spans[j]->chans[x]->lock, flags); + dahdi_hangup(spans[j]->chans[x]); + spin_unlock_irqrestore(&spans[j]->chans[x]->lock, flags); + /* + * Set the rxhooksig back to + * DAHDI_RXSIG_INITIAL so that new events are + * queued on the channel with the actual + * recieved hook state. + * + */ + spans[j]->chans[x]->rxhooksig = DAHDI_RXSIG_INITIAL; + } + } + return 0; + case DAHDI_SHUTDOWN: + CHECK_VALID_SPAN(j); + if (spans[j]->shutdown) + res = spans[j]->shutdown(spans[j]); + spans[j]->flags &= ~DAHDI_FLAG_RUNNING; + return 0; + case DAHDI_ATTACH_ECHOCAN: + { + struct dahdi_attach_echocan ae; + const struct dahdi_echocan_factory *new = NULL, *old; + + if (copy_from_user(&ae, (struct dahdi_attach_echocan *) data, sizeof(ae))) { + return -EFAULT; + } + + VALID_CHANNEL(ae.chan); + + ae.echocan[sizeof(ae.echocan) - 1] = 0; + if (ae.echocan[0]) { + if (!(new = find_echocan(ae.echocan))) { + return -EINVAL; + } + } + + spin_lock_irqsave(&chans[ae.chan]->lock, flags); + old = chans[ae.chan]->ec_factory; + chans[ae.chan]->ec_factory = new; + spin_unlock_irqrestore(&chans[ae.chan]->lock, flags); + + if (old) { + release_echocan(old); + } + + break; + } + case DAHDI_CHANCONFIG: + { + struct dahdi_chanconfig ch; + + if (copy_from_user(&ch, (struct dahdi_chanconfig *)data, sizeof(ch))) + return -EFAULT; + VALID_CHANNEL(ch.chan); + if (ch.sigtype == DAHDI_SIG_SLAVE) { + /* We have to use the master's sigtype */ + if ((ch.master < 1) || (ch.master >= DAHDI_MAX_CHANNELS)) + return -EINVAL; + if (!chans[ch.master]) + return -EINVAL; + ch.sigtype = chans[ch.master]->sig; + newmaster = chans[ch.master]; + } else if ((ch.sigtype & __DAHDI_SIG_DACS) == __DAHDI_SIG_DACS) { + newmaster = chans[ch.chan]; + if ((ch.idlebits < 1) || (ch.idlebits >= DAHDI_MAX_CHANNELS)) + return -EINVAL; + if (!chans[ch.idlebits]) + return -EINVAL; + } else { + newmaster = chans[ch.chan]; + } + spin_lock_irqsave(&chans[ch.chan]->lock, flags); +#ifdef CONFIG_DAHDI_NET + if (chans[ch.chan]->flags & DAHDI_FLAG_NETDEV) { + if (ztchan_to_dev(chans[ch.chan])->flags & IFF_UP) { + spin_unlock_irqrestore(&chans[ch.chan]->lock, flags); + module_printk(KERN_WARNING, "Can't switch HDLC net mode on channel %s, since current interface is up\n", chans[ch.chan]->name); + return -EBUSY; + } + spin_unlock_irqrestore(&chans[ch.chan]->lock, flags); + unregister_hdlc_device(chans[ch.chan]->hdlcnetdev->netdev); + spin_lock_irqsave(&chans[ch.chan]->lock, flags); + free_netdev(chans[ch.chan]->hdlcnetdev->netdev); + kfree(chans[ch.chan]->hdlcnetdev); + chans[ch.chan]->hdlcnetdev = NULL; + chans[ch.chan]->flags &= ~DAHDI_FLAG_NETDEV; + } +#else + if (ch.sigtype == DAHDI_SIG_HDLCNET) { + spin_unlock_irqrestore(&chans[ch.chan]->lock, flags); + module_printk(KERN_WARNING, "DAHDI networking not supported by this build.\n"); + return -ENOSYS; + } +#endif + sigcap = chans[ch.chan]->sigcap; + /* If they support clear channel, then they support the HDLC and such through + us. */ + if (sigcap & DAHDI_SIG_CLEAR) + sigcap |= (DAHDI_SIG_HDLCRAW | DAHDI_SIG_HDLCFCS | DAHDI_SIG_HDLCNET | DAHDI_SIG_DACS); + + if ((sigcap & ch.sigtype) != ch.sigtype) + res = -EINVAL; + + if (chans[ch.chan]->master != chans[ch.chan]) { + struct dahdi_chan *oldmaster = chans[ch.chan]->master; + + /* Clear the master channel */ + chans[ch.chan]->master = chans[ch.chan]; + chans[ch.chan]->nextslave = 0; + /* Unlink this channel from the master's channel list */ + recalc_slaves(oldmaster); + } + + if (!res) { + chans[ch.chan]->sig = ch.sigtype; + if (chans[ch.chan]->sig == DAHDI_SIG_CAS) + chans[ch.chan]->idlebits = ch.idlebits; + else + chans[ch.chan]->idlebits = 0; + if ((ch.sigtype & DAHDI_SIG_CLEAR) == DAHDI_SIG_CLEAR) { + /* Set clear channel flag if appropriate */ + chans[ch.chan]->flags &= ~DAHDI_FLAG_AUDIO; + chans[ch.chan]->flags |= DAHDI_FLAG_CLEAR; + } else { + /* Set audio flag and not clear channel otherwise */ + chans[ch.chan]->flags |= DAHDI_FLAG_AUDIO; + chans[ch.chan]->flags &= ~DAHDI_FLAG_CLEAR; + } + if ((ch.sigtype & DAHDI_SIG_HDLCRAW) == DAHDI_SIG_HDLCRAW) { + /* Set the HDLC flag */ + chans[ch.chan]->flags |= DAHDI_FLAG_HDLC; + } else { + /* Clear the HDLC flag */ + chans[ch.chan]->flags &= ~DAHDI_FLAG_HDLC; + } + if ((ch.sigtype & DAHDI_SIG_HDLCFCS) == DAHDI_SIG_HDLCFCS) { + /* Set FCS to be calculated if appropriate */ + chans[ch.chan]->flags |= DAHDI_FLAG_FCS; + } else { + /* Clear FCS flag */ + chans[ch.chan]->flags &= ~DAHDI_FLAG_FCS; + } + if ((ch.sigtype & __DAHDI_SIG_DACS) == __DAHDI_SIG_DACS) { + /* Setup conference properly */ + chans[ch.chan]->confmode = DAHDI_CONF_DIGITALMON; + chans[ch.chan]->confna = ch.idlebits; + if (chans[ch.chan]->span && + chans[ch.chan]->span->dacs && + chans[ch.idlebits] && + chans[ch.chan]->span && + (chans[ch.chan]->span->dacs == chans[ch.idlebits]->span->dacs)) + chans[ch.chan]->span->dacs(chans[ch.chan], chans[ch.idlebits]); + } else if (chans[ch.chan]->span && chans[ch.chan]->span->dacs) { + chans[ch.chan]->span->dacs(chans[ch.chan], NULL); + } + chans[ch.chan]->master = newmaster; + /* Note new slave if we are not our own master */ + if (newmaster != chans[ch.chan]) { + recalc_slaves(chans[ch.chan]->master); + } + if ((ch.sigtype & DAHDI_SIG_HARDHDLC) == DAHDI_SIG_HARDHDLC) { + chans[ch.chan]->flags &= ~DAHDI_FLAG_FCS; + chans[ch.chan]->flags &= ~DAHDI_FLAG_HDLC; + chans[ch.chan]->flags |= DAHDI_FLAG_NOSTDTXRX; + } else { + chans[ch.chan]->flags &= ~DAHDI_FLAG_NOSTDTXRX; + } + + if ((ch.sigtype & DAHDI_SIG_MTP2) == DAHDI_SIG_MTP2) + chans[ch.chan]->flags |= DAHDI_FLAG_MTP2; + else + chans[ch.chan]->flags &= ~DAHDI_FLAG_MTP2; + } + + if (!res && chans[ch.chan]->span->chanconfig) { + res = chans[ch.chan]->span->chanconfig(chans[ch.chan], + ch.sigtype); + } + +#ifdef CONFIG_DAHDI_NET + if (!res && + (newmaster == chans[ch.chan]) && + (chans[ch.chan]->sig == DAHDI_SIG_HDLCNET)) { + chans[ch.chan]->hdlcnetdev = dahdi_hdlc_alloc(); + if (chans[ch.chan]->hdlcnetdev) { +/* struct hdlc_device *hdlc = chans[ch.chan]->hdlcnetdev; + struct net_device *d = hdlc_to_dev(hdlc); mmm...get it right later --byg */ + + chans[ch.chan]->hdlcnetdev->netdev = alloc_hdlcdev(chans[ch.chan]->hdlcnetdev); + if (chans[ch.chan]->hdlcnetdev->netdev) { + chans[ch.chan]->hdlcnetdev->chan = chans[ch.chan]; +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23) + SET_MODULE_OWNER(chans[ch.chan]->hdlcnetdev->netdev); +#endif + chans[ch.chan]->hdlcnetdev->netdev->irq = chans[ch.chan]->span->irq; + chans[ch.chan]->hdlcnetdev->netdev->tx_queue_len = 50; + chans[ch.chan]->hdlcnetdev->netdev->do_ioctl = dahdi_net_ioctl; + chans[ch.chan]->hdlcnetdev->netdev->open = dahdi_net_open; + chans[ch.chan]->hdlcnetdev->netdev->stop = dahdi_net_stop; + dev_to_hdlc(chans[ch.chan]->hdlcnetdev->netdev)->attach = dahdi_net_attach; + dev_to_hdlc(chans[ch.chan]->hdlcnetdev->netdev)->xmit = dahdi_xmit; + spin_unlock_irqrestore(&chans[ch.chan]->lock, flags); + /* Briefly restore interrupts while we register the device */ + res = dahdi_register_hdlc_device(chans[ch.chan]->hdlcnetdev->netdev, ch.netdev_name); + spin_lock_irqsave(&chans[ch.chan]->lock, flags); + } else { + module_printk(KERN_NOTICE, "Unable to allocate hdlc: *shrug*\n"); + res = -1; + } + if (!res) + chans[ch.chan]->flags |= DAHDI_FLAG_NETDEV; + } else { + module_printk(KERN_NOTICE, "Unable to allocate netdev: out of memory\n"); + res = -1; + } + } +#endif + if ((chans[ch.chan]->sig == DAHDI_SIG_HDLCNET) && + (chans[ch.chan] == newmaster) && + !(chans[ch.chan]->flags & DAHDI_FLAG_NETDEV)) + module_printk(KERN_NOTICE, "Unable to register HDLC device for channel %s\n", chans[ch.chan]->name); + if (!res) { + /* (CNET) Ignore remote hookflash? */ + chans[ch.chan]->ignoreflash = ch.ignoreflash; + /* (CNET) Use Oslo/NZ or Swedish pulse mapping? */ + chans[ch.chan]->map_pulse = ch.map_pulse; + /* (CNET) Make outpulsing audible */ + chans[ch.chan]->hearpulsing = ch.hearpulsing; + /* Setup default law */ + chans[ch.chan]->deflaw = ch.deflaw; + /* Copy back any modified settings */ + spin_unlock_irqrestore(&chans[ch.chan]->lock, flags); + if (copy_to_user((struct dahdi_chanconfig *)data, &ch, sizeof(ch))) + return -EFAULT; + spin_lock_irqsave(&chans[ch.chan]->lock, flags); + /* And hangup */ + dahdi_hangup(chans[ch.chan]); + y = dahdi_q_sig(chans[ch.chan]) & 0xff; + if (y >= 0) + chans[ch.chan]->rxsig = (unsigned char) y; + chans[ch.chan]->rxhooksig = DAHDI_RXSIG_INITIAL; + } +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "Configured channel %s, flags %04lx, sig %04x\n", chans[ch.chan]->name, chans[ch.chan]->flags, chans[ch.chan]->sig); +#endif + spin_unlock_irqrestore(&chans[ch.chan]->lock, flags); + + return res; + } + case DAHDI_SFCONFIG: + { + struct dahdi_sfconfig sf; + + if (copy_from_user(&sf, (struct dahdi_chanconfig *)data, sizeof(sf))) + return -EFAULT; + VALID_CHANNEL(sf.chan); + if (chans[sf.chan]->sig != DAHDI_SIG_SF) return -EINVAL; + spin_lock_irqsave(&chans[sf.chan]->lock, flags); + chans[sf.chan]->rxp1 = sf.rxp1; + chans[sf.chan]->rxp2 = sf.rxp2; + chans[sf.chan]->rxp3 = sf.rxp3; + chans[sf.chan]->txtone = sf.txtone; + chans[sf.chan]->tx_v2 = sf.tx_v2; + chans[sf.chan]->tx_v3 = sf.tx_v3; + chans[sf.chan]->toneflags = sf.toneflag; + if (sf.txtone) /* if set to make tone for tx */ + { + if ((chans[sf.chan]->txhooksig && !(sf.toneflag & DAHDI_REVERSE_TXTONE)) || + ((!chans[sf.chan]->txhooksig) && (sf.toneflag & DAHDI_REVERSE_TXTONE))) + { + set_txtone(chans[sf.chan],sf.txtone,sf.tx_v2,sf.tx_v3); + } + else + { + set_txtone(chans[sf.chan],0,0,0); + } + } + spin_unlock_irqrestore(&chans[sf.chan]->lock, flags); + return res; + } + case DAHDI_DEFAULTZONE: + if (get_user(j,(int *)data)) + return -EFAULT; + return dahdi_set_default_zone(j); + case DAHDI_LOADZONE: + return ioctl_load_zone(data); + case DAHDI_FREEZONE: + get_user(j, (int *) data); + return free_tone_zone(j); + case DAHDI_SET_DIALPARAMS: + { + struct dahdi_dialparams tdp; + + if (copy_from_user(&tdp, (struct dahdi_dialparams *) data, sizeof(tdp))) + return -EFAULT; + + if ((tdp.dtmf_tonelen >= 10) && (tdp.dtmf_tonelen <= 4000)) { + global_dialparams.dtmf_tonelen = tdp.dtmf_tonelen; + } + if ((tdp.mfv1_tonelen >= 10) && (tdp.mfv1_tonelen <= 4000)) { + global_dialparams.mfv1_tonelen = tdp.mfv1_tonelen; + } + if ((tdp.mfr2_tonelen >= 10) && (tdp.mfr2_tonelen <= 4000)) { + global_dialparams.mfr2_tonelen = tdp.mfr2_tonelen; + } + + /* update the lengths in all currently loaded zones */ + write_lock(&zone_lock); + for (j = 0; j < ARRAY_SIZE(tone_zones); j++) { + struct dahdi_zone *z = tone_zones[j]; + + if (!z) + continue; + + for (i = 0; i < ARRAY_SIZE(z->dtmf); i++) { + z->dtmf[i].tonesamples = global_dialparams.dtmf_tonelen * DAHDI_CHUNKSIZE; + } + + /* for MFR1, we only adjust the length of the digits */ + for (i = DAHDI_TONE_MFR1_0; i <= DAHDI_TONE_MFR1_9; i++) { + z->mfr1[i - DAHDI_TONE_MFR1_BASE].tonesamples = global_dialparams.mfv1_tonelen * DAHDI_CHUNKSIZE; + } + + for (i = 0; i < ARRAY_SIZE(z->mfr2_fwd); i++) { + z->mfr2_fwd[i].tonesamples = global_dialparams.mfr2_tonelen * DAHDI_CHUNKSIZE; + } + + for (i = 0; i < ARRAY_SIZE(z->mfr2_rev); i++) { + z->mfr2_rev[i].tonesamples = global_dialparams.mfr2_tonelen * DAHDI_CHUNKSIZE; + } + } + write_unlock(&zone_lock); + + dtmf_silence.tonesamples = global_dialparams.dtmf_tonelen * DAHDI_CHUNKSIZE; + mfr1_silence.tonesamples = global_dialparams.mfv1_tonelen * DAHDI_CHUNKSIZE; + mfr2_silence.tonesamples = global_dialparams.mfr2_tonelen * DAHDI_CHUNKSIZE; + + break; + } + case DAHDI_GET_DIALPARAMS: + { + struct dahdi_dialparams tdp; + + tdp = global_dialparams; + if (copy_to_user((struct dahdi_dialparams *) data, &tdp, sizeof(tdp))) + return -EFAULT; + break; + } + case DAHDI_GETVERSION: + { + struct dahdi_versioninfo vi; + struct ecfactory *cur; + size_t space = sizeof(vi.echo_canceller) - 1; + + memset(&vi, 0, sizeof(vi)); + dahdi_copy_string(vi.version, DAHDI_VERSION, sizeof(vi.version)); + read_lock(&ecfactory_list_lock); + list_for_each_entry(cur, &ecfactory_list, list) { + strncat(vi.echo_canceller + strlen(vi.echo_canceller), cur->ec->name, space); + space -= strlen(cur->ec->name); + if (space < 1) { + break; + } + if (cur->list.next && (cur->list.next != &ecfactory_list)) { + strncat(vi.echo_canceller + strlen(vi.echo_canceller), ", ", space); + space -= 2; + if (space < 1) { + break; + } + } + } + read_unlock(&ecfactory_list_lock); + if (copy_to_user((struct dahdi_versioninfo *) data, &vi, sizeof(vi))) + return -EFAULT; + break; + } + case DAHDI_MAINT: /* do maintenance stuff */ + { + struct dahdi_maintinfo maint; + /* get struct from user */ + if (copy_from_user(&maint,(struct dahdi_maintinfo *) data, sizeof(maint))) + return -EFAULT; + /* must be valid span number */ + if ((maint.spanno < 1) || (maint.spanno > DAHDI_MAX_SPANS) || (!spans[maint.spanno])) + return -EINVAL; + if (!spans[maint.spanno]->maint) + return -ENOSYS; + spin_lock_irqsave(&spans[maint.spanno]->lock, flags); + /* save current maint state */ + i = spans[maint.spanno]->maintstat; + /* set maint mode */ + spans[maint.spanno]->maintstat = maint.command; + switch(maint.command) { + case DAHDI_MAINT_NONE: + case DAHDI_MAINT_LOCALLOOP: + case DAHDI_MAINT_REMOTELOOP: + /* if same, ignore it */ + if (i == maint.command) + break; + rv = spans[maint.spanno]->maint(spans[maint.spanno], maint.command); + spin_unlock_irqrestore(&spans[maint.spanno]->lock, flags); + if (rv) + return rv; + spin_lock_irqsave(&spans[maint.spanno]->lock, flags); + break; + case DAHDI_MAINT_LOOPUP: + case DAHDI_MAINT_LOOPDOWN: + spans[maint.spanno]->mainttimer = DAHDI_LOOPCODE_TIME * DAHDI_CHUNKSIZE; + rv = spans[maint.spanno]->maint(spans[maint.spanno], maint.command); + spin_unlock_irqrestore(&spans[maint.spanno]->lock, flags); + if (rv) + return rv; + rv = schluffen(&spans[maint.spanno]->maintq); + if (rv) + return rv; + spin_lock_irqsave(&spans[maint.spanno]->lock, flags); + break; + default: + module_printk(KERN_NOTICE, "Unknown maintenance event: %d\n", maint.command); + } + dahdi_alarm_notify(spans[maint.spanno]); /* process alarm-related events */ + spin_unlock_irqrestore(&spans[maint.spanno]->lock, flags); + break; + } + case DAHDI_DYNAMIC_CREATE: + case DAHDI_DYNAMIC_DESTROY: + if (dahdi_dynamic_ioctl) { + return dahdi_dynamic_ioctl(cmd, data); + } else { + request_module("dahdi_dynamic"); + if (dahdi_dynamic_ioctl) + return dahdi_dynamic_ioctl(cmd, data); + } + return -ENOSYS; + case DAHDI_EC_LICENSE_CHALLENGE: + case DAHDI_EC_LICENSE_RESPONSE: + if (dahdi_hpec_ioctl) { + return dahdi_hpec_ioctl(cmd, data); + } else { + request_module("dahdi_echocan_hpec"); + if (dahdi_hpec_ioctl) + return dahdi_hpec_ioctl(cmd, data); + } + return -ENOSYS; + default: + return dahdi_common_ioctl(inode, file, cmd, data, 0); + } + return 0; +} + +static int ioctl_dahdi_dial(struct dahdi_chan *chan, unsigned long data) +{ + struct dahdi_dialoperation *tdo; + unsigned long flags; + char *s; + int rv; + + tdo = kmalloc(sizeof(*tdo), GFP_KERNEL); + + if (!tdo) + return -ENOMEM; + + if (copy_from_user(tdo, (struct dahdi_dialoperation *)data, sizeof(*tdo))) + return -EFAULT; + rv = 0; + /* Force proper NULL termination and uppercase entry */ + tdo->dialstr[DAHDI_MAX_DTMF_BUF - 1] = '\0'; + for (s = tdo->dialstr; *s; s++) + *s = toupper(*s); + spin_lock_irqsave(&chan->lock, flags); + if (!chan->curzone) { + spin_unlock_irqrestore(&chan->lock, flags); + /* The tone zones are loaded by dahdi_cfg from /etc/dahdi/system.conf */ + module_printk(KERN_WARNING, "Cannot dial until a tone zone is loaded.\n"); + return -ENODATA; + } + switch (tdo->op) { + case DAHDI_DIAL_OP_CANCEL: + chan->curtone = NULL; + chan->dialing = 0; + chan->txdialbuf[0] = '\0'; + chan->tonep = 0; + chan->pdialcount = 0; + break; + case DAHDI_DIAL_OP_REPLACE: + strcpy(chan->txdialbuf, tdo->dialstr); + chan->dialing = 1; + __do_dtmf(chan); + break; + case DAHDI_DIAL_OP_APPEND: + if (strlen(tdo->dialstr) + strlen(chan->txdialbuf) >= (DAHDI_MAX_DTMF_BUF - 1)) { + rv = -EBUSY; + break; + } + dahdi_copy_string(chan->txdialbuf + strlen(chan->txdialbuf), tdo->dialstr, DAHDI_MAX_DTMF_BUF - strlen(chan->txdialbuf)); + if (!chan->dialing) { + chan->dialing = 1; + __do_dtmf(chan); + } + break; + default: + rv = -EINVAL; + } + spin_unlock_irqrestore(&chan->lock, flags); + return rv; +} + +static int dahdi_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit) +{ + struct dahdi_chan *chan = chans[unit]; + union { + struct dahdi_bufferinfo bi; + struct dahdi_confinfo conf; + struct dahdi_ring_cadence cad; + } stack; + unsigned long flags; + int i, j, k, rv; + int ret, c; + + if (!chan) + return -EINVAL; + switch(cmd) { + case DAHDI_DIALING: + spin_lock_irqsave(&chan->lock, flags); + j = chan->dialing; + spin_unlock_irqrestore(&chan->lock, flags); + if (copy_to_user((int *)data,&j,sizeof(int))) + return -EFAULT; + return 0; + case DAHDI_DIAL: + return ioctl_dahdi_dial(chan, data); + case DAHDI_GET_BUFINFO: + memset(&stack.bi, 0, sizeof(stack.bi)); + stack.bi.rxbufpolicy = chan->rxbufpolicy; + stack.bi.txbufpolicy = chan->txbufpolicy; + stack.bi.numbufs = chan->numbufs; + stack.bi.bufsize = chan->blocksize; + /* XXX FIXME! XXX */ + stack.bi.readbufs = -1; + stack.bi.writebufs = -1; + if (copy_to_user((struct dahdi_bufferinfo *)data, &stack.bi, sizeof(stack.bi))) + return -EFAULT; + break; + case DAHDI_SET_BUFINFO: + if (copy_from_user(&stack.bi, (struct dahdi_bufferinfo *)data, sizeof(stack.bi))) + return -EFAULT; + if (stack.bi.bufsize > DAHDI_MAX_BLOCKSIZE) + return -EINVAL; + if (stack.bi.bufsize < 16) + return -EINVAL; + if (stack.bi.bufsize * stack.bi.numbufs > DAHDI_MAX_BUF_SPACE) + return -EINVAL; + /* It does not make sense to allow user mode to change the + * receive buffering policy. DAHDI always provides received + * buffers to upper layers immediately. Transmission is + * different since we might want to allow the kernel to build + * up a buffer in order to prevent underruns from the + * interrupt context. */ + chan->txbufpolicy = stack.bi.txbufpolicy & 0x3; + if ((rv = dahdi_reallocbufs(chan, stack.bi.bufsize, stack.bi.numbufs))) + return (rv); + break; + case DAHDI_GET_BLOCKSIZE: /* get blocksize */ + put_user(chan->blocksize,(int *)data); /* return block size */ + break; + case DAHDI_SET_BLOCKSIZE: /* set blocksize */ + get_user(j,(int *)data); + /* cannot be larger than max amount */ + if (j > DAHDI_MAX_BLOCKSIZE) return(-EINVAL); + /* cannot be less then 16 */ + if (j < 16) return(-EINVAL); + /* allocate a single kernel buffer which we then + sub divide into four pieces */ + if ((rv = dahdi_reallocbufs(chan, j, chan->numbufs))) + return (rv); + break; + case DAHDI_FLUSH: /* flush input buffer, output buffer, and/or event queue */ + get_user(i,(int *)data); /* get param */ + spin_lock_irqsave(&chan->lock, flags); + if (i & DAHDI_FLUSH_READ) /* if for read (input) */ + { + /* initialize read buffers and pointers */ + chan->inreadbuf = 0; + chan->outreadbuf = -1; + for (j=0;jnumbufs;j++) { + /* Do we need this? */ + chan->readn[j] = 0; + chan->readidx[j] = 0; + } + wake_up_interruptible(&chan->readbufq); /* wake_up_interruptible waiting on read */ + wake_up_interruptible(&chan->sel); /* wake_up_interruptible waiting on select */ + } + if (i & DAHDI_FLUSH_WRITE) /* if for write (output) */ + { + /* initialize write buffers and pointers */ + chan->outwritebuf = -1; + chan->inwritebuf = 0; + for (j=0;jnumbufs;j++) { + /* Do we need this? */ + chan->writen[j] = 0; + chan->writeidx[j] = 0; + } + wake_up_interruptible(&chan->writebufq); /* wake_up_interruptible waiting on write */ + wake_up_interruptible(&chan->sel); /* wake_up_interruptible waiting on select */ + /* if IO MUX wait on write empty, well, this + certainly *did* empty the write */ + if (chan->iomask & DAHDI_IOMUX_WRITEEMPTY) + wake_up_interruptible(&chan->eventbufq); /* wake_up_interruptible waiting on IOMUX */ + } + if (i & DAHDI_FLUSH_EVENT) /* if for events */ + { + /* initialize the event pointers */ + chan->eventinidx = chan->eventoutidx = 0; + } + spin_unlock_irqrestore(&chan->lock, flags); + break; + case DAHDI_SYNC: /* wait for no tx */ + for(;;) /* loop forever */ + { + spin_lock_irqsave(&chan->lock, flags); + /* Know if there is a write pending */ + i = (chan->outwritebuf > -1); + spin_unlock_irqrestore(&chan->lock, flags); + if (!i) break; /* skip if none */ + rv = schluffen(&chan->writebufq); + if (rv) return(rv); + } + break; + case DAHDI_IOMUX: /* wait for something to happen */ + get_user(chan->iomask,(int*)data); /* save mask */ + if (!chan->iomask) return(-EINVAL); /* cant wait for nothing */ + for(;;) /* loop forever */ + { + /* has to have SOME mask */ + ret = 0; /* start with empty return value */ + spin_lock_irqsave(&chan->lock, flags); + /* if looking for read */ + if (chan->iomask & DAHDI_IOMUX_READ) + { + /* if read available */ + if ((chan->outreadbuf > -1) && !chan->rxdisable) + ret |= DAHDI_IOMUX_READ; + } + /* if looking for write avail */ + if (chan->iomask & DAHDI_IOMUX_WRITE) + { + if (chan->inwritebuf > -1) + ret |= DAHDI_IOMUX_WRITE; + } + /* if looking for write empty */ + if (chan->iomask & DAHDI_IOMUX_WRITEEMPTY) + { + /* if everything empty -- be sure the transmitter is enabled */ + chan->txdisable = 0; + if (chan->outwritebuf < 0) + ret |= DAHDI_IOMUX_WRITEEMPTY; + } + /* if looking for signalling event */ + if (chan->iomask & DAHDI_IOMUX_SIGEVENT) + { + /* if event */ + if (chan->eventinidx != chan->eventoutidx) + ret |= DAHDI_IOMUX_SIGEVENT; + } + spin_unlock_irqrestore(&chan->lock, flags); + /* if something to return, or not to wait */ + if (ret || (chan->iomask & DAHDI_IOMUX_NOWAIT)) + { + /* set return value */ + put_user(ret,(int *)data); + break; /* get out of loop */ + } + rv = schluffen(&chan->eventbufq); + if (rv) return(rv); + } + /* clear IO MUX mask */ + chan->iomask = 0; + break; + case DAHDI_GETEVENT: /* Get event on queue */ + /* set up for no event */ + j = DAHDI_EVENT_NONE; + spin_lock_irqsave(&chan->lock, flags); + /* if some event in queue */ + if (chan->eventinidx != chan->eventoutidx) + { + j = chan->eventbuf[chan->eventoutidx++]; + /* get the data, bump index */ + /* if index overflow, set to beginning */ + if (chan->eventoutidx >= DAHDI_MAX_EVENTSIZE) + chan->eventoutidx = 0; + } + spin_unlock_irqrestore(&chan->lock, flags); + put_user(j,(int *)data); + break; + case DAHDI_CONFMUTE: /* set confmute flag */ + get_user(j,(int *)data); /* get conf # */ + if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL); + spin_lock_irqsave(&bigzaplock, flags); + chan->confmute = j; + spin_unlock_irqrestore(&bigzaplock, flags); + break; + case DAHDI_GETCONFMUTE: /* get confmute flag */ + if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL); + j = chan->confmute; + put_user(j,(int *)data); /* get conf # */ + rv = 0; + break; + case DAHDI_SETTONEZONE: + get_user(j, (int *) data); + rv = set_tone_zone(chan, j); + return rv; + case DAHDI_GETTONEZONE: + spin_lock_irqsave(&chan->lock, flags); + if (chan->curzone) + j = chan->tonezone; + spin_unlock_irqrestore(&chan->lock, flags); + put_user(j, (int *) data); + break; + case DAHDI_SENDTONE: + get_user(j,(int *)data); + spin_lock_irqsave(&chan->lock, flags); + rv = start_tone(chan, j); + spin_unlock_irqrestore(&chan->lock, flags); + return rv; + case DAHDI_GETCONF_V1: /* intentional drop through */ + case DAHDI_GETCONF: /* get conf stuff */ + if (copy_from_user(&stack.conf,(struct dahdi_confinfo *) data,sizeof(stack.conf))) + return -EFAULT; + i = stack.conf.chan; /* get channel no */ + /* if zero, use current channel no */ + if (!i) i = chan->channo; + /* make sure channel number makes sense */ + if ((i < 0) || (i > DAHDI_MAX_CONF) || (!chans[i])) return(-EINVAL); + if (!(chans[i]->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL); + stack.conf.chan = i; /* get channel number */ + stack.conf.confno = chans[i]->confna; /* get conference number */ + stack.conf.confmode = chans[i]->confmode; /* get conference mode */ + if (copy_to_user((struct dahdi_confinfo *) data,&stack.conf,sizeof(stack.conf))) + return -EFAULT; + break; + case DAHDI_SETCONF_V1: /* Intentional fall through. */ + case DAHDI_SETCONF: /* set conf stuff */ + if (copy_from_user(&stack.conf,(struct dahdi_confinfo *) data,sizeof(stack.conf))) + return -EFAULT; + i = stack.conf.chan; /* get channel no */ + /* if zero, use current channel no */ + if (!i) i = chan->channo; + /* make sure channel number makes sense */ + if ((i < 1) || (i > DAHDI_MAX_CHANNELS) || (!chans[i])) return(-EINVAL); + if (!(chans[i]->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL); + if ((stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR || + (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORTX || + (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORBOTH || + (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR_RX_PREECHO || + (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR_TX_PREECHO || + (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORBOTH_PREECHO) { + /* Monitor mode -- it's a channel */ + if ((stack.conf.confno < 0) || (stack.conf.confno >= DAHDI_MAX_CHANNELS) || !chans[stack.conf.confno]) return(-EINVAL); + } else { + /* make sure conf number makes sense, too */ + if ((stack.conf.confno < -1) || (stack.conf.confno > DAHDI_MAX_CONF)) return(-EINVAL); + } + + /* if taking off of any conf, must have 0 mode */ + if ((!stack.conf.confno) && stack.conf.confmode) return(-EINVAL); + /* likewise if 0 mode must have no conf */ + if ((!stack.conf.confmode) && stack.conf.confno) return (-EINVAL); + stack.conf.chan = i; /* return with real channel # */ + spin_lock_irqsave(&bigzaplock, flags); + spin_lock(&chan->lock); + if (stack.conf.confno == -1) + stack.conf.confno = dahdi_first_empty_conference(); + if ((stack.conf.confno < 1) && (stack.conf.confmode)) { + /* No more empty conferences */ + spin_unlock(&chan->lock); + spin_unlock_irqrestore(&bigzaplock, flags); + return -EBUSY; + } + /* if changing confs, clear last added info */ + if (stack.conf.confno != chans[i]->confna) { + memset(chans[i]->conflast, 0, DAHDI_MAX_CHUNKSIZE); + memset(chans[i]->conflast1, 0, DAHDI_MAX_CHUNKSIZE); + memset(chans[i]->conflast2, 0, DAHDI_MAX_CHUNKSIZE); + } + j = chans[i]->confna; /* save old conference number */ + chans[i]->confna = stack.conf.confno; /* set conference number */ + chans[i]->confmode = stack.conf.confmode; /* set conference mode */ + chans[i]->_confn = 0; /* Clear confn */ + dahdi_check_conf(j); + dahdi_check_conf(stack.conf.confno); + if (chans[i]->span && chans[i]->span->dacs) { + if (((stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_DIGITALMON) && + chans[stack.conf.confno]->span && + chans[stack.conf.confno]->span->dacs == chans[i]->span->dacs && + chans[i]->txgain == defgain && + chans[i]->rxgain == defgain && + chans[stack.conf.confno]->txgain == defgain && + chans[stack.conf.confno]->rxgain == defgain) { + chans[i]->span->dacs(chans[i], chans[stack.conf.confno]); + } else { + chans[i]->span->dacs(chans[i], NULL); + } + } + /* if we are going onto a conf */ + if (stack.conf.confno && + ((stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONF || + (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONFANN || + (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONFMON || + (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_CONFANNMON || + (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_REALANDPSEUDO)) { + /* Get alias */ + chans[i]->_confn = dahdi_get_conf_alias(stack.conf.confno); + } + + if (chans[stack.conf.confno]) { + if ((stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR_RX_PREECHO || + (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITOR_TX_PREECHO || + (stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_MONITORBOTH_PREECHO) + chans[stack.conf.confno]->readchunkpreec = kmalloc(sizeof(*chans[stack.conf.confno]->readchunkpreec) * DAHDI_CHUNKSIZE, GFP_ATOMIC); + else { + if (chans[stack.conf.confno]->readchunkpreec) { + kfree(chans[stack.conf.confno]->readchunkpreec); + chans[stack.conf.confno]->readchunkpreec = NULL; + } + } + } + + spin_unlock(&chan->lock); + spin_unlock_irqrestore(&bigzaplock, flags); + if (copy_to_user((struct dahdi_confinfo *) data,&stack.conf,sizeof(stack.conf))) + return -EFAULT; + break; + case DAHDI_CONFLINK: /* do conf link stuff */ + if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL); + if (copy_from_user(&stack.conf,(struct dahdi_confinfo *) data,sizeof(stack.conf))) + return -EFAULT; + /* check sanity of arguments */ + if ((stack.conf.chan < 0) || (stack.conf.chan > DAHDI_MAX_CONF)) return(-EINVAL); + if ((stack.conf.confno < 0) || (stack.conf.confno > DAHDI_MAX_CONF)) return(-EINVAL); + /* cant listen to self!! */ + if (stack.conf.chan && (stack.conf.chan == stack.conf.confno)) return(-EINVAL); + spin_lock_irqsave(&bigzaplock, flags); + spin_lock(&chan->lock); + /* if to clear all links */ + if ((!stack.conf.chan) && (!stack.conf.confno)) + { + /* clear all the links */ + memset(conf_links,0,sizeof(conf_links)); + recalc_maxlinks(); + spin_unlock(&chan->lock); + spin_unlock_irqrestore(&bigzaplock, flags); + break; + } + rv = 0; /* clear return value */ + /* look for already existant specified combination */ + for(i = 1; i <= DAHDI_MAX_CONF; i++) + { + /* if found, exit */ + if ((conf_links[i].src == stack.conf.chan) && + (conf_links[i].dst == stack.conf.confno)) break; + } + if (i <= DAHDI_MAX_CONF) /* if found */ + { + if (!stack.conf.confmode) /* if to remove link */ + { + conf_links[i].src = conf_links[i].dst = 0; + } + else /* if to add and already there, error */ + { + rv = -EEXIST; + } + } + else /* if not found */ + { + if (stack.conf.confmode) /* if to add link */ + { + /* look for empty location */ + for(i = 1; i <= DAHDI_MAX_CONF; i++) + { + /* if empty, exit loop */ + if ((!conf_links[i].src) && + (!conf_links[i].dst)) break; + } + /* if empty spot found */ + if (i <= DAHDI_MAX_CONF) + { + conf_links[i].src = stack.conf.chan; + conf_links[i].dst = stack.conf.confno; + } + else /* if no empties -- error */ + { + rv = -ENOSPC; + } + } + else /* if to remove, and not found -- error */ + { + rv = -ENOENT; + } + } + recalc_maxlinks(); + spin_unlock(&chan->lock); + spin_unlock_irqrestore(&bigzaplock, flags); + return(rv); + case DAHDI_CONFDIAG_V1: /* Intention fall-through */ + case DAHDI_CONFDIAG: /* output diagnostic info to console */ + if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL); + get_user(j,(int *)data); /* get conf # */ + /* loop thru the interesting ones */ + for(i = ((j) ? j : 1); i <= ((j) ? j : DAHDI_MAX_CONF); i++) + { + c = 0; + for(k = 1; k < DAHDI_MAX_CHANNELS; k++) + { + /* skip if no pointer */ + if (!chans[k]) continue; + /* skip if not in this conf */ + if (chans[k]->confna != i) continue; + if (!c) module_printk(KERN_NOTICE, "Conf #%d:\n",i); + c = 1; + module_printk(KERN_NOTICE, "chan %d, mode %x\n", k,chans[k]->confmode); + } + rv = 0; + for(k = 1; k <= DAHDI_MAX_CONF; k++) + { + if (conf_links[k].dst == i) + { + if (!c) module_printk(KERN_NOTICE, "Conf #%d:\n",i); + c = 1; + if (!rv) module_printk(KERN_NOTICE, "Snooping on:\n"); + rv = 1; + module_printk(KERN_NOTICE, "conf %d\n",conf_links[k].src); + } + } + if (c) module_printk(KERN_NOTICE, "\n"); + } + break; + case DAHDI_CHANNO: /* get channel number of stream */ + put_user(unit,(int *)data); /* return unit/channel number */ + break; + case DAHDI_SETLAW: + get_user(j, (int *)data); + if ((j < 0) || (j > DAHDI_LAW_ALAW)) + return -EINVAL; + dahdi_set_law(chan, j); + break; + case DAHDI_SETLINEAR: + get_user(j, (int *)data); + /* Makes no sense on non-audio channels */ + if (!(chan->flags & DAHDI_FLAG_AUDIO)) + return -EINVAL; + + if (j) + chan->flags |= DAHDI_FLAG_LINEAR; + else + chan->flags &= ~DAHDI_FLAG_LINEAR; + break; + case DAHDI_SETCADENCE: + if (data) { + /* Use specific ring cadence */ + if (copy_from_user(&stack.cad, (struct dahdi_ring_cadence *)data, sizeof(stack.cad))) + return -EFAULT; + memcpy(chan->ringcadence, &stack.cad, sizeof(chan->ringcadence)); + chan->firstcadencepos = 0; + /* Looking for negative ringing time indicating where to loop back into ringcadence */ + for (i=0; iringcadence[i]<0) { + chan->ringcadence[i] *= -1; + chan->firstcadencepos = i; + break; + } + } + } else { + /* Reset to default */ + chan->firstcadencepos = 0; + if (chan->curzone) { + memcpy(chan->ringcadence, chan->curzone->ringcadence, sizeof(chan->ringcadence)); + /* Looking for negative ringing time indicating where to loop back into ringcadence */ + for (i=0; iringcadence[i]<0) { + chan->ringcadence[i] *= -1; + chan->firstcadencepos = i; + break; + } + } + } else { + memset(chan->ringcadence, 0, sizeof(chan->ringcadence)); + chan->ringcadence[0] = chan->starttime; + chan->ringcadence[1] = DAHDI_RINGOFFTIME; + } + } + break; + default: + /* Check for common ioctl's and private ones */ + rv = dahdi_common_ioctl(inode, file, cmd, data, unit); + /* if no span, just return with value */ + if (!chan->span) return rv; + if ((rv == -ENOTTY) && chan->span->ioctl) + rv = chan->span->ioctl(chan, cmd, data); + return rv; + + } + return 0; +} + +#ifdef CONFIG_DAHDI_PPP +/* + * This is called at softirq (BH) level when there are calls + * we need to make to the ppp_generic layer. We do it this + * way because the ppp_generic layer functions may not be called + * at interrupt level. + */ +static void do_ppp_calls(unsigned long data) +{ + struct dahdi_chan *chan = (struct dahdi_chan *) data; + struct sk_buff *skb; + + if (!chan->ppp) + return; + if (chan->do_ppp_wakeup) { + chan->do_ppp_wakeup = 0; + ppp_output_wakeup(chan->ppp); + } + while ((skb = skb_dequeue(&chan->ppp_rq)) != NULL) + ppp_input(chan->ppp, skb); + if (chan->do_ppp_error) { + chan->do_ppp_error = 0; + ppp_input_error(chan->ppp, 0); + } +} +#endif + +static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, void *data) +{ + struct dahdi_echocan_state *ec = NULL, *ec_state; + const struct dahdi_echocan_factory *ec_current; + struct dahdi_echocanparam *params; + int ret; + unsigned long flags; + + if (ecp->param_count > DAHDI_MAX_ECHOCANPARAMS) + return -E2BIG; + + if (ecp->tap_length == 0) { + /* disable mode, don't need to inspect params */ + spin_lock_irqsave(&chan->lock, flags); + ec_state = chan->ec_state; + chan->ec_state = NULL; + ec_current = chan->ec_current; + chan->ec_current = NULL; + spin_unlock_irqrestore(&chan->lock, flags); + if (ec_state) { + ec_state->ops->echocan_free(chan, ec_state); + release_echocan(ec_current); + } + + return 0; + } + + params = kmalloc(sizeof(params[0]) * DAHDI_MAX_ECHOCANPARAMS, GFP_KERNEL); + + if (!params) + return -ENOMEM; + + /* enable mode, need the params */ + + if (copy_from_user(params, (struct dahdi_echocanparam *) data, sizeof(params[0]) * ecp->param_count)) { + ret = -EFAULT; + goto exit_with_free; + } + + /* free any echocan that may be on the channel already */ + spin_lock_irqsave(&chan->lock, flags); + ec_state = chan->ec_state; + chan->ec_state = NULL; + ec_current = chan->ec_current; + chan->ec_current = NULL; + spin_unlock_irqrestore(&chan->lock, flags); + if (ec_state) { + ec_state->ops->echocan_free(chan, ec_state); + release_echocan(ec_current); + } + + switch (ecp->tap_length) { + case 32: + case 64: + case 128: + case 256: + case 512: + case 1024: + break; + default: + ecp->tap_length = deftaps; + } + + ret = -ENODEV; + ec_current = NULL; + + /* attempt to use the span's echo canceler; fall back to built-in + if it fails (but not if an error occurs) */ + if (chan->span && chan->span->echocan_create) + ret = chan->span->echocan_create(chan, ecp, params, &ec); + + if ((ret == -ENODEV) && chan->ec_factory) { + /* try to get another reference to the module providing + this channel's echo canceler */ + if (!try_module_get(chan->ec_factory->owner)) { + module_printk(KERN_ERR, "Cannot get a reference to the '%s' echo canceler\n", chan->ec_factory->name); + goto exit_with_free; + } + + /* got the reference, copy the pointer and use it for making + an echo canceler instance if possible */ + ec_current = chan->ec_factory; + + ret = ec_current->echocan_create(chan, ecp, params, &ec); + if (ret) { + release_echocan(ec_current); + + goto exit_with_free; + } + if (!ec) { + module_printk(KERN_ERR, "%s failed to allocate an " \ + "dahdi_echocan_state instance.\n", + ec_current->name); + ret = -EFAULT; + goto exit_with_free; + } + } + + if (ec) { + spin_lock_irqsave(&chan->lock, flags); + chan->ec_current = ec_current; + chan->ec_state = ec; + ec->status.mode = ECHO_MODE_ACTIVE; + if (!ec->features.CED_tx_detect) { + echo_can_disable_detector_init(&chan->ec_state->txecdis); + } + if (!ec->features.CED_rx_detect) { + echo_can_disable_detector_init(&chan->ec_state->rxecdis); + } + spin_unlock_irqrestore(&chan->lock, flags); + } + +exit_with_free: + kfree(params); + + return ret; +} + +static void set_echocan_fax_mode(struct dahdi_chan *chan, unsigned int channo, const char *reason, unsigned int enable) +{ + if (enable) { + if (!chan->ec_state) + module_printk(KERN_NOTICE, "Ignoring FAX mode request because of %s for channel %d with no echo canceller\n", reason, channo); + else if (chan->ec_state->status.mode == ECHO_MODE_FAX) + module_printk(KERN_NOTICE, "Ignoring FAX mode request because of %s for echo canceller already in FAX mode on channel %d\n", reason, channo); + else if (chan->ec_state->status.mode != ECHO_MODE_ACTIVE) + module_printk(KERN_NOTICE, "Ignoring FAX mode request because of %s for echo canceller not in active mode on channel %d\n", reason, channo); + else if (chan->ec_state->features.NLP_automatic) { + /* for echocans that automatically do the right thing, just + * mark it as being in FAX mode without making any + * changes, as none are necessary. + */ + chan->ec_state->status.mode = ECHO_MODE_FAX; + } else if (chan->ec_state->features.NLP_toggle) { + module_printk(KERN_NOTICE, "Disabled echo canceller NLP because of %s on channel %d\n", reason, channo); + dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_DISABLED); + chan->ec_state->ops->echocan_NLP_toggle(chan->ec_state, 0); + chan->ec_state->status.mode = ECHO_MODE_FAX; + } else { + module_printk(KERN_NOTICE, "Idled echo canceller because of %s on channel %d\n", reason, channo); + chan->ec_state->status.mode = ECHO_MODE_IDLE; + } + } else { + if (!chan->ec_state) + module_printk(KERN_NOTICE, "Ignoring voice mode request because of %s for channel %d with no echo canceller\n", reason, channo); + else if (chan->ec_state->status.mode == ECHO_MODE_ACTIVE) + module_printk(KERN_NOTICE, "Ignoring voice mode request because of %s for echo canceller already in voice mode on channel %d\n", reason, channo); + else if ((chan->ec_state->status.mode != ECHO_MODE_FAX) && + (chan->ec_state->status.mode != ECHO_MODE_IDLE)) + module_printk(KERN_NOTICE, "Ignoring voice mode request because of %s for echo canceller not in FAX or idle mode on channel %d\n", reason, channo); + else if (chan->ec_state->features.NLP_automatic) { + /* for echocans that automatically do the right thing, just + * mark it as being in active mode without making any + * changes, as none are necessary. + */ + chan->ec_state->status.mode = ECHO_MODE_ACTIVE; + } else if (chan->ec_state->features.NLP_toggle) { + module_printk(KERN_NOTICE, "Enabled echo canceller NLP because of %s on channel %d\n", reason, channo); + dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_ENABLED); + chan->ec_state->ops->echocan_NLP_toggle(chan->ec_state, 1); + chan->ec_state->status.mode = ECHO_MODE_ACTIVE; + } else { + module_printk(KERN_NOTICE, "Activated echo canceller because of %s on channel %d\n", reason, channo); + chan->ec_state->status.mode = ECHO_MODE_ACTIVE; + } + } +} + +static int dahdi_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit) +{ + struct dahdi_chan *chan = chans[unit]; + unsigned long flags; + int j, rv; + int ret; + int oldconf; + void *rxgain=NULL; + + WARN_ON(!chan->master); + if (!chan) + return -ENOSYS; + + switch(cmd) { + case DAHDI_SETSIGFREEZE: + get_user(j, (int *)data); + spin_lock_irqsave(&chan->lock, flags); + if (j) { + chan->flags |= DAHDI_FLAG_SIGFREEZE; + } else { + chan->flags &= ~DAHDI_FLAG_SIGFREEZE; + } + spin_unlock_irqrestore(&chan->lock, flags); + break; + case DAHDI_GETSIGFREEZE: + spin_lock_irqsave(&chan->lock, flags); + if (chan->flags & DAHDI_FLAG_SIGFREEZE) + j = 1; + else + j = 0; + spin_unlock_irqrestore(&chan->lock, flags); + put_user(j, (int *)data); + break; + case DAHDI_AUDIOMODE: + /* Only literal clear channels can be put in */ + if (chan->sig != DAHDI_SIG_CLEAR) return (-EINVAL); + get_user(j, (int *)data); + if (j) { + spin_lock_irqsave(&chan->lock, flags); + chan->flags |= DAHDI_FLAG_AUDIO; + chan->flags &= ~(DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS); + spin_unlock_irqrestore(&chan->lock, flags); + } else { + /* Coming out of audio mode, also clear all + conferencing and gain related info as well + as echo canceller */ + struct dahdi_echocan_state *ec_state; + const struct dahdi_echocan_factory *ec_current; + + spin_lock_irqsave(&chan->lock, flags); + chan->flags &= ~DAHDI_FLAG_AUDIO; + /* save old conf number, if any */ + oldconf = chan->confna; + /* initialize conference variables */ + chan->_confn = 0; + chan->confna = 0; + if (chan->span && chan->span->dacs) + chan->span->dacs(chan, NULL); + chan->confmode = 0; + chan->confmute = 0; + memset(chan->conflast, 0, sizeof(chan->conflast)); + memset(chan->conflast1, 0, sizeof(chan->conflast1)); + memset(chan->conflast2, 0, sizeof(chan->conflast2)); + ec_state = chan->ec_state; + chan->ec_state = NULL; + ec_current = chan->ec_current; + chan->ec_current = NULL; + /* release conference resource, if any to release */ + reset_conf(chan); + if (chan->gainalloc && chan->rxgain) + rxgain = chan->rxgain; + else + rxgain = NULL; + + chan->rxgain = defgain; + chan->txgain = defgain; + chan->gainalloc = 0; + spin_unlock_irqrestore(&chan->lock, flags); + + if (ec_state) { + ec_state->ops->echocan_free(chan, ec_state); + release_echocan(ec_current); + } + + if (rxgain) + kfree(rxgain); + if (oldconf) dahdi_check_conf(oldconf); + } + break; + case DAHDI_HDLCPPP: +#ifdef CONFIG_DAHDI_PPP + if (chan->sig != DAHDI_SIG_CLEAR) return (-EINVAL); + get_user(j, (int *)data); + if (j) { + if (!chan->ppp) { + chan->ppp = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL); + if (chan->ppp) { + struct dahdi_echocan_state *tec; + const struct dahdi_echocan_factory *ec_current; + + chan->ppp->private = chan; + chan->ppp->ops = &ztppp_ops; + chan->ppp->mtu = DAHDI_DEFAULT_MTU_MRU; + chan->ppp->hdrlen = 0; + skb_queue_head_init(&chan->ppp_rq); + chan->do_ppp_wakeup = 0; + tasklet_init(&chan->ppp_calls, do_ppp_calls, + (unsigned long)chan); + if ((ret = dahdi_reallocbufs(chan, DAHDI_DEFAULT_MTU_MRU, DAHDI_DEFAULT_NUM_BUFS))) { + kfree(chan->ppp); + chan->ppp = NULL; + return ret; + } + + if ((ret = ppp_register_channel(chan->ppp))) { + kfree(chan->ppp); + chan->ppp = NULL; + return ret; + } + tec = chan->ec_state; + chan->ec_state = NULL; + ec_current = chan->ec_current; + chan->ec_current = NULL; + /* Make sure there's no gain */ + if (chan->gainalloc) + kfree(chan->rxgain); + chan->rxgain = defgain; + chan->txgain = defgain; + chan->gainalloc = 0; + chan->flags &= ~DAHDI_FLAG_AUDIO; + chan->flags |= (DAHDI_FLAG_PPP | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS); + + if (tec) { + tec->ops->echocan_free(chan, tec); + release_echocan(ec_current); + } + } else + return -ENOMEM; + } + } else { + chan->flags &= ~(DAHDI_FLAG_PPP | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS); + if (chan->ppp) { + struct ppp_channel *ppp = chan->ppp; + chan->ppp = NULL; + tasklet_kill(&chan->ppp_calls); + skb_queue_purge(&chan->ppp_rq); + ppp_unregister_channel(ppp); + kfree(ppp); + } + } +#else + module_printk(KERN_NOTICE, "PPP support not compiled in\n"); + return -ENOSYS; +#endif + break; + case DAHDI_HDLCRAWMODE: + if (chan->sig != DAHDI_SIG_CLEAR) return (-EINVAL); + get_user(j, (int *)data); + chan->flags &= ~(DAHDI_FLAG_AUDIO | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS); + if (j) { + chan->flags |= DAHDI_FLAG_HDLC; + fasthdlc_init(&chan->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64); + fasthdlc_init(&chan->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64); + } + break; + case DAHDI_HDLCFCSMODE: + if (chan->sig != DAHDI_SIG_CLEAR) return (-EINVAL); + get_user(j, (int *)data); + chan->flags &= ~(DAHDI_FLAG_AUDIO | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS); + if (j) { + chan->flags |= DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS; + fasthdlc_init(&chan->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64); + fasthdlc_init(&chan->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64); + } + break; + case DAHDI_HDLC_RATE: + get_user(j, (int *) data); + if (j == 56) { + chan->flags |= DAHDI_FLAG_HDLC56; + } else { + chan->flags &= ~DAHDI_FLAG_HDLC56; + } + + fasthdlc_init(&chan->rxhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64); + fasthdlc_init(&chan->txhdlc, (chan->flags & DAHDI_FLAG_HDLC56) ? FASTHDLC_MODE_56 : FASTHDLC_MODE_64); + break; + case DAHDI_ECHOCANCEL_PARAMS: + { + struct dahdi_echocanparams ecp; + + if (!(chan->flags & DAHDI_FLAG_AUDIO)) + return -EINVAL; + if (copy_from_user(&ecp, (struct dahdi_echocanparams *) data, sizeof(ecp))) + return -EFAULT; + data += sizeof(ecp); + if ((ret = ioctl_echocancel(chan, &ecp, (void *) data))) + return ret; + break; + } + case DAHDI_ECHOCANCEL: + { + struct dahdi_echocanparams ecp; + + if (!(chan->flags & DAHDI_FLAG_AUDIO)) + return -EINVAL; + get_user(j, (int *) data); + ecp.tap_length = j; + ecp.param_count = 0; + if ((ret = ioctl_echocancel(chan, &ecp, NULL))) + return ret; + break; + } + case DAHDI_ECHOTRAIN: + get_user(j, (int *)data); /* get pre-training time from user */ + if ((j < 0) || (j >= DAHDI_MAX_PRETRAINING)) + return -EINVAL; + j <<= 3; + spin_lock_irqsave(&chan->lock, flags); + if (chan->ec_state) { + /* Start pretraining stage */ + if (chan->ec_state->ops->echocan_traintap) { + chan->ec_state->status.mode = ECHO_MODE_PRETRAINING; + chan->ec_state->status.pretrain_timer = j; + } + spin_unlock_irqrestore(&chan->lock, flags); + } else { + spin_unlock_irqrestore(&chan->lock, flags); + return -EINVAL; + } + break; + case DAHDI_ECHOCANCEL_FAX_MODE: + if (!chan->ec_state) { + return -EINVAL; + } else { + get_user(j, (int *) data); + spin_lock_irqsave(&chan->lock, flags); + set_echocan_fax_mode(chan, chan->channo, "ioctl", j ? 1 : 0); + spin_unlock_irqrestore(&chan->lock, flags); + } + break; + case DAHDI_SETTXBITS: + if (chan->sig != DAHDI_SIG_CAS) + return -EINVAL; + get_user(j,(int *)data); + dahdi_cas_setbits(chan, j); + break; + case DAHDI_GETRXBITS: + put_user(chan->rxsig, (int *)data); + break; + case DAHDI_LOOPBACK: + get_user(j, (int *)data); + spin_lock_irqsave(&chan->lock, flags); + if (j) + chan->flags |= DAHDI_FLAG_LOOPED; + else + chan->flags &= ~DAHDI_FLAG_LOOPED; + spin_unlock_irqrestore(&chan->lock, flags); + break; + case DAHDI_HOOK: + get_user(j,(int *)data); + if (chan->flags & DAHDI_FLAG_CLEAR) + return -EINVAL; + if (chan->sig == DAHDI_SIG_CAS) + return -EINVAL; + /* if no span, just do nothing */ + if (!chan->span) return(0); + spin_lock_irqsave(&chan->lock, flags); + /* if dialing, stop it */ + chan->curtone = NULL; + chan->dialing = 0; + chan->txdialbuf[0] = '\0'; + chan->tonep = 0; + chan->pdialcount = 0; + spin_unlock_irqrestore(&chan->lock, flags); + if (chan->span->flags & DAHDI_FLAG_RBS) { + switch (j) { + case DAHDI_ONHOOK: + spin_lock_irqsave(&chan->lock, flags); + dahdi_hangup(chan); + spin_unlock_irqrestore(&chan->lock, flags); + break; + case DAHDI_OFFHOOK: + spin_lock_irqsave(&chan->lock, flags); + if ((chan->txstate == DAHDI_TXSTATE_KEWL) || + (chan->txstate == DAHDI_TXSTATE_AFTERKEWL)) { + spin_unlock_irqrestore(&chan->lock, flags); + return -EBUSY; + } + dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_DEBOUNCE, chan->debouncetime); + spin_unlock_irqrestore(&chan->lock, flags); + break; + case DAHDI_RING: + case DAHDI_START: + spin_lock_irqsave(&chan->lock, flags); + if (!chan->curzone) { + spin_unlock_irqrestore(&chan->lock, flags); + module_printk(KERN_WARNING, "Cannot start tone until a tone zone is loaded.\n"); + return -ENODATA; + } + if (chan->txstate != DAHDI_TXSTATE_ONHOOK) { + spin_unlock_irqrestore(&chan->lock, flags); + return -EBUSY; + } + if (chan->sig & __DAHDI_SIG_FXO) { + ret = 0; + chan->cadencepos = 0; + ret = chan->ringcadence[0]; + dahdi_rbs_sethook(chan, DAHDI_TXSIG_START, DAHDI_TXSTATE_RINGON, ret); + } else + dahdi_rbs_sethook(chan, DAHDI_TXSIG_START, DAHDI_TXSTATE_START, chan->starttime); + spin_unlock_irqrestore(&chan->lock, flags); + if (file->f_flags & O_NONBLOCK) + return -EINPROGRESS; +#if 0 + rv = schluffen(&chan->txstateq); + if (rv) return rv; +#endif + break; + case DAHDI_WINK: + spin_lock_irqsave(&chan->lock, flags); + if (chan->txstate != DAHDI_TXSTATE_ONHOOK) { + spin_unlock_irqrestore(&chan->lock, flags); + return -EBUSY; + } + dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_PREWINK, chan->prewinktime); + spin_unlock_irqrestore(&chan->lock, flags); + if (file->f_flags & O_NONBLOCK) + return -EINPROGRESS; + rv = schluffen(&chan->txstateq); + if (rv) return rv; + break; + case DAHDI_FLASH: + if(chan->ignoreflash) break; /* (CNET) Ignore remote hookflash */ + spin_lock_irqsave(&chan->lock, flags); + if (chan->txstate != DAHDI_TXSTATE_OFFHOOK) { + spin_unlock_irqrestore(&chan->lock, flags); + return -EBUSY; + } + dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_PREFLASH, chan->preflashtime); + spin_unlock_irqrestore(&chan->lock, flags); + if (file->f_flags & O_NONBLOCK) + return -EINPROGRESS; + rv = schluffen(&chan->txstateq); + if (rv) return rv; + break; + case DAHDI_RINGOFF: + spin_lock_irqsave(&chan->lock, flags); + dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_ONHOOK, 0); + spin_unlock_irqrestore(&chan->lock, flags); + break; + default: + return -EINVAL; + } + } else if (chan->span->sethook) { + if (chan->txhooksig != j) { + chan->txhooksig = j; + chan->span->sethook(chan, j); + } + } else + return -ENOSYS; + break; +#ifdef CONFIG_DAHDI_PPP + case PPPIOCGCHAN: + if (chan->flags & DAHDI_FLAG_PPP) + return put_user(ppp_channel_index(chan->ppp), (int *)data) ? -EFAULT : 0; + else + return -EINVAL; + break; + case PPPIOCGUNIT: + if (chan->flags & DAHDI_FLAG_PPP) + return put_user(ppp_unit_number(chan->ppp), (int *)data) ? -EFAULT : 0; + else + return -EINVAL; + break; +#endif + default: + return dahdi_chanandpseudo_ioctl(inode, file, cmd, data, unit); + } + return 0; +} + +static int dahdi_prechan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit) +{ + struct dahdi_chan *chan = file->private_data; + int channo; + int res; + + if (chan) { + module_printk(KERN_NOTICE, "Huh? Prechan already has private data??\n"); + } + switch(cmd) { + case DAHDI_SPECIFY: + get_user(channo,(int *)data); + if (channo < 1) + return -EINVAL; + if (channo > DAHDI_MAX_CHANNELS) + return -EINVAL; + res = dahdi_specchan_open(inode, file, channo); + if (!res) { + /* Setup the pointer for future stuff */ + chan = chans[channo]; + file->private_data = chan; + /* Return success */ + return 0; + } + return res; + default: + return -ENOSYS; + } + return 0; +} + +static int dahdi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data) +{ + int unit = UNIT(file); + struct dahdi_chan *chan; + struct dahdi_timer *timer; + + if (!unit) + return dahdi_ctl_ioctl(inode, file, cmd, data); + + if (unit == 250) { + /* dahdi_transcode should have updated the file_operations on + * this file object on open, so we shouldn't be here. */ + WARN_ON(1); + return -EFAULT; + } + + if (unit == 253) { + timer = file->private_data; + if (timer) + return dahdi_timer_ioctl(inode, file, cmd, data, timer); + else + return -EINVAL; + } + if (unit == 254) { + chan = file->private_data; + if (chan) + return dahdi_chan_ioctl(inode, file, cmd, data, chan->channo); + else + return dahdi_prechan_ioctl(inode, file, cmd, data, unit); + } + if (unit == 255) { + chan = file->private_data; + if (!chan) { + module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n"); + return -EINVAL; + } + return dahdi_chanandpseudo_ioctl(inode, file, cmd, data, chan->channo); + } + return dahdi_chan_ioctl(inode, file, cmd, data, unit); +} + +int dahdi_register(struct dahdi_span *span, int prefmaster) +{ + int x; + + if (!span) + return -EINVAL; + + if (test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags)) { + module_printk(KERN_ERR, "Span %s already appears to be registered\n", span->name); + return -EBUSY; + } + + for (x = 1; x < maxspans; x++) { + if (spans[x] == span) { + module_printk(KERN_ERR, "Span %s already in list\n", span->name); + return -EBUSY; + } + } + + for (x = 1; x < DAHDI_MAX_SPANS; x++) { + if (!spans[x]) + break; + } + + if (x < DAHDI_MAX_SPANS) { + spans[x] = span; + if (maxspans < x + 1) + maxspans = x + 1; + } else { + module_printk(KERN_ERR, "Too many DAHDI spans registered\n"); + return -EBUSY; + } + + set_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags); + span->spanno = x; + + spin_lock_init(&span->lock); + + if (!span->deflaw) { + module_printk(KERN_NOTICE, "Span %s didn't specify default law. " + "Assuming mulaw, please fix driver!\n", span->name); + span->deflaw = DAHDI_LAW_MULAW; + } + + for (x = 0; x < span->channels; x++) { + span->chans[x]->span = span; + dahdi_chan_reg(span->chans[x]); + } + +#ifdef CONFIG_PROC_FS + { + char tempfile[17]; + snprintf(tempfile, sizeof(tempfile), "dahdi/%d", span->spanno); + proc_entries[span->spanno] = create_proc_read_entry(tempfile, 0444, + NULL, dahdi_proc_read, (int *) (long) span->spanno); + } +#endif + + for (x = 0; x < span->channels; x++) { + if (span->chans[x]->channo < 250) { + char chan_name[32]; + snprintf(chan_name, sizeof(chan_name), "dahdi!%d", + span->chans[x]->channo); + CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, + span->chans[x]->channo), NULL, chan_name); + } + } + + if (debug) { + module_printk(KERN_NOTICE, "Registered Span %d ('%s') with " + "%d channels\n", span->spanno, span->name, span->channels); + } + + if (!master || prefmaster) { + master = span; + if (debug) { + module_printk(KERN_NOTICE, "Span ('%s') is new master\n", + span->name); + } + } + + return 0; +} + +int dahdi_unregister(struct dahdi_span *span) +{ + int x; + int new_maxspans; + static struct dahdi_span *new_master; + +#ifdef CONFIG_PROC_FS + char tempfile[17]; +#endif /* CONFIG_PROC_FS */ + + if (!test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags)) { + module_printk(KERN_ERR, "Span %s does not appear to be registered\n", span->name); + return -1; + } + /* Shutdown the span if it's running */ + if (span->flags & DAHDI_FLAG_RUNNING) + if (span->shutdown) + span->shutdown(span); + + if (spans[span->spanno] != span) { + module_printk(KERN_ERR, "Span %s has spanno %d which is something else\n", span->name, span->spanno); + return -1; + } + if (debug) + module_printk(KERN_NOTICE, "Unregistering Span '%s' with %d channels\n", span->name, span->channels); +#ifdef CONFIG_PROC_FS + snprintf(tempfile, sizeof(tempfile)-1, "dahdi/%d", span->spanno); + remove_proc_entry(tempfile, NULL); +#endif /* CONFIG_PROC_FS */ + + for (x = 0; x < span->channels; x++) { + if (span->chans[x]->channo < 250) + CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, span->chans[x]->channo)); + } + + spans[span->spanno] = NULL; + span->spanno = 0; + clear_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags); + for (x=0;xchannels;x++) + dahdi_chan_unreg(span->chans[x]); + new_maxspans = 0; + new_master = master; /* FIXME: locking */ + if (master == span) + new_master = NULL; + for (x=1;xname: "no master"); + master = new_master; + + return 0; +} + +/* +** This routine converts from linear to ulaw +** +** Craig Reese: IDA/Supercomputing Research Center +** Joe Campbell: Department of Defense +** 29 September 1989 +** +** References: +** 1) CCITT Recommendation G.711 (very difficult to follow) +** 2) "A New Digital Technique for Implementation of Any +** Continuous PCM Companding Law," Villeret, Michel, +** et al. 1973 IEEE Int. Conf. on Communications, Vol 1, +** 1973, pg. 11.12-11.17 +** 3) MIL-STD-188-113,"Interoperability and Performance Standards +** for Analog-to_Digital Conversion Techniques," +** 17 February 1987 +** +** Input: Signed 16 bit linear sample +** Output: 8 bit ulaw sample +*/ + +#define ZEROTRAP /* turn on the trap as per the MIL-STD */ +#define BIAS 0x84 /* define the add-in bias for 16 bit samples */ +#define CLIP 32635 + +#ifdef CONFIG_CALC_XLAW +unsigned char +#else +static unsigned char __init +#endif +__dahdi_lineartoulaw(short sample) +{ + static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7}; + int sign, exponent, mantissa; + unsigned char ulawbyte; + + /* Get the sample into sign-magnitude. */ + sign = (sample >> 8) & 0x80; /* set aside the sign */ + if (sign != 0) sample = -sample; /* get magnitude */ + if (sample > CLIP) sample = CLIP; /* clip the magnitude */ + + /* Convert from 16 bit linear to ulaw. */ + sample = sample + BIAS; + exponent = exp_lut[(sample >> 7) & 0xFF]; + mantissa = (sample >> (exponent + 3)) & 0x0F; + ulawbyte = ~(sign | (exponent << 4) | mantissa); +#ifdef ZEROTRAP + if (ulawbyte == 0) ulawbyte = 0x02; /* optional CCITT trap */ +#endif + if (ulawbyte == 0xff) ulawbyte = 0x7f; /* never return 0xff */ + return(ulawbyte); +} + +#define AMI_MASK 0x55 + +#ifdef CONFIG_CALC_XLAW +unsigned char +#else +static inline unsigned char __init +#endif +__dahdi_lineartoalaw (short linear) +{ + int mask; + int seg; + int pcm_val; + static int seg_end[8] = + { + 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF + }; + + pcm_val = linear; + if (pcm_val >= 0) + { + /* Sign (7th) bit = 1 */ + mask = AMI_MASK | 0x80; + } + else + { + /* Sign bit = 0 */ + mask = AMI_MASK; + pcm_val = -pcm_val; + } + + /* Convert the scaled magnitude to segment number. */ + for (seg = 0; seg < 8; seg++) + { + if (pcm_val <= seg_end[seg]) + break; + } + /* Combine the sign, segment, and quantization bits. */ + return ((seg << 4) | ((pcm_val >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask; +} +/*- End of function --------------------------------------------------------*/ + +static inline short int __init alaw2linear (uint8_t alaw) +{ + int i; + int seg; + + alaw ^= AMI_MASK; + i = ((alaw & 0x0F) << 4); + seg = (((int) alaw & 0x70) >> 4); + if (seg) + i = (i + 0x100) << (seg - 1); + return (short int) ((alaw & 0x80) ? i : -i); +} +/*- End of function --------------------------------------------------------*/ +static void __init dahdi_conv_init(void) +{ + int i; + + /* + * Set up mu-law conversion table + */ + for(i = 0;i < 256;i++) + { + short mu,e,f,y; + static short etab[]={0,132,396,924,1980,4092,8316,16764}; + + mu = 255-i; + e = (mu & 0x70)/16; + f = mu & 0x0f; + y = f * (1 << (e + 3)); + y += etab[e]; + if (mu & 0x80) y = -y; + __dahdi_mulaw[i] = y; + __dahdi_alaw[i] = alaw2linear(i); + /* Default (0.0 db) gain table */ + defgain[i] = i; + } +#ifndef CONFIG_CALC_XLAW + /* set up the reverse (mu-law) conversion table */ + for(i = -32768; i < 32768; i += 4) + { + __dahdi_lin2mu[((unsigned short)(short)i) >> 2] = __dahdi_lineartoulaw(i); + __dahdi_lin2a[((unsigned short)(short)i) >> 2] = __dahdi_lineartoalaw(i); + } +#endif +} + +static inline void __dahdi_process_getaudio_chunk(struct dahdi_chan *ss, unsigned char *txb) +{ + /* We transmit data from our master channel */ + /* Called with ss->lock held */ + struct dahdi_chan *ms = ss->master; + /* Linear representation */ + short getlin[DAHDI_CHUNKSIZE], k[DAHDI_CHUNKSIZE]; + int x; + + /* Okay, now we've got something to transmit */ + for (x=0;xec_state && (ms->ec_state->status.mode == ECHO_MODE_ACTIVE) && !ms->ec_state->features.CED_tx_detect) { + for (x = 0; x < DAHDI_CHUNKSIZE; x++) { + if (echo_can_disable_detector_update(&ms->ec_state->txecdis, getlin[x])) { + set_echocan_fax_mode(ms, ss->channo, "CED tx detected", 1); + dahdi_qevent_nolock(ms, DAHDI_EVENT_TX_CED_DETECTED); + break; + } + } + } + + if ((!ms->confmute && !ms->dialing) || (ms->flags & DAHDI_FLAG_PSEUDO)) { + /* Handle conferencing on non-clear channel and non-HDLC channels */ + switch(ms->confmode & DAHDI_CONF_MODE_MASK) { + case DAHDI_CONF_NORMAL: + /* Do nuffin */ + break; + case DAHDI_CONF_MONITOR: /* Monitor a channel's rx mode */ + /* if a pseudo-channel, ignore */ + if (ms->flags & DAHDI_FLAG_PSEUDO) break; + /* Add monitored channel */ + if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) { + ACSS(getlin, chans[ms->confna]->getlin); + } else { + ACSS(getlin, chans[ms->confna]->putlin); + } + for (x=0;xflags & DAHDI_FLAG_PSEUDO) break; + /* Add monitored channel */ + if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) { + ACSS(getlin, chans[ms->confna]->putlin); + } else { + ACSS(getlin, chans[ms->confna]->getlin); + } + + for (x=0;xflags & DAHDI_FLAG_PSEUDO) break; + ACSS(getlin, chans[ms->confna]->putlin); + ACSS(getlin, chans[ms->confna]->getlin); + for (x=0;xflags & DAHDI_FLAG_PSEUDO) + break; + + if (!chans[ms->confna]->readchunkpreec) + break; + + /* Add monitored channel */ + ACSS(getlin, chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO ? + chans[ms->confna]->readchunkpreec : chans[ms->confna]->putlin); + for (x = 0; x < DAHDI_CHUNKSIZE; x++) + txb[x] = DAHDI_LIN2X(getlin[x], ms); + + break; + case DAHDI_CONF_MONITOR_TX_PREECHO: /* Monitor a channel's tx mode */ + /* if a pseudo-channel, ignore */ + if (ms->flags & DAHDI_FLAG_PSEUDO) + break; + + if (!chans[ms->confna]->readchunkpreec) + break; + + /* Add monitored channel */ + ACSS(getlin, chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO ? + chans[ms->confna]->putlin : chans[ms->confna]->readchunkpreec); + for (x = 0; x < DAHDI_CHUNKSIZE; x++) + txb[x] = DAHDI_LIN2X(getlin[x], ms); + + break; + case DAHDI_CONF_MONITORBOTH_PREECHO: /* monitor a channel's rx and tx mode */ + /* if a pseudo-channel, ignore */ + if (ms->flags & DAHDI_FLAG_PSEUDO) + break; + + if (!chans[ms->confna]->readchunkpreec) + break; + + ACSS(getlin, chans[ms->confna]->putlin); + ACSS(getlin, chans[ms->confna]->readchunkpreec); + + for (x = 0; x < DAHDI_CHUNKSIZE; x++) + txb[x] = DAHDI_LIN2X(getlin[x], ms); + + break; + case DAHDI_CONF_REALANDPSEUDO: + /* This strange mode takes the transmit buffer and + puts it on the conference, minus its last sample, + then outputs from the conference minus the + real channel's last sample. */ + /* if to talk on conf */ + if (ms->confmode & DAHDI_CONF_PSEUDO_TALKER) { + /* Store temp value */ + memcpy(k, getlin, DAHDI_CHUNKSIZE * sizeof(short)); + /* Add conf value */ + ACSS(k, conf_sums_next[ms->_confn]); + /* save last one */ + memcpy(ms->conflast2, ms->conflast1, DAHDI_CHUNKSIZE * sizeof(short)); + memcpy(ms->conflast1, k, DAHDI_CHUNKSIZE * sizeof(short)); + /* get amount actually added */ + SCSS(ms->conflast1, conf_sums_next[ms->_confn]); + /* Really add in new value */ + ACSS(conf_sums_next[ms->_confn], ms->conflast1); + } else { + memset(ms->conflast1, 0, DAHDI_CHUNKSIZE * sizeof(short)); + memset(ms->conflast2, 0, DAHDI_CHUNKSIZE * sizeof(short)); + } + memset(getlin, 0, DAHDI_CHUNKSIZE * sizeof(short)); + txb[0] = DAHDI_LIN2X(0, ms); + memset(txb + 1, txb[0], DAHDI_CHUNKSIZE - 1); + /* fall through to normal conf mode */ + case DAHDI_CONF_CONF: /* Normal conference mode */ + if (ms->flags & DAHDI_FLAG_PSEUDO) /* if pseudo-channel */ + { + /* if to talk on conf */ + if (ms->confmode & DAHDI_CONF_TALKER) { + /* Store temp value */ + memcpy(k, getlin, DAHDI_CHUNKSIZE * sizeof(short)); + /* Add conf value */ + ACSS(k, conf_sums[ms->_confn]); + /* get amount actually added */ + memcpy(ms->conflast, k, DAHDI_CHUNKSIZE * sizeof(short)); + SCSS(ms->conflast, conf_sums[ms->_confn]); + /* Really add in new value */ + ACSS(conf_sums[ms->_confn], ms->conflast); + memcpy(ms->getlin, getlin, DAHDI_CHUNKSIZE * sizeof(short)); + } else { + memset(ms->conflast, 0, DAHDI_CHUNKSIZE * sizeof(short)); + memcpy(getlin, ms->getlin, DAHDI_CHUNKSIZE * sizeof(short)); + } + txb[0] = DAHDI_LIN2X(0, ms); + memset(txb + 1, txb[0], DAHDI_CHUNKSIZE - 1); + break; + } + /* fall through */ + case DAHDI_CONF_CONFMON: /* Conference monitor mode */ + if (ms->confmode & DAHDI_CONF_LISTENER) { + /* Subtract out last sample written to conf */ + SCSS(getlin, ms->conflast); + /* Add in conference */ + ACSS(getlin, conf_sums[ms->_confn]); + } + for (x=0;x_confn], getlin); + /* Start with silence */ + memset(getlin, 0, DAHDI_CHUNKSIZE * sizeof(short)); + /* If a listener on the conf... */ + if (ms->confmode & DAHDI_CONF_LISTENER) { + /* Subtract last value written */ + SCSS(getlin, ms->conflast); + /* Add in conf */ + ACSS(getlin, conf_sums[ms->_confn]); + } + for (x=0;xconfna]) + break; + if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) { + if (ms->ec_state) { + for (x=0;xconfna]->getlin[x], ms); + } else { + memcpy(txb, chans[ms->confna]->getraw, DAHDI_CHUNKSIZE); + } + } else { + if (ms->ec_state) { + for (x=0;xconfna]->putlin[x], ms); + } else { + memcpy(txb, chans[ms->confna]->putraw, DAHDI_CHUNKSIZE); + } + } + for (x=0;xconfmute || (ms->ec_state && (ms->ec_state->status.mode) & __ECHO_MODE_MUTE)) { + txb[0] = DAHDI_LIN2X(0, ms); + memset(txb + 1, txb[0], DAHDI_CHUNKSIZE - 1); + if (ms->ec_state && (ms->ec_state->status.mode == ECHO_MODE_STARTTRAINING)) { + /* Transmit impulse now */ + txb[0] = DAHDI_LIN2X(16384, ms); + ms->ec_state->status.mode = ECHO_MODE_AWAITINGECHO; + } + } + /* save value from last chunk */ + memcpy(ms->getlin_lastchunk, ms->getlin, DAHDI_CHUNKSIZE * sizeof(short)); + /* save value from current */ + memcpy(ms->getlin, getlin, DAHDI_CHUNKSIZE * sizeof(short)); + /* save value from current */ + memcpy(ms->getraw, txb, DAHDI_CHUNKSIZE); + /* if to make tx tone */ + if (ms->v1_1 || ms->v2_1 || ms->v3_1) + { + for (x=0;xtxgain[txb[x]]; +} + +static inline void __dahdi_getbuf_chunk(struct dahdi_chan *ss, unsigned char *txb) +{ + /* Called with ss->lock held */ + /* We transmit data from our master channel */ + struct dahdi_chan *ms = ss->master; + /* Buffer we're using */ + unsigned char *buf; + /* Old buffer number */ + int oldbuf; + /* Linear representation */ + int getlin; + /* How many bytes we need to process */ + int bytes = DAHDI_CHUNKSIZE, left; + int x; + + /* Let's pick something to transmit. First source to + try is our write-out buffer. Always check it first because + its our 'fast path' for whatever that's worth. */ + while(bytes) { + if ((ms->outwritebuf > -1) && !ms->txdisable) { + buf= ms->writebuf[ms->outwritebuf]; + left = ms->writen[ms->outwritebuf] - ms->writeidx[ms->outwritebuf]; + if (left > bytes) + left = bytes; + if (ms->flags & DAHDI_FLAG_HDLC) { + /* If this is an HDLC channel we only send a byte of + HDLC. */ + for(x=0;xtxhdlc)) + /* Load a byte of data only if needed */ + fasthdlc_tx_load_nocheck(&ms->txhdlc, buf[ms->writeidx[ms->outwritebuf]++]); + *(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc); + } + bytes -= left; + } else { + memcpy(txb, buf + ms->writeidx[ms->outwritebuf], left); + ms->writeidx[ms->outwritebuf]+=left; + txb += left; + bytes -= left; + } + /* Check buffer status */ + if (ms->writeidx[ms->outwritebuf] >= ms->writen[ms->outwritebuf]) { + /* We've reached the end of our buffer. Go to the next. */ + oldbuf = ms->outwritebuf; + /* Clear out write index and such */ + ms->writeidx[oldbuf] = 0; + ms->outwritebuf = (ms->outwritebuf + 1) % ms->numbufs; + + if (!(ms->flags & DAHDI_FLAG_MTP2)) { + ms->writen[oldbuf] = 0; + if (ms->outwritebuf == ms->inwritebuf) { + /* Whoopsies, we're run out of buffers. Mark ours + as -1 and wait for the filler to notify us that + there is something to write */ + ms->outwritebuf = -1; + if (ms->iomask & (DAHDI_IOMUX_WRITE | DAHDI_IOMUX_WRITEEMPTY)) + wake_up_interruptible(&ms->eventbufq); + /* If we're only supposed to start when full, disable the transmitter */ + if ((ms->txbufpolicy == DAHDI_POLICY_WHEN_FULL) || + (ms->txbufpolicy == DAHDI_POLICY_HALF_FULL)) + ms->txdisable = 1; + } + } else { + if (ms->outwritebuf == ms->inwritebuf) { + ms->outwritebuf = oldbuf; + if (ms->iomask & (DAHDI_IOMUX_WRITE | DAHDI_IOMUX_WRITEEMPTY)) + wake_up_interruptible(&ms->eventbufq); + /* If we're only supposed to start when full, disable the transmitter */ + if ((ms->txbufpolicy == DAHDI_POLICY_WHEN_FULL) || + (ms->txbufpolicy == DAHDI_POLICY_HALF_FULL)) + ms->txdisable = 1; + } + } + if (ms->inwritebuf < 0) { + /* The filler doesn't have a place to put data. Now + that we're done with this buffer, notify them. */ + ms->inwritebuf = oldbuf; + } +/* In the very orignal driver, it was quite well known to me (Jim) that there +was a possibility that a channel sleeping on a write block needed to +be potentially woken up EVERY time a buffer was emptied, not just on the first +one, because if only done on the first one there is a slight timing potential +of missing the wakeup (between where it senses the (lack of) active condition +(with interrupts disabled) and where it does the sleep (interrupts enabled) +in the read or iomux call, etc). That is why the write and iomux calls start +with an infinite loop that gets broken out of upon an active condition, +otherwise keeps sleeping and looking. The part in this code got "optimized" +out in the later versions, and is put back now. */ + if (!(ms->flags & (DAHDI_FLAG_NETDEV | DAHDI_FLAG_PPP))) { + wake_up_interruptible(&ms->writebufq); + wake_up_interruptible(&ms->sel); + if (ms->iomask & DAHDI_IOMUX_WRITE) + wake_up_interruptible(&ms->eventbufq); + } + /* Transmit a flag if this is an HDLC channel */ + if (ms->flags & DAHDI_FLAG_HDLC) + fasthdlc_tx_frame_nocheck(&ms->txhdlc); +#ifdef CONFIG_DAHDI_NET + if (ms->flags & DAHDI_FLAG_NETDEV) + netif_wake_queue(ztchan_to_dev(ms)); +#endif +#ifdef CONFIG_DAHDI_PPP + if (ms->flags & DAHDI_FLAG_PPP) { + ms->do_ppp_wakeup = 1; + tasklet_schedule(&ms->ppp_calls); + } +#endif + } + } else if (ms->curtone && !(ms->flags & DAHDI_FLAG_PSEUDO)) { + left = ms->curtone->tonesamples - ms->tonep; + if (left > bytes) + left = bytes; + for (x=0;xts, ms->curtone); + *(txb++) = DAHDI_LIN2X(getlin, ms); + } + ms->tonep+=left; + bytes -= left; + if (ms->tonep >= ms->curtone->tonesamples) { + struct dahdi_tone *last; + /* Go to the next sample of the tone */ + ms->tonep = 0; + last = ms->curtone; + ms->curtone = ms->curtone->next; + if (!ms->curtone) { + /* No more tones... Is this dtmf or mf? If so, go to the next digit */ + if (ms->dialing) + __do_dtmf(ms); + } else { + if (last != ms->curtone) + dahdi_init_tone_state(&ms->ts, ms->curtone); + } + } + } else if (ms->flags & DAHDI_FLAG_LOOPED) { + for (x = 0; x < bytes; x++) + txb[x] = ms->readchunk[x]; + bytes = 0; + } else if (ms->flags & DAHDI_FLAG_HDLC) { + for (x=0;xtxhdlc)) + fasthdlc_tx_frame_nocheck(&ms->txhdlc); + *(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc); + } + bytes = 0; + } else if (ms->flags & DAHDI_FLAG_CLEAR) { + /* Clear channels that are idle in audio mode need + to send silence; in non-audio mode, always send 0xff + so stupid switches won't consider the channel active + */ + if (ms->flags & DAHDI_FLAG_AUDIO) { + memset(txb, DAHDI_LIN2X(0, ms), bytes); + } else { + memset(txb, 0xFF, bytes); + } + bytes = 0; + } else { + memset(txb, DAHDI_LIN2X(0, ms), bytes); /* Lastly we use silence on telephony channels */ + bytes = 0; + } + } +} + +static inline void rbs_itimer_expire(struct dahdi_chan *chan) +{ + /* the only way this could have gotten here, is if a channel + went onf hook longer then the wink or flash detect timeout */ + /* Called with chan->lock held */ + switch(chan->sig) + { + case DAHDI_SIG_FXOLS: /* if FXO, its definitely on hook */ + case DAHDI_SIG_FXOGS: + case DAHDI_SIG_FXOKS: + __qevent(chan,DAHDI_EVENT_ONHOOK); + chan->gotgs = 0; + break; +#if defined(EMFLASH) || defined(EMPULSE) + case DAHDI_SIG_EM: + case DAHDI_SIG_EM_E1: + if (chan->rxhooksig == DAHDI_RXSIG_ONHOOK) { + __qevent(chan,DAHDI_EVENT_ONHOOK); + break; + } + __qevent(chan,DAHDI_EVENT_RINGOFFHOOK); + break; +#endif +#ifdef FXSFLASH + case DAHDI_SIG_FXSKS: + if (chan->rxhooksig == DAHDI_RXSIG_ONHOOK) { + __qevent(chan, DAHDI_EVENT_ONHOOK); + break; + } +#endif + /* fall thru intentionally */ + default: /* otherwise, its definitely off hook */ + __qevent(chan,DAHDI_EVENT_RINGOFFHOOK); + break; + } +} + +static inline void __rbs_otimer_expire(struct dahdi_chan *chan) +{ + int len = 0; + /* Called with chan->lock held */ + + chan->otimer = 0; + /* Move to the next timer state */ + switch(chan->txstate) { + case DAHDI_TXSTATE_RINGOFF: + /* Turn on the ringer now that the silent time has passed */ + ++chan->cadencepos; + if (chan->cadencepos >= DAHDI_MAX_CADENCE) + chan->cadencepos = chan->firstcadencepos; + len = chan->ringcadence[chan->cadencepos]; + + if (!len) { + chan->cadencepos = chan->firstcadencepos; + len = chan->ringcadence[chan->cadencepos]; + } + + dahdi_rbs_sethook(chan, DAHDI_TXSIG_START, DAHDI_TXSTATE_RINGON, len); + __qevent(chan, DAHDI_EVENT_RINGERON); + break; + + case DAHDI_TXSTATE_RINGON: + /* Turn off the ringer now that the loud time has passed */ + ++chan->cadencepos; + if (chan->cadencepos >= DAHDI_MAX_CADENCE) + chan->cadencepos = 0; + len = chan->ringcadence[chan->cadencepos]; + + if (!len) { + chan->cadencepos = 0; + len = chan->curzone->ringcadence[chan->cadencepos]; + } + + dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_RINGOFF, len); + __qevent(chan, DAHDI_EVENT_RINGEROFF); + break; + + case DAHDI_TXSTATE_START: + /* If we were starting, go off hook now ready to debounce */ + dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_AFTERSTART, DAHDI_AFTERSTART_TIME); + wake_up_interruptible(&chan->txstateq); + break; + + case DAHDI_TXSTATE_PREWINK: + /* Actually wink */ + dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_WINK, chan->winktime); + break; + + case DAHDI_TXSTATE_WINK: + /* Wink complete, go on hook and stabalize */ + dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_ONHOOK, 0); + if (chan->file && (chan->file->f_flags & O_NONBLOCK)) + __qevent(chan, DAHDI_EVENT_HOOKCOMPLETE); + wake_up_interruptible(&chan->txstateq); + break; + + case DAHDI_TXSTATE_PREFLASH: + /* Actually flash */ + dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_FLASH, chan->flashtime); + break; + + case DAHDI_TXSTATE_FLASH: + dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_OFFHOOK, 0); + if (chan->file && (chan->file->f_flags & O_NONBLOCK)) + __qevent(chan, DAHDI_EVENT_HOOKCOMPLETE); + wake_up_interruptible(&chan->txstateq); + break; + + case DAHDI_TXSTATE_DEBOUNCE: + dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_OFFHOOK, 0); + /* See if we've gone back on hook */ + if ((chan->rxhooksig == DAHDI_RXSIG_ONHOOK) && (chan->rxflashtime > 2)) + chan->itimerset = chan->itimer = chan->rxflashtime * DAHDI_CHUNKSIZE; + wake_up_interruptible(&chan->txstateq); + break; + + case DAHDI_TXSTATE_AFTERSTART: + dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_OFFHOOK, 0); + if (chan->file && (chan->file->f_flags & O_NONBLOCK)) + __qevent(chan, DAHDI_EVENT_HOOKCOMPLETE); + wake_up_interruptible(&chan->txstateq); + break; + + case DAHDI_TXSTATE_KEWL: + dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_AFTERKEWL, DAHDI_AFTERKEWLTIME); + if (chan->file && (chan->file->f_flags & O_NONBLOCK)) + __qevent(chan, DAHDI_EVENT_HOOKCOMPLETE); + wake_up_interruptible(&chan->txstateq); + break; + + case DAHDI_TXSTATE_AFTERKEWL: + if (chan->kewlonhook) { + __qevent(chan,DAHDI_EVENT_ONHOOK); + } + chan->txstate = DAHDI_TXSTATE_ONHOOK; + chan->gotgs = 0; + break; + + case DAHDI_TXSTATE_PULSEBREAK: + dahdi_rbs_sethook(chan, DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_PULSEMAKE, + chan->pulsemaketime); + wake_up_interruptible(&chan->txstateq); + break; + + case DAHDI_TXSTATE_PULSEMAKE: + if (chan->pdialcount) + chan->pdialcount--; + if (chan->pdialcount) + { + dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, + DAHDI_TXSTATE_PULSEBREAK, chan->pulsebreaktime); + break; + } + chan->txstate = DAHDI_TXSTATE_PULSEAFTER; + chan->otimer = chan->pulseaftertime * DAHDI_CHUNKSIZE; + wake_up_interruptible(&chan->txstateq); + break; + + case DAHDI_TXSTATE_PULSEAFTER: + chan->txstate = DAHDI_TXSTATE_OFFHOOK; + __do_dtmf(chan); + wake_up_interruptible(&chan->txstateq); + break; + + default: + break; + } +} + +static void __dahdi_hooksig_pvt(struct dahdi_chan *chan, enum dahdi_rxsig rxsig) +{ + + /* State machines for receive hookstate transitions + called with chan->lock held */ + + if ((chan->rxhooksig) == rxsig) return; + + if ((chan->flags & DAHDI_FLAG_SIGFREEZE)) return; + + chan->rxhooksig = rxsig; +#ifdef RINGBEGIN + if ((chan->sig & __DAHDI_SIG_FXS) && (rxsig == DAHDI_RXSIG_RING) && + (!chan->ringdebtimer)) + __qevent(chan,DAHDI_EVENT_RINGBEGIN); +#endif + switch(chan->sig) { + case DAHDI_SIG_EM: /* E and M */ + case DAHDI_SIG_EM_E1: + switch(rxsig) { + case DAHDI_RXSIG_OFFHOOK: /* went off hook */ + /* The interface is going off hook */ +#ifdef EMFLASH + if (chan->itimer) + { + __qevent(chan,DAHDI_EVENT_WINKFLASH); + chan->itimerset = chan->itimer = 0; + break; + } +#endif +#ifdef EMPULSE + if (chan->itimer) /* if timer still running */ + { + int plen = chan->itimerset - chan->itimer; + if (plen <= DAHDI_MAXPULSETIME) + { + if (plen >= DAHDI_MINPULSETIME) + { + chan->pulsecount++; + + chan->pulsetimer = DAHDI_PULSETIMEOUT; + chan->itimerset = chan->itimer = 0; + if (chan->pulsecount == 1) + __qevent(chan,DAHDI_EVENT_PULSE_START); + } + } + break; + } +#endif + /* set wink timer */ + chan->itimerset = chan->itimer = chan->rxwinktime * DAHDI_CHUNKSIZE; + break; + case DAHDI_RXSIG_ONHOOK: /* went on hook */ + /* This interface is now going on hook. + Check for WINK, etc */ + if (chan->itimer) + __qevent(chan,DAHDI_EVENT_WINKFLASH); +#if defined(EMFLASH) || defined(EMPULSE) + else { +#ifdef EMFLASH + chan->itimerset = chan->itimer = chan->rxflashtime * DAHDI_CHUNKSIZE; + +#else /* EMFLASH */ + chan->itimerset = chan->itimer = chan->rxwinktime * DAHDI_CHUNKSIZE; + +#endif /* EMFLASH */ + chan->gotgs = 0; + break; + } +#else /* EMFLASH || EMPULSE */ + else { + __qevent(chan,DAHDI_EVENT_ONHOOK); + chan->gotgs = 0; + } +#endif + chan->itimerset = chan->itimer = 0; + break; + default: + break; + } + break; + case DAHDI_SIG_FXSKS: /* FXS Kewlstart */ + /* ignore a bit error if loop not closed and stable */ + if (chan->txstate != DAHDI_TXSTATE_OFFHOOK) break; +#ifdef FXSFLASH + if (rxsig == DAHDI_RXSIG_ONHOOK) { + chan->itimer = DAHDI_FXSFLASHMAXTIME * DAHDI_CHUNKSIZE; + break; + } else if (rxsig == DAHDI_RXSIG_OFFHOOK) { + if (chan->itimer) { + /* did the offhook occur in the window? if not, ignore both events */ + if (chan->itimer <= ((DAHDI_FXSFLASHMAXTIME - DAHDI_FXSFLASHMINTIME) * DAHDI_CHUNKSIZE)) + __qevent(chan, DAHDI_EVENT_WINKFLASH); + } + chan->itimer = 0; + break; + } +#endif + /* fall through intentionally */ + case DAHDI_SIG_FXSGS: /* FXS Groundstart */ + if (rxsig == DAHDI_RXSIG_ONHOOK) { + chan->ringdebtimer = RING_DEBOUNCE_TIME; + chan->ringtrailer = 0; + if (chan->txstate != DAHDI_TXSTATE_DEBOUNCE) { + chan->gotgs = 0; + __qevent(chan,DAHDI_EVENT_ONHOOK); + } + } + break; + case DAHDI_SIG_FXOGS: /* FXO Groundstart */ + if (rxsig == DAHDI_RXSIG_START) { + /* if havent got gs, report it */ + if (!chan->gotgs) { + __qevent(chan,DAHDI_EVENT_RINGOFFHOOK); + chan->gotgs = 1; + } + } + /* fall through intentionally */ + case DAHDI_SIG_FXOLS: /* FXO Loopstart */ + case DAHDI_SIG_FXOKS: /* FXO Kewlstart */ + switch(rxsig) { + case DAHDI_RXSIG_OFFHOOK: /* went off hook */ + /* if asserti ng ring, stop it */ + if (chan->txstate == DAHDI_TXSTATE_START) { + dahdi_rbs_sethook(chan,DAHDI_TXSIG_OFFHOOK, DAHDI_TXSTATE_AFTERSTART, DAHDI_AFTERSTART_TIME); + } + chan->kewlonhook = 0; +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "Off hook on channel %d, itimer = %d, gotgs = %d\n", chan->channo, chan->itimer, chan->gotgs); +#endif + if (chan->itimer) /* if timer still running */ + { + int plen = chan->itimerset - chan->itimer; + if (plen <= DAHDI_MAXPULSETIME) + { + if (plen >= DAHDI_MINPULSETIME) + { + chan->pulsecount++; + chan->pulsetimer = DAHDI_PULSETIMEOUT; + chan->itimer = chan->itimerset; + if (chan->pulsecount == 1) + __qevent(chan,DAHDI_EVENT_PULSE_START); + } + } else + __qevent(chan,DAHDI_EVENT_WINKFLASH); + } else { + /* if havent got GS detect */ + if (!chan->gotgs) { + __qevent(chan,DAHDI_EVENT_RINGOFFHOOK); + chan->gotgs = 1; + chan->itimerset = chan->itimer = 0; + } + } + chan->itimerset = chan->itimer = 0; + break; + case DAHDI_RXSIG_ONHOOK: /* went on hook */ + /* if not during offhook debounce time */ + if ((chan->txstate != DAHDI_TXSTATE_DEBOUNCE) && + (chan->txstate != DAHDI_TXSTATE_KEWL) && + (chan->txstate != DAHDI_TXSTATE_AFTERKEWL)) { + chan->itimerset = chan->itimer = chan->rxflashtime * DAHDI_CHUNKSIZE; + } + if (chan->txstate == DAHDI_TXSTATE_KEWL) + chan->kewlonhook = 1; + break; + default: + break; + } + default: + break; + } +} + +void dahdi_hooksig(struct dahdi_chan *chan, enum dahdi_rxsig rxsig) +{ + /* skip if no change */ + unsigned long flags; + spin_lock_irqsave(&chan->lock, flags); + __dahdi_hooksig_pvt(chan,rxsig); + spin_unlock_irqrestore(&chan->lock, flags); +} + +void dahdi_rbsbits(struct dahdi_chan *chan, int cursig) +{ + unsigned long flags; + if (cursig == chan->rxsig) + return; + + if ((chan->flags & DAHDI_FLAG_SIGFREEZE)) return; + + spin_lock_irqsave(&chan->lock, flags); + switch(chan->sig) { + case DAHDI_SIG_FXOGS: /* FXO Groundstart */ + /* B-bit only matters for FXO GS */ + if (!(cursig & DAHDI_BBIT)) { + __dahdi_hooksig_pvt(chan, DAHDI_RXSIG_START); + break; + } + /* Fall through */ + case DAHDI_SIG_EM: /* E and M */ + case DAHDI_SIG_EM_E1: + case DAHDI_SIG_FXOLS: /* FXO Loopstart */ + case DAHDI_SIG_FXOKS: /* FXO Kewlstart */ + if (cursig & DAHDI_ABIT) /* off hook */ + __dahdi_hooksig_pvt(chan,DAHDI_RXSIG_OFFHOOK); + else /* on hook */ + __dahdi_hooksig_pvt(chan,DAHDI_RXSIG_ONHOOK); + break; + + case DAHDI_SIG_FXSKS: /* FXS Kewlstart */ + case DAHDI_SIG_FXSGS: /* FXS Groundstart */ + /* Fall through */ + case DAHDI_SIG_FXSLS: + if (!(cursig & DAHDI_BBIT)) { + /* Check for ringing first */ + __dahdi_hooksig_pvt(chan, DAHDI_RXSIG_RING); + break; + } + if ((chan->sig != DAHDI_SIG_FXSLS) && (cursig & DAHDI_ABIT)) { + /* if went on hook */ + __dahdi_hooksig_pvt(chan, DAHDI_RXSIG_ONHOOK); + } else { + __dahdi_hooksig_pvt(chan, DAHDI_RXSIG_OFFHOOK); + } + break; + case DAHDI_SIG_CAS: + /* send event that something changed */ + __qevent(chan, DAHDI_EVENT_BITSCHANGED); + break; + + default: + break; + } + /* Keep track of signalling for next time */ + chan->rxsig = cursig; + spin_unlock_irqrestore(&chan->lock, flags); +} + +static void process_echocan_events(struct dahdi_chan *chan) +{ + union dahdi_echocan_events events = chan->ec_state->events; + + if (events.CED_tx_detected) { + dahdi_qevent_nolock(chan, DAHDI_EVENT_TX_CED_DETECTED); + if (chan->ec_state) { + if (chan->ec_state->status.mode == ECHO_MODE_ACTIVE) + set_echocan_fax_mode(chan, chan->channo, "CED tx detected", 1); + else + module_printk(KERN_NOTICE, "Detected CED tone (tx) on channel %d\n", chan->channo); + } + } + + if (events.CED_rx_detected) { + dahdi_qevent_nolock(chan, DAHDI_EVENT_RX_CED_DETECTED); + if (chan->ec_state) { + if (chan->ec_state->status.mode == ECHO_MODE_ACTIVE) + set_echocan_fax_mode(chan, chan->channo, "CED rx detected", 1); + else + module_printk(KERN_NOTICE, "Detected CED tone (rx) on channel %d\n", chan->channo); + } + } + + if (events.CNG_tx_detected) + dahdi_qevent_nolock(chan, DAHDI_EVENT_TX_CNG_DETECTED); + + if (events.CNG_rx_detected) + dahdi_qevent_nolock(chan, DAHDI_EVENT_RX_CNG_DETECTED); + + if (events.NLP_auto_disabled) { + dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_DISABLED); + chan->ec_state->status.mode = ECHO_MODE_FAX; + } + + if (events.NLP_auto_enabled) { + dahdi_qevent_nolock(chan, DAHDI_EVENT_EC_NLP_ENABLED); + chan->ec_state->status.mode = ECHO_MODE_ACTIVE; + } +} + +static inline void __dahdi_ec_chunk(struct dahdi_chan *ss, unsigned char *rxchunk, const unsigned char *txchunk) +{ + short rxlin, txlin; + int x; + unsigned long flags; + + spin_lock_irqsave(&ss->lock, flags); + + if (ss->readchunkpreec) { + /* Save a copy of the audio before the echo can has its way with it */ + for (x = 0; x < DAHDI_CHUNKSIZE; x++) + /* We only ever really need to deal with signed linear - let's just convert it now */ + ss->readchunkpreec[x] = DAHDI_XLAW(rxchunk[x], ss); + } + + /* Perform echo cancellation on a chunk if necessary */ + if (ss->ec_state) { +#if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP) + dahdi_kernel_fpu_begin(); +#endif + if (ss->ec_state->status.mode & __ECHO_MODE_MUTE) { + /* Special stuff for training the echo can */ + for (x=0;xec_state->status.mode == ECHO_MODE_PRETRAINING) { + if (--ss->ec_state->status.pretrain_timer <= 0) { + ss->ec_state->status.pretrain_timer = 0; + ss->ec_state->status.mode = ECHO_MODE_STARTTRAINING; + } + } + if (ss->ec_state->status.mode == ECHO_MODE_AWAITINGECHO) { + ss->ec_state->status.last_train_tap = 0; + ss->ec_state->status.mode = ECHO_MODE_TRAINING; + } + if ((ss->ec_state->status.mode == ECHO_MODE_TRAINING) && + (ss->ec_state->ops->echocan_traintap)) { + if (ss->ec_state->ops->echocan_traintap(ss->ec_state, ss->ec_state->status.last_train_tap++, rxlin)) { +#if 0 + module_printk(KERN_NOTICE, "Finished training (%d taps trained)!\n", ss->ec_state->status.last_train_tap); +#endif + ss->ec_state->status.mode = ECHO_MODE_ACTIVE; + } + } + rxlin = 0; + rxchunk[x] = DAHDI_LIN2X((int)rxlin, ss); + } + } else if (ss->ec_state->status.mode != ECHO_MODE_IDLE) { + ss->ec_state->events.all = 0; + + if (ss->ec_state->ops->echocan_process) { + short rxlins[DAHDI_CHUNKSIZE], txlins[DAHDI_CHUNKSIZE]; + + for (x = 0; x < DAHDI_CHUNKSIZE; x++) { + rxlins[x] = DAHDI_XLAW(rxchunk[x], ss); + txlins[x] = DAHDI_XLAW(txchunk[x], ss); + } + ss->ec_state->ops->echocan_process(ss->ec_state, rxlins, txlins, DAHDI_CHUNKSIZE); + + for (x = 0; x < DAHDI_CHUNKSIZE; x++) + rxchunk[x] = DAHDI_LIN2X((int) rxlins[x], ss); + } else if (ss->ec_state->ops->echocan_events) + ss->ec_state->ops->echocan_events(ss->ec_state); + + if (ss->ec_state->events.all) + process_echocan_events(ss); + + } +#if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP) + kernel_fpu_end(); +#endif + } + spin_unlock_irqrestore(&ss->lock, flags); +} + +void dahdi_ec_chunk(struct dahdi_chan *ss, unsigned char *rxchunk, const unsigned char *txchunk) +{ + __dahdi_ec_chunk(ss, rxchunk, txchunk); +} + +void dahdi_ec_span(struct dahdi_span *span) +{ + int x; + for (x = 0; x < span->channels; x++) { + if (span->chans[x]->ec_current) + __dahdi_ec_chunk(span->chans[x], span->chans[x]->readchunk, span->chans[x]->writechunk); + } +} + +/* return 0 if nothing detected, 1 if lack of tone, 2 if presence of tone */ +/* modifies buffer pointed to by 'amp' with notched-out values */ +static inline int sf_detect(struct sf_detect_state *s, + short *amp, + int samples,long p1, long p2, long p3) +{ +int i,rv = 0; +long x,y; + +#define SF_DETECT_SAMPLES (DAHDI_CHUNKSIZE * 5) +#define SF_DETECT_MIN_ENERGY 500 +#define NB 14 /* number of bits to shift left */ + + /* determine energy level before filtering */ + for(i = 0; i < samples; i++) + { + if (amp[i] < 0) s->e1 -= amp[i]; + else s->e1 += amp[i]; + } + /* do 2nd order IIR notch filter at given freq. and calculate + energy */ + for(i = 0; i < samples; i++) + { + x = amp[i] << NB; + y = s->x2 + (p1 * (s->x1 >> NB)) + x; + y += (p2 * (s->y2 >> NB)) + + (p3 * (s->y1 >> NB)); + s->x2 = s->x1; + s->x1 = x; + s->y2 = s->y1; + s->y1 = y; + amp[i] = y >> NB; + if (amp[i] < 0) s->e2 -= amp[i]; + else s->e2 += amp[i]; + } + s->samps += i; + /* if time to do determination */ + if ((s->samps) >= SF_DETECT_SAMPLES) + { + rv = 1; /* default to no tone */ + /* if enough energy, it is determined to be a tone */ + if (((s->e1 - s->e2) / s->samps) > SF_DETECT_MIN_ENERGY) rv = 2; + /* reset energy processing variables */ + s->samps = 0; + s->e1 = s->e2 = 0; + } + return(rv); +} + +static inline void __dahdi_process_putaudio_chunk(struct dahdi_chan *ss, unsigned char *rxb) +{ + /* We transmit data from our master channel */ + /* Called with ss->lock held */ + struct dahdi_chan *ms = ss->master; + /* Linear version of received data */ + short putlin[DAHDI_CHUNKSIZE],k[DAHDI_CHUNKSIZE]; + int x,r; + + /* (CNET) Allow caller to hear outpulsing if hearpulsing is true. + NOTE: This also requires a patched chan_zap with its own hearpulsing option! */ + if(!ms->hearpulsing) { + if (ms->dialing) ms->afterdialingtimer = 50; + else if (ms->afterdialingtimer) ms->afterdialingtimer--; + if (ms->afterdialingtimer && (!(ms->flags & DAHDI_FLAG_PSEUDO))) { + /* Be careful since memset is likely a macro */ + rxb[0] = DAHDI_LIN2X(0, ms); + memset(&rxb[1], rxb[0], DAHDI_CHUNKSIZE - 1); /* receive as silence if dialing */ + } + } + for (x=0;xrxgain[rxb[x]]; + putlin[x] = DAHDI_XLAW(rxb[x], ms); + } + + if (ms->ec_state && (ms->ec_state->status.mode == ECHO_MODE_ACTIVE) && !ms->ec_state->features.CED_rx_detect) { + for (x = 0; x < DAHDI_CHUNKSIZE; x++) { + if (echo_can_disable_detector_update(&ms->ec_state->rxecdis, putlin[x])) { + set_echocan_fax_mode(ms, ss->channo, "CED rx detected", 1); + dahdi_qevent_nolock(ms, DAHDI_EVENT_RX_CED_DETECTED); + break; + } + } + } + + /* if doing rx tone decoding */ + if (ms->rxp1 && ms->rxp2 && ms->rxp3) + { + r = sf_detect(&ms->rd,putlin,DAHDI_CHUNKSIZE,ms->rxp1, + ms->rxp2,ms->rxp3); + /* Convert back */ + for(x=0;xrd.lastdetect) + { + if (((r == 2) && !(ms->toneflags & DAHDI_REVERSE_RXTONE)) || + ((r == 1) && (ms->toneflags & DAHDI_REVERSE_RXTONE))) + { + __qevent(ms,DAHDI_EVENT_RINGOFFHOOK); + } + else + { + __qevent(ms,DAHDI_EVENT_ONHOOK); + } + ms->rd.lastdetect = r; + } + } + } + + if (!(ms->flags & DAHDI_FLAG_PSEUDO)) { + memcpy(ms->putlin, putlin, DAHDI_CHUNKSIZE * sizeof(short)); + memcpy(ms->putraw, rxb, DAHDI_CHUNKSIZE); + } + + /* Take the rxc, twiddle it for conferencing if appropriate and put it + back */ + if ((!ms->confmute && !ms->afterdialingtimer) || + (ms->flags & DAHDI_FLAG_PSEUDO)) { + switch(ms->confmode & DAHDI_CONF_MODE_MASK) { + case DAHDI_CONF_NORMAL: /* Normal mode */ + /* Do nothing. rx goes output */ + break; + case DAHDI_CONF_MONITOR: /* Monitor a channel's rx mode */ + /* if not a pseudo-channel, ignore */ + if (!(ms->flags & DAHDI_FLAG_PSEUDO)) break; + /* Add monitored channel */ + if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) { + ACSS(putlin, chans[ms->confna]->getlin); + } else { + ACSS(putlin, chans[ms->confna]->putlin); + } + /* Convert back */ + for(x=0;xflags & DAHDI_FLAG_PSEUDO)) break; + /* Add monitored channel */ + if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) { + ACSS(putlin, chans[ms->confna]->putlin); + } else { + ACSS(putlin, chans[ms->confna]->getlin); + } + /* Convert back */ + for(x=0;xflags & DAHDI_FLAG_PSEUDO)) break; + /* Note: Technically, saturation should be done at + the end of the whole addition, but for performance + reasons, we don't do that. Besides, it only matters + when you're so loud you're clipping anyway */ + ACSS(putlin, chans[ms->confna]->getlin); + ACSS(putlin, chans[ms->confna]->putlin); + /* Convert back */ + for(x=0;xflags & DAHDI_FLAG_PSEUDO)) + break; + + if (!chans[ms->confna]->readchunkpreec) + break; + + /* Add monitored channel */ + ACSS(putlin, chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO ? + chans[ms->confna]->getlin : chans[ms->confna]->readchunkpreec); + for (x = 0; x < DAHDI_CHUNKSIZE; x++) + rxb[x] = DAHDI_LIN2X(putlin[x], ms); + + break; + case DAHDI_CONF_MONITOR_TX_PREECHO: /* Monitor a channel's tx mode */ + /* if not a pseudo-channel, ignore */ + if (!(ms->flags & DAHDI_FLAG_PSEUDO)) + break; + + if (!chans[ms->confna]->readchunkpreec) + break; + + /* Add monitored channel */ + ACSS(putlin, chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO ? + chans[ms->confna]->readchunkpreec : chans[ms->confna]->getlin); + for (x = 0; x < DAHDI_CHUNKSIZE; x++) + rxb[x] = DAHDI_LIN2X(putlin[x], ms); + + break; + case DAHDI_CONF_MONITORBOTH_PREECHO: /* Monitor a channel's tx and rx mode */ + /* if not a pseudo-channel, ignore */ + if (!(ms->flags & DAHDI_FLAG_PSEUDO)) + break; + + if (!chans[ms->confna]->readchunkpreec) + break; + + /* Note: Technically, saturation should be done at + the end of the whole addition, but for performance + reasons, we don't do that. Besides, it only matters + when you're so loud you're clipping anyway */ + ACSS(putlin, chans[ms->confna]->getlin); + ACSS(putlin, chans[ms->confna]->readchunkpreec); + for (x = 0; x < DAHDI_CHUNKSIZE; x++) + rxb[x] = DAHDI_LIN2X(putlin[x], ms); + + break; + case DAHDI_CONF_REALANDPSEUDO: + /* do normal conf mode processing */ + if (ms->confmode & DAHDI_CONF_TALKER) { + /* Store temp value */ + memcpy(k, putlin, DAHDI_CHUNKSIZE * sizeof(short)); + /* Add conf value */ + ACSS(k, conf_sums_next[ms->_confn]); + /* get amount actually added */ + memcpy(ms->conflast, k, DAHDI_CHUNKSIZE * sizeof(short)); + SCSS(ms->conflast, conf_sums_next[ms->_confn]); + /* Really add in new value */ + ACSS(conf_sums_next[ms->_confn], ms->conflast); + } else memset(ms->conflast, 0, DAHDI_CHUNKSIZE * sizeof(short)); + /* do the pseudo-channel part processing */ + memset(putlin, 0, DAHDI_CHUNKSIZE * sizeof(short)); + if (ms->confmode & DAHDI_CONF_PSEUDO_LISTENER) { + /* Subtract out previous last sample written to conf */ + SCSS(putlin, ms->conflast2); + /* Add in conference */ + ACSS(putlin, conf_sums[ms->_confn]); + } + /* Convert back */ + for(x=0;xflags & DAHDI_FLAG_PSEUDO) /* if a pseudo-channel */ + { + if (ms->confmode & DAHDI_CONF_LISTENER) { + /* Subtract out last sample written to conf */ + SCSS(putlin, ms->conflast); + /* Add in conference */ + ACSS(putlin, conf_sums[ms->_confn]); + } + /* Convert back */ + for(x=0;xputlin, putlin, DAHDI_CHUNKSIZE * sizeof(short)); + break; + } + /* fall through */ + case DAHDI_CONF_CONFANN: /* Conference with announce */ + if (ms->confmode & DAHDI_CONF_TALKER) { + /* Store temp value */ + memcpy(k, putlin, DAHDI_CHUNKSIZE * sizeof(short)); + /* Add conf value */ + ACSS(k, conf_sums_next[ms->_confn]); + /* get amount actually added */ + memcpy(ms->conflast, k, DAHDI_CHUNKSIZE * sizeof(short)); + SCSS(ms->conflast, conf_sums_next[ms->_confn]); + /* Really add in new value */ + ACSS(conf_sums_next[ms->_confn], ms->conflast); + } else + memset(ms->conflast, 0, DAHDI_CHUNKSIZE * sizeof(short)); + /* rxc unmodified */ + break; + case DAHDI_CONF_CONFMON: + case DAHDI_CONF_CONFANNMON: + if (ms->confmode & DAHDI_CONF_TALKER) { + /* Store temp value */ + memcpy(k, putlin, DAHDI_CHUNKSIZE * sizeof(short)); + /* Subtract last value */ + SCSS(conf_sums[ms->_confn], ms->conflast); + /* Add conf value */ + ACSS(k, conf_sums[ms->_confn]); + /* get amount actually added */ + memcpy(ms->conflast, k, DAHDI_CHUNKSIZE * sizeof(short)); + SCSS(ms->conflast, conf_sums[ms->_confn]); + /* Really add in new value */ + ACSS(conf_sums[ms->_confn], ms->conflast); + } else + memset(ms->conflast, 0, DAHDI_CHUNKSIZE * sizeof(short)); + for (x=0;x_confn][x], ms); + break; + case DAHDI_CONF_DIGITALMON: + /* if not a pseudo-channel, ignore */ + if (!(ms->flags & DAHDI_FLAG_PSEUDO)) break; + /* Add monitored channel */ + if (chans[ms->confna]->flags & DAHDI_FLAG_PSEUDO) { + memcpy(rxb, chans[ms->confna]->getraw, DAHDI_CHUNKSIZE); + } else { + memcpy(rxb, chans[ms->confna]->putraw, DAHDI_CHUNKSIZE); + } + break; + } + } +} + +/* HDLC (or other) receiver buffer functions for read side */ +static inline void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb, int bytes) +{ + /* We transmit data from our master channel */ + /* Called with ss->lock held */ + struct dahdi_chan *ms = ss->master; + /* Our receive buffer */ + unsigned char *buf; +#if defined(CONFIG_DAHDI_NET) || defined(CONFIG_DAHDI_PPP) + /* SKB for receiving network stuff */ + struct sk_buff *skb=NULL; +#endif + int oldbuf; + int eof=0; + int abort=0; + int res; + int left, x; + + while(bytes) { +#if defined(CONFIG_DAHDI_NET) || defined(CONFIG_DAHDI_PPP) + skb = NULL; +#endif + abort = 0; + eof = 0; + /* Next, figure out if we've got a buffer to receive into */ + if (ms->inreadbuf > -1) { + /* Read into the current buffer */ + buf = ms->readbuf[ms->inreadbuf]; + left = ms->blocksize - ms->readidx[ms->inreadbuf]; + if (left > bytes) + left = bytes; + if (ms->flags & DAHDI_FLAG_HDLC) { + for (x=0;xrxhdlc, *(rxb++)); + bytes--; + res = fasthdlc_rx_run(&ms->rxhdlc); + /* If there is nothing there, continue */ + if (res & RETURN_EMPTY_FLAG) + continue; + else if (res & RETURN_COMPLETE_FLAG) { + /* Only count this if it's a non-empty frame */ + if (ms->readidx[ms->inreadbuf]) { + if ((ms->flags & DAHDI_FLAG_FCS) && (ms->infcs != PPP_GOODFCS)) { + abort = DAHDI_EVENT_BADFCS; + } else + eof=1; + break; + } + continue; + } else if (res & RETURN_DISCARD_FLAG) { + /* This could be someone idling with + "idle" instead of "flag" */ + if (!ms->readidx[ms->inreadbuf]) + continue; + abort = DAHDI_EVENT_ABORT; + break; + } else { + unsigned char rxc; + rxc = res; + ms->infcs = PPP_FCS(ms->infcs, rxc); + buf[ms->readidx[ms->inreadbuf]++] = rxc; + /* Pay attention to the possibility of an overrun */ + if (ms->readidx[ms->inreadbuf] >= ms->blocksize) { + if (!ss->span->alarms) + module_printk(KERN_WARNING, "HDLC Receiver overrun on channel %s (master=%s)\n", ss->name, ss->master->name); + abort=DAHDI_EVENT_OVERRUN; + /* Force the HDLC state back to frame-search mode */ + ms->rxhdlc.state = 0; + ms->rxhdlc.bits = 0; + ms->readidx[ms->inreadbuf]=0; + break; + } + } + } + } else { + /* Not HDLC */ + memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left); + rxb += left; + ms->readidx[ms->inreadbuf] += left; + bytes -= left; + /* End of frame is decided by block size of 'N' */ + eof = (ms->readidx[ms->inreadbuf] >= ms->blocksize); + if (eof && (ss->flags & DAHDI_FLAG_NOSTDTXRX)) { + eof = 0; + abort = DAHDI_EVENT_OVERRUN; + } + } + if (eof) { + /* Finished with this buffer, try another. */ + oldbuf = ms->inreadbuf; + ms->infcs = PPP_INITFCS; + ms->readn[ms->inreadbuf] = ms->readidx[ms->inreadbuf]; +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "EOF, len is %d\n", ms->readn[ms->inreadbuf]); +#endif +#if defined(CONFIG_DAHDI_NET) || defined(CONFIG_DAHDI_PPP) + if (ms->flags & (DAHDI_FLAG_NETDEV | DAHDI_FLAG_PPP)) { +#ifdef CONFIG_DAHDI_NET +#endif /* CONFIG_DAHDI_NET */ + /* Our network receiver logic is MUCH + different. We actually only use a single + buffer */ + if (ms->readn[ms->inreadbuf] > 1) { + /* Drop the FCS */ + ms->readn[ms->inreadbuf] -= 2; + /* Allocate an SKB */ +#ifdef CONFIG_DAHDI_PPP + if (!ms->do_ppp_error) +#endif + skb = dev_alloc_skb(ms->readn[ms->inreadbuf]); + if (skb) { + /* XXX Get rid of this memcpy XXX */ + memcpy(skb->data, ms->readbuf[ms->inreadbuf], ms->readn[ms->inreadbuf]); + skb_put(skb, ms->readn[ms->inreadbuf]); +#ifdef CONFIG_DAHDI_NET + if (ms->flags & DAHDI_FLAG_NETDEV) { + struct net_device_stats *stats = hdlc_stats(ms->hdlcnetdev->netdev); + stats->rx_packets++; + stats->rx_bytes += ms->readn[ms->inreadbuf]; + } +#endif + + } else { +#ifdef CONFIG_DAHDI_NET + if (ms->flags & DAHDI_FLAG_NETDEV) { + struct net_device_stats *stats = hdlc_stats(ms->hdlcnetdev->netdev); + stats->rx_dropped++; + } +#endif +#ifdef CONFIG_DAHDI_PPP + if (ms->flags & DAHDI_FLAG_PPP) { + abort = DAHDI_EVENT_OVERRUN; + } +#endif +#if 1 +#ifdef CONFIG_DAHDI_PPP + if (!ms->do_ppp_error) +#endif + module_printk(KERN_NOTICE, "Memory squeeze, dropped one\n"); +#endif + } + } + /* We don't cycle through buffers, just + reuse the same one */ + ms->readn[ms->inreadbuf] = 0; + ms->readidx[ms->inreadbuf] = 0; + } else +#endif + { + /* This logic might confuse and astound. Basically we need to find + * the previous buffer index. It should be safe because, regardless + * of whether or not it has been copied to user space, nothing should + * have messed around with it since then */ + + int comparemessage; + /* Shut compiler up */ + int myres = 0; + + if (ms->flags & DAHDI_FLAG_MTP2) { + comparemessage = (ms->inreadbuf - 1) & (ms->numbufs - 1); + + myres = memcmp(ms->readbuf[comparemessage], ms->readbuf[ms->inreadbuf], ms->readn[ms->inreadbuf]); + } + + if ((ms->flags & DAHDI_FLAG_MTP2) && !myres) { + /* Our messages are the same, so discard - + * Don't advance buffers, reset indexes and buffer sizes. */ + ms->readn[ms->inreadbuf] = 0; + ms->readidx[ms->inreadbuf] = 0; + } else { + ms->inreadbuf = (ms->inreadbuf + 1) % ms->numbufs; + if (ms->inreadbuf == ms->outreadbuf) { + /* Whoops, we're full, and have no where else + to store into at the moment. We'll drop it + until there's a buffer available */ +#ifdef BUFFER_DEBUG + module_printk(KERN_NOTICE, "Out of storage space\n"); +#endif + ms->inreadbuf = -1; + /* Enable the receiver in case they've got POLICY_WHEN_FULL */ + ms->rxdisable = 0; + } + if (ms->outreadbuf < 0) { /* start out buffer if not already */ + ms->outreadbuf = oldbuf; + /* if there are processes waiting in poll() on this channel, + wake them up */ + if (!ms->rxdisable) { + wake_up_interruptible(&ms->sel); + } + } +/* In the very orignal driver, it was quite well known to me (Jim) that there +was a possibility that a channel sleeping on a receive block needed to +be potentially woken up EVERY time a buffer was filled, not just on the first +one, because if only done on the first one there is a slight timing potential +of missing the wakeup (between where it senses the (lack of) active condition +(with interrupts disabled) and where it does the sleep (interrupts enabled) +in the read or iomux call, etc). That is why the read and iomux calls start +with an infinite loop that gets broken out of upon an active condition, +otherwise keeps sleeping and looking. The part in this code got "optimized" +out in the later versions, and is put back now. Note that this is *NOT* +needed for poll() waiters, because the poll_wait() function that is used there +is atomic enough for this purpose; it will not go to sleep before ensuring +that the waitqueue is empty. */ + if (!ms->rxdisable) { /* if receiver enabled */ + /* Notify a blocked reader that there is data available + to be read, unless we're waiting for it to be full */ +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "Notifying reader data in block %d\n", oldbuf); +#endif + wake_up_interruptible(&ms->readbufq); + if (ms->iomask & DAHDI_IOMUX_READ) + wake_up_interruptible(&ms->eventbufq); + } + } + } + } + if (abort) { + /* Start over reading frame */ + ms->readidx[ms->inreadbuf] = 0; + ms->infcs = PPP_INITFCS; + +#ifdef CONFIG_DAHDI_NET + if (ms->flags & DAHDI_FLAG_NETDEV) { + struct net_device_stats *stats = hdlc_stats(ms->hdlcnetdev->netdev); + stats->rx_errors++; + if (abort == DAHDI_EVENT_OVERRUN) + stats->rx_over_errors++; + if (abort == DAHDI_EVENT_BADFCS) + stats->rx_crc_errors++; + if (abort == DAHDI_EVENT_ABORT) + stats->rx_frame_errors++; + } else +#endif +#ifdef CONFIG_DAHDI_PPP + if (ms->flags & DAHDI_FLAG_PPP) { + ms->do_ppp_error = 1; + tasklet_schedule(&ms->ppp_calls); + } else +#endif + if (test_bit(DAHDI_FLAGBIT_OPEN, &ms->flags) && !ss->span->alarms) { + /* Notify the receiver... */ + __qevent(ss->master, abort); + } +#if 0 + module_printk(KERN_NOTICE, "torintr_receive: Aborted %d bytes of frame on %d\n", amt, ss->master); +#endif + + } + } else /* No place to receive -- drop on the floor */ + break; +#ifdef CONFIG_DAHDI_NET + if (skb && (ms->flags & DAHDI_FLAG_NETDEV)) +#ifdef NEW_HDLC_INTERFACE + { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + skb->mac.raw = skb->data; +#else + skb_reset_mac_header(skb); +#endif + skb->dev = ztchan_to_dev(ms); +#ifdef DAHDI_HDLC_TYPE_TRANS + skb->protocol = hdlc_type_trans(skb, ztchan_to_dev(ms)); +#else + skb->protocol = htons (ETH_P_HDLC); +#endif + netif_rx(skb); + } +#else + hdlc_netif_rx(&ms->hdlcnetdev->netdev, skb); +#endif +#endif +#ifdef CONFIG_DAHDI_PPP + if (skb && (ms->flags & DAHDI_FLAG_PPP)) { + unsigned char *tmp; + tmp = skb->data; + skb_pull(skb, 2); + /* Make sure that it's addressed to ALL STATIONS and UNNUMBERED */ + if (!tmp || (tmp[0] != 0xff) || (tmp[1] != 0x03)) { + /* Invalid SKB -- drop */ + if (tmp) + module_printk(KERN_NOTICE, "Received invalid SKB (%02x, %02x)\n", tmp[0], tmp[1]); + dev_kfree_skb_irq(skb); + } else { + skb_queue_tail(&ms->ppp_rq, skb); + tasklet_schedule(&ms->ppp_calls); + } + } +#endif + } +} + +static inline void __dahdi_putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb) +{ + __putbuf_chunk(ss, rxb, DAHDI_CHUNKSIZE); +} + +static void __dahdi_hdlc_abort(struct dahdi_chan *ss, int event) +{ + if (ss->inreadbuf >= 0) + ss->readidx[ss->inreadbuf] = 0; + if (test_bit(DAHDI_FLAGBIT_OPEN, &ss->flags) && !ss->span->alarms) + __qevent(ss->master, event); +} + +void dahdi_hdlc_abort(struct dahdi_chan *ss, int event) +{ + unsigned long flags; + spin_lock_irqsave(&ss->lock, flags); + __dahdi_hdlc_abort(ss, event); + spin_unlock_irqrestore(&ss->lock, flags); +} + +void dahdi_hdlc_putbuf(struct dahdi_chan *ss, unsigned char *rxb, int bytes) +{ + unsigned long flags; + int res; + int left; + + spin_lock_irqsave(&ss->lock, flags); + if (ss->inreadbuf < 0) { +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "No place to receive HDLC frame\n"); +#endif + spin_unlock_irqrestore(&ss->lock, flags); + return; + } + /* Read into the current buffer */ + left = ss->blocksize - ss->readidx[ss->inreadbuf]; + if (left > bytes) + left = bytes; + if (left > 0) { + memcpy(ss->readbuf[ss->inreadbuf] + ss->readidx[ss->inreadbuf], rxb, left); + rxb += left; + ss->readidx[ss->inreadbuf] += left; + bytes -= left; + } + /* Something isn't fit into buffer */ + if (bytes) { +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "HDLC frame isn't fit into buffer space\n"); +#endif + __dahdi_hdlc_abort(ss, DAHDI_EVENT_OVERRUN); + } + res = left; + spin_unlock_irqrestore(&ss->lock, flags); +} + +void dahdi_hdlc_finish(struct dahdi_chan *ss) +{ + int oldreadbuf; + unsigned long flags; + + spin_lock_irqsave(&ss->lock, flags); + + if ((oldreadbuf = ss->inreadbuf) < 0) { +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "No buffers to finish\n"); +#endif + spin_unlock_irqrestore(&ss->lock, flags); + return; + } + + if (!ss->readidx[ss->inreadbuf]) { +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "Empty HDLC frame received\n"); +#endif + spin_unlock_irqrestore(&ss->lock, flags); + return; + } + + ss->readn[ss->inreadbuf] = ss->readidx[ss->inreadbuf]; + ss->inreadbuf = (ss->inreadbuf + 1) % ss->numbufs; + if (ss->inreadbuf == ss->outreadbuf) { + ss->inreadbuf = -1; +#ifdef CONFIG_DAHDI_DEBUG + module_printk(KERN_NOTICE, "Notifying reader data in block %d\n", oldreadbuf); +#endif + ss->rxdisable = 0; + } + if (ss->outreadbuf < 0) { + ss->outreadbuf = oldreadbuf; + } + + if (!ss->rxdisable) { + wake_up_interruptible(&ss->readbufq); + wake_up_interruptible(&ss->sel); + if (ss->iomask & DAHDI_IOMUX_READ) + wake_up_interruptible(&ss->eventbufq); + } + spin_unlock_irqrestore(&ss->lock, flags); +} + +/* Returns 1 if EOF, 0 if data is still in frame, -1 if EOF and no buffers left */ +int dahdi_hdlc_getbuf(struct dahdi_chan *ss, unsigned char *bufptr, unsigned int *size) +{ + unsigned char *buf; + unsigned long flags; + int left = 0; + int res; + int oldbuf; + + spin_lock_irqsave(&ss->lock, flags); + if (ss->outwritebuf > -1) { + buf = ss->writebuf[ss->outwritebuf]; + left = ss->writen[ss->outwritebuf] - ss->writeidx[ss->outwritebuf]; + /* Strip off the empty HDLC CRC end */ + left -= 2; + if (left <= *size) { + *size = left; + res = 1; + } else + res = 0; + + memcpy(bufptr, &buf[ss->writeidx[ss->outwritebuf]], *size); + ss->writeidx[ss->outwritebuf] += *size; + + if (res) { + /* Rotate buffers */ + oldbuf = ss->outwritebuf; + ss->writeidx[oldbuf] = 0; + ss->writen[oldbuf] = 0; + ss->outwritebuf = (ss->outwritebuf + 1) % ss->numbufs; + if (ss->outwritebuf == ss->inwritebuf) { + ss->outwritebuf = -1; + if (ss->iomask & (DAHDI_IOMUX_WRITE | DAHDI_IOMUX_WRITEEMPTY)) + wake_up_interruptible(&ss->eventbufq); + /* If we're only supposed to start when full, disable the transmitter */ + if ((ss->txbufpolicy == DAHDI_POLICY_WHEN_FULL) || (ss->txbufpolicy == DAHDI_POLICY_HALF_FULL)) + ss->txdisable = 1; + res = -1; + } + + if (ss->inwritebuf < 0) + ss->inwritebuf = oldbuf; + + if (!(ss->flags & (DAHDI_FLAG_NETDEV | DAHDI_FLAG_PPP))) { + wake_up_interruptible(&ss->writebufq); + wake_up_interruptible(&ss->sel); + if ((ss->iomask & DAHDI_IOMUX_WRITE) && (res >= 0)) + wake_up_interruptible(&ss->eventbufq); + } + } + } else { + res = -1; + *size = 0; + } + spin_unlock_irqrestore(&ss->lock, flags); + + return res; +} + + +static void process_timers(void) +{ + unsigned long flags; + struct dahdi_timer *cur; + + spin_lock_irqsave(&zaptimerlock, flags); + + list_for_each_entry(cur, &zaptimers, list) { + if (cur->ms) { + cur->pos -= DAHDI_CHUNKSIZE; + if (cur->pos <= 0) { + cur->tripped++; + cur->pos = cur->ms; + wake_up_interruptible(&cur->sel); + } + } + } + + spin_unlock_irqrestore(&zaptimerlock, flags); +} + +static unsigned int dahdi_timer_poll(struct file *file, struct poll_table_struct *wait_table) +{ + struct dahdi_timer *timer = file->private_data; + unsigned long flags; + int ret = 0; + if (timer) { + poll_wait(file, &timer->sel, wait_table); + spin_lock_irqsave(&zaptimerlock, flags); + if (timer->tripped || timer->ping) + ret |= POLLPRI; + spin_unlock_irqrestore(&zaptimerlock, flags); + } else + ret = -EINVAL; + return ret; +} + +/* device poll routine */ +static unsigned int +dahdi_chan_poll(struct file *file, struct poll_table_struct *wait_table, int unit) +{ + + struct dahdi_chan *chan = chans[unit]; + int ret; + unsigned long flags; + + /* do the poll wait */ + if (chan) { + poll_wait(file, &chan->sel, wait_table); + ret = 0; /* start with nothing to return */ + spin_lock_irqsave(&chan->lock, flags); + /* if at least 1 write buffer avail */ + if (chan->inwritebuf > -1) { + ret |= POLLOUT | POLLWRNORM; + } + if ((chan->outreadbuf > -1) && !chan->rxdisable) { + ret |= POLLIN | POLLRDNORM; + } + if (chan->eventoutidx != chan->eventinidx) + { + /* Indicate an exception */ + ret |= POLLPRI; + } + spin_unlock_irqrestore(&chan->lock, flags); + } else + ret = -EINVAL; + return(ret); /* return what we found */ +} + +static int dahdi_mmap(struct file *file, struct vm_area_struct *vm) +{ + int unit = UNIT(file); + if (unit == 250) + return dahdi_transcode_fops->mmap(file, vm); + return -ENOSYS; +} + +static unsigned int dahdi_poll(struct file *file, struct poll_table_struct *wait_table) +{ + int unit = UNIT(file); + struct dahdi_chan *chan; + + if (!unit) + return -EINVAL; + + if (unit == 250) + return dahdi_transcode_fops->poll(file, wait_table); + + if (unit == 253) + return dahdi_timer_poll(file, wait_table); + + if (unit == 254) { + chan = file->private_data; + if (!chan) + return -EINVAL; + return dahdi_chan_poll(file, wait_table,chan->channo); + } + if (unit == 255) { + chan = file->private_data; + if (!chan) { + module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n"); + return -EINVAL; + } + return dahdi_chan_poll(file, wait_table, chan->channo); + } + return dahdi_chan_poll(file, wait_table, unit); +} + +static void __dahdi_transmit_chunk(struct dahdi_chan *chan, unsigned char *buf) +{ + unsigned char silly[DAHDI_CHUNKSIZE]; + /* Called with chan->lock locked */ +#ifdef OPTIMIZE_CHANMUTE + if(likely(chan->chanmute)) + return; +#endif + if (!buf) + buf = silly; + __dahdi_getbuf_chunk(chan, buf); + + if ((chan->flags & DAHDI_FLAG_AUDIO) || (chan->confmode)) { +#ifdef CONFIG_DAHDI_MMX + dahdi_kernel_fpu_begin(); +#endif + __dahdi_process_getaudio_chunk(chan, buf); +#ifdef CONFIG_DAHDI_MMX + kernel_fpu_end(); +#endif + } +} + +static inline void __dahdi_real_transmit(struct dahdi_chan *chan) +{ + /* Called with chan->lock held */ +#ifdef OPTIMIZE_CHANMUTE + if(likely(chan->chanmute)) + return; +#endif + if (chan->confmode) { + /* Pull queued data off the conference */ + __buf_pull(&chan->confout, chan->writechunk, chan, "dahdi_real_transmit"); + } else { + __dahdi_transmit_chunk(chan, chan->writechunk); + } +} + +static void __dahdi_getempty(struct dahdi_chan *ms, unsigned char *buf) +{ + int bytes = DAHDI_CHUNKSIZE; + int left; + unsigned char *txb = buf; + int x; + short getlin; + /* Called with ms->lock held */ + + while(bytes) { + /* Receive silence, or tone */ + if (ms->curtone) { + left = ms->curtone->tonesamples - ms->tonep; + if (left > bytes) + left = bytes; + for (x=0;xts, ms->curtone); + *(txb++) = DAHDI_LIN2X(getlin, ms); + } + ms->tonep+=left; + bytes -= left; + if (ms->tonep >= ms->curtone->tonesamples) { + struct dahdi_tone *last; + /* Go to the next sample of the tone */ + ms->tonep = 0; + last = ms->curtone; + ms->curtone = ms->curtone->next; + if (!ms->curtone) { + /* No more tones... Is this dtmf or mf? If so, go to the next digit */ + if (ms->dialing) + __do_dtmf(ms); + } else { + if (last != ms->curtone) + dahdi_init_tone_state(&ms->ts, ms->curtone); + } + } + } else { + /* Use silence */ + memset(txb, DAHDI_LIN2X(0, ms), bytes); + bytes = 0; + } + } + +} + +static void __dahdi_receive_chunk(struct dahdi_chan *chan, unsigned char *buf) +{ + /* Receive chunk of audio -- called with chan->lock held */ + unsigned char waste[DAHDI_CHUNKSIZE]; + +#ifdef OPTIMIZE_CHANMUTE + if(likely(chan->chanmute)) + return; +#endif + if (!buf) { + memset(waste, DAHDI_LIN2X(0, chan), sizeof(waste)); + buf = waste; + } + if ((chan->flags & DAHDI_FLAG_AUDIO) || (chan->confmode)) { +#ifdef CONFIG_DAHDI_MMX + dahdi_kernel_fpu_begin(); +#endif + __dahdi_process_putaudio_chunk(chan, buf); +#ifdef CONFIG_DAHDI_MMX + kernel_fpu_end(); +#endif + } + __dahdi_putbuf_chunk(chan, buf); +} + +static inline void __dahdi_real_receive(struct dahdi_chan *chan) +{ + /* Called with chan->lock held */ +#ifdef OPTIMIZE_CHANMUTE + if(likely(chan->chanmute)) + return; +#endif + if (chan->confmode) { + /* Load into queue if we have space */ + __buf_push(&chan->confin, chan->readchunk, "dahdi_real_receive"); + } else { + __dahdi_receive_chunk(chan, chan->readchunk); + } +} + +int dahdi_transmit(struct dahdi_span *span) +{ + int x,y,z; + unsigned long flags; + +#if 1 + for (x=0;xchannels;x++) { + spin_lock_irqsave(&span->chans[x]->lock, flags); + if (span->chans[x]->flags & DAHDI_FLAG_NOSTDTXRX) { + spin_unlock_irqrestore(&span->chans[x]->lock, flags); + continue; + } + if (span->chans[x] == span->chans[x]->master) { + if (span->chans[x]->otimer) { + span->chans[x]->otimer -= DAHDI_CHUNKSIZE; + if (span->chans[x]->otimer <= 0) { + __rbs_otimer_expire(span->chans[x]); + } + } + if (span->chans[x]->flags & DAHDI_FLAG_AUDIO) { + __dahdi_real_transmit(span->chans[x]); + } else { + if (span->chans[x]->nextslave) { + u_char data[DAHDI_CHUNKSIZE]; + int pos=DAHDI_CHUNKSIZE; + /* Process master/slaves one way */ + for (y=0;ychans[x], data); + pos = 0; + } + span->chans[z]->writechunk[y] = data[pos++]; + z = span->chans[z]->nextslave; + } while(z); + } + } else { + /* Process independents elsewise */ + __dahdi_real_transmit(span->chans[x]); + } + } + if (span->chans[x]->sig == DAHDI_SIG_DACS_RBS) { + if (chans[span->chans[x]->confna]) { + /* Just set bits for our destination */ + if (span->chans[x]->txsig != chans[span->chans[x]->confna]->rxsig) { + span->chans[x]->txsig = chans[span->chans[x]->confna]->rxsig; + span->rbsbits(span->chans[x], chans[span->chans[x]->confna]->rxsig); + } + } + } + + } + spin_unlock_irqrestore(&span->chans[x]->lock, flags); + } + if (span->mainttimer) { + span->mainttimer -= DAHDI_CHUNKSIZE; + if (span->mainttimer <= 0) { + span->mainttimer = 0; + if (span->maint) + span->maint(span, DAHDI_MAINT_LOOPSTOP); + span->maintstat = 0; + wake_up_interruptible(&span->maintq); + } + } +#endif + return 0; +} + +static void process_masterspan(void) +{ + unsigned long flags; + int x, y, z; + +#ifdef CONFIG_DAHDI_CORE_TIMER + /* We increment the calls since start here, so that if we switch over + * to the core timer, we know how many times we need to call + * process_masterspan in order to catch up since this function needs + * to be called 1000 times per second. */ + atomic_inc(&core_timer.count); +#endif + /* Hold the big zap lock for the duration of major + activities which touch all sorts of channels */ + spin_lock_irqsave(&bigzaplock, flags); + read_lock(&chan_lock); + /* Process any timers */ + process_timers(); + /* If we have dynamic stuff, call the ioctl with 0,0 parameters to + make it run */ + if (dahdi_dynamic_ioctl) + dahdi_dynamic_ioctl(0, 0); + + for (x = 1; x < maxchans; x++) { + if (chans[x] && chans[x]->confmode && + !(chans[x]->flags & DAHDI_FLAG_PSEUDO)) { + u_char *data; + spin_lock(&chans[x]->lock); + data = __buf_peek(&chans[x]->confin); + __dahdi_receive_chunk(chans[x], data); + if (data) { + __buf_pull(&chans[x]->confin, NULL, chans[x], + "confreceive"); + } + spin_unlock(&chans[x]->lock); + } + } + /* This is the master channel, so make things switch over */ + rotate_sums(); + /* do all the pseudo and/or conferenced channel receives (getbuf's) */ + for (x = 1; x < maxchans; x++) { + if (chans[x] && (chans[x]->flags & DAHDI_FLAG_PSEUDO)) { + spin_lock(&chans[x]->lock); + __dahdi_transmit_chunk(chans[x], NULL); + spin_unlock(&chans[x]->lock); + } + } + if (maxlinks) { +#ifdef CONFIG_DAHDI_MMX + dahdi_kernel_fpu_begin(); +#endif + /* process all the conf links */ + for (x = 1; x <= maxlinks; x++) { + /* if we have a destination conf */ + z = confalias[conf_links[x].dst]; + if (z) { + y = confalias[conf_links[x].src]; + if (y) + ACSS(conf_sums[z], conf_sums[y]); + } + } +#ifdef CONFIG_DAHDI_MMX + dahdi_kernel_fpu_end(); +#endif + } + /* do all the pseudo/conferenced channel transmits (putbuf's) */ + for (x = 1; x < maxchans; x++) { + if (chans[x] && (chans[x]->flags & DAHDI_FLAG_PSEUDO)) { + unsigned char tmp[DAHDI_CHUNKSIZE]; + spin_lock(&chans[x]->lock); + __dahdi_getempty(chans[x], tmp); + __dahdi_receive_chunk(chans[x], tmp); + spin_unlock(&chans[x]->lock); + } + } + for (x = 1; x < maxchans; x++) { + if (chans[x] && chans[x]->confmode && + !(chans[x]->flags & DAHDI_FLAG_PSEUDO)) { + u_char *data; + spin_lock(&chans[x]->lock); + data = __buf_pushpeek(&chans[x]->confout); + __dahdi_transmit_chunk(chans[x], data); + if (data) + __buf_push(&chans[x]->confout, NULL, + "conftransmit"); + spin_unlock(&chans[x]->lock); + } + } +#ifdef DAHDI_SYNC_TICK + for (x = 0; x < maxspans; x++) { + struct dahdi_span *const s = spans[x]; + if (s && s->sync_tick) + s->sync_tick(s, s == master); + } +#endif + read_unlock(&chan_lock); + spin_unlock_irqrestore(&bigzaplock, flags); +} + +#ifndef CONFIG_DAHDI_CORE_TIMER + +static void coretimer_init(void) +{ + return; +} + +static void coretimer_cleanup(void) +{ + return; +} + +#else + +static unsigned long core_diff_ms(struct timespec *t0, struct timespec *t1) +{ + long nanosec, sec; + unsigned long ms; + sec = (t1->tv_sec - t0->tv_sec); + nanosec = (t1->tv_nsec - t0->tv_nsec); + while (nanosec >= NSEC_PER_SEC) { + nanosec -= NSEC_PER_SEC; + ++sec; + } + while (nanosec < 0) { + nanosec += NSEC_PER_SEC; + --sec; + } + ms = (sec * 1000) + (nanosec / 1000000L); + return ms; +} + +static void coretimer_func(unsigned long param) +{ + unsigned long ms_since_start; + struct timespec now; + const unsigned long MAX_INTERVAL = 100000L; + const unsigned long FOURMS_INTERVAL = HZ/250; + const unsigned long ONESEC_INTERVAL = HZ; + const unsigned long MS_LIMIT = 3000; + + now = current_kernel_time(); + + if (atomic_read(&core_timer.count) == + atomic_read(&core_timer.last_count)) { + + /* This is the code path if a board driver is not calling + * dahdi_receive, and therefore the core of dahdi needs to + * perform the master span processing itself. */ + + if (!atomic_read(&core_timer.shutdown)) + mod_timer(&core_timer.timer, jiffies + FOURMS_INTERVAL); + + ms_since_start = core_diff_ms(&core_timer.start_interval, &now); + + /* + * If the system time has changed, it is possible for us to be + * far behind. If we are more than MS_LIMIT milliseconds + * behind, just reset our time base and continue so that we do + * not hang the system here. + * + */ + if (unlikely((ms_since_start - atomic_read(&core_timer.count)) > MS_LIMIT)) { + if (printk_ratelimit()) + module_printk(KERN_INFO, "Detected time shift.\n"); + atomic_set(&core_timer.count, 0); + atomic_set(&core_timer.last_count, 0); + core_timer.start_interval = now; + return; + } + + while (ms_since_start > atomic_read(&core_timer.count)) + process_masterspan(); + + if (ms_since_start > MAX_INTERVAL) { + atomic_set(&core_timer.count, 0); + atomic_set(&core_timer.last_count, 0); + core_timer.start_interval = now; + } else { + atomic_set(&core_timer.last_count, + atomic_read(&core_timer.count)); + } + + } else { + + /* It looks like a board driver is calling dahdi_receive. We + * will just check again in a second. */ + atomic_set(&core_timer.count, 0); + atomic_set(&core_timer.last_count, 0); + core_timer.start_interval = now; + if (!atomic_read(&core_timer.shutdown)) + mod_timer(&core_timer.timer, jiffies + ONESEC_INTERVAL); + } +} + +static void coretimer_init(void) +{ + init_timer(&core_timer.timer); + core_timer.timer.function = coretimer_func; + core_timer.start_interval = current_kernel_time(); + core_timer.timer.expires = jiffies + HZ; + atomic_set(&core_timer.count, 0); + atomic_set(&core_timer.shutdown, 0); + add_timer(&core_timer.timer); +} + +static void coretimer_cleanup(void) +{ + atomic_set(&core_timer.shutdown, 1); + del_timer_sync(&core_timer.timer); +} + +#endif /* CONFIG_DAHDI_CORE_TIMER */ + + +int dahdi_receive(struct dahdi_span *span) +{ + int x,y,z; + unsigned long flags; + +#ifdef CONFIG_DAHDI_WATCHDOG + span->watchcounter--; +#endif + for (x=0;xchannels;x++) { + if (span->chans[x]->master == span->chans[x]) { + spin_lock_irqsave(&span->chans[x]->lock, flags); + if (span->chans[x]->nextslave) { + /* Must process each slave at the same time */ + u_char data[DAHDI_CHUNKSIZE]; + int pos = 0; + for (y=0;ychans[z]->readchunk[y]; + if (pos == DAHDI_CHUNKSIZE) { + if(!(span->chans[x]->flags & DAHDI_FLAG_NOSTDTXRX)) + __dahdi_receive_chunk(span->chans[x], data); + pos = 0; + } + z=span->chans[z]->nextslave; + } while(z); + } + } else { + /* Process a normal channel */ + if (!(span->chans[x]->flags & DAHDI_FLAG_NOSTDTXRX)) + __dahdi_real_receive(span->chans[x]); + } + if (span->chans[x]->itimer) { + span->chans[x]->itimer -= DAHDI_CHUNKSIZE; + if (span->chans[x]->itimer <= 0) { + rbs_itimer_expire(span->chans[x]); + } + } + if (span->chans[x]->ringdebtimer) + span->chans[x]->ringdebtimer--; + if (span->chans[x]->sig & __DAHDI_SIG_FXS) { + if (span->chans[x]->rxhooksig == DAHDI_RXSIG_RING) + span->chans[x]->ringtrailer = DAHDI_RINGTRAILER; + else if (span->chans[x]->ringtrailer) { + span->chans[x]->ringtrailer-= DAHDI_CHUNKSIZE; + /* See if RING trailer is expired */ + if (!span->chans[x]->ringtrailer && !span->chans[x]->ringdebtimer) + __qevent(span->chans[x],DAHDI_EVENT_RINGOFFHOOK); + } + } + if (span->chans[x]->pulsetimer) + { + span->chans[x]->pulsetimer--; + if (span->chans[x]->pulsetimer <= 0) + { + if (span->chans[x]->pulsecount) + { + if (span->chans[x]->pulsecount > 12) { + + module_printk(KERN_NOTICE, "Got pulse digit %d on %s???\n", + span->chans[x]->pulsecount, + span->chans[x]->name); + } else if (span->chans[x]->pulsecount > 11) { + __qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | '#'); + } else if (span->chans[x]->pulsecount > 10) { + __qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | '*'); + } else if (span->chans[x]->map_pulse == MAP_PULSE_NZ_OSLO) { + /* (CNET) NZ/Oslo pluse mapping */ + __qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | ('0' + + (10 - span->chans[x]->pulsecount))); + } else if (span->chans[x]->map_pulse == MAP_PULSE_SWEDEN) { + /* (CNET) Swedish pulse mapping */ + __qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | ('0' + + (span->chans[x]->pulsecount - 1))); + } else if (span->chans[x]->pulsecount > 9) { + __qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | '0'); + } else { + __qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | ('0' + + span->chans[x]->pulsecount)); + } + span->chans[x]->pulsecount = 0; + } + } + } +#ifdef BUFFER_DEBUG + span->chans[x]->statcount -= DAHDI_CHUNKSIZE; +#endif + spin_unlock_irqrestore(&span->chans[x]->lock, flags); + } + } + + if (span == master) + process_masterspan(); + + return 0; +} + +MODULE_AUTHOR("Mark Spencer "); +MODULE_DESCRIPTION("DAHDI Telephony Interface"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(DAHDI_VERSION); + +module_param(debug, int, 0644); +module_param(deftaps, int, 0644); + +static struct file_operations dahdi_fops = { + .owner = THIS_MODULE, + .llseek = NULL, + .open = dahdi_open, + .release = dahdi_release, + .ioctl = dahdi_ioctl, + .read = dahdi_read, + .write = dahdi_write, + .poll = dahdi_poll, + .mmap = dahdi_mmap, + .flush = NULL, + .fsync = NULL, + .fasync = NULL, +}; + +#ifdef CONFIG_DAHDI_WATCHDOG +static struct timer_list watchdogtimer; + +static void watchdog_check(unsigned long ignored) +{ + int x; + unsigned long flags; + static int wdcheck=0; + + local_irq_save(flags); + for (x=0;xflags & DAHDI_FLAG_RUNNING)) { + if (spans[x]->watchcounter == DAHDI_WATCHDOG_INIT) { + /* Whoops, dead card */ + if ((spans[x]->watchstate == DAHDI_WATCHSTATE_OK) || + (spans[x]->watchstate == DAHDI_WATCHSTATE_UNKNOWN)) { + spans[x]->watchstate = DAHDI_WATCHSTATE_RECOVERING; + if (spans[x]->watchdog) { + module_printk(KERN_NOTICE, "Kicking span %s\n", spans[x]->name); + spans[x]->watchdog(spans[x], DAHDI_WATCHDOG_NOINTS); + } else { + module_printk(KERN_NOTICE, "Span %s is dead with no revival\n", spans[x]->name); + spans[x]->watchstate = DAHDI_WATCHSTATE_FAILED; + } + } + } else { + if ((spans[x]->watchstate != DAHDI_WATCHSTATE_OK) && + (spans[x]->watchstate != DAHDI_WATCHSTATE_UNKNOWN)) + module_printk(KERN_NOTICE, "Span %s is alive!\n", spans[x]->name); + spans[x]->watchstate = DAHDI_WATCHSTATE_OK; + } + spans[x]->watchcounter = DAHDI_WATCHDOG_INIT; + } + } + local_irq_restore(flags); + if (!wdcheck) { + module_printk(KERN_NOTICE, "watchdog on duty!\n"); + wdcheck=1; + } + mod_timer(&watchdogtimer, jiffies + 2); +} + +static int __init watchdog_init(void) +{ + init_timer(&watchdogtimer); + watchdogtimer.expires = 0; + watchdogtimer.data =0; + watchdogtimer.function = watchdog_check; + /* Run every couple of jiffy or so */ + mod_timer(&watchdogtimer, jiffies + 2); + return 0; +} + +static void __exit watchdog_cleanup(void) +{ + del_timer(&watchdogtimer); +} + +#endif + +int dahdi_register_chardev(struct dahdi_chardev *dev) +{ + char udevname[strlen(dev->name) + sizeof("dahdi!")]; + + strcpy(udevname, "dahdi!"); + strcat(udevname, dev->name); + CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor), NULL, udevname); + + return 0; +} + +int dahdi_unregister_chardev(struct dahdi_chardev *dev) +{ + CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor)); + + return 0; +} + +static int __init dahdi_init(void) +{ + int res = 0; + +#ifdef CONFIG_PROC_FS + proc_entries[0] = proc_mkdir("dahdi", NULL); +#endif + + if ((res = register_chrdev(DAHDI_MAJOR, "dahdi", &dahdi_fops))) { + module_printk(KERN_ERR, "Unable to register DAHDI character device handler on %d\n", DAHDI_MAJOR); + return res; + } + + dahdi_class = class_create(THIS_MODULE, "dahdi"); + CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 253), NULL, "dahdi!timer"); + CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 254), NULL, "dahdi!channel"); + CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 255), NULL, "dahdi!pseudo"); + CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, 0), NULL, "dahdi!ctl"); + + module_printk(KERN_INFO, "Telephony Interface Registered on major %d\n", DAHDI_MAJOR); + module_printk(KERN_INFO, "Version: %s\n", DAHDI_VERSION); + dahdi_conv_init(); + fasthdlc_precalc(); + rotate_sums(); +#ifdef CONFIG_DAHDI_WATCHDOG + watchdog_init(); +#endif + coretimer_init(); + return res; +} + +static void __exit dahdi_cleanup(void) +{ + int x; + + coretimer_cleanup(); + + CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 253)); /* timer */ + CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 254)); /* channel */ + CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 255)); /* pseudo */ + CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 0)); /* ctl */ + class_destroy(dahdi_class); + + unregister_chrdev(DAHDI_MAJOR, "dahdi"); + +#ifdef CONFIG_PROC_FS + remove_proc_entry("dahdi", NULL); +#endif + + module_printk(KERN_INFO, "Telephony Interface Unloaded\n"); + for (x = 0; x < DAHDI_TONE_ZONE_MAX; x++) { + if (tone_zones[x]) + kfree(tone_zones[x]); + } + +#ifdef CONFIG_DAHDI_WATCHDOG + watchdog_cleanup(); +#endif +} + +module_init(dahdi_init); +module_exit(dahdi_cleanup); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_dummy.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_dummy.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_dummy.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_dummy.c 2009-11-09 13:32:45.000000000 -0600 @@ -0,0 +1,282 @@ +/* + * Dummy DAHDI Driver for DAHDI Telephony interface + * + * Required: kernel > 2.6.0 + * + * Written by Robert Pleh + * 2.6 version by Tony Hoyle + * Unified by Mark Spencer + * + * Converted to use HighResTimers on i386 by Jeffery Palmer + * + * Copyright (C) 2002, Hermes Softlab + * Copyright (C) 2004-2009, Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +/* + * To use the high resolution timers, in your kernel CONFIG_HIGH_RES_TIMERS + * needs to be enabled (Processor type and features -> High Resolution + * Timer Support), and optionally HPET (Processor type and features -> + * HPET Timer Support) provides a better clock source. + */ + +#include + +#if defined(CONFIG_HIGH_RES_TIMERS) && \ + LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) +#define USE_HIGHRESTIMER +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(USE_HIGHRESTIMER) +#include +#else +#include +#endif + +#include + +#ifndef HAVE_HRTIMER_ACCESSORS +#if defined(USE_HIGHRESTIMER) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)) +/* Compatibility with new hrtimer interface */ +static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer) +{ + return timer->expires; +} + +static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time) +{ + timer->expires = time; +} +#endif +#endif + +struct dahdi_dummy { + struct dahdi_span span; + struct dahdi_chan _chan; + struct dahdi_chan *chan; +#if !defined(USE_HIGHRESTIMER) + unsigned long calls_since_start; + struct timespec start_interval; +#endif +}; + +static struct dahdi_dummy *ztd; + +static int debug = 0; + +#ifdef USE_HIGHRESTIMER +#define CLOCK_SRC "HRtimer" +static struct hrtimer zaptimer; +#define DAHDI_RATE 1000 /* DAHDI ticks per second */ +#define DAHDI_TIME (1000000 / DAHDI_RATE) /* DAHDI tick time in us */ +#define DAHDI_TIME_NS (DAHDI_TIME * 1000) /* DAHDI tick time in ns */ +#else +#define CLOCK_SRC "Linux26" +static struct timer_list timer; +static atomic_t shutdown; +#define JIFFIES_INTERVAL (HZ/250) /* 4ms is fine for dahdi_dummy */ +#endif + +/* Different bits of the debug variable: */ +#define DEBUG_GENERAL (1 << 0) +#define DEBUG_TICKS (1 << 1) + +#if defined(USE_HIGHRESTIMER) +static enum hrtimer_restart dahdi_dummy_hr_int(struct hrtimer *htmr) +{ + unsigned long overrun; + + /* Trigger DAHDI */ + dahdi_receive(&ztd->span); + dahdi_transmit(&ztd->span); + + /* Overrun should always return 1, since we are in the timer that + * expired. + * We should worry if overrun is 2 or more; then we really missed + * a tick */ + overrun = hrtimer_forward(&zaptimer, hrtimer_get_expires(htmr), + ktime_set(0, DAHDI_TIME_NS)); + if(overrun > 1) { + if(printk_ratelimit()) + printk(KERN_NOTICE "dahdi_dummy: HRTimer missed %lu ticks\n", + overrun - 1); + } + + if(debug && DEBUG_TICKS) { + static int count = 0; + /* Printk every 5 seconds, good test to see if timer is + * running properly */ + if (count++ % 5000 == 0) + printk(KERN_DEBUG "dahdi_dummy: 5000 ticks from hrtimer\n"); + } + + /* Always restart the timer */ + return HRTIMER_RESTART; +} +#else +static unsigned long timespec_diff_ms(struct timespec *t0, struct timespec *t1) +{ + long nanosec, sec; + unsigned long ms; + sec = (t1->tv_sec - t0->tv_sec); + nanosec = (t1->tv_nsec - t0->tv_nsec); + while (nanosec >= NSEC_PER_SEC) { + nanosec -= NSEC_PER_SEC; + ++sec; + } + while (nanosec < 0) { + nanosec += NSEC_PER_SEC; + --sec; + } + ms = (sec * 1000) + (nanosec / 1000000L); + return ms; +} + +static void dahdi_dummy_timer(unsigned long param) +{ + unsigned long ms_since_start; + struct timespec now; + const unsigned long MAX_INTERVAL = 100000L; + const unsigned long MS_LIMIT = 3000; + + if (!atomic_read(&shutdown)) + mod_timer(&timer, jiffies + JIFFIES_INTERVAL); + + now = current_kernel_time(); + ms_since_start = timespec_diff_ms(&ztd->start_interval, &now); + + /* + * If the system time has changed, it is possible for us to be far + * behind. If we are more than MS_LIMIT milliseconds behind, just + * reset our time base and continue so that we do not hang the system + * here. + * + */ + if (unlikely((ms_since_start - ztd->calls_since_start) > MS_LIMIT)) { + if (printk_ratelimit()) { + printk(KERN_INFO + "dahdi_dummy: Detected time shift.\n"); + } + ztd->calls_since_start = 0; + ztd->start_interval = now; + return; + } + + while (ms_since_start > ztd->calls_since_start) { + ztd->calls_since_start++; + dahdi_receive(&ztd->span); + dahdi_transmit(&ztd->span); + } + + if (ms_since_start > MAX_INTERVAL) { + ztd->calls_since_start = 0; + ztd->start_interval = now; + } +} +#endif + +static int dahdi_dummy_initialize(struct dahdi_dummy *ztd) +{ + /* DAHDI stuff */ + ztd->chan = &ztd->_chan; + sprintf(ztd->span.name, "DAHDI_DUMMY/1"); + snprintf(ztd->span.desc, sizeof(ztd->span.desc) - 1, "%s (source: " CLOCK_SRC ") %d", ztd->span.name, 1); + sprintf(ztd->chan->name, "DAHDI_DUMMY/%d/%d", 1, 0); + dahdi_copy_string(ztd->span.devicetype, "DAHDI Dummy Timing", sizeof(ztd->span.devicetype)); + ztd->chan->chanpos = 1; + ztd->span.chans = &ztd->chan; + ztd->span.channels = 0; /* no channels on our span */ + ztd->span.deflaw = DAHDI_LAW_MULAW; + init_waitqueue_head(&ztd->span.maintq); + ztd->span.pvt = ztd; + ztd->chan->pvt = ztd; + if (dahdi_register(&ztd->span, 0)) { + return -1; + } + return 0; +} + +int init_module(void) +{ + ztd = kzalloc(sizeof(*ztd), GFP_KERNEL); + if (ztd == NULL) { + printk(KERN_ERR "dahdi_dummy: Unable to allocate memory\n"); + return -ENOMEM; + } + + if (dahdi_dummy_initialize(ztd)) { + printk(KERN_ERR "dahdi_dummy: Unable to intialize DAHDI driver\n"); + kfree(ztd); + return -ENODEV; + } + +#if defined(USE_HIGHRESTIMER) + printk(KERN_DEBUG "dahdi_dummy: Trying to load High Resolution Timer\n"); + hrtimer_init(&zaptimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + printk(KERN_DEBUG "dahdi_dummy: Initialized High Resolution Timer\n"); + + /* Set timer callback function */ + zaptimer.function = dahdi_dummy_hr_int; + + printk(KERN_DEBUG "dahdi_dummy: Starting High Resolution Timer\n"); + hrtimer_start(&zaptimer, ktime_set(0, DAHDI_TIME_NS), HRTIMER_MODE_REL); + printk(KERN_INFO "dahdi_dummy: High Resolution Timer started, good to go\n"); +#else + init_timer(&timer); + timer.function = dahdi_dummy_timer; + ztd->start_interval = current_kernel_time(); + timer.expires = jiffies + JIFFIES_INTERVAL; + atomic_set(&shutdown, 0); + add_timer(&timer); +#endif + + if (debug) + printk(KERN_DEBUG "dahdi_dummy: init() finished\n"); + return 0; +} + + +void cleanup_module(void) +{ +#if defined(USE_HIGHRESTIMER) + /* Stop high resolution timer */ + hrtimer_cancel(&zaptimer); +#else + atomic_set(&shutdown, 1); + del_timer_sync(&timer); +#endif + dahdi_unregister(&ztd->span); + kfree(ztd); + if (debug) + printk(KERN_DEBUG "dahdi_dummy: cleanup() finished\n"); +} + +module_param(debug, int, 0600); + +MODULE_DESCRIPTION("Timing-Only Driver"); +MODULE_AUTHOR("Robert Pleh "); +MODULE_LICENSE("GPL v2"); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_dynamic.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_dynamic.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_dynamic.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_dynamic.c 2009-11-09 13:32:45.000000000 -0600 @@ -0,0 +1,859 @@ +/* + * Dynamic Span Interface for DAHDI + * + * Written by Mark Spencer + * + * Copyright (C) 2001-2008, Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * Tasklets provide better system interactive response at the cost of the + * possibility of losing a frame of data at very infrequent intervals. If + * you are more concerned with the performance of your machine, enable the + * tasklets. If you are strict about absolutely no drops, then do not enable + * tasklets. + */ + +#define ENABLE_TASKLETS + +/* + * Dynamic spans implemented using TDM over X with standard message + * types. Message format is as follows: + * + * Byte #: Meaning + * 0 Number of samples per channel + * 1 Current flags on span + * Bit 0: Yellow Alarm + * Bit 1: Sig bits present + * Bits 2-7: reserved for future use + * 2-3 16-bit counter value for detecting drops, network byte order. + * 4-5 Number of channels in the message, network byte order + * 6... 16-bit words, containing sig bits for each + * four channels, least significant 4 bits being + * the least significant channel, network byte order. + * the rest data for each channel, all samples per channel + before moving to the next. + */ + +/* Arbitrary limit to the max # of channels in a span */ +#define DAHDI_DYNAMIC_MAX_CHANS 256 + +#define ZTD_FLAG_YELLOW_ALARM (1 << 0) +#define ZTD_FLAG_SIGBITS_PRESENT (1 << 1) +#define ZTD_FLAG_LOOPBACK (1 << 2) + +#define ERR_NSAMP (1 << 16) +#define ERR_NCHAN (1 << 17) +#define ERR_LEN (1 << 18) + +EXPORT_SYMBOL(dahdi_dynamic_register); +EXPORT_SYMBOL(dahdi_dynamic_unregister); +EXPORT_SYMBOL(dahdi_dynamic_receive); + +#ifdef ENABLE_TASKLETS +static int taskletrun; +static int taskletsched; +static int taskletpending; +static int taskletexec; +static int txerrors; +static struct tasklet_struct ztd_tlet; + +static void ztd_tasklet(unsigned long data); +#endif + + +static struct dahdi_dynamic { + char addr[40]; + char dname[20]; + int err; + int usecount; + int dead; + long rxjif; + unsigned short txcnt; + unsigned short rxcnt; + struct dahdi_span span; + struct dahdi_chan *chans[DAHDI_DYNAMIC_MAX_CHANS]; + struct dahdi_dynamic *next; + struct dahdi_dynamic_driver *driver; + void *pvt; + int timing; + int master; + unsigned char *msgbuf; +} *dspans; + +static struct dahdi_dynamic_driver *drivers = NULL; + +static int debug = 0; + +static int hasmaster = 0; +#ifdef DEFINE_SPINLOCK +static DEFINE_SPINLOCK(dlock); +#else +static spinlock_t dlock = SPIN_LOCK_UNLOCKED; +#endif + +#ifdef DEFINE_RWLOCK +static DEFINE_RWLOCK(drvlock); +#else +static rwlock_t drvlock = RW_LOCK_UNLOCKED; +#endif + +static void checkmaster(void) +{ + unsigned long flags; + int newhasmaster=0; + int best = 9999999; + struct dahdi_dynamic *z, *master=NULL; + spin_lock_irqsave(&dlock, flags); + z = dspans; + while(z) { + if (z->timing) { + z->master = 0; + if (!(z->span.alarms & DAHDI_ALARM_RED) && + (z->timing < best) && !z->dead) { + /* If not in alarm and they're + a better timing source, use them */ + master = z; + best = z->timing; + newhasmaster = 1; + } + } + z = z->next; + } + hasmaster = newhasmaster; + /* Mark the new master if there is one */ + if (master) + master->master = 1; + spin_unlock_irqrestore(&dlock, flags); + if (master) + printk(KERN_INFO "TDMoX: New master: %s\n", master->span.name); + else + printk(KERN_INFO "TDMoX: No master.\n"); +} + +static void ztd_sendmessage(struct dahdi_dynamic *z) +{ + unsigned char *buf = z->msgbuf; + unsigned short bits; + int msglen = 0; + int x; + int offset; + + /* Byte 0: Number of samples per channel */ + *buf = DAHDI_CHUNKSIZE; + buf++; msglen++; + + /* Byte 1: Flags */ + *buf = 0; + if (z->span.alarms & DAHDI_ALARM_RED) + *buf |= ZTD_FLAG_YELLOW_ALARM; + *buf |= ZTD_FLAG_SIGBITS_PRESENT; + buf++; msglen++; + + /* Bytes 2-3: Transmit counter */ + *((unsigned short *)buf) = htons((unsigned short)z->txcnt); + z->txcnt++; + buf++; msglen++; + buf++; msglen++; + + /* Bytes 4-5: Number of channels */ + *((unsigned short *)buf) = htons((unsigned short)z->span.channels); + buf++; msglen++; + buf++; msglen++; + bits = 0; + offset = 0; + for (x=0;xspan.channels;x++) { + offset = x % 4; + bits |= (z->chans[x]->txsig & 0xf) << (offset << 2); + if (offset == 3) { + /* Write the bits when we have four channels */ + *((unsigned short *)buf) = htons(bits); + buf++; msglen++; + buf++; msglen++; + bits = 0; + } + } + + if (offset != 3) { + /* Finish it off if it's not done already */ + *((unsigned short *)buf) = htons(bits); + buf++; msglen++; + buf++; msglen++; + } + + for (x=0;xspan.channels;x++) { + memcpy(buf, z->chans[x]->writechunk, DAHDI_CHUNKSIZE); + buf += DAHDI_CHUNKSIZE; + msglen += DAHDI_CHUNKSIZE; + } + + z->driver->transmit(z->pvt, z->msgbuf, msglen); + +} + +static void __ztdynamic_run(void) +{ + unsigned long flags; + struct dahdi_dynamic *z; + struct dahdi_dynamic_driver *drv; + int y; + spin_lock_irqsave(&dlock, flags); + z = dspans; + while(z) { + if (!z->dead) { + /* Ignore dead spans */ + for (y=0;yspan.channels;y++) { + /* Echo cancel double buffered data */ + dahdi_ec_chunk(z->span.chans[y], z->span.chans[y]->readchunk, z->span.chans[y]->writechunk); + } + dahdi_receive(&z->span); + dahdi_transmit(&z->span); + /* Handle all transmissions now */ + spin_unlock_irqrestore(&dlock, flags); + ztd_sendmessage(z); + spin_lock_irqsave(&dlock, flags); + } + z = z->next; + } + spin_unlock_irqrestore(&dlock, flags); + + read_lock(&drvlock); + drv = drivers; + while(drv) { + /* Flush any traffic still pending in the driver */ + if (drv->flush) { + drv->flush(); + } + drv = drv->next; + } + read_unlock(&drvlock); +} + +#ifdef ENABLE_TASKLETS +static void ztdynamic_run(void) +{ + if (!taskletpending) { + taskletpending = 1; + taskletsched++; + tasklet_hi_schedule(&ztd_tlet); + } else { + txerrors++; + } +} +#else +#define ztdynamic_run __ztdynamic_run +#endif + +void dahdi_dynamic_receive(struct dahdi_span *span, unsigned char *msg, int msglen) +{ + struct dahdi_dynamic *ztd = span->pvt; + int newerr=0; + unsigned long flags; + int sflags; + int xlen; + int x, bits, sig; + int nchans, master; + int newalarm; + unsigned short rxpos, rxcnt; + + + spin_lock_irqsave(&dlock, flags); + if (msglen < 6) { + spin_unlock_irqrestore(&dlock, flags); + newerr = ERR_LEN; + if (newerr != ztd->err) { + printk(KERN_NOTICE "Span %s: Insufficient samples for header (only %d)\n", span->name, msglen); + } + ztd->err = newerr; + return; + } + + /* First, check the chunksize */ + if (*msg != DAHDI_CHUNKSIZE) { + spin_unlock_irqrestore(&dlock, flags); + newerr = ERR_NSAMP | msg[0]; + if (newerr != ztd->err) { + printk(KERN_NOTICE "Span %s: Expected %d samples, but receiving %d\n", span->name, DAHDI_CHUNKSIZE, msg[0]); + } + ztd->err = newerr; + return; + } + msg++; + sflags = *msg; + msg++; + + rxpos = ntohs(*((unsigned short *)msg)); + msg++; + msg++; + + nchans = ntohs(*((unsigned short *)msg)); + if (nchans != span->channels) { + spin_unlock_irqrestore(&dlock, flags); + newerr = ERR_NCHAN | nchans; + if (newerr != ztd->err) { + printk(KERN_NOTICE "Span %s: Expected %d channels, but receiving %d\n", span->name, span->channels, nchans); + } + ztd->err = newerr; + return; + } + msg++; + msg++; + + /* Okay now we've accepted the header, lets check our message + length... */ + + /* Start with header */ + xlen = 6; + /* Add samples of audio */ + xlen += nchans * DAHDI_CHUNKSIZE; + /* If RBS info is there, add that */ + if (sflags & ZTD_FLAG_SIGBITS_PRESENT) { + /* Account for sigbits -- one short per 4 channels*/ + xlen += ((nchans + 3) / 4) * 2; + } + + if (xlen != msglen) { + spin_unlock_irqrestore(&dlock, flags); + newerr = ERR_LEN | xlen; + if (newerr != ztd->err) { + printk(KERN_NOTICE "Span %s: Expected message size %d, but was %d instead\n", span->name, xlen, msglen); + } + ztd->err = newerr; + return; + } + + bits = 0; + + /* Record sigbits if present */ + if (sflags & ZTD_FLAG_SIGBITS_PRESENT) { + for (x=0;x> ((x % 4) << 2)) & 0xff; + + /* Update signalling if appropriate */ + if (sig != span->chans[x]->rxsig) + dahdi_rbsbits(span->chans[x], sig); + + } + } + + /* Record data for channels */ + for (x=0;xchans[x]->readchunk, msg, DAHDI_CHUNKSIZE); + msg += DAHDI_CHUNKSIZE; + } + + master = ztd->master; + + rxcnt = ztd->rxcnt; + ztd->rxcnt = rxpos+1; + + spin_unlock_irqrestore(&dlock, flags); + + /* Check for Yellow alarm */ + newalarm = span->alarms & ~(DAHDI_ALARM_YELLOW | DAHDI_ALARM_RED); + if (sflags & ZTD_FLAG_YELLOW_ALARM) + newalarm |= DAHDI_ALARM_YELLOW; + + if (newalarm != span->alarms) { + span->alarms = newalarm; + dahdi_alarm_notify(span); + checkmaster(); + } + + /* Keep track of last received packet */ + ztd->rxjif = jiffies; + + /* note if we had a missing packet */ + if (rxpos != rxcnt) + printk(KERN_NOTICE "Span %s: Expected seq no %d, but received %d instead\n", span->name, rxcnt, rxpos); + + /* If this is our master span, then run everything */ + if (master) + ztdynamic_run(); + +} + +static void dynamic_destroy(struct dahdi_dynamic *z) +{ + unsigned int x; + + /* Unregister span if appropriate */ + if (test_bit(DAHDI_FLAGBIT_REGISTERED, &z->span.flags)) + dahdi_unregister(&z->span); + + /* Destroy the pvt stuff if there */ + if (z->pvt) + z->driver->destroy(z->pvt); + + /* Free message buffer if appropriate */ + if (z->msgbuf) + kfree(z->msgbuf); + + /* Free channels */ + for (x = 0; x < z->span.channels; x++) { + kfree(z->chans[x]); + } + + /* Free z */ + kfree(z); + + checkmaster(); +} + +static struct dahdi_dynamic *find_dynamic(struct dahdi_dynamic_span *zds) +{ + struct dahdi_dynamic *z; + z = dspans; + while(z) { + if (!strcmp(z->dname, zds->driver) && + !strcmp(z->addr, zds->addr)) + break; + z = z->next; + } + return z; +} + +static struct dahdi_dynamic_driver *find_driver(char *name) +{ + struct dahdi_dynamic_driver *ztd; + ztd = drivers; + while(ztd) { + /* here's our driver */ + if (!strcmp(name, ztd->name)) + break; + ztd = ztd->next; + } + return ztd; +} + +static int destroy_dynamic(struct dahdi_dynamic_span *zds) +{ + unsigned long flags; + struct dahdi_dynamic *z, *cur, *prev=NULL; + spin_lock_irqsave(&dlock, flags); + z = find_dynamic(zds); + if (!z) { + spin_unlock_irqrestore(&dlock, flags); + return -EINVAL; + } + /* Don't destroy span until it is in use */ + if (z->usecount) { + spin_unlock_irqrestore(&dlock, flags); + printk(KERN_NOTICE "Attempt to destroy dynamic span while it is in use\n"); + return -EBUSY; + } + /* Unlink it */ + cur = dspans; + while(cur) { + if (cur == z) { + if (prev) + prev->next = z->next; + else + dspans = z->next; + break; + } + prev = cur; + cur = cur->next; + } + spin_unlock_irqrestore(&dlock, flags); + + /* Destroy it */ + dynamic_destroy(z); + + return 0; +} + +static int ztd_rbsbits(struct dahdi_chan *chan, int bits) +{ + /* Don't have to do anything */ + return 0; +} + +static int ztd_open(struct dahdi_chan *chan) +{ + struct dahdi_dynamic *z; + z = chan->span->pvt; + if (z) { + if (z->dead) + return -ENODEV; + z->usecount++; + } + if(!try_module_get(THIS_MODULE)) + printk(KERN_NOTICE "TDMoX: Unable to increment module use count\n"); + return 0; +} + +static int ztd_chanconfig(struct dahdi_chan *chan, int sigtype) +{ + return 0; +} + +static int ztd_close(struct dahdi_chan *chan) +{ + struct dahdi_dynamic *z; + z = chan->span->pvt; + if (z) + z->usecount--; + if (z->dead && !z->usecount) + dynamic_destroy(z); + module_put(THIS_MODULE); + return 0; +} + +static int create_dynamic(struct dahdi_dynamic_span *zds) +{ + struct dahdi_dynamic *z; + struct dahdi_dynamic_driver *ztd; + unsigned long flags; + int x; + int bufsize; + + if (zds->numchans < 1) { + printk(KERN_NOTICE "Can't be less than 1 channel (%d)!\n", zds->numchans); + return -EINVAL; + } + if (zds->numchans >= DAHDI_DYNAMIC_MAX_CHANS) { + printk(KERN_NOTICE "Can't create dynamic span with greater than %d channels. See ztdynamic.c and increase DAHDI_DYNAMIC_MAX_CHANS\n", zds->numchans); + return -EINVAL; + } + + spin_lock_irqsave(&dlock, flags); + z = find_dynamic(zds); + spin_unlock_irqrestore(&dlock, flags); + if (z) + return -EEXIST; + + /* XXX There is a silly race here. We check it doesn't exist, but + someone could create it between now and then and we'd end up + with two of them. We don't want to hold the spinlock + for *too* long though, especially not if there is a possibility + of kmalloc. XXX */ + + + /* Allocate memory */ + if (!(z = kmalloc(sizeof(*z), GFP_KERNEL))) { + return -ENOMEM; + } + + /* Zero it out */ + memset(z, 0, sizeof(*z)); + + for (x = 0; x < zds->numchans; x++) { + if (!(z->chans[x] = kmalloc(sizeof(*z->chans[x]), GFP_KERNEL))) { + dynamic_destroy(z); + return -ENOMEM; + } + + memset(z->chans[x], 0, sizeof(*z->chans[x])); + } + + /* Allocate message buffer with sample space and header space */ + bufsize = zds->numchans * DAHDI_CHUNKSIZE + zds->numchans / 4 + 48; + + z->msgbuf = kmalloc(bufsize, GFP_KERNEL); + + if (!z->msgbuf) { + dynamic_destroy(z); + return -ENOMEM; + } + + /* Zero out -- probably not needed but why not */ + memset(z->msgbuf, 0, bufsize); + + /* Setup parameters properly assuming we're going to be okay. */ + dahdi_copy_string(z->dname, zds->driver, sizeof(z->dname)); + dahdi_copy_string(z->addr, zds->addr, sizeof(z->addr)); + z->timing = zds->timing; + sprintf(z->span.name, "DYN/%s/%s", zds->driver, zds->addr); + sprintf(z->span.desc, "Dynamic '%s' span at '%s'", zds->driver, zds->addr); + z->span.channels = zds->numchans; + z->span.pvt = z; + z->span.deflaw = DAHDI_LAW_MULAW; + z->span.flags |= DAHDI_FLAG_RBS; + z->span.chans = z->chans; + z->span.rbsbits = ztd_rbsbits; + z->span.open = ztd_open; + z->span.close = ztd_close; + z->span.chanconfig = ztd_chanconfig; + for (x=0; x < z->span.channels; x++) { + sprintf(z->chans[x]->name, "DYN/%s/%s/%d", zds->driver, zds->addr, x+1); + z->chans[x]->sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_FXSLS | + DAHDI_SIG_FXSKS | DAHDI_SIG_FXSGS | DAHDI_SIG_FXOLS | + DAHDI_SIG_FXOKS | DAHDI_SIG_FXOGS | DAHDI_SIG_SF | + DAHDI_SIG_DACS_RBS | DAHDI_SIG_CAS; + z->chans[x]->chanpos = x + 1; + z->chans[x]->pvt = z; + } + + spin_lock_irqsave(&dlock, flags); + ztd = find_driver(zds->driver); + if (!ztd) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,70) + char fn[80]; +#endif + + spin_unlock_irqrestore(&dlock, flags); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,70) + request_module("dahdi_dynamic_%s", zds->driver); +#else + sprintf(fn, "dahdi_dynamic_%s", zds->driver); + request_module(fn); +#endif + spin_lock_irqsave(&dlock, flags); + ztd = find_driver(zds->driver); + } + spin_unlock_irqrestore(&dlock, flags); + + + /* Another race -- should let the module get unloaded while we + have it here */ + if (!ztd) { + printk(KERN_NOTICE "No such driver '%s' for dynamic span\n", zds->driver); + dynamic_destroy(z); + return -EINVAL; + } + + /* Create the stuff */ + z->pvt = ztd->create(&z->span, z->addr); + if (!z->pvt) { + printk(KERN_NOTICE "Driver '%s' (%s) rejected address '%s'\n", ztd->name, ztd->desc, z->addr); + /* Creation failed */ + return -EINVAL; + } + + /* Remember the driver */ + z->driver = ztd; + + /* Whee! We're created. Now register the span */ + if (dahdi_register(&z->span, 0)) { + printk(KERN_NOTICE "Unable to register span '%s'\n", z->span.name); + dynamic_destroy(z); + return -EINVAL; + } + + /* Okay, created and registered. add it to the list */ + spin_lock_irqsave(&dlock, flags); + z->next = dspans; + dspans = z; + spin_unlock_irqrestore(&dlock, flags); + + checkmaster(); + + /* All done */ + return z->span.spanno; + +} + +#ifdef ENABLE_TASKLETS +static void ztd_tasklet(unsigned long data) +{ + taskletrun++; + if (taskletpending) { + taskletexec++; + __ztdynamic_run(); + } + taskletpending = 0; +} +#endif + +static int ztdynamic_ioctl(unsigned int cmd, unsigned long data) +{ + struct dahdi_dynamic_span zds; + int res; + switch(cmd) { + case 0: + /* This is called just before rotation. If none of our + spans are pulling timing, then now is the time to process + them */ + if (!hasmaster) + ztdynamic_run(); + return 0; + case DAHDI_DYNAMIC_CREATE: + if (copy_from_user(&zds, (__user const void *) data, sizeof(zds))) + return -EFAULT; + if (debug) + printk(KERN_DEBUG "Dynamic Create\n"); + res = create_dynamic(&zds); + if (res < 0) + return res; + zds.spanno = res; + /* Let them know the new span number */ + if (copy_to_user((__user void *) data, &zds, sizeof(zds))) + return -EFAULT; + return 0; + case DAHDI_DYNAMIC_DESTROY: + if (copy_from_user(&zds, (__user const void *) data, sizeof(zds))) + return -EFAULT; + if (debug) + printk(KERN_DEBUG "Dynamic Destroy\n"); + return destroy_dynamic(&zds); + } + + return -ENOTTY; +} + +int dahdi_dynamic_register(struct dahdi_dynamic_driver *dri) +{ + unsigned long flags; + int res = 0; + write_lock_irqsave(&drvlock, flags); + if (find_driver(dri->name)) + res = -1; + else { + dri->next = drivers; + drivers = dri; + } + write_unlock_irqrestore(&drvlock, flags); + return res; +} + +void dahdi_dynamic_unregister(struct dahdi_dynamic_driver *dri) +{ + struct dahdi_dynamic_driver *cur, *prev=NULL; + struct dahdi_dynamic *z, *zp, *zn; + unsigned long flags; + write_lock_irqsave(&drvlock, flags); + cur = drivers; + while(cur) { + if (cur == dri) { + if (prev) + prev->next = cur->next; + else + drivers = cur->next; + break; + } + prev = cur; + cur = cur->next; + } + write_unlock_irqrestore(&drvlock, flags); + spin_lock_irqsave(&dlock, flags); + z = dspans; + zp = NULL; + while(z) { + zn = z->next; + if (z->driver == dri) { + /* Unlink */ + if (zp) + zp->next = z->next; + else + dspans = z->next; + if (!z->usecount) + dynamic_destroy(z); + else + z->dead = 1; + } else { + zp = z; + } + z = zn; + } + spin_unlock_irqrestore(&dlock, flags); +} + +static struct timer_list alarmcheck; + +static void check_for_red_alarm(unsigned long ignored) +{ + unsigned long flags; + int newalarm; + int alarmchanged = 0; + struct dahdi_dynamic *z; + spin_lock_irqsave(&dlock, flags); + z = dspans; + while(z) { + newalarm = z->span.alarms & ~DAHDI_ALARM_RED; + /* If nothing received for a second, consider that RED ALARM */ + if ((jiffies - z->rxjif) > 1 * HZ) { + newalarm |= DAHDI_ALARM_RED; + if (z->span.alarms != newalarm) { + z->span.alarms = newalarm; + dahdi_alarm_notify(&z->span); + alarmchanged++; + } + } + z = z->next; + } + spin_unlock_irqrestore(&dlock, flags); + if (alarmchanged) + checkmaster(); + + /* Do the next one */ + mod_timer(&alarmcheck, jiffies + 1 * HZ); + +} + +static int ztdynamic_init(void) +{ + dahdi_set_dynamic_ioctl(ztdynamic_ioctl); + /* Start process to check for RED ALARM */ + init_timer(&alarmcheck); + alarmcheck.expires = 0; + alarmcheck.data = 0; + alarmcheck.function = check_for_red_alarm; + /* Check once per second */ + mod_timer(&alarmcheck, jiffies + 1 * HZ); +#ifdef ENABLE_TASKLETS + tasklet_init(&ztd_tlet, ztd_tasklet, 0); +#endif + printk(KERN_INFO "DAHDI Dynamic Span support LOADED\n"); + return 0; +} + +static void ztdynamic_cleanup(void) +{ +#ifdef ENABLE_TASKLETS + if (taskletpending) { + tasklet_disable(&ztd_tlet); + tasklet_kill(&ztd_tlet); + } +#endif + dahdi_set_dynamic_ioctl(NULL); + del_timer(&alarmcheck); + printk(KERN_INFO "DAHDI Dynamic Span support unloaded\n"); +} + +module_param(debug, int, 0600); + +MODULE_DESCRIPTION("DAHDI Dynamic Span Support"); +MODULE_AUTHOR("Mark Spencer "); +MODULE_LICENSE("GPL v2"); + +module_init(ztdynamic_init); +module_exit(ztdynamic_cleanup); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_dynamic_eth.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_dynamic_eth.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_dynamic_eth.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_dynamic_eth.c 2008-10-28 16:49:02.000000000 -0500 @@ -0,0 +1,438 @@ +/* + * Dynamic Span Interface for DAHDI (Ethernet Interface) + * + * Written by Mark Spencer + * + * Copyright (C) 2001-2008, Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define ETH_P_DAHDI_DETH 0xd00d + +struct ztdeth_header { + unsigned short subaddr; +}; + +/* We take the raw message, put it in an ethernet frame, and add a + two byte addressing header at the top for future use */ +#ifdef DEFINE_SPINLOCK +static DEFINE_SPINLOCK(zlock); +#else +static spinlock_t zlock = SPIN_LOCK_UNLOCKED; +#endif + +static struct sk_buff_head skbs; + +static struct ztdeth { + unsigned char addr[ETH_ALEN]; + unsigned short subaddr; /* Network byte order */ + struct dahdi_span *span; + char ethdev[IFNAMSIZ]; + struct net_device *dev; + struct ztdeth *next; +} *zdevs = NULL; + +static struct dahdi_span *ztdeth_getspan(unsigned char *addr, unsigned short subaddr) +{ + unsigned long flags; + struct ztdeth *z; + struct dahdi_span *span = NULL; + spin_lock_irqsave(&zlock, flags); + z = zdevs; + while(z) { + if (!memcmp(addr, z->addr, ETH_ALEN) && + z->subaddr == subaddr) + break; + z = z->next; + } + if (z) + span = z->span; + spin_unlock_irqrestore(&zlock, flags); + return span; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) +static int ztdeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) +#else +static int ztdeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) +#endif +{ + struct dahdi_span *span; + struct ztdeth_header *zh; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + zh = (struct ztdeth_header *)skb_network_header(skb); +#else + zh = (struct ztdeth_header *)skb->nh.raw; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9) + span = ztdeth_getspan(eth_hdr(skb)->h_source, zh->subaddr); +#else + span = ztdeth_getspan(skb->mac.ethernet->h_source, zh->subaddr); +#endif + if (span) { + skb_pull(skb, sizeof(struct ztdeth_header)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + skb_linearize(skb); +#else + skb_linearize(skb, GFP_KERNEL); +#endif + dahdi_dynamic_receive(span, (unsigned char *)skb->data, skb->len); + } + kfree_skb(skb); + return 0; +} + +static int ztdeth_notifier(struct notifier_block *block, unsigned long event, void *ptr) +{ + struct net_device *dev = ptr; + struct ztdeth *z; + unsigned long flags; + switch(event) { + case NETDEV_GOING_DOWN: + case NETDEV_DOWN: + spin_lock_irqsave(&zlock, flags); + z = zdevs; + while(z) { + /* Note that the device no longer exists */ + if (z->dev == dev) + z->dev = NULL; + z = z->next; + } + spin_unlock_irqrestore(&zlock, flags); + break; + case NETDEV_UP: + spin_lock_irqsave(&zlock, flags); + z = zdevs; + while(z) { + /* Now that the device exists again, use it */ + if (!strcmp(z->ethdev, dev->name)) + z->dev = dev; + z = z->next; + } + spin_unlock_irqrestore(&zlock, flags); + break; + } + return 0; +} + +static int ztdeth_transmit(void *pvt, unsigned char *msg, int msglen) +{ + struct ztdeth *z; + struct sk_buff *skb; + struct ztdeth_header *zh; + unsigned long flags; + struct net_device *dev; + unsigned char addr[ETH_ALEN]; + unsigned short subaddr; /* Network byte order */ + + spin_lock_irqsave(&zlock, flags); + z = pvt; + if (z->dev) { + /* Copy fields to local variables to remove spinlock ASAP */ + dev = z->dev; + memcpy(addr, z->addr, sizeof(z->addr)); + subaddr = z->subaddr; + spin_unlock_irqrestore(&zlock, flags); + skb = dev_alloc_skb(msglen + dev->hard_header_len + sizeof(struct ztdeth_header) + 32); + if (skb) { + /* Reserve header space */ + skb_reserve(skb, dev->hard_header_len + sizeof(struct ztdeth_header)); + + /* Copy message body */ + memcpy(skb_put(skb, msglen), msg, msglen); + + /* Throw on header */ + zh = (struct ztdeth_header *)skb_push(skb, sizeof(struct ztdeth_header)); + zh->subaddr = subaddr; + + /* Setup protocol and such */ + skb->protocol = __constant_htons(ETH_P_DAHDI_DETH); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + skb_set_network_header(skb, 0); +#else + skb->nh.raw = skb->data; +#endif + skb->dev = dev; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) + dev_hard_header(skb, dev, ETH_P_DAHDI_DETH, addr, dev->dev_addr, skb->len); +#else + if (dev->hard_header) + dev->hard_header(skb, dev, ETH_P_DAHDI_DETH, addr, dev->dev_addr, skb->len); +#endif + skb_queue_tail(&skbs, skb); + } + } + else + spin_unlock_irqrestore(&zlock, flags); + return 0; +} + + +static int ztdeth_flush(void) +{ + struct sk_buff *skb; + + /* Handle all transmissions now */ + while ((skb = skb_dequeue(&skbs))) { + dev_queue_xmit(skb); + } + return 0; +} + +static struct packet_type ztdeth_ptype = { + .type = __constant_htons(ETH_P_DAHDI_DETH), /* Protocol */ + .dev = NULL, /* Device (NULL = wildcard) */ + .func = ztdeth_rcv, /* Receiver */ +}; + +static int digit2int(char d) +{ + switch(d) { + case 'F': + case 'E': + case 'D': + case 'C': + case 'B': + case 'A': + return d - 'A' + 10; + case 'f': + case 'e': + case 'd': + case 'c': + case 'b': + case 'a': + return d - 'a' + 10; + case '9': + case '8': + case '7': + case '6': + case '5': + case '4': + case '3': + case '2': + case '1': + case '0': + return d - '0'; + } + return -1; +} + +static int hex2int(char *s) +{ + int res; + int tmp; + /* Gotta be at least one digit */ + if (strlen(s) < 1) + return -1; + /* Can't be more than two */ + if (strlen(s) > 2) + return -1; + /* Grab the first digit */ + res = digit2int(s[0]); + if (res < 0) + return -1; + tmp = res; + /* Grab the next */ + if (strlen(s) > 1) { + res = digit2int(s[1]); + if (res < 0) + return -1; + tmp = tmp * 16 + res; + } + return tmp; +} + +static void ztdeth_destroy(void *pvt) +{ + struct ztdeth *z = pvt; + unsigned long flags; + struct ztdeth *prev=NULL, *cur; + spin_lock_irqsave(&zlock, flags); + cur = zdevs; + while(cur) { + if (cur == z) { + if (prev) + prev->next = cur->next; + else + zdevs = cur->next; + break; + } + prev = cur; + cur = cur->next; + } + spin_unlock_irqrestore(&zlock, flags); + if (cur == z) { /* Successfully removed */ + printk(KERN_INFO "TDMoE: Removed interface for %s\n", z->span->name); + kfree(z); + module_put(THIS_MODULE); + } +} + +static void *ztdeth_create(struct dahdi_span *span, char *addr) +{ + struct ztdeth *z; + char src[256]; + char tmp[256], *tmp2, *tmp3, *tmp4 = NULL; + int res,x; + unsigned long flags; + + z = kmalloc(sizeof(struct ztdeth), GFP_KERNEL); + if (z) { + /* Zero it out */ + memset(z, 0, sizeof(struct ztdeth)); + + /* Address should be /[/subaddr] */ + dahdi_copy_string(tmp, addr, sizeof(tmp)); + tmp2 = strchr(tmp, '/'); + if (tmp2) { + *tmp2 = '\0'; + tmp2++; + dahdi_copy_string(z->ethdev, tmp, sizeof(z->ethdev)); + } else { + printk(KERN_NOTICE "Invalid TDMoE address (no device) '%s'\n", addr); + kfree(z); + return NULL; + } + if (tmp2) { + tmp4 = strchr(tmp2+1, '/'); + if (tmp4) { + *tmp4 = '\0'; + tmp4++; + } + /* We don't have SSCANF :( Gotta do this the hard way */ + tmp3 = strchr(tmp2, ':'); + for (x=0;x<6;x++) { + if (tmp2) { + if (tmp3) { + *tmp3 = '\0'; + tmp3++; + } + res = hex2int(tmp2); + if (res < 0) + break; + z->addr[x] = res & 0xff; + } else + break; + if ((tmp2 = tmp3)) + tmp3 = strchr(tmp2, ':'); + } + if (x != 6) { + printk(KERN_NOTICE "TDMoE: Invalid MAC address in: %s\n", addr); + kfree(z); + return NULL; + } + } else { + printk(KERN_NOTICE "TDMoE: Missing MAC address\n"); + kfree(z); + return NULL; + } + if (tmp4) { + int sub = 0; + int mul = 1; + + /* We have a subaddr */ + tmp3 = tmp4 + strlen (tmp4) - 1; + while (tmp3 >= tmp4) { + if (*tmp3 >= '0' && *tmp3 <= '9') { + sub += (*tmp3 - '0') * mul; + } else { + printk(KERN_NOTICE "TDMoE: Invalid subaddress\n"); + kfree(z); + return NULL; + } + mul *= 10; + tmp3--; + } + z->subaddr = htons(sub); + } + z->dev = dev_get_by_name( +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) + &init_net, +#endif + z->ethdev); + if (!z->dev) { + printk(KERN_NOTICE "TDMoE: Invalid device '%s'\n", z->ethdev); + kfree(z); + return NULL; + } + z->span = span; + src[0] ='\0'; + for (x=0;x<5;x++) + sprintf(src + strlen(src), "%02x:", z->dev->dev_addr[x]); + sprintf(src + strlen(src), "%02x", z->dev->dev_addr[5]); + printk(KERN_INFO "TDMoE: Added new interface for %s at %s (addr=%s, src=%s, subaddr=%d)\n", span->name, z->dev->name, addr, src, ntohs(z->subaddr)); + + spin_lock_irqsave(&zlock, flags); + z->next = zdevs; + zdevs = z; + spin_unlock_irqrestore(&zlock, flags); + if(!try_module_get(THIS_MODULE)) + printk(KERN_DEBUG "TDMoE: Unable to increment module use count\n"); + } + return z; +} + +static struct dahdi_dynamic_driver ztd_eth = { + "eth", + "Ethernet", + ztdeth_create, + ztdeth_destroy, + ztdeth_transmit, + ztdeth_flush +}; + +static struct notifier_block ztdeth_nblock = { + .notifier_call = ztdeth_notifier, +}; + +static int __init ztdeth_init(void) +{ + dev_add_pack(&ztdeth_ptype); + register_netdevice_notifier(&ztdeth_nblock); + dahdi_dynamic_register(&ztd_eth); + + skb_queue_head_init(&skbs); + + return 0; +} + +static void __exit ztdeth_exit(void) +{ + dev_remove_pack(&ztdeth_ptype); + unregister_netdevice_notifier(&ztdeth_nblock); + dahdi_dynamic_unregister(&ztd_eth); +} + +MODULE_DESCRIPTION("DAHDI Dynamic TDMoE Support"); +MODULE_AUTHOR("Mark Spencer "); +MODULE_LICENSE("GPL v2"); + +module_init(ztdeth_init); +module_exit(ztdeth_exit); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_dynamic_loc.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_dynamic_loc.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_dynamic_loc.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_dynamic_loc.c 2009-03-18 13:48:41.000000000 -0500 @@ -0,0 +1,265 @@ +/* + * Dynamic Span Interface for DAHDI (Local Interface) + * + * Written by Nicolas Bougues + * + * Copyright (C) 2004, Axialys Interactive + * + * All rights reserved. + * + * Note : a DAHDI timing source must exist prior to loading this driver + * + * Address syntax : + * :[:] + * + * As of now, keys and ids are single digit only + * + * One span may have up to one "normal" peer, and one "monitor" peer + * + * Example : + * + * Say you have two spans cross connected, a third one monitoring RX on the + * first one, a fourth one monitoring RX on the second one + * + * 1:0 + * 1:1 + * 1:2:0 + * 1:3:1 + * + * Contrary to TDMoE, no frame loss can occur. + * + * See bug #2021 for more details + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef DEFINE_SPINLOCK +static DEFINE_SPINLOCK(zlock); +#else +static spinlock_t zlock = SPIN_LOCK_UNLOCKED; +#endif + +static struct ztdlocal { + unsigned short key; + unsigned short id; + struct ztdlocal *monitor_rx_peer; /* Indicates the peer span that monitors this span */ + struct ztdlocal *peer; /* Indicates the rw peer for this span */ + struct dahdi_span *span; + struct ztdlocal *next; +} *zdevs = NULL; + +static int ztdlocal_transmit(void *pvt, unsigned char *msg, int msglen) +{ + struct ztdlocal *z; + unsigned long flags; + + spin_lock_irqsave(&zlock, flags); + z = pvt; + if (z->peer && z->peer->span) { + dahdi_dynamic_receive(z->peer->span, msg, msglen); + } + if (z->monitor_rx_peer && z->monitor_rx_peer->span) { + dahdi_dynamic_receive(z->monitor_rx_peer->span, msg, msglen); + } + spin_unlock_irqrestore(&zlock, flags); + return 0; +} + +static int digit2int(char d) +{ + switch(d) { + case 'F': + case 'E': + case 'D': + case 'C': + case 'B': + case 'A': + return d - 'A' + 10; + case 'f': + case 'e': + case 'd': + case 'c': + case 'b': + case 'a': + return d - 'a' + 10; + case '9': + case '8': + case '7': + case '6': + case '5': + case '4': + case '3': + case '2': + case '1': + case '0': + return d - '0'; + } + return -1; +} + +static void ztdlocal_destroy(void *pvt) +{ + struct ztdlocal *z = pvt; + unsigned long flags; + struct ztdlocal *prev=NULL, *cur; + + spin_lock_irqsave(&zlock, flags); + cur = zdevs; + while(cur) { + if (cur->peer == z) + cur->peer = NULL; + if (cur->monitor_rx_peer == z) + cur->monitor_rx_peer = NULL; + cur = cur->next; + } + cur = zdevs; + while(cur) { + if (cur == z) { + if (prev) + prev->next = cur->next; + else + zdevs = cur->next; + break; + } + prev = cur; + cur = cur->next; + } + spin_unlock_irqrestore(&zlock, flags); + if (cur == z) { + printk(KERN_INFO "TDMoL: Removed interface for %s, key %d id %d\n", z->span->name, z->key, z->id); + module_put(THIS_MODULE); + kfree(z); + } +} + +static void *ztdlocal_create(struct dahdi_span *span, char *address) +{ + struct ztdlocal *z, *l; + unsigned long flags; + int key = -1, id = -1, monitor = -1; + + if (strlen(address) >= 3) { + if (address[1] != ':') + goto INVALID_ADDRESS; + key = digit2int(address[0]); + id = digit2int(address[2]); + } + if (strlen (address) == 5) { + if (address[3] != ':') + goto INVALID_ADDRESS; + monitor = digit2int(address[4]); + } + + if (key == -1 || id == -1) + goto INVALID_ADDRESS; + + z = kmalloc(sizeof(struct ztdlocal), GFP_KERNEL); + if (z) { + /* Zero it out */ + memset(z, 0, sizeof(struct ztdlocal)); + + z->key = key; + z->id = id; + z->span = span; + + spin_lock_irqsave(&zlock, flags); + /* Add this peer to any existing spans with same key + And add them as peers to this one */ + for (l = zdevs; l; l = l->next) + if (l->key == z->key) { + if (l->id == z->id) { + printk(KERN_DEBUG "TDMoL: Duplicate id (%d) for key %d\n", z->id, z->key); + goto CLEAR_AND_DEL_FROM_PEERS; + } + if (monitor == -1) { + if (l->peer) { + printk(KERN_DEBUG "TDMoL: Span with key %d and id %d already has a R/W peer\n", z->key, z->id); + goto CLEAR_AND_DEL_FROM_PEERS; + } else { + l->peer = z; + z->peer = l; + } + } + if (monitor == l->id) { + if (l->monitor_rx_peer) { + printk(KERN_DEBUG "TDMoL: Span with key %d and id %d already has a monitoring peer\n", z->key, z->id); + goto CLEAR_AND_DEL_FROM_PEERS; + } else { + l->monitor_rx_peer = z; + } + } + } + z->next = zdevs; + zdevs = z; + spin_unlock_irqrestore(&zlock, flags); + if(!try_module_get(THIS_MODULE)) + printk(KERN_DEBUG "TDMoL: Unable to increment module use count\n"); + + printk(KERN_INFO "TDMoL: Added new interface for %s, key %d id %d\n", span->name, z->key, z->id); + } + return z; + +CLEAR_AND_DEL_FROM_PEERS: + for (l = zdevs; l; l = l->next) { + if (l->peer == z) + l->peer = NULL; + if (l->monitor_rx_peer == z) + l->monitor_rx_peer = NULL; + } + kfree (z); + spin_unlock_irqrestore(&zlock, flags); + return NULL; + +INVALID_ADDRESS: + printk (KERN_NOTICE "TDMoL: Invalid address %s\n", address); + return NULL; +} + +static struct dahdi_dynamic_driver ztd_local = { + "loc", + "Local", + ztdlocal_create, + ztdlocal_destroy, + ztdlocal_transmit, + NULL /* flush */ +}; + +static int __init ztdlocal_init(void) +{ + dahdi_dynamic_register(&ztd_local); + return 0; +} + +static void __exit ztdlocal_exit(void) +{ + dahdi_dynamic_unregister(&ztd_local); +} + +module_init(ztdlocal_init); +module_exit(ztdlocal_exit); + +MODULE_LICENSE("GPL v2"); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_jpah.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_jpah.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_jpah.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_jpah.c 2009-04-29 13:24:04.000000000 -0500 @@ -0,0 +1,144 @@ +/* + * ECHO_CAN_JPAH + * + * by Jason Parker + * + * Based upon mg2ec.h - sort of. + * This "echo can" will completely hose your audio. + * Don't use it unless you're absolutely sure you know what you're doing. + * + * Copyright (C) 2007-2008, Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include + +#include + +static int debug; + +#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args) +#define debug_printk(level, fmt, args...) if (debug >= level) printk("%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args) + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec); +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec); +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size); +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val); + +static const struct dahdi_echocan_factory my_factory = { + .name = "JPAH", + .owner = THIS_MODULE, + .echocan_create = echo_can_create, +}; + +static const struct dahdi_echocan_ops my_ops = { + .name = "JPAH", + .echocan_free = echo_can_free, + .echocan_process = echo_can_process, + .echocan_traintap = echo_can_traintap, +}; + +struct ec_pvt { + struct dahdi_echocan_state dahdi; + int blah; +}; + +#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi) + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec) +{ + struct ec_pvt *pvt; + + if (ecp->param_count > 0) { + printk(KERN_WARNING "JPAH does not support parameters; failing request\n"); + return -EINVAL; + } + + pvt = kzalloc(sizeof(*pvt), GFP_KERNEL); + if (!pvt) + return -ENOMEM; + + pvt->dahdi.ops = &my_ops; + + *ec = &pvt->dahdi; + return 0; +} + +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + kfree(pvt); +} + +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + u32 x; + + for (x = 0; x < size; x++) { + if (pvt->blah < 2) { + pvt->blah++; + + *isig++ = 0; + } else { + pvt->blah = 0; + + isig++; + } + } +} + +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val) +{ + return 0; +} + +static int __init mod_init(void) +{ + if (dahdi_register_echocan_factory(&my_factory)) { + module_printk(KERN_ERR, "could not register with DAHDI core\n"); + + return -EPERM; + } + + module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", my_factory.name); + + return 0; +} + +static void __exit mod_exit(void) +{ + dahdi_unregister_echocan_factory(&my_factory); +} + +module_param(debug, int, S_IRUGO | S_IWUSR); + +MODULE_DESCRIPTION("DAHDI Jason Parker Audio Hoser"); +MODULE_AUTHOR("Jason Parker "); +MODULE_LICENSE("GPL v2"); + +module_init(mod_init); +module_exit(mod_exit); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_kb1.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_kb1.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_kb1.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_kb1.c 2009-04-29 13:24:04.000000000 -0500 @@ -0,0 +1,744 @@ +/* + * ECHO_CAN_KB1 + * + * by Kris Boutilier + * + * Based upon mec2.h + * + * Copyright (C) 2002, Digium, Inc. + * + * Additional background on the techniques used in this code can be found in: + * + * Messerschmitt, David; Hedberg, David; Cole, Christopher; Haoui, Amine; + * Winship, Peter; "Digital Voice Echo Canceller with a TMS32020," + * in Digital Signal Processing Applications with the TMS320 Family, + * pp. 415-437, Texas Instruments, Inc., 1986. + * + * A pdf of which is available by searching on the document title at http://www.ti.com/ + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +static int debug; +static int aggressive; + +#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args) +#define debug_printk(level, fmt, args...) if (debug >= level) printk(KERN_DEBUG "%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args) + +/* Uncomment to provide summary statistics for overall echo can performance every 4000 samples */ +/* #define MEC2_STATS 4000 */ + +/* Uncomment to generate per-sample statistics - this will severely degrade system performance and audio quality */ +/* #define MEC2_STATS_DETAILED */ + +/* Get optimized routines for math */ +#include "arith.h" + +/* + Important constants for tuning kb1 echo can + */ + +/* Convergence (aka. adaptation) speed -- higher means slower */ +#define DEFAULT_BETA1_I 2048 + +/* Constants for various power computations */ +#define DEFAULT_SIGMA_LY_I 7 +#define DEFAULT_SIGMA_LU_I 7 +#define DEFAULT_ALPHA_ST_I 5 /* near-end speech detection sensitivity factor */ +#define DEFAULT_ALPHA_YT_I 5 + +#define DEFAULT_CUTOFF_I 128 + +/* Define the near-end speech hangover counter: if near-end speech + * is declared, hcntr is set equal to hangt (see pg. 432) + */ +#define DEFAULT_HANGT 600 /* in samples, so 600 samples = 75ms */ + +/* define the residual error suppression threshold */ +#define DEFAULT_SUPPR_I 16 /* 16 = -24db */ + +/* This is the minimum reference signal power estimate level + * that will result in filter adaptation. + * If this is too low then background noise will cause the filter + * coefficients to constantly be updated. + */ +#define MIN_UPDATE_THRESH_I 4096 + +/* The number of samples used to update coefficients using the + * the block update method (M). It should be related back to the + * length of the echo can. + * ie. it only updates coefficients when (sample number MOD default_m) = 0 + * + * Getting this wrong may cause an oops. Consider yourself warned! + */ +#define DEFAULT_M 16 /* every 16th sample */ + +/* If AGGRESSIVE supression is enabled, then we start cancelling residual + * echos again even while there is potentially the very end of a near-side + * signal present. + * This defines how many samples of DEFAULT_HANGT can remain before we + * kick back in + */ +#define AGGRESSIVE_HCNTR 160 /* in samples, so 160 samples = 20ms */ + + +/***************************************************************/ +/* The following knobs are not implemented in the current code */ + +/* we need a dynamic level of suppression varying with the ratio of the + power of the echo to the power of the reference signal this is + done so that we have a smoother background. + we have a higher suppression when the power ratio is closer to + suppr_ceil and reduces logarithmically as we approach suppr_floor. + */ +#define SUPPR_FLOOR -64 +#define SUPPR_CEIL -24 + +/* in a second departure, we calculate the residual error suppression + * as a percentage of the reference signal energy level. The threshold + * is defined in terms of dB below the reference signal. + */ +#define RES_SUPR_FACTOR -20 + +#ifndef NULL +#define NULL 0 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +/* Generic circular buffer definition */ +typedef struct { + /* Pointer to the relative 'start' of the buffer */ + int idx_d; + /* The absolute size of the buffer */ + int size_d; + /* The actual sample - twice as large as we need, however we do store values at idx_d and idx_d+size_d */ + short *buf_d; +} echo_can_cb_s; + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec); +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec); +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size); +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val); +static void echocan_NLP_toggle(struct dahdi_echocan_state *ec, unsigned int enable); + +static const struct dahdi_echocan_factory my_factory = { + .name = "KB1", + .owner = THIS_MODULE, + .echocan_create = echo_can_create, +}; + +static const struct dahdi_echocan_features my_features = { + .NLP_toggle = 1, +}; + +static const struct dahdi_echocan_ops my_ops = { + .name = "KB1", + .echocan_free = echo_can_free, + .echocan_process = echo_can_process, + .echocan_traintap = echo_can_traintap, + .echocan_NLP_toggle = echocan_NLP_toggle, +}; + +struct ec_pvt { + struct dahdi_echocan_state dahdi; + /* an arbitrary ID for this echo can - this really should be settable from the calling channel... */ + int id; + + /* absolute time - aka. sample number index - essentially the number of samples since this can was init'ed */ + int i_d; + + /* Pre-computed constants */ + /* ---------------------- */ + /* Number of filter coefficents */ + int N_d; + /* Rate of adaptation of filter */ + int beta2_i; + + /* Accumulators for power computations */ + /* ----------------------------------- */ + /* reference signal power estimate - aka. Average absolute value of y(k) */ + int Ly_i; + /* ... */ + int Lu_i; + + /* Accumulators for signal detectors */ + /* --------------------------------- */ + /* Power estimate of the recent past of the near-end hybrid signal - aka. Short-time average of: 2 x |s(i)| */ + int s_tilde_i; + /* Power estimate of the recent past of the far-end receive signal - aka. Short-time average of: |y(i)| */ + int y_tilde_i; + + /* Near end speech detection counter - stores Hangover counter time remaining, in samples */ + int HCNTR_d; + + /* Circular buffers and coefficients */ + /* --------------------------------- */ + /* ... */ + int *a_i; + /* ... */ + short *a_s; + /* Reference samples of far-end receive signal */ + echo_can_cb_s y_s; + /* Reference samples of near-end signal */ + echo_can_cb_s s_s; + /* Reference samples of near-end signal minus echo estimate */ + echo_can_cb_s u_s; + /* Reference samples of far-end receive signal used to calculate short-time average */ + echo_can_cb_s y_tilde_s; + + /* Peak far-end receive signal */ + /* --------------------------- */ + /* Highest y_tilde value in the sample buffer */ + short max_y_tilde; + /* Index of the sample containing the max_y_tilde value */ + int max_y_tilde_pos; + +#ifdef MEC2_STATS + /* Storage for performance statistics */ + int cntr_nearend_speech_frames; + int cntr_residualcorrected_frames; + int cntr_residualcorrected_framesskipped; + int cntr_coeff_updates; + int cntr_coeff_missedupdates; + + int avg_Lu_i_toolow; + int avg_Lu_i_ok; +#endif + unsigned int aggressive:1; + int use_nlp; +}; + +#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi) + +static inline void init_cb_s(echo_can_cb_s *cb, int len, void *where) +{ + cb->buf_d = (short *)where; + cb->idx_d = 0; + cb->size_d = len; +} + +static inline void add_cc_s(echo_can_cb_s *cb, short newval) +{ + /* Can't use modulus because N+M isn't a power of two (generally) */ + cb->idx_d--; + if (cb->idx_d < (int)0) + /* Whoops - the pointer to the 'start' wrapped around so reset it to the top of the buffer */ + cb->idx_d += cb->size_d; + + /* Load two copies into memory */ + cb->buf_d[cb->idx_d] = newval; + cb->buf_d[cb->idx_d + cb->size_d] = newval; +} + +static inline short get_cc_s(echo_can_cb_s *cb, int pos) +{ + /* Load two copies into memory */ + return cb->buf_d[cb->idx_d + pos]; +} + +static inline void init_cc(struct ec_pvt *pvt, int N, int maxy, int maxu) +{ + void *ptr = pvt; + unsigned long tmp; + + /* Double-word align past end of state */ + ptr += sizeof(*pvt); + tmp = (unsigned long)ptr; + tmp += 3; + tmp &= ~3L; + ptr = (void *)tmp; + + /* Reset parameters */ + pvt->N_d = N; + pvt->beta2_i = DEFAULT_BETA1_I; + + /* Allocate coefficient memory */ + pvt->a_i = ptr; + ptr += (sizeof(int) * pvt->N_d); + pvt->a_s = ptr; + ptr += (sizeof(short) * pvt->N_d); + + /* Reset Y circular buffer (short version) */ + init_cb_s(&pvt->y_s, maxy, ptr); + ptr += (sizeof(short) * (maxy) * 2); + + /* Reset Sigma circular buffer (short version for FIR filter) */ + init_cb_s(&pvt->s_s, (1 << DEFAULT_ALPHA_ST_I), ptr); + ptr += (sizeof(short) * (1 << DEFAULT_ALPHA_ST_I) * 2); + + init_cb_s(&pvt->u_s, maxu, ptr); + ptr += (sizeof(short) * maxu * 2); + + /* Allocate a buffer for the reference signal power computation */ + init_cb_s(&pvt->y_tilde_s, pvt->N_d, ptr); + + /* Reset the absolute time index */ + pvt->i_d = (int)0; + + /* Reset the power computations (for y and u) */ + pvt->Ly_i = DEFAULT_CUTOFF_I; + pvt->Lu_i = DEFAULT_CUTOFF_I; + +#ifdef MEC2_STATS + /* set the identity */ + pvt->id = (int)&ptr; + + /* Reset performance stats */ + pvt->cntr_nearend_speech_frames = (int)0; + pvt->cntr_residualcorrected_frames = (int)0; + pvt->cntr_residualcorrected_framesskipped = (int)0; + pvt->cntr_coeff_updates = (int)0; + pvt->cntr_coeff_missedupdates = (int)0; + + pvt->avg_Lu_i_toolow = (int)0; + pvt->avg_Lu_i_ok = (int)0; +#endif + + /* Reset the near-end speech detector */ + pvt->s_tilde_i = (int)0; + pvt->y_tilde_i = (int)0; + pvt->HCNTR_d = (int)0; + +} + +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + kfree(pvt); +} + +static inline short sample_update(struct ec_pvt *pvt, short iref, short isig) +{ + /* Declare local variables that are used more than once */ + /* ... */ + int k; + /* ... */ + int rs; + /* ... */ + short u; + /* ... */ + int Py_i; + /* ... */ + int two_beta_i; + + /* flow A on pg. 428 */ + /* eq. (16): high-pass filter the input to generate the next value; + * push the current value into the circular buffer + * + * sdc_im1_d = sdc_d; + * sdc_d = sig; + * s_i_d = sdc_d; + * s_d = s_i_d; + * s_i_d = (float)(1.0 - gamma_d) * s_i_d + * + (float)(0.5 * (1.0 - gamma_d)) * (sdc_d - sdc_im1_d); + */ + + /* Update the Far-end receive signal circular buffers and accumulators */ + /* ------------------------------------------------------------------- */ + /* Delete the oldest sample from the power estimate accumulator */ + pvt->y_tilde_i -= abs(get_cc_s(&pvt->y_s, (1 << DEFAULT_ALPHA_YT_I) - 1)) >> DEFAULT_ALPHA_YT_I; + /* Add the new sample to the power estimate accumulator */ + pvt->y_tilde_i += abs(iref) >> DEFAULT_ALPHA_ST_I; + /* Push a copy of the new sample into its circular buffer */ + add_cc_s(&pvt->y_s, iref); + + + /* eq. (2): compute r in fixed-point */ + rs = CONVOLVE2(pvt->a_s, + pvt->y_s.buf_d + pvt->y_s.idx_d, + pvt->N_d); + rs >>= 15; + + /* eq. (3): compute the output value (see figure 3) and the error + * note: the error is the same as the output signal when near-end + * speech is not present + */ + u = isig - rs; + + /* Push a copy of the output value sample into its circular buffer */ + add_cc_s(&pvt->u_s, u); + + + /* Update the Near-end hybrid signal circular buffers and accumulators */ + /* ------------------------------------------------------------------- */ + /* Delete the oldest sample from the power estimate accumulator */ + pvt->s_tilde_i -= abs(get_cc_s(&pvt->s_s, (1 << DEFAULT_ALPHA_ST_I) - 1)); + /* Add the new sample to the power estimate accumulator */ + pvt->s_tilde_i += abs(isig); + /* Push a copy of the new sample into it's circular buffer */ + add_cc_s(&pvt->s_s, isig); + + + /* Push a copy of the current short-time average of the far-end receive signal into it's circular buffer */ + add_cc_s(&pvt->y_tilde_s, pvt->y_tilde_i); + + /* flow B on pg. 428 */ + + /* If the hangover timer isn't running then compute the new convergence factor, otherwise set Py_i to 32768 */ + if (!pvt->HCNTR_d) { + Py_i = (pvt->Ly_i >> DEFAULT_SIGMA_LY_I) * (pvt->Ly_i >> DEFAULT_SIGMA_LY_I); + Py_i >>= 15; + } else { + Py_i = (1 << 15); + } + +#if 0 + /* Vary rate of adaptation depending on position in the file + * Do not do this for the first (DEFAULT_UPDATE_TIME) secs after speech + * has begun of the file to allow the echo cancellor to estimate the + * channel accurately + * Still needs conversion! + */ + + if (pvt->start_speech_d != 0) { + if (pvt->i_d > (DEFAULT_T0 + pvt->start_speech_d)*(SAMPLE_FREQ)) { + pvt->beta2_d = max_cc_float(MIN_BETA, DEFAULT_BETA1 * exp((-1/DEFAULT_TAU)*((pvt->i_d/(float)SAMPLE_FREQ) - DEFAULT_T0 - pvt->start_speech_d))); + } + } else { + pvt->beta2_d = DEFAULT_BETA1; + } +#endif + + /* Fixed point, inverted */ + pvt->beta2_i = DEFAULT_BETA1_I; + + /* Fixed point version, inverted */ + two_beta_i = (pvt->beta2_i * Py_i) >> 15; + if (!two_beta_i) + two_beta_i++; + + /* Update the Suppressed signal power estimate accumulator */ + /* ------------------------------------------------------- */ + /* Delete the oldest sample from the power estimate accumulator */ + pvt->Lu_i -= abs(get_cc_s(&pvt->u_s, (1 << DEFAULT_SIGMA_LU_I) - 1)); + /* Add the new sample to the power estimate accumulator */ + pvt->Lu_i += abs(u); + + /* Update the Far-end reference signal power estimate accumulator */ + /* -------------------------------------------------------------- */ + /* eq. (10): update power estimate of the reference */ + /* Delete the oldest sample from the power estimate accumulator */ + pvt->Ly_i -= abs(get_cc_s(&pvt->y_s, (1 << DEFAULT_SIGMA_LY_I) - 1)) ; + /* Add the new sample to the power estimate accumulator */ + pvt->Ly_i += abs(iref); + + if (pvt->Ly_i < DEFAULT_CUTOFF_I) + pvt->Ly_i = DEFAULT_CUTOFF_I; + + + /* Update the Peak far-end receive signal detected */ + /* ----------------------------------------------- */ + if (pvt->y_tilde_i > pvt->max_y_tilde) { + /* New highest y_tilde with full life */ + pvt->max_y_tilde = pvt->y_tilde_i; + pvt->max_y_tilde_pos = pvt->N_d - 1; + } else if (--pvt->max_y_tilde_pos < 0) { + /* Time to find new max y tilde... */ + pvt->max_y_tilde = MAX16(pvt->y_tilde_s.buf_d + pvt->y_tilde_s.idx_d, pvt->N_d, &pvt->max_y_tilde_pos); + } + + /* Determine if near end speech was detected in this sample */ + /* -------------------------------------------------------- */ + if (((pvt->s_tilde_i >> (DEFAULT_ALPHA_ST_I - 1)) > pvt->max_y_tilde) + && (pvt->max_y_tilde > 0)) { + /* Then start the Hangover counter */ + pvt->HCNTR_d = DEFAULT_HANGT; +#ifdef MEC2_STATS_DETAILED + printk(KERN_INFO "Reset near end speech timer with: s_tilde_i %d, stmnt %d, max_y_tilde %d\n", pvt->s_tilde_i, (pvt->s_tilde_i >> (DEFAULT_ALPHA_ST_I - 1)), pvt->max_y_tilde); +#endif +#ifdef MEC2_STATS + ++pvt->cntr_nearend_speech_frames; +#endif + } else if (pvt->HCNTR_d > (int)0) { + /* otherwise, if it's still non-zero, decrement the Hangover counter by one sample */ +#ifdef MEC2_STATS + ++pvt->cntr_nearend_speech_frames; +#endif + pvt->HCNTR_d--; + } + + /* Update coefficients if no near-end speech in this sample (ie. HCNTR_d = 0) + * and we have enough signal to bother trying to update. + * -------------------------------------------------------------------------- + */ + if (!pvt->HCNTR_d && /* no near-end speech present */ + !(pvt->i_d % DEFAULT_M)) { /* we only update on every DEFAULM_M'th sample from the stream */ + if (pvt->Lu_i > MIN_UPDATE_THRESH_I) { /* there is sufficient energy above the noise floor to contain meaningful data */ + /* so loop over all the filter coefficients */ +#ifdef MEC2_STATS_DETAILED + printk(KERN_INFO "updating coefficients with: pvt->Lu_i %9d\n", pvt->Lu_i); +#endif +#ifdef MEC2_STATS + pvt->avg_Lu_i_ok = pvt->avg_Lu_i_ok + pvt->Lu_i; + ++pvt->cntr_coeff_updates; +#endif + for (k = 0; k < pvt->N_d; k++) { + /* eq. (7): compute an expectation over M_d samples */ + int grad2; + grad2 = CONVOLVE2(pvt->u_s.buf_d + pvt->u_s.idx_d, + pvt->y_s.buf_d + pvt->y_s.idx_d + k, + DEFAULT_M); + /* eq. (7): update the coefficient */ + pvt->a_i[k] += grad2 / two_beta_i; + pvt->a_s[k] = pvt->a_i[k] >> 16; + } + } else { +#ifdef MEC2_STATS_DETAILED + printk(KERN_INFO "insufficient signal to update coefficients pvt->Lu_i %5d < %5d\n", pvt->Lu_i, MIN_UPDATE_THRESH_I); +#endif +#ifdef MEC2_STATS + pvt->avg_Lu_i_toolow = pvt->avg_Lu_i_toolow + pvt->Lu_i; + ++pvt->cntr_coeff_missedupdates; +#endif + } + } + + /* paragraph below eq. (15): if no near-end speech in the sample and + * the reference signal power estimate > cutoff threshold + * then perform residual error suppression + */ +#ifdef MEC2_STATS_DETAILED + if (pvt->HCNTR_d == 0) + printk(KERN_INFO "possibly correcting frame with pvt->Ly_i %9d pvt->Lu_i %9d and expression %d\n", pvt->Ly_i, pvt->Lu_i, (pvt->Ly_i/(pvt->Lu_i + 1))); +#endif + +#ifndef NO_ECHO_SUPPRESSOR + if (pvt->use_nlp) { + if (pvt->aggressive) { + if ((pvt->HCNTR_d < AGGRESSIVE_HCNTR) && (pvt->Ly_i > (pvt->Lu_i << 1))) { + for (k = 0; k < 2; k++) { + u = u * (pvt->Lu_i >> DEFAULT_SIGMA_LU_I) / ((pvt->Ly_i >> (DEFAULT_SIGMA_LY_I)) + 1); + } +#ifdef MEC2_STATS_DETAILED + printk(KERN_INFO "aggresively correcting frame with pvt->Ly_i %9d pvt->Lu_i %9d expression %d\n", pvt->Ly_i, pvt->Lu_i, (pvt->Ly_i/(pvt->Lu_i + 1))); +#endif +#ifdef MEC2_STATS + ++pvt->cntr_residualcorrected_frames; +#endif + } + } else { + if (pvt->HCNTR_d == 0) { + if ((pvt->Ly_i/(pvt->Lu_i + 1)) > DEFAULT_SUPPR_I) { + for (k = 0; k < 1; k++) { + u = u * (pvt->Lu_i >> DEFAULT_SIGMA_LU_I) / ((pvt->Ly_i >> (DEFAULT_SIGMA_LY_I + 2)) + 1); + } +#ifdef MEC2_STATS_DETAILED + printk(KERN_INFO "correcting frame with pvt->Ly_i %9d pvt->Lu_i %9d expression %d\n", pvt->Ly_i, pvt->Lu_i, (pvt->Ly_i/(pvt->Lu_i + 1))); +#endif +#ifdef MEC2_STATS + ++pvt->cntr_residualcorrected_frames; +#endif + } +#ifdef MEC2_STATS + else { + ++pvt->cntr_residualcorrected_framesskipped; + } +#endif + } + } + } +#endif + +#if 0 + /* This will generate a non-linear supression factor, once converted */ + if ((pvt->HCNTR_d == 0) && + ((pvt->Lu_d/pvt->Ly_d) < DEFAULT_SUPPR) && + (pvt->Lu_d/pvt->Ly_d > EC_MIN_DB_VALUE)) { + suppr_factor = (10 / (float)(SUPPR_FLOOR - SUPPR_CEIL)) * log(pvt->Lu_d/pvt->Ly_d) + - SUPPR_CEIL / (float)(SUPPR_FLOOR - SUPPR_CEIL); + u_suppr = pow(10.0, (suppr_factor) * RES_SUPR_FACTOR / 10.0) * u_suppr; + } +#endif + +#ifdef MEC2_STATS + /* Periodically dump performance stats */ + if ((pvt->i_d % MEC2_STATS) == 0) { + /* make sure to avoid div0's! */ + if (pvt->cntr_coeff_missedupdates > 0) + pvt->avg_Lu_i_toolow = (int)(pvt->avg_Lu_i_toolow / pvt->cntr_coeff_missedupdates); + else + pvt->avg_Lu_i_toolow = -1; + + if (pvt->cntr_coeff_updates > 0) + pvt->avg_Lu_i_ok = (pvt->avg_Lu_i_ok / pvt->cntr_coeff_updates); + else + pvt->avg_Lu_i_ok = -1; + + printk( KERN_INFO "%d: Near end speech: %5d Residuals corrected/skipped: %5d/%5d Coefficients updated ok/low sig: %3d/%3d Lu_i avg ok/low sig %6d/%5d\n", + pvt->id, + pvt->cntr_nearend_speech_frames, + pvt->cntr_residualcorrected_frames, pvt->cntr_residualcorrected_framesskipped, + pvt->cntr_coeff_updates, pvt->cntr_coeff_missedupdates, + pvt->avg_Lu_i_ok, pvt->avg_Lu_i_toolow); + + pvt->cntr_nearend_speech_frames = 0; + pvt->cntr_residualcorrected_frames = 0; + pvt->cntr_residualcorrected_framesskipped = 0; + pvt->cntr_coeff_updates = 0; + pvt->cntr_coeff_missedupdates = 0; + pvt->avg_Lu_i_ok = 0; + pvt->avg_Lu_i_toolow = 0; + } +#endif + + /* Increment the sample index and return the corrected sample */ + pvt->i_d++; + return u; +} + +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + u32 x; + short result; + + for (x = 0; x < size; x++) { + result = sample_update(pvt, *iref, *isig); + *isig++ = result; + ++iref; + } +} + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec) +{ + int maxy; + int maxu; + size_t size; + unsigned int x; + char *c; + struct ec_pvt *pvt; + + maxy = ecp->tap_length + DEFAULT_M; + maxu = DEFAULT_M; + if (maxy < (1 << DEFAULT_ALPHA_YT_I)) + maxy = (1 << DEFAULT_ALPHA_YT_I); + if (maxy < (1 << DEFAULT_SIGMA_LY_I)) + maxy = (1 << DEFAULT_SIGMA_LY_I); + if (maxu < (1 << DEFAULT_SIGMA_LU_I)) + maxu = (1 << DEFAULT_SIGMA_LU_I); + + size = sizeof(*ec) + + 4 + /* align */ + sizeof(int) * ecp->tap_length + /* a_i */ + sizeof(short) * ecp->tap_length + /* a_s */ + 2 * sizeof(short) * (maxy) + /* y_s */ + 2 * sizeof(short) * (1 << DEFAULT_ALPHA_ST_I) + /* s_s */ + 2 * sizeof(short) * (maxu) + /* u_s */ + 2 * sizeof(short) * ecp->tap_length; /* y_tilde_s */ + + pvt = kzalloc(size, GFP_KERNEL); + if (!pvt) + return -ENOMEM; + + pvt->dahdi.ops = &my_ops; + + pvt->aggressive = aggressive; + pvt->dahdi.features = my_features; + + for (x = 0; x < ecp->param_count; x++) { + for (c = p[x].name; *c; c++) + *c = tolower(*c); + if (!strcmp(p[x].name, "aggressive")) { + pvt->aggressive = p[x].value ? 1 : 0; + } else { + printk(KERN_WARNING "Unknown parameter supplied to KB1 echo canceler: '%s'\n", p[x].name); + kfree(pvt); + + return -EINVAL; + } + } + + init_cc(pvt, ecp->tap_length, maxy, maxu); + /* Non-linear processor - a fancy way to say "zap small signals, to avoid + accumulating noise". */ + pvt->use_nlp = TRUE; + + *ec = &pvt->dahdi; + return 0; +} + +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + /* Set the hangover counter to the length of the can to + * avoid adjustments occuring immediately after initial forced training + */ + pvt->HCNTR_d = pvt->N_d << 1; + + if (pos >= pvt->N_d) + return 1; + + pvt->a_i[pos] = val << 17; + pvt->a_s[pos] = val << 1; + + if (++pos >= pvt->N_d) + return 1; + + return 0; +} + +static void echocan_NLP_toggle(struct dahdi_echocan_state *ec, unsigned int enable) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + pvt->use_nlp = enable ? 1 : 0; +} + +static int __init mod_init(void) +{ + if (dahdi_register_echocan_factory(&my_factory)) { + module_printk(KERN_ERR, "could not register with DAHDI core\n"); + + return -EPERM; + } + + module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", my_factory.name); + + return 0; +} + +static void __exit mod_exit(void) +{ + dahdi_unregister_echocan_factory(&my_factory); +} + +module_param(debug, int, S_IRUGO | S_IWUSR); +module_param(aggressive, int, S_IRUGO | S_IWUSR); + +MODULE_DESCRIPTION("DAHDI 'KB1' Echo Canceler"); +MODULE_AUTHOR("Kris Boutilier"); +MODULE_LICENSE("GPL v2"); + +module_init(mod_init); +module_exit(mod_exit); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_mg2.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_mg2.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_mg2.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_mg2.c 2009-04-29 13:24:04.000000000 -0500 @@ -0,0 +1,891 @@ +/* + * ECHO_CAN_MG2 + * + * by Michael Gernoth + * + * Based upon kb1ec.h and mec2.h + * + * Copyright (C) 2002, Digium, Inc. + * + * Additional background on the techniques used in this code can be found in: + * + * Messerschmitt, David; Hedberg, David; Cole, Christopher; Haoui, Amine; + * Winship, Peter; "Digital Voice Echo Canceller with a TMS32020," + * in Digital Signal Processing Applications with the TMS320 Family, + * pp. 415-437, Texas Instruments, Inc., 1986. + * + * A pdf of which is available by searching on the document title at http://www.ti.com/ + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +static int debug; +static int aggressive; + +#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args) +#define debug_printk(level, fmt, args...) if (debug >= level) printk("%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args) + +#define ABS(a) abs(a!=-32768?a:-32767) + +#define RESTORE_COEFFS {\ + int x;\ + memcpy(pvt->a_i, pvt->c_i, pvt->N_d*sizeof(int));\ + for (x = 0; x < pvt->N_d; x++) {\ + pvt->a_s[x] = pvt->a_i[x] >> 16;\ + }\ + pvt->backup = BACKUP;\ + } + +/* Uncomment to provide summary statistics for overall echo can performance every 4000 samples */ +/* #define MEC2_STATS 4000 */ + +/* Uncomment to generate per-sample statistics - this will severely degrade system performance and audio quality */ +/* #define MEC2_STATS_DETAILED */ + +/* Uncomment to generate per-call DC bias offset messages */ +/* #define MEC2_DCBIAS_MESSAGE */ + +/* Get optimized routines for math */ +#include "arith.h" + +/* + Important constants for tuning mg2 echo can + */ + +/* Convergence (aka. adaptation) speed -- higher means slower */ +#define DEFAULT_BETA1_I 2048 + +/* Constants for various power computations */ +#define DEFAULT_SIGMA_LY_I 7 +#define DEFAULT_SIGMA_LU_I 7 +#define DEFAULT_ALPHA_ST_I 5 /* near-end speech detection sensitivity factor */ +#define DEFAULT_ALPHA_YT_I 5 + +#define DEFAULT_CUTOFF_I 128 + +/* Define the near-end speech hangover counter: if near-end speech + * is declared, hcntr is set equal to hangt (see pg. 432) + */ +#define DEFAULT_HANGT 600 /* in samples, so 600 samples = 75ms */ + +/* define the residual error suppression threshold */ +#define DEFAULT_SUPPR_I 16 /* 16 = -24db */ + +/* This is the minimum reference signal power estimate level + * that will result in filter adaptation. + * If this is too low then background noise will cause the filter + * coefficients to constantly be updated. + */ +#define MIN_UPDATE_THRESH_I 2048 + +/* The number of samples used to update coefficients using the + * the block update method (M). It should be related back to the + * length of the echo can. + * ie. it only updates coefficients when (sample number MOD default_m) = 0 + * + * Getting this wrong may cause an oops. Consider yourself warned! + */ +#define DEFAULT_M 16 /* every 16th sample */ + +/* If AGGRESSIVE supression is enabled, then we start cancelling residual + * echos again even while there is potentially the very end of a near-side + * signal present. + * This defines how many samples of DEFAULT_HANGT can remain before we + * kick back in + */ +#define AGGRESSIVE_HCNTR 160 /* in samples, so 160 samples = 20ms */ + +/* Treat sample as error if it has a different sign as the + * input signal and is this number larger in ABS() as + * the input-signal */ +#define MAX_SIGN_ERROR 3000 + +/* Number of coefficients really used for calculating the + * simulated echo. The value specifies how many of the + * biggest coefficients are used for calculating rs. + * This helps on long echo-tails by artificially limiting + * the number of coefficients for the calculation and + * preventing overflows. + * Comment this to deactivate the code */ +#define USED_COEFFS 64 + +/* Backup coefficients every this number of samples */ +#define BACKUP 256 + +/***************************************************************/ +/* The following knobs are not implemented in the current code */ + +/* we need a dynamic level of suppression varying with the ratio of the + power of the echo to the power of the reference signal this is + done so that we have a smoother background. + we have a higher suppression when the power ratio is closer to + suppr_ceil and reduces logarithmically as we approach suppr_floor. + */ +#define SUPPR_FLOOR -64 +#define SUPPR_CEIL -24 + +/* in a second departure, we calculate the residual error suppression + * as a percentage of the reference signal energy level. The threshold + * is defined in terms of dB below the reference signal. + */ +#define RES_SUPR_FACTOR -20 + +#define DC_NORMALIZE + +#ifndef NULL +#define NULL 0 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +/* Generic circular buffer definition */ +typedef struct { + /* Pointer to the relative 'start' of the buffer */ + int idx_d; + /* The absolute size of the buffer */ + int size_d; + /* The actual sample - twice as large as we need, however we do store values at idx_d and idx_d+size_d */ + short *buf_d; +} echo_can_cb_s; + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec); +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec); +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size); +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val); +static void echocan_NLP_toggle(struct dahdi_echocan_state *ec, unsigned int enable); + +static const struct dahdi_echocan_factory my_factory = { + .name = "MG2", + .owner = THIS_MODULE, + .echocan_create = echo_can_create, +}; + +static const struct dahdi_echocan_features my_features = { + .NLP_toggle = 1, +}; + +static const struct dahdi_echocan_ops my_ops = { + .name = "MG2", + .echocan_free = echo_can_free, + .echocan_process = echo_can_process, + .echocan_traintap = echo_can_traintap, + .echocan_NLP_toggle = echocan_NLP_toggle, +}; + +struct ec_pvt { + struct dahdi_echocan_state dahdi; + /* an arbitrary ID for this echo can - this really should be settable from the calling channel... */ + int id; + + /* absolute time - aka. sample number index - essentially the number of samples since this can was init'ed */ + int i_d; + + /* Pre-computed constants */ + /* ---------------------- */ + /* Number of filter coefficents */ + int N_d; + /* Rate of adaptation of filter */ + int beta2_i; + + /* Accumulators for power computations */ + /* ----------------------------------- */ + /* reference signal power estimate - aka. Average absolute value of y(k) */ + int Ly_i; + /* ... */ + int Lu_i; + + /* Accumulators for signal detectors */ + /* --------------------------------- */ + /* Power estimate of the recent past of the near-end hybrid signal - aka. Short-time average of: 2 x |s(i)| */ + int s_tilde_i; + /* Power estimate of the recent past of the far-end receive signal - aka. Short-time average of: |y(i)| */ + int y_tilde_i; + + /* Near end speech detection counter - stores Hangover counter time remaining, in samples */ + int HCNTR_d; + + /* Circular buffers and coefficients */ + /* --------------------------------- */ + /* ... */ + int *a_i; + /* ... */ + short *a_s; + /* Backups */ + int *b_i; + int *c_i; + /* Reference samples of far-end receive signal */ + echo_can_cb_s y_s; + /* Reference samples of near-end signal */ + echo_can_cb_s s_s; + /* Reference samples of near-end signal minus echo estimate */ + echo_can_cb_s u_s; + /* Reference samples of far-end receive signal used to calculate short-time average */ + echo_can_cb_s y_tilde_s; + + /* Peak far-end receive signal */ + /* --------------------------- */ + /* Highest y_tilde value in the sample buffer */ + short max_y_tilde; + /* Index of the sample containing the max_y_tilde value */ + int max_y_tilde_pos; + +#ifdef MEC2_STATS + /* Storage for performance statistics */ + int cntr_nearend_speech_frames; + int cntr_residualcorrected_frames; + int cntr_residualcorrected_framesskipped; + int cntr_coeff_updates; + int cntr_coeff_missedupdates; + + int avg_Lu_i_toolow; + int avg_Lu_i_ok; +#endif + unsigned int aggressive:1; + short lastsig; + int lastcount; + int backup; +#ifdef DC_NORMALIZE + int dc_estimate; +#endif + int use_nlp; +}; + +#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi) + +static inline void init_cb_s(echo_can_cb_s *cb, int len, void *where) +{ + cb->buf_d = (short *)where; + cb->idx_d = 0; + cb->size_d = len; +} + +static inline void add_cc_s(echo_can_cb_s *cb, short newval) +{ + /* Can't use modulus because N+M isn't a power of two (generally) */ + cb->idx_d--; + if (cb->idx_d < (int)0) + /* Whoops - the pointer to the 'start' wrapped around so reset it to the top of the buffer */ + cb->idx_d += cb->size_d; + + /* Load two copies into memory */ + cb->buf_d[cb->idx_d] = newval; + cb->buf_d[cb->idx_d + cb->size_d] = newval; +} + +static inline short get_cc_s(echo_can_cb_s *cb, int pos) +{ + /* Load two copies into memory */ + return cb->buf_d[cb->idx_d + pos]; +} + +static inline void init_cc(struct ec_pvt *pvt, int N, int maxy, int maxu) +{ + void *ptr = pvt; + unsigned long tmp; + + /* Double-word align past end of state */ + ptr += sizeof(*pvt); + tmp = (unsigned long)ptr; + tmp += 3; + tmp &= ~3L; + ptr = (void *)tmp; + + /* Reset parameters */ + pvt->N_d = N; + pvt->beta2_i = DEFAULT_BETA1_I; + + /* Allocate coefficient memory */ + pvt->a_i = ptr; + ptr += (sizeof(int) * pvt->N_d); + pvt->a_s = ptr; + ptr += (sizeof(short) * pvt->N_d); + + /* Allocate backup memory */ + pvt->b_i = ptr; + ptr += (sizeof(int) * pvt->N_d); + pvt->c_i = ptr; + ptr += (sizeof(int) * pvt->N_d); + + /* Reset Y circular buffer (short version) */ + init_cb_s(&pvt->y_s, maxy, ptr); + ptr += (sizeof(short) * (maxy) * 2); + + /* Reset Sigma circular buffer (short version for FIR filter) */ + init_cb_s(&pvt->s_s, (1 << DEFAULT_ALPHA_ST_I), ptr); + ptr += (sizeof(short) * (1 << DEFAULT_ALPHA_ST_I) * 2); + + init_cb_s(&pvt->u_s, maxu, ptr); + ptr += (sizeof(short) * maxu * 2); + + /* Allocate a buffer for the reference signal power computation */ + init_cb_s(&pvt->y_tilde_s, pvt->N_d, ptr); + + /* Reset the absolute time index */ + pvt->i_d = (int)0; + + /* Reset the power computations (for y and u) */ + pvt->Ly_i = DEFAULT_CUTOFF_I; + pvt->Lu_i = DEFAULT_CUTOFF_I; + +#ifdef MEC2_STATS + /* set the identity */ + pvt->id = (int)&ptr; + + /* Reset performance stats */ + pvt->cntr_nearend_speech_frames = (int)0; + pvt->cntr_residualcorrected_frames = (int)0; + pvt->cntr_residualcorrected_framesskipped = (int)0; + pvt->cntr_coeff_updates = (int)0; + pvt->cntr_coeff_missedupdates = (int)0; + + pvt->avg_Lu_i_toolow = (int)0; + pvt->avg_Lu_i_ok = (int)0; +#endif + + /* Reset the near-end speech detector */ + pvt->s_tilde_i = (int)0; + pvt->y_tilde_i = (int)0; + pvt->HCNTR_d = (int)0; + +} + +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + +#if defined(DC_NORMALIZE) && defined(MEC2_DCBIAS_MESSAGE) + printk(KERN_INFO "EC: DC bias calculated: %d V\n", pvt->dc_estimate >> 15); +#endif + kfree(pvt); +} + +#ifdef DC_NORMALIZE +short inline dc_removal(int *dc_estimate, short samp) +{ + *dc_estimate += ((((int)samp << 15) - *dc_estimate) >> 9); + return samp - (*dc_estimate >> 15); +} +#endif + +static inline short sample_update(struct ec_pvt *pvt, short iref, short isig) +{ + /* Declare local variables that are used more than once */ + /* ... */ + int k; + /* ... */ + int rs; + /* ... */ + short u; + /* ... */ + int Py_i; + /* ... */ + int two_beta_i; + +#ifdef DC_NORMALIZE + isig = dc_removal(&pvt->dc_estimate, isig); +#endif + + /* flow A on pg. 428 */ + /* eq. (16): high-pass filter the input to generate the next value; + * push the current value into the circular buffer + * + * sdc_im1_d = sdc_d; + * sdc_d = sig; + * s_i_d = sdc_d; + * s_d = s_i_d; + * s_i_d = (float)(1.0 - gamma_d) * s_i_d + * + (float)(0.5 * (1.0 - gamma_d)) * (sdc_d - sdc_im1_d); + */ + + /* Update the Far-end receive signal circular buffers and accumulators */ + /* ------------------------------------------------------------------- */ + /* Delete the oldest sample from the power estimate accumulator */ + pvt->y_tilde_i -= abs(get_cc_s(&pvt->y_s, (1 << DEFAULT_ALPHA_YT_I) - 1)) >> DEFAULT_ALPHA_YT_I; + /* Add the new sample to the power estimate accumulator */ + pvt->y_tilde_i += abs(iref) >> DEFAULT_ALPHA_ST_I; + /* Push a copy of the new sample into its circular buffer */ + add_cc_s(&pvt->y_s, iref); + + + /* eq. (2): compute r in fixed-point */ + rs = CONVOLVE2(pvt->a_s, + pvt->y_s.buf_d + pvt->y_s.idx_d, + pvt->N_d); + rs >>= 15; + + if (pvt->lastsig == isig) { + pvt->lastcount++; + } else { + pvt->lastcount = 0; + pvt->lastsig = isig; + } + + if (isig == 0) { + u = 0; + } else if (pvt->lastcount > 255) { + /* We have seen the same input-signal more than 255 times, + * we should pass it through uncancelled, as we are likely on hold */ + u = isig; + } else { + int sign_error; + + if (rs < -32768) { + rs = -32768; + pvt->HCNTR_d = DEFAULT_HANGT; + RESTORE_COEFFS; + } else if (rs > 32767) { + rs = 32767; + pvt->HCNTR_d = DEFAULT_HANGT; + RESTORE_COEFFS; + } + + sign_error = ABS(rs) - ABS(isig); + + if (ABS(sign_error) > MAX_SIGN_ERROR) + { + rs = 0; + RESTORE_COEFFS; + } + + /* eq. (3): compute the output value (see figure 3) and the error + * note: the error is the same as the output signal when near-end + * speech is not present + */ + u = isig - rs; + + if (u / isig < 0) + u = isig - (rs >> 1); + } + + /* Push a copy of the output value sample into its circular buffer */ + add_cc_s(&pvt->u_s, u); + + if (!pvt->backup) { + /* Backup coefficients periodically */ + pvt->backup = BACKUP; + memcpy(pvt->c_i, pvt->b_i, pvt->N_d*sizeof(int)); + memcpy(pvt->b_i, pvt->a_i, pvt->N_d*sizeof(int)); + } else + pvt->backup--; + + + /* Update the Near-end hybrid signal circular buffers and accumulators */ + /* ------------------------------------------------------------------- */ + /* Delete the oldest sample from the power estimate accumulator */ + pvt->s_tilde_i -= abs(get_cc_s(&pvt->s_s, (1 << DEFAULT_ALPHA_ST_I) - 1)); + /* Add the new sample to the power estimate accumulator */ + pvt->s_tilde_i += abs(isig); + /* Push a copy of the new sample into it's circular buffer */ + add_cc_s(&pvt->s_s, isig); + + + /* Push a copy of the current short-time average of the far-end receive signal into it's circular buffer */ + add_cc_s(&pvt->y_tilde_s, pvt->y_tilde_i); + + /* flow B on pg. 428 */ + + /* If the hangover timer isn't running then compute the new convergence factor, otherwise set Py_i to 32768 */ + if (!pvt->HCNTR_d) { + Py_i = (pvt->Ly_i >> DEFAULT_SIGMA_LY_I) * (pvt->Ly_i >> DEFAULT_SIGMA_LY_I); + Py_i >>= 15; + } else { + Py_i = (1 << 15); + } + +#if 0 + /* Vary rate of adaptation depending on position in the file + * Do not do this for the first (DEFAULT_UPDATE_TIME) secs after speech + * has begun of the file to allow the echo cancellor to estimate the + * channel accurately + * Still needs conversion! + */ + + if (pvt->start_speech_d != 0) { + if (pvt->i_d > (DEFAULT_T0 + pvt->start_speech_d)*(SAMPLE_FREQ)) { + pvt->beta2_d = max_cc_float(MIN_BETA, DEFAULT_BETA1 * exp((-1/DEFAULT_TAU)*((pvt->i_d/(float)SAMPLE_FREQ) - DEFAULT_T0 - pvt->start_speech_d))); + } + } else { + pvt->beta2_d = DEFAULT_BETA1; + } +#endif + + /* Fixed point, inverted */ + pvt->beta2_i = DEFAULT_BETA1_I; + + /* Fixed point version, inverted */ + two_beta_i = (pvt->beta2_i * Py_i) >> 15; + if (!two_beta_i) + two_beta_i++; + + /* Update the Suppressed signal power estimate accumulator */ + /* ------------------------------------------------------- */ + /* Delete the oldest sample from the power estimate accumulator */ + pvt->Lu_i -= abs(get_cc_s(&pvt->u_s, (1 << DEFAULT_SIGMA_LU_I) - 1)); + /* Add the new sample to the power estimate accumulator */ + pvt->Lu_i += abs(u); + + /* Update the Far-end reference signal power estimate accumulator */ + /* -------------------------------------------------------------- */ + /* eq. (10): update power estimate of the reference */ + /* Delete the oldest sample from the power estimate accumulator */ + pvt->Ly_i -= abs(get_cc_s(&pvt->y_s, (1 << DEFAULT_SIGMA_LY_I) - 1)) ; + /* Add the new sample to the power estimate accumulator */ + pvt->Ly_i += abs(iref); + + if (pvt->Ly_i < DEFAULT_CUTOFF_I) + pvt->Ly_i = DEFAULT_CUTOFF_I; + + + /* Update the Peak far-end receive signal detected */ + /* ----------------------------------------------- */ + if (pvt->y_tilde_i > pvt->max_y_tilde) { + /* New highest y_tilde with full life */ + pvt->max_y_tilde = pvt->y_tilde_i; + pvt->max_y_tilde_pos = pvt->N_d - 1; + } else if (--pvt->max_y_tilde_pos < 0) { + /* Time to find new max y tilde... */ + pvt->max_y_tilde = MAX16(pvt->y_tilde_s.buf_d + pvt->y_tilde_s.idx_d, pvt->N_d, &pvt->max_y_tilde_pos); + } + + /* Determine if near end speech was detected in this sample */ + /* -------------------------------------------------------- */ + if (((pvt->s_tilde_i >> (DEFAULT_ALPHA_ST_I - 1)) > pvt->max_y_tilde) + && (pvt->max_y_tilde > 0)) { + /* Then start the Hangover counter */ + pvt->HCNTR_d = DEFAULT_HANGT; + RESTORE_COEFFS; +#ifdef MEC2_STATS_DETAILED + printk(KERN_INFO "Reset near end speech timer with: s_tilde_i %d, stmnt %d, max_y_tilde %d\n", pvt->s_tilde_i, (pvt->s_tilde_i >> (DEFAULT_ALPHA_ST_I - 1)), pvt->max_y_tilde); +#endif +#ifdef MEC2_STATS + ++pvt->cntr_nearend_speech_frames; +#endif + } else if (pvt->HCNTR_d > (int)0) { + /* otherwise, if it's still non-zero, decrement the Hangover counter by one sample */ +#ifdef MEC2_STATS + ++pvt->cntr_nearend_speech_frames; +#endif + pvt->HCNTR_d--; + } + + /* Update coefficients if no near-end speech in this sample (ie. HCNTR_d = 0) + * and we have enough signal to bother trying to update. + * -------------------------------------------------------------------------- + */ + if (!pvt->HCNTR_d && /* no near-end speech present */ + !(pvt->i_d % DEFAULT_M)) { /* we only update on every DEFAULM_M'th sample from the stream */ + if (pvt->Lu_i > MIN_UPDATE_THRESH_I) { /* there is sufficient energy above the noise floor to contain meaningful data */ + /* so loop over all the filter coefficients */ +#ifdef USED_COEFFS + int max_coeffs[USED_COEFFS]; + int *pos; + + if (pvt->N_d > USED_COEFFS) + memset(max_coeffs, 0, USED_COEFFS*sizeof(int)); +#endif +#ifdef MEC2_STATS_DETAILED + printk(KERN_INFO "updating coefficients with: pvt->Lu_i %9d\n", pvt->Lu_i); +#endif +#ifdef MEC2_STATS + pvt->avg_Lu_i_ok = pvt->avg_Lu_i_ok + pvt->Lu_i; + ++pvt->cntr_coeff_updates; +#endif + for (k = 0; k < pvt->N_d; k++) { + /* eq. (7): compute an expectation over M_d samples */ + int grad2; + grad2 = CONVOLVE2(pvt->u_s.buf_d + pvt->u_s.idx_d, + pvt->y_s.buf_d + pvt->y_s.idx_d + k, + DEFAULT_M); + /* eq. (7): update the coefficient */ + pvt->a_i[k] += grad2 / two_beta_i; + pvt->a_s[k] = pvt->a_i[k] >> 16; + +#ifdef USED_COEFFS + if (pvt->N_d > USED_COEFFS) { + if (abs(pvt->a_i[k]) > max_coeffs[USED_COEFFS-1]) { + /* More or less insertion-sort... */ + pos = max_coeffs; + while (*pos > abs(pvt->a_i[k])) + pos++; + + if (*pos > max_coeffs[USED_COEFFS-1]) + memmove(pos+1, pos, (USED_COEFFS-(pos-max_coeffs)-1)*sizeof(int)); + + *pos = abs(pvt->a_i[k]); + } + } +#endif + } + +#ifdef USED_COEFFS + /* Filter out irrelevant coefficients */ + if (pvt->N_d > USED_COEFFS) + for (k = 0; k < pvt->N_d; k++) + if (abs(pvt->a_i[k]) < max_coeffs[USED_COEFFS-1]) + pvt->a_i[k] = pvt->a_s[k] = 0; +#endif + } else { +#ifdef MEC2_STATS_DETAILED + printk(KERN_INFO "insufficient signal to update coefficients pvt->Lu_i %5d < %5d\n", pvt->Lu_i, MIN_UPDATE_THRESH_I); +#endif +#ifdef MEC2_STATS + pvt->avg_Lu_i_toolow = pvt->avg_Lu_i_toolow + pvt->Lu_i; + ++pvt->cntr_coeff_missedupdates; +#endif + } + } + + /* paragraph below eq. (15): if no near-end speech in the sample and + * the reference signal power estimate > cutoff threshold + * then perform residual error suppression + */ +#ifdef MEC2_STATS_DETAILED + if (pvt->HCNTR_d == 0) + printk(KERN_INFO "possibly correcting frame with pvt->Ly_i %9d pvt->Lu_i %9d and expression %d\n", pvt->Ly_i, pvt->Lu_i, (pvt->Ly_i/(pvt->Lu_i + 1))); +#endif + +#ifndef NO_ECHO_SUPPRESSOR + if (pvt->use_nlp) { + if (pvt->aggressive) { + if ((pvt->HCNTR_d < AGGRESSIVE_HCNTR) && (pvt->Ly_i > (pvt->Lu_i << 1))) { + for (k = 0; k < 2; k++) { + u = u * (pvt->Lu_i >> DEFAULT_SIGMA_LU_I) / ((pvt->Ly_i >> (DEFAULT_SIGMA_LY_I)) + 1); + } +#ifdef MEC2_STATS_DETAILED + printk(KERN_INFO "aggresively correcting frame with pvt->Ly_i %9d pvt->Lu_i %9d expression %d\n", pvt->Ly_i, pvt->Lu_i, (pvt->Ly_i/(pvt->Lu_i + 1))); +#endif +#ifdef MEC2_STATS + ++pvt->cntr_residualcorrected_frames; +#endif + } + } else { + if (pvt->HCNTR_d == 0) { + if ((pvt->Ly_i/(pvt->Lu_i + 1)) > DEFAULT_SUPPR_I) { + for (k = 0; k < 1; k++) { + u = u * (pvt->Lu_i >> DEFAULT_SIGMA_LU_I) / ((pvt->Ly_i >> (DEFAULT_SIGMA_LY_I + 2)) + 1); + } +#ifdef MEC2_STATS_DETAILED + printk(KERN_INFO "correcting frame with pvt->Ly_i %9d pvt->Lu_i %9d expression %d\n", pvt->Ly_i, pvt->Lu_i, (pvt->Ly_i/(pvt->Lu_i + 1))); +#endif +#ifdef MEC2_STATS + ++pvt->cntr_residualcorrected_frames; +#endif + } +#ifdef MEC2_STATS + else { + ++pvt->cntr_residualcorrected_framesskipped; + } +#endif + } + } + } +#endif + +#if 0 + /* This will generate a non-linear supression factor, once converted */ + if ((pvt->HCNTR_d == 0) && + ((pvt->Lu_d/pvt->Ly_d) < DEFAULT_SUPPR) && + (pvt->Lu_d/pvt->Ly_d > EC_MIN_DB_VALUE)) { + suppr_factor = (10 / (float)(SUPPR_FLOOR - SUPPR_CEIL)) * log(pvt->Lu_d/pvt->Ly_d) + - SUPPR_CEIL / (float)(SUPPR_FLOOR - SUPPR_CEIL); + u_suppr = pow(10.0, (suppr_factor) * RES_SUPR_FACTOR / 10.0) * u_suppr; + } +#endif + +#ifdef MEC2_STATS + /* Periodically dump performance stats */ + if ((pvt->i_d % MEC2_STATS) == 0) { + /* make sure to avoid div0's! */ + if (pvt->cntr_coeff_missedupdates > 0) + pvt->avg_Lu_i_toolow = (int)(pvt->avg_Lu_i_toolow / pvt->cntr_coeff_missedupdates); + else + pvt->avg_Lu_i_toolow = -1; + + if (pvt->cntr_coeff_updates > 0) + pvt->avg_Lu_i_ok = (pvt->avg_Lu_i_ok / pvt->cntr_coeff_updates); + else + pvt->avg_Lu_i_ok = -1; + + printk(KERN_INFO "%d: Near end speech: %5d Residuals corrected/skipped: %5d/%5d Coefficients updated ok/low sig: %3d/%3d Lu_i avg ok/low sig %6d/%5d\n", + pvt->id, + pvt->cntr_nearend_speech_frames, + pvt->cntr_residualcorrected_frames, pvt->cntr_residualcorrected_framesskipped, + pvt->cntr_coeff_updates, pvt->cntr_coeff_missedupdates, + pvt->avg_Lu_i_ok, pvt->avg_Lu_i_toolow); + + pvt->cntr_nearend_speech_frames = 0; + pvt->cntr_residualcorrected_frames = 0; + pvt->cntr_residualcorrected_framesskipped = 0; + pvt->cntr_coeff_updates = 0; + pvt->cntr_coeff_missedupdates = 0; + pvt->avg_Lu_i_ok = 0; + pvt->avg_Lu_i_toolow = 0; + } +#endif + + /* Increment the sample index and return the corrected sample */ + pvt->i_d++; + return u; +} + +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + u32 x; + short result; + + for (x = 0; x < size; x++) { + result = sample_update(pvt, *iref, *isig); + *isig++ = result; + ++iref; + } +} + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec) +{ + int maxy; + int maxu; + size_t size; + unsigned int x; + char *c; + struct ec_pvt *pvt; + + maxy = ecp->tap_length + DEFAULT_M; + maxu = DEFAULT_M; + if (maxy < (1 << DEFAULT_ALPHA_YT_I)) + maxy = (1 << DEFAULT_ALPHA_YT_I); + if (maxy < (1 << DEFAULT_SIGMA_LY_I)) + maxy = (1 << DEFAULT_SIGMA_LY_I); + if (maxu < (1 << DEFAULT_SIGMA_LU_I)) + maxu = (1 << DEFAULT_SIGMA_LU_I); + size = sizeof(**ec) + + 4 + /* align */ + sizeof(int) * ecp->tap_length + /* a_i */ + sizeof(short) * ecp->tap_length + /* a_s */ + sizeof(int) * ecp->tap_length + /* b_i */ + sizeof(int) * ecp->tap_length + /* c_i */ + 2 * sizeof(short) * (maxy) + /* y_s */ + 2 * sizeof(short) * (1 << DEFAULT_ALPHA_ST_I) + /* s_s */ + 2 * sizeof(short) * (maxu) + /* u_s */ + 2 * sizeof(short) * ecp->tap_length; /* y_tilde_s */ + + pvt = kzalloc(size, GFP_KERNEL); + if (!pvt) + return -ENOMEM; + + pvt->dahdi.ops = &my_ops; + + pvt->aggressive = aggressive; + pvt->dahdi.features = my_features; + + for (x = 0; x < ecp->param_count; x++) { + for (c = p[x].name; *c; c++) + *c = tolower(*c); + if (!strcmp(p[x].name, "aggressive")) { + pvt->aggressive = p[x].value ? 1 : 0; + } else { + printk(KERN_WARNING "Unknown parameter supplied to MG2 echo canceler: '%s'\n", p[x].name); + kfree(pvt); + + return -EINVAL; + } + } + + init_cc(pvt, ecp->tap_length, maxy, maxu); + /* Non-linear processor - a fancy way to say "zap small signals, to avoid + accumulating noise". */ + pvt->use_nlp = TRUE; + + *ec = &pvt->dahdi; + return 0; +} + +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + /* Set the hangover counter to the length of the can to + * avoid adjustments occuring immediately after initial forced training + */ + pvt->HCNTR_d = pvt->N_d << 1; + + if (pos >= pvt->N_d) { + memcpy(pvt->b_i, pvt->a_i, pvt->N_d*sizeof(int)); + memcpy(pvt->c_i, pvt->a_i, pvt->N_d*sizeof(int)); + return 1; + } + + pvt->a_i[pos] = val << 17; + pvt->a_s[pos] = val << 1; + + if (++pos >= pvt->N_d) { + memcpy(pvt->b_i, pvt->a_i, pvt->N_d*sizeof(int)); + memcpy(pvt->c_i, pvt->a_i, pvt->N_d*sizeof(int)); + return 1; + } + + return 0; +} + +static void echocan_NLP_toggle(struct dahdi_echocan_state *ec, unsigned int enable) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + pvt->use_nlp = enable ? 1 : 0; +} + +static int __init mod_init(void) +{ + if (dahdi_register_echocan_factory(&my_factory)) { + module_printk(KERN_ERR, "could not register with DAHDI core\n"); + + return -EPERM; + } + + module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", my_factory.name); + + return 0; +} + +static void __exit mod_exit(void) +{ + dahdi_unregister_echocan_factory(&my_factory); +} + +module_param(debug, int, S_IRUGO | S_IWUSR); +module_param(aggressive, int, S_IRUGO | S_IWUSR); + +MODULE_DESCRIPTION("DAHDI 'MG2' Echo Canceler"); +MODULE_AUTHOR("Michael Gernoth"); +MODULE_LICENSE("GPL v2"); + +module_init(mod_init); +module_exit(mod_exit); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_oslec.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_oslec.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_oslec.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_oslec.c 2009-04-29 13:24:04.000000000 -0500 @@ -0,0 +1,143 @@ +/* + * DAHDI Telephony Interface to the Open Source Line Echo Canceller (OSLEC) + * + * Written by Tzafrir Cohen + * Copyright (C) 2008 Xorcom, Inc. + * + * All rights reserved. + * + * Based on dahdi_echocan_hpec.c, Copyright (C) 2006-2008 Digium, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +/* Fix this if OSLEC is elsewhere */ +#include "../staging/echo/oslec.h" +//#include + +#include + +#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args) + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec); +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec); +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size); +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val); + +static const struct dahdi_echocan_factory my_factory = { + .name = "OSLEC", + .owner = THIS_MODULE, + .echocan_create = echo_can_create, +}; + +static const struct dahdi_echocan_ops my_ops = { + .name = "OSLEC", + .echocan_free = echo_can_free, + .echocan_process = echo_can_process, + .echocan_traintap = echo_can_traintap, +}; + +struct ec_pvt { + struct oslec_state *oslec; + struct dahdi_echocan_state dahdi; +}; + +#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi) + +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + oslec_free(pvt->oslec); + kfree(pvt); +} + +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + u32 SampleNum; + + for (SampleNum = 0; SampleNum < size; SampleNum++, iref++) { + short iCleanSample; + + iCleanSample = oslec_update(pvt->oslec, *iref, *isig); + *isig++ = iCleanSample; + } +} + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec) +{ + struct ec_pvt *pvt; + + if (ecp->param_count > 0) { + printk(KERN_WARNING "OSLEC does not support parameters; failing request\n"); + return -EINVAL; + } + + pvt = kzalloc(sizeof(*pvt), GFP_KERNEL); + if (!pvt) + return -ENOMEM; + + pvt->dahdi.ops = &my_ops; + + pvt->oslec = oslec_create(ecp->tap_length, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP | ECHO_CAN_USE_CLIP | ECHO_CAN_USE_TX_HPF | ECHO_CAN_USE_RX_HPF); + + if (!pvt->oslec) { + kfree(pvt); + *ec = NULL; + return -ENOTTY; + } else { + *ec = &pvt->dahdi; + return 0; + } +} + +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val) +{ + return 1; +} + +static int __init mod_init(void) +{ + if (dahdi_register_echocan_factory(&my_factory)) { + module_printk(KERN_ERR, "could not register with DAHDI core\n"); + + return -EPERM; + } + + module_printk(KERN_INFO, "Registered echo canceler '%s'\n", my_factory.name); + + return 0; +} + +static void __exit mod_exit(void) +{ + dahdi_unregister_echocan_factory(&my_factory); +} + +MODULE_DESCRIPTION("DAHDI OSLEC wrapper"); +MODULE_AUTHOR("Tzafrir Cohen "); +MODULE_LICENSE("GPL"); + +module_init(mod_init); +module_exit(mod_exit); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_sec2.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_sec2.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_sec2.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_sec2.c 2009-04-29 13:24:04.000000000 -0500 @@ -0,0 +1,351 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * echo.c - An echo cancellor, suitable for electrical and acoustic + * cancellation. This code does not currently comply with + * any relevant standards (e.g. G.164/5/7/8). One day.... + * + * Written by Steve Underwood + * + * Copyright (C) 2001 Steve Underwood + * + * Based on a bit from here, a bit from there, eye of toad, + * ear of bat, etc - plus, of course, my own 2 cents. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +/* TODO: + Finish the echo suppressor option, however nasty suppression may be + Add an option to reintroduce side tone at -24dB under appropriate conditions. + Improve double talk detector (iterative!) +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +static int debug; + +#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args) +#define debug_printk(level, fmt, args...) if (debug >= level) printk(KERN_DEBUG "%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args) + +#include "fir.h" + +#ifndef NULL +#define NULL 0 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +#define NONUPDATE_DWELL_TIME 600 /* 600 samples, or 75ms */ + +/* + * According to Jim... + */ +#define MIN_TX_POWER_FOR_ADAPTION 512 +#define MIN_RX_POWER_FOR_ADAPTION 64 + +/* + * According to Steve... + */ +/* #define MIN_TX_POWER_FOR_ADAPTION 4096 +#define MIN_RX_POWER_FOR_ADAPTION 64 */ + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec); +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec); +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size); +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val); + +static const struct dahdi_echocan_factory my_factory = { + .name = "SEC2", + .owner = THIS_MODULE, + .echocan_create = echo_can_create, +}; + +static const struct dahdi_echocan_ops my_ops = { + .name = "SEC2", + .echocan_free = echo_can_free, + .echocan_process = echo_can_process, + .echocan_traintap = echo_can_traintap, +}; + +struct ec_pvt { + struct dahdi_echocan_state dahdi; + int tx_power; + int rx_power; + int clean_rx_power; + + int rx_power_threshold; + int nonupdate_dwell; + + fir16_state_t fir_state; + int16_t *fir_taps16; /* 16-bit version of FIR taps */ + int32_t *fir_taps32; /* 32-bit version of FIR taps */ + + int curr_pos; + + int taps; + int tap_mask; + int use_nlp; + int use_suppressor; + + int32_t supp_test1; + int32_t supp_test2; + int32_t supp1; + int32_t supp2; + + int32_t latest_correction; /* Indication of the magnitude of the latest + adaption, or a code to indicate why adaption + was skipped, for test purposes */ +}; + +#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi) + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec) +{ + struct ec_pvt *pvt; + size_t size; + + if (ecp->param_count > 0) { + printk(KERN_WARNING "SEC2 does not support parameters; failing request\n"); + return -EINVAL; + } + + size = sizeof(*pvt) + ecp->tap_length * sizeof(int32_t) + ecp->tap_length * 3 * sizeof(int16_t); + + pvt = kzalloc(size, GFP_KERNEL); + if (!pvt) + return -ENOMEM; + + pvt->dahdi.ops = &my_ops; + + if (ecp->param_count > 0) { + printk(KERN_WARNING "SEC-2 echo canceler does not support parameters; failing request\n"); + return -EINVAL; + } + + pvt->taps = ecp->tap_length; + pvt->curr_pos = ecp->tap_length - 1; + pvt->tap_mask = ecp->tap_length - 1; + pvt->fir_taps32 = (int32_t *) (pvt + sizeof(*pvt)); + pvt->fir_taps16 = (int16_t *) (pvt + sizeof(*pvt) + ecp->tap_length * sizeof(int32_t)); + /* Create FIR filter */ + fir16_create(&pvt->fir_state, pvt->fir_taps16, pvt->taps); + pvt->rx_power_threshold = 10000000; + pvt->use_suppressor = FALSE; + /* Non-linear processor - a fancy way to say "zap small signals, to avoid + accumulating noise". */ + pvt->use_nlp = FALSE; + + *ec = &pvt->dahdi; + return 0; +} + +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + fir16_free(&pvt->fir_state); + kfree(pvt); +} + +static inline int16_t sample_update(struct ec_pvt *pvt, int16_t tx, int16_t rx) +{ + int offset1; + int offset2; + int32_t echo_value; + int clean_rx; + int nsuppr; + int i; + int correction; + + /* Evaluate the echo - i.e. apply the FIR filter */ + /* Assume the gain of the FIR does not exceed unity. Exceeding unity + would seem like a rather poor thing for an echo cancellor to do :) + This means we can compute the result with a total disregard for + overflows. 16bits x 16bits -> 31bits, so no overflow can occur in + any multiply. While accumulating we may overflow and underflow the + 32 bit scale often. However, if the gain does not exceed unity, + everything should work itself out, and the final result will be + OK, without any saturation logic. */ + /* Overflow is very much possible here, and we do nothing about it because + of the compute costs */ + /* 16 bit coeffs for the LMS give lousy results (maths good, actual sound + bad!), but 32 bit coeffs require some shifting. On balance 32 bit seems + best */ + echo_value = fir16 (&pvt->fir_state, tx); + + /* And the answer is..... */ + clean_rx = rx - echo_value; + + /* That was the easy part. Now we need to adapt! */ + if (pvt->nonupdate_dwell > 0) + pvt->nonupdate_dwell--; + + /* If there is very little being transmitted, any attempt to train is + futile. We would either be training on the far end's noise or signal, + the channel's own noise, or our noise. Either way, this is hardly good + training, so don't do it (avoid trouble). */ + /* If the received power is very low, either we are sending very little or + we are already well adapted. There is little point in trying to improve + the adaption under these circumstanceson, so don't do it (reduce the + compute load). */ + if (pvt->tx_power > MIN_TX_POWER_FOR_ADAPTION && pvt->rx_power > MIN_RX_POWER_FOR_ADAPTION) { + /* This is a really crude piece of decision logic, but it does OK + for now. */ + if (pvt->tx_power > 2*pvt->rx_power) { + /* There is no far-end speech detected */ + if (pvt->nonupdate_dwell == 0) { + /* ... and we are not in the dwell time from previous speech. */ + /* nsuppr = saturate((clean_rx << 16)/pvt->tx_power); */ + nsuppr = clean_rx >> 3; + + /* Update the FIR taps */ + offset2 = pvt->curr_pos + 1; + offset1 = pvt->taps - offset2; + pvt->latest_correction = 0; + for (i = pvt->taps - 1; i >= offset1; i--) { + correction = pvt->fir_state.history[i - offset1]*nsuppr; + /* Leak to avoid false training on signals with multiple + strong correlations. */ + pvt->fir_taps32[i] -= (pvt->fir_taps32[i] >> 12); + pvt->fir_taps32[i] += correction; + pvt->fir_state.coeffs[i] = pvt->fir_taps32[i] >> 15; + pvt->latest_correction += abs(correction); + } + for ( ; i >= 0; i--) { + correction = pvt->fir_state.history[i + offset2]*nsuppr; + /* Leak to avoid false training on signals with multiple + strong correlations. */ + pvt->fir_taps32[i] -= (pvt->fir_taps32[i] >> 12); + pvt->fir_taps32[i] += correction; + pvt->fir_state.coeffs[i] = pvt->fir_taps32[i] >> 15; + pvt->latest_correction += abs(correction); + } + } else { + pvt->latest_correction = -1; + } + } else { + pvt->nonupdate_dwell = NONUPDATE_DWELL_TIME; + pvt->latest_correction = -2; + } + } else { + pvt->nonupdate_dwell = 0; + pvt->latest_correction = -3; + } + /* Calculate short term power levels using very simple single pole IIRs */ + /* TODO: Is the nasty modulus approach the fastest, or would a real + tx*tx power calculation actually be faster? */ + pvt->tx_power += ((abs(tx) - pvt->tx_power) >> 5); + pvt->rx_power += ((abs(rx) - pvt->rx_power) >> 5); + pvt->clean_rx_power += ((abs(clean_rx) - pvt->clean_rx_power) >> 5); + +#if defined(XYZZY) + if (pvt->use_suppressor) { + pvt->supp_test1 += (pvt->fir_state.history[pvt->curr_pos] - pvt->fir_state.history[(pvt->curr_pos - 7) & pvt->tap_mask]); + pvt->supp_test2 += (pvt->fir_state.history[(pvt->curr_pos - 24) & pvt->tap_mask] - pvt->fir_state.history[(pvt->curr_pos - 31) & pvt->tap_mask]); + if (pvt->supp_test1 > 42 && pvt->supp_test2 > 42) + supp_change = 25; + else + supp_change = 50; + supp = supp_change + k1*pvt->supp1 + k2*pvt->supp2; + pvt->supp2 = pvt->supp1; + pvt->supp1 = supp; + clean_rx *= (1 - supp); + } +#endif + + if (pvt->use_nlp && pvt->rx_power < 32) + clean_rx = 0; + + /* Roll around the rolling buffer */ + if (pvt->curr_pos <= 0) + pvt->curr_pos = pvt->taps; + pvt->curr_pos--; + + return clean_rx; +} + +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + u32 x; + short result; + + for (x = 0; x < size; x++) { + result = sample_update(pvt, *iref, *isig); + *isig++ = result; + ++iref; + } +} + +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + /* Reset hang counter to avoid adjustments after + initial forced training */ + pvt->nonupdate_dwell = pvt->taps << 1; + if (pos >= pvt->taps) + return 1; + pvt->fir_taps32[pos] = val << 17; + pvt->fir_taps16[pos] = val << 1; + if (++pos >= pvt->taps) + return 1; + else + return 0; +} + +static int __init mod_init(void) +{ + if (dahdi_register_echocan_factory(&my_factory)) { + module_printk(KERN_ERR, "could not register with DAHDI core\n"); + + return -EPERM; + } + + module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", my_factory.name); + + return 0; +} + +static void __exit mod_exit(void) +{ + dahdi_unregister_echocan_factory(&my_factory); +} + +module_param(debug, int, S_IRUGO | S_IWUSR); + +MODULE_DESCRIPTION("DAHDI 'SEC2' Echo Canceler"); +MODULE_AUTHOR("Steve Underwood "); +MODULE_LICENSE("GPL"); + +module_init(mod_init); +module_exit(mod_exit); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_sec.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_sec.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_sec.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_echocan_sec.c 2009-04-29 13:24:04.000000000 -0500 @@ -0,0 +1,356 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * echo.c - An echo cancellor, suitable for electrical and acoustic + * cancellation. This code does not currently comply with + * any relevant standards (e.g. G.164/5/7/8). One day.... + * + * Written by Steve Underwood + * Various optimizations and improvements by Mark Spencer + * + * Copyright (C) 2001 Steve Underwood + * + * Based on a bit from here, a bit from there, eye of toad, + * ear of bat, etc - plus, of course, my own 2 cents. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +/* TODO: + Finish the echo suppressor option, however nasty suppression may be + Add an option to reintroduce side tone at -24dB under appropriate conditions. + Improve double talk detector (iterative!) +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +static int debug; + +#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args) +#define debug_printk(level, fmt, args...) if (debug >= level) printk(KERN_DEBUG "%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args) + +#include "arith.h" + +#ifndef NULL +#define NULL 0 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +#define USE_SHORTS + +#define NONUPDATE_DWELL_TIME 600 /* 600 samples, or 75ms */ + +/* Original parameters : +#define MIN_TX_POWER_FOR_ADAPTION 256 +#define MIN_RX_POWER_FOR_ADAPTION 128 +*/ + +#define MIN_TX_POWER_FOR_ADAPTION 256 +#define MIN_RX_POWER_FOR_ADAPTION 64 + +/* Better ones found by Jim +#define MIN_TX_POWER_FOR_ADAPTION 128 +#define MIN_RX_POWER_FOR_ADAPTION 64 +*/ + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec); +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec); +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size); +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val); +static void echocan_NLP_toggle(struct dahdi_echocan_state *ec, unsigned int enable); + +static const struct dahdi_echocan_factory my_factory = { + .name = "SEC", + .owner = THIS_MODULE, + .echocan_create = echo_can_create, +}; + +static const struct dahdi_echocan_features my_features = { + .NLP_toggle = 1, +}; + +static const struct dahdi_echocan_ops my_ops = { + .name = "SEC", + .echocan_free = echo_can_free, + .echocan_process = echo_can_process, + .echocan_traintap = echo_can_traintap, + .echocan_NLP_toggle = echocan_NLP_toggle, +}; + +struct ec_pvt { + struct dahdi_echocan_state dahdi; + int tx_power; + int rx_power; + int clean_rx_power; + + int rx_power_threshold; + int nonupdate_dwell; + + int16_t *tx_history; /* Last N tx samples */ + int32_t *fir_taps; /* Echo FIR taps */ + int16_t *fir_taps_short; /* Echo FIR taps, shorts instead of ints */ + + int curr_pos; + + int taps; + int tap_mask; + int use_nlp; + int use_suppressor; + + int32_t supp_test1; + int32_t supp_test2; + int32_t supp1; + int32_t supp2; + + int32_t latest_correction; /* Indication of the magnitude of the latest + adaption, or a code to indicate why adaption + was skipped, for test purposes */ +}; + +#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi) + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec) +{ + struct ec_pvt *pvt; + size_t size; + + if (ecp->param_count > 0) { + printk(KERN_WARNING "SEC does not support parameters; failing request\n"); + return -EINVAL; + } + + size = sizeof(*pvt) + ecp->tap_length * sizeof(int32_t) + ecp->tap_length * 3 * sizeof(int16_t); + + pvt = kzalloc(size, GFP_KERNEL); + if (!pvt) + return -ENOMEM; + + pvt->dahdi.ops = &my_ops; + pvt->dahdi.features = my_features; + + pvt->taps = ecp->tap_length; + pvt->tap_mask = ecp->tap_length - 1; + pvt->tx_history = (int16_t *) (pvt + sizeof(*pvt)); + pvt->fir_taps = (int32_t *) (pvt + sizeof(*pvt) + + ecp->tap_length * 2 * sizeof(int16_t)); + pvt->fir_taps_short = (int16_t *) (pvt + sizeof(*pvt) + + ecp->tap_length * sizeof(int32_t) + + ecp->tap_length * 2 * sizeof(int16_t)); + pvt->rx_power_threshold = 10000000; + pvt->use_suppressor = FALSE; + /* Non-linear processor - a fancy way to say "zap small signals, to avoid + accumulating noise". */ + pvt->use_nlp = TRUE; + + *ec = &pvt->dahdi; + return 0; +} + +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + kfree(pvt); +} + +static inline int16_t sample_update(struct ec_pvt *pvt, int16_t tx, int16_t rx) +{ + int32_t echo_value; + int clean_rx; + int nsuppr; + + pvt->tx_history[pvt->curr_pos] = tx; + pvt->tx_history[pvt->curr_pos + pvt->taps] = tx; + + /* Evaluate the echo - i.e. apply the FIR filter */ + /* Assume the gain of the FIR does not exceed unity. Exceeding unity + would seem like a rather poor thing for an echo cancellor to do :) + This means we can compute the result with a total disregard for + overflows. 16bits x 16bits -> 31bits, so no overflow can occur in + any multiply. While accumulating we may overflow and underflow the + 32 bit scale often. However, if the gain does not exceed unity, + everything should work itself out, and the final result will be + OK, without any saturation logic. */ + /* Overflow is very much possible here, and we do nothing about it because + of the compute costs */ + /* 16 bit coeffs for the LMS give lousy results (maths good, actual sound + bad!), but 32 bit coeffs require some shifting. On balance 32 bit seems + best */ +#ifdef USE_SHORTS + echo_value = CONVOLVE2(pvt->fir_taps_short, pvt->tx_history + pvt->curr_pos, pvt->taps); +#else + echo_value = CONVOLVE(pvt->fir_taps, pvt->tx_history + pvt->curr_pos, pvt->taps); +#endif + echo_value >>= 16; + + /* And the answer is..... */ + clean_rx = rx - echo_value; + + /* That was the easy part. Now we need to adapt! */ + if (pvt->nonupdate_dwell > 0) + pvt->nonupdate_dwell--; + + /* If there is very little being transmitted, any attempt to train is + futile. We would either be training on the far end's noise or signal, + the channel's own noise, or our noise. Either way, this is hardly good + training, so don't do it (avoid trouble). */ + /* If the received power is very low, either we are sending very little or + we are already well adapted. There is little point in trying to improve + the adaption under these circumstanceson, so don't do it (reduce the + compute load). */ + if (pvt->tx_power > MIN_TX_POWER_FOR_ADAPTION && pvt->rx_power > MIN_RX_POWER_FOR_ADAPTION) { + /* This is a really crude piece of decision logic, but it does OK + for now. */ + if (pvt->tx_power > pvt->rx_power << 1) { + /* There is no far-end speech detected */ + if (pvt->nonupdate_dwell == 0) { + /* ... and we are not in the dwell time from previous speech. */ + /* nsuppr = saturate((clean_rx << 16)/pvt->tx_power); */ + nsuppr = (clean_rx << 16) / pvt->tx_power; + nsuppr >>= 4; + if (nsuppr > 512) + nsuppr = 512; + if (nsuppr < -512) + nsuppr = -512; + + /* Update the FIR taps */ + pvt->latest_correction = 0; +#ifdef USE_SHORTS + UPDATE2(pvt->fir_taps, pvt->fir_taps_short, pvt->tx_history + pvt->curr_pos, nsuppr, pvt->taps); +#else + UPDATE(pvt->fir_taps, pvt->fir_taps_short, pvt->tx_history + pvt->curr_pos, nsuppr, pvt->taps); +#endif + } else { + pvt->latest_correction = -3; + } + } else { + pvt->nonupdate_dwell = NONUPDATE_DWELL_TIME; + pvt->latest_correction = -2; + } + } else { + pvt->nonupdate_dwell = 0; + pvt->latest_correction = -1; + } + /* Calculate short term power levels using very simple single pole IIRs */ + /* TODO: Is the nasty modulus approach the fastest, or would a real + tx*tx power calculation actually be faster? */ + pvt->tx_power += ((abs(tx) - pvt->tx_power) >> 5); + pvt->rx_power += ((abs(rx) - pvt->rx_power) >> 5); + pvt->clean_rx_power += ((abs(clean_rx) - pvt->clean_rx_power) >> 5); + +#if defined(XYZZY) + if (pvt->use_suppressor) { + pvt->supp_test1 += (pvt->tx_history[pvt->curr_pos] - pvt->tx_history[(pvt->curr_pos - 7) & pvt->tap_mask]); + pvt->supp_test2 += (pvt->tx_history[(pvt->curr_pos - 24) & pvt->tap_mask] - pvt->tx_history[(pvt->curr_pos - 31) & pvt->tap_mask]); + if (pvt->supp_test1 > 42 && pvt->supp_test2 > 42) + supp_change = 25; + else + supp_change = 50; + supp = supp_change + k1*pvt->supp1 + k2*pvt->supp2; + pvt->supp2 = pvt->supp1; + pvt->supp1 = supp; + clean_rx *= (1 - supp); + } +#endif + + if (pvt->use_nlp && pvt->rx_power < 32) + clean_rx = 0; + + /* Roll around the rolling buffer */ + pvt->curr_pos = (pvt->curr_pos - 1) & pvt->tap_mask; + + return clean_rx; +} + +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + u32 x; + short result; + + for (x = 0; x < size; x++) { + result = sample_update(pvt, *iref, *isig); + *isig++ = result; + ++iref; + } +} + +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + /* Reset hang counter to avoid adjustments after + initial forced training */ + pvt->nonupdate_dwell = pvt->taps << 1; + if (pos >= pvt->taps) + return 1; + pvt->fir_taps[pos] = val << 17; + pvt->fir_taps_short[pos] = val << 1; + if (++pos >= pvt->taps) + return 1; + else + return 0; +} + +static void echocan_NLP_toggle(struct dahdi_echocan_state *ec, unsigned int enable) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + pvt->use_nlp = enable ? 1 : 0; +} + +static int __init mod_init(void) +{ + if (dahdi_register_echocan_factory(&my_factory)) { + module_printk(KERN_ERR, "could not register with DAHDI core\n"); + + return -EPERM; + } + + module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", my_factory.name); + + return 0; +} + +static void __exit mod_exit(void) +{ + dahdi_unregister_echocan_factory(&my_factory); +} + +module_param(debug, int, S_IRUGO | S_IWUSR); + +MODULE_DESCRIPTION("DAHDI 'SEC' Echo Canceler"); +MODULE_AUTHOR("Steve Underwood "); +MODULE_LICENSE("GPL"); + +module_init(mod_init); +module_exit(mod_exit); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_transcode.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_transcode.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/dahdi_transcode.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/dahdi_transcode.c 2009-03-11 09:50:06.000000000 -0500 @@ -0,0 +1,483 @@ +/* + * Transcoder Interface for DAHDI + * + * Written by Mark Spencer + * + * Copyright (C) 2006-2008, Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static int debug; +/* The registration list contains transcoders in the order in which they were + * registered. */ +static LIST_HEAD(registration_list); +/* The active list is sorted by the most recently used transcoder is last. This + * is used as a simplistic way to spread the load amongst the different hardware + * transcoders in the system. */ +static LIST_HEAD(active_list); +static spinlock_t translock = SPIN_LOCK_UNLOCKED; + +EXPORT_SYMBOL(dahdi_transcoder_register); +EXPORT_SYMBOL(dahdi_transcoder_unregister); +EXPORT_SYMBOL(dahdi_transcoder_alert); +EXPORT_SYMBOL(dahdi_transcoder_alloc); +EXPORT_SYMBOL(dahdi_transcoder_free); + +struct dahdi_transcoder *dahdi_transcoder_alloc(int numchans) +{ + struct dahdi_transcoder *tc; + unsigned int x; + size_t size = sizeof(*tc) + (sizeof(tc->channels[0]) * numchans); + + if (!(tc = kmalloc(size, GFP_KERNEL))) + return NULL; + + memset(tc, 0, size); + strcpy(tc->name, ""); + INIT_LIST_HEAD(&tc->registration_list_node); + INIT_LIST_HEAD(&tc->active_list_node); + tc->numchannels = numchans; + for (x=0; x < tc->numchannels; x++) { + init_waitqueue_head(&tc->channels[x].ready); + tc->channels[x].parent = tc; + } + + WARN_ON(!dahdi_transcode_fops); + /* Individual transcoders should supply their own file_operations for + * write and read. But they will by default use the file_operations + * provided by the dahdi_transcode layer. */ + memcpy(&tc->fops, dahdi_transcode_fops, sizeof(*dahdi_transcode_fops)); + return tc; +} + +void dahdi_transcoder_free(struct dahdi_transcoder *tc) +{ + kfree(tc); +} + +/* Returns 1 if the item is on the list pointed to by head, otherwise, returns + * 0 */ +static int is_on_list(struct list_head *entry, struct list_head *head) +{ + struct list_head *cur; + list_for_each(cur, head) { + if (cur == entry) return 1; + } + return 0; +} + +/* Register a transcoder */ +int dahdi_transcoder_register(struct dahdi_transcoder *tc) +{ + spin_lock(&translock); + BUG_ON(is_on_list(&tc->registration_list_node, ®istration_list)); + list_add_tail(&tc->registration_list_node, ®istration_list); + list_add_tail(&tc->active_list_node, &active_list); + spin_unlock(&translock); + + printk(KERN_INFO "%s: Registered codec translator '%s' " \ + "with %d transcoders (srcs=%08x, dsts=%08x)\n", + THIS_MODULE->name, tc->name, tc->numchannels, + tc->srcfmts, tc->dstfmts); + + return 0; +} + +/* Unregister a transcoder */ +int dahdi_transcoder_unregister(struct dahdi_transcoder *tc) +{ + int res = -EINVAL; + + /* \todo Perhaps we should check to make sure there isn't a channel + * that is still in use? */ + + spin_lock(&translock); + if (!is_on_list(&tc->registration_list_node, ®istration_list)) { + spin_unlock(&translock); + printk(KERN_WARNING "%s: Failed to unregister %s, which is " \ + "not currently registerd.\n", THIS_MODULE->name, tc->name); + return -EINVAL; + } + list_del_init(&tc->registration_list_node); + list_del_init(&tc->active_list_node); + spin_unlock(&translock); + + printk(KERN_INFO "Unregistered codec translator '%s' with %d " \ + "transcoders (srcs=%08x, dsts=%08x)\n", + tc->name, tc->numchannels, tc->srcfmts, tc->dstfmts); + res = 0; + + return res; +} + +/* Alert a transcoder */ +int dahdi_transcoder_alert(struct dahdi_transcoder_channel *chan) +{ + wake_up_interruptible(&chan->ready); + return 0; +} + +static int dahdi_tc_open(struct inode *inode, struct file *file) +{ + const struct file_operations *original_fops; + BUG_ON(!dahdi_transcode_fops); + original_fops = file->f_op; + file->f_op = dahdi_transcode_fops; + file->private_data = NULL; + /* Under normal operation, this releases the reference on the DAHDI + * module that was created when the file was opened. dahdi_open is + * responsible for taking a reference out on this module before + * calling this function. */ + module_put(original_fops->owner); + return 0; +} + +static void dtc_release(struct dahdi_transcoder_channel *chan) +{ + BUG_ON(!chan); + if (chan->parent && chan->parent->release) { + chan->parent->release(chan); + } + dahdi_tc_clear_busy(chan); +} + +static int dahdi_tc_release(struct inode *inode, struct file *file) +{ + struct dahdi_transcoder_channel *chan = file->private_data; + /* There will not be a transcoder channel associated with this file if + * the ALLOCATE ioctl never succeeded. + */ + if (chan) { + dtc_release(chan); + } + return 0; +} + +/* Find a free channel on the transcoder and mark it busy. */ +static inline struct dahdi_transcoder_channel * +get_free_channel(struct dahdi_transcoder *tc, + const struct dahdi_transcoder_formats *fmts) +{ + struct dahdi_transcoder_channel *chan; + int i; + /* Should be called with the translock held. */ +#ifdef CONFIG_SMP + WARN_ON(!spin_is_locked(&translock)); +#endif + + for (i = 0; i < tc->numchannels; i++) { + chan = &tc->channels[i]; + if (!dahdi_tc_is_busy(chan)) { + if (!dahdi_tc_is_built(chan)) { + dahdi_tc_set_busy(chan); + return chan; + } else { + /* If the channel is already built, we must + * make sure that it can support the formats + * that we're interested in. */ + if ((fmts->srcfmt|fmts->dstfmt) == chan->built_fmts) { + dahdi_tc_set_busy(chan); + return chan; + } + } + } + } + return NULL; +} + +/* Search the list for a transcoder that supports the specified format, and + * allocate and return an available channel on it. + * + * Returns either a pointer to the allocated channel, -EBUSY if the format is + * supported but all the channels are busy, or -ENODEV if there are not any + * transcoders that support the formats. + */ +static struct dahdi_transcoder_channel * +__find_free_channel(struct list_head *list, const struct dahdi_transcoder_formats *fmts) +{ + struct dahdi_transcoder *tc; + struct dahdi_transcoder_channel *chan = NULL; + unsigned int match = 0; + + list_for_each_entry(tc, list, active_list_node) { + if ((tc->dstfmts & fmts->dstfmt) && (tc->srcfmts & fmts->srcfmt)) { + /* We found a transcoder that can handle our formats. + * Now look for an available channel. */ + match = 1; + if ((chan = get_free_channel(tc, fmts))) { + /* transcoder tc has a free channel. In order + * to spread the load among available + * transcoders (when there are more than one + * transcoder in the system) we'll move tc + * to the end of the list. */ + list_move_tail(&tc->active_list_node, list); + return chan; + } + } + } + return (void*)((long)((match) ? -EBUSY : -ENODEV)); +} + +static long dahdi_tc_allocate(struct file *file, unsigned long data) +{ + struct dahdi_transcoder_channel *chan = NULL; + struct dahdi_transcoder_formats fmts; + + if (copy_from_user(&fmts, (__user const void *) data, sizeof(fmts))) { + return -EFAULT; + } + + spin_lock(&translock); + chan = __find_free_channel(&active_list, &fmts); + spin_unlock(&translock); + + if (IS_ERR(chan)) { + return PTR_ERR(chan); + } + + /* Every transcoder channel must be associated with a parent + * transcoder. */ + BUG_ON(!chan->parent); + + chan->srcfmt = fmts.srcfmt; + chan->dstfmt = fmts.dstfmt; + + if (file->private_data) { + /* This open file is moving to a new channel. Cleanup and + * close the old channel here. */ + dtc_release(file->private_data); + } + + file->private_data = chan; + if (chan->parent->fops.owner != file->f_op->owner) { + if (!try_module_get(chan->parent->fops.owner)) { + /* Failed to get a reference on the driver for the + * actual transcoding hardware. */ + return -EINVAL; + } + /* Release the reference on the existing driver. */ + module_put(file->f_op->owner); + file->f_op = &chan->parent->fops; + } + + if (file->f_flags & O_NONBLOCK) { + dahdi_tc_set_nonblock(chan); + } else { + dahdi_tc_clear_nonblock(chan); + } + + /* Actually reset the transcoder channel */ + if (chan->parent->allocate) + return chan->parent->allocate(chan); + + return -EINVAL; +} + +static long dahdi_tc_getinfo(unsigned long data) +{ + struct dahdi_transcoder_info info; + struct dahdi_transcoder *cur; + struct dahdi_transcoder *tc = NULL; + unsigned int count = 0; + + if (copy_from_user(&info, (__user const void *) data, sizeof(info))) { + return -EFAULT; + } + + spin_lock(&translock); + list_for_each_entry(cur, ®istration_list, registration_list_node) { + if (info.tcnum == count++) { + tc = cur; + break; + } + } + spin_unlock(&translock); + + if (!tc) { + return -ENOSYS; + } + + dahdi_copy_string(info.name, tc->name, sizeof(info.name)); + info.numchannels = tc->numchannels; + info.srcfmts = tc->srcfmts; + info.dstfmts = tc->dstfmts; + + return copy_to_user((__user void *) data, &info, sizeof(info)) ? -EFAULT : 0; +} + +static ssize_t dahdi_tc_write(struct file *file, __user const char *usrbuf, size_t count, loff_t *ppos) +{ + if (file->private_data) { + /* file->private_data will not be NULL if DAHDI_TC_ALLOCATE was + * called, and therefore indicates that the transcoder driver + * did not export a read function. */ + WARN_ON(1); + return -ENOSYS; + } else { + printk(KERN_INFO "%s: Attempt to write to unallocated " \ + "channel.\n", THIS_MODULE->name); + return -EINVAL; + } +} + +static ssize_t dahdi_tc_read(struct file *file, __user char *usrbuf, size_t count, loff_t *ppos) +{ + if (file->private_data) { + /* file->private_data will not be NULL if DAHDI_TC_ALLOCATE was + * called, and therefore indicates that the transcoder driver + * did not export a write function. */ + WARN_ON(1); + return -ENOSYS; + } else { + printk(KERN_INFO "%s: Attempt to read from unallocated " \ + "channel.\n", THIS_MODULE->name); + return -EINVAL; + } +} + +static long dahdi_tc_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long data) +{ + switch (cmd) { + case DAHDI_TC_ALLOCATE: + return dahdi_tc_allocate(file, data); + case DAHDI_TC_GETINFO: + return dahdi_tc_getinfo(data); + case DAHDI_TRANSCODE_OP: + /* This is a deprecated call from the previous transcoder + * interface, which was all routed through the dahdi_ioctl in + * dahdi-base.c, and this ioctl request was used to indicate + * that the call should be forwarded to this function. Now + * when the file is opened, the f_ops pointer is updated to + * point directly to this function, and we don't need a + * general indication that the ioctl is destined for the + * transcoder. + * + * I'm keeping this ioctl here in order to explain why there + * might be a hole in the ioctl numbering scheme in the header + * files. + */ + printk(KERN_WARNING "%s: DAHDI_TRANSCODE_OP is no longer " \ + "supported. Please call DAHDI_TC ioctls directly.\n", + THIS_MODULE->name); + return -EINVAL; + default: + return -EINVAL; + }; +} + +static int dahdi_tc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data) +{ + return (int)dahdi_tc_unlocked_ioctl(file, cmd, data); +} + +static int dahdi_tc_mmap(struct file *file, struct vm_area_struct *vma) +{ + printk(KERN_ERR "%s: mmap interface deprecated.\n", THIS_MODULE->name); + return -ENOSYS; +} + +static unsigned int dahdi_tc_poll(struct file *file, struct poll_table_struct *wait_table) +{ + int ret; + struct dahdi_transcoder_channel *chan = file->private_data; + + if (!chan) { + /* This is because the DAHDI_TC_ALLOCATE ioctl was not called + * before calling poll, which is invalid. */ + return -EINVAL; + } + + poll_wait(file, &chan->ready, wait_table); + + ret = dahdi_tc_is_busy(chan) ? 0 : POLLPRI; + ret |= dahdi_tc_is_built(chan) ? POLLOUT : 0; + ret |= dahdi_tc_is_data_waiting(chan) ? POLLIN : 0; + return ret; +} + +static struct file_operations __dahdi_transcode_fops = { + .owner = THIS_MODULE, + .open = dahdi_tc_open, + .release = dahdi_tc_release, + .ioctl = dahdi_tc_ioctl, + .read = dahdi_tc_read, + .write = dahdi_tc_write, + .poll = dahdi_tc_poll, + .mmap = dahdi_tc_mmap, +#if HAVE_UNLOCKED_IOCTL + .unlocked_ioctl = dahdi_tc_unlocked_ioctl, +#endif +}; + +static struct dahdi_chardev transcode_chardev = { + .name = "transcode", + .minor = 250, +}; + +static int dahdi_transcode_init(void) +{ + int res; + + if (dahdi_transcode_fops) { + printk(KERN_WARNING "dahdi_transcode_fops already set.\n"); + return -EBUSY; + } + + dahdi_transcode_fops = &__dahdi_transcode_fops; + + if ((res = dahdi_register_chardev(&transcode_chardev))) + return res; + + printk(KERN_INFO "%s: Loaded.\n", THIS_MODULE->name); + return 0; +} + +static void dahdi_transcode_cleanup(void) +{ + dahdi_unregister_chardev(&transcode_chardev); + + dahdi_transcode_fops = NULL; + + printk(KERN_DEBUG "%s: Unloaded.\n", THIS_MODULE->name); +} + +module_param(debug, int, S_IRUGO | S_IWUSR); +MODULE_DESCRIPTION("DAHDI Transcoder Support"); +MODULE_AUTHOR("Mark Spencer "); +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +module_init(dahdi_transcode_init); +module_exit(dahdi_transcode_cleanup); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_cisco.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_cisco.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_cisco.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_cisco.c 2008-02-04 17:00:48.000000000 -0600 @@ -0,0 +1,335 @@ +/* + * Generic HDLC support routines for Linux + * Cisco HDLC support + * + * Copyright (C) 2000 - 2003 Krzysztof Halasa + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG_HARD_HEADER + +#define CISCO_MULTICAST 0x8F /* Cisco multicast address */ +#define CISCO_UNICAST 0x0F /* Cisco unicast address */ +#define CISCO_KEEPALIVE 0x8035 /* Cisco keepalive protocol */ +#define CISCO_SYS_INFO 0x2000 /* Cisco interface/system info */ +#define CISCO_ADDR_REQ 0 /* Cisco address request */ +#define CISCO_ADDR_REPLY 1 /* Cisco address reply */ +#define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */ + + +static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev, + u16 type, void *daddr, void *saddr, + unsigned int len) +{ + hdlc_header *data; +#ifdef DEBUG_HARD_HEADER + printk(KERN_DEBUG "%s: cisco_hard_header called\n", dev->name); +#endif + + skb_push(skb, sizeof(hdlc_header)); + data = (hdlc_header*)skb->data; + if (type == CISCO_KEEPALIVE) + data->address = CISCO_MULTICAST; + else + data->address = CISCO_UNICAST; + data->control = 0; + data->protocol = htons(type); + + return sizeof(hdlc_header); +} + + + +static void cisco_keepalive_send(struct net_device *dev, u32 type, + u32 par1, u32 par2) +{ + struct sk_buff *skb; + cisco_packet *data; + + skb = dev_alloc_skb(sizeof(hdlc_header) + sizeof(cisco_packet)); + if (!skb) { + printk(KERN_WARNING + "%s: Memory squeeze on cisco_keepalive_send()\n", + dev->name); + return; + } + skb_reserve(skb, 4); + cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0); + data = (cisco_packet*)(skb->data + 4); + + data->type = htonl(type); + data->par1 = htonl(par1); + data->par2 = htonl(par2); + data->rel = 0xFFFF; + /* we will need do_div here if 1000 % HZ != 0 */ + data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ)); + + skb_put(skb, sizeof(cisco_packet)); + skb->priority = TC_PRIO_CONTROL; + skb->dev = dev; + skb->nh.raw = skb->data; + + dev_queue_xmit(skb); +} + + + +static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev) +{ + hdlc_header *data = (hdlc_header*)skb->data; + + if (skb->len < sizeof(hdlc_header)) + return __constant_htons(ETH_P_HDLC); + + if (data->address != CISCO_MULTICAST && + data->address != CISCO_UNICAST) + return __constant_htons(ETH_P_HDLC); + + switch(data->protocol) { + case __constant_htons(ETH_P_IP): + case __constant_htons(ETH_P_IPX): + case __constant_htons(ETH_P_IPV6): + skb_pull(skb, sizeof(hdlc_header)); + return data->protocol; + default: + return __constant_htons(ETH_P_HDLC); + } +} + + +static int cisco_rx(struct sk_buff *skb) +{ + struct net_device *dev = skb->dev; + hdlc_device *hdlc = dev_to_hdlc(dev); + hdlc_header *data = (hdlc_header*)skb->data; + cisco_packet *cisco_data; + struct in_device *in_dev; + u32 addr, mask; + + if (skb->len < sizeof(hdlc_header)) + goto rx_error; + + if (data->address != CISCO_MULTICAST && + data->address != CISCO_UNICAST) + goto rx_error; + + switch(ntohs(data->protocol)) { + case CISCO_SYS_INFO: + /* Packet is not needed, drop it. */ + dev_kfree_skb_any(skb); + return NET_RX_SUCCESS; + + case CISCO_KEEPALIVE: + if (skb->len != sizeof(hdlc_header) + CISCO_PACKET_LEN && + skb->len != sizeof(hdlc_header) + CISCO_BIG_PACKET_LEN) { + printk(KERN_INFO "%s: Invalid length of Cisco " + "control packet (%d bytes)\n", + dev->name, skb->len); + goto rx_error; + } + + cisco_data = (cisco_packet*)(skb->data + sizeof(hdlc_header)); + + switch(ntohl (cisco_data->type)) { + case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ + in_dev = dev->ip_ptr; + addr = 0; + mask = ~0; /* is the mask correct? */ + + if (in_dev != NULL) { + struct in_ifaddr **ifap = &in_dev->ifa_list; + + while (*ifap != NULL) { + if (strcmp(dev->name, + (*ifap)->ifa_label) == 0) { + addr = (*ifap)->ifa_local; + mask = (*ifap)->ifa_mask; + break; + } + ifap = &(*ifap)->ifa_next; + } + + cisco_keepalive_send(dev, CISCO_ADDR_REPLY, + addr, mask); + } + dev_kfree_skb_any(skb); + return NET_RX_SUCCESS; + + case CISCO_ADDR_REPLY: + printk(KERN_INFO "%s: Unexpected Cisco IP address " + "reply\n", dev->name); + goto rx_error; + + case CISCO_KEEPALIVE_REQ: + hdlc->state.cisco.rxseq = ntohl(cisco_data->par1); + if (hdlc->state.cisco.request_sent && + ntohl(cisco_data->par2)==hdlc->state.cisco.txseq) { + hdlc->state.cisco.last_poll = jiffies; + if (!hdlc->state.cisco.up) { + u32 sec, min, hrs, days; + sec = ntohl(cisco_data->time) / 1000; + min = sec / 60; sec -= min * 60; + hrs = min / 60; min -= hrs * 60; + days = hrs / 24; hrs -= days * 24; + printk(KERN_INFO "%s: Link up (peer " + "uptime %ud%uh%um%us)\n", + dev->name, days, hrs, + min, sec); +#if 0 + netif_carrier_on(dev); +#endif + hdlc->state.cisco.up = 1; + } + } + + dev_kfree_skb_any(skb); + return NET_RX_SUCCESS; + } /* switch(keepalive type) */ + } /* switch(protocol) */ + + printk(KERN_INFO "%s: Unsupported protocol %x\n", dev->name, + data->protocol); + dev_kfree_skb_any(skb); + return NET_RX_DROP; + + rx_error: + hdlc->stats.rx_errors++; /* Mark error */ + dev_kfree_skb_any(skb); + return NET_RX_DROP; +} + + + +static void cisco_timer(unsigned long arg) +{ + struct net_device *dev = (struct net_device *)arg; + hdlc_device *hdlc = dev_to_hdlc(dev); + + if (hdlc->state.cisco.up && + time_after(jiffies, hdlc->state.cisco.last_poll + + hdlc->state.cisco.settings.timeout * HZ)) { + hdlc->state.cisco.up = 0; + printk(KERN_INFO "%s: Link down\n", dev->name); +#if 0 + netif_carrier_off(dev); +#endif + } + + cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, + ++hdlc->state.cisco.txseq, + hdlc->state.cisco.rxseq); + hdlc->state.cisco.request_sent = 1; + hdlc->state.cisco.timer.expires = jiffies + + hdlc->state.cisco.settings.interval * HZ; + hdlc->state.cisco.timer.function = cisco_timer; + hdlc->state.cisco.timer.data = arg; + add_timer(&hdlc->state.cisco.timer); +} + + + +static void cisco_start(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + hdlc->state.cisco.up = 0; + hdlc->state.cisco.request_sent = 0; + hdlc->state.cisco.txseq = hdlc->state.cisco.rxseq = 0; + + init_timer(&hdlc->state.cisco.timer); + hdlc->state.cisco.timer.expires = jiffies + HZ; /*First poll after 1s*/ + hdlc->state.cisco.timer.function = cisco_timer; + hdlc->state.cisco.timer.data = (unsigned long)dev; + add_timer(&hdlc->state.cisco.timer); +} + + + +static void cisco_stop(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + del_timer_sync(&hdlc->state.cisco.timer); +#if 0 + if (netif_carrier_ok(dev)) + netif_carrier_off(dev); +#endif + hdlc->state.cisco.up = 0; + hdlc->state.cisco.request_sent = 0; +} + + + +int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr) +{ + cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; + const size_t size = sizeof(cisco_proto); + cisco_proto new_settings; + hdlc_device *hdlc = dev_to_hdlc(dev); + int result; + + switch (ifr->ifr_settings.type) { + case IF_GET_PROTO: + ifr->ifr_settings.type = IF_PROTO_CISCO; + if (ifr->ifr_settings.size < size) { + ifr->ifr_settings.size = size; /* data size wanted */ + return -ENOBUFS; + } + if (copy_to_user(cisco_s, &hdlc->state.cisco.settings, size)) + return -EFAULT; + return 0; + + case IF_PROTO_CISCO: + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + + if(dev->flags & IFF_UP) + return -EBUSY; + + if (copy_from_user(&new_settings, cisco_s, size)) + return -EFAULT; + + if (new_settings.interval < 1 || + new_settings.timeout < 2) + return -EINVAL; + + result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); + + if (result) + return result; + + hdlc_proto_detach(hdlc); + memcpy(&hdlc->state.cisco.settings, &new_settings, size); + memset(&hdlc->proto, 0, sizeof(hdlc->proto)); + + hdlc->proto.start = cisco_start; + hdlc->proto.stop = cisco_stop; + hdlc->proto.netif_rx = cisco_rx; + hdlc->proto.type_trans = cisco_type_trans; + hdlc->proto.id = IF_PROTO_CISCO; + dev->hard_start_xmit = hdlc->xmit; + dev->hard_header = cisco_hard_header; + dev->hard_header_cache = NULL; + dev->type = ARPHRD_CISCO; + dev->flags = IFF_POINTOPOINT | IFF_NOARP; + dev->addr_len = 0; + return 0; + } + + return -EINVAL; +} diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_fr.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_fr.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_fr.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_fr.c 2008-02-04 17:00:48.000000000 -0600 @@ -0,0 +1,1273 @@ +/* + * Generic HDLC support routines for Linux + * Frame Relay support + * + * Copyright (C) 1999 - 2005 Krzysztof Halasa + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + + Theory of PVC state + + DCE mode: + + (exist,new) -> 0,0 when "PVC create" or if "link unreliable" + 0,x -> 1,1 if "link reliable" when sending FULL STATUS + 1,1 -> 1,0 if received FULL STATUS ACK + + (active) -> 0 when "ifconfig PVC down" or "link unreliable" or "PVC create" + -> 1 when "PVC up" and (exist,new) = 1,0 + + DTE mode: + (exist,new,active) = FULL STATUS if "link reliable" + = 0, 0, 0 if "link unreliable" + No LMI: + active = open and "link reliable" + exist = new = not used + + CCITT LMI: ITU-T Q.933 Annex A + ANSI LMI: ANSI T1.617 Annex D + CISCO LMI: the original, aka "Gang of Four" LMI + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG_PKT +#undef DEBUG_ECN +#undef DEBUG_LINK + +#define FR_UI 0x03 +#define FR_PAD 0x00 + +#define NLPID_IP 0xCC +#define NLPID_IPV6 0x8E +#define NLPID_SNAP 0x80 +#define NLPID_PAD 0x00 +#define NLPID_CCITT_ANSI_LMI 0x08 +#define NLPID_CISCO_LMI 0x09 + + +#define LMI_CCITT_ANSI_DLCI 0 /* LMI DLCI */ +#define LMI_CISCO_DLCI 1023 + +#define LMI_CALLREF 0x00 /* Call Reference */ +#define LMI_ANSI_LOCKSHIFT 0x95 /* ANSI locking shift */ +#define LMI_ANSI_CISCO_REPTYPE 0x01 /* report type */ +#define LMI_CCITT_REPTYPE 0x51 +#define LMI_ANSI_CISCO_ALIVE 0x03 /* keep alive */ +#define LMI_CCITT_ALIVE 0x53 +#define LMI_ANSI_CISCO_PVCSTAT 0x07 /* PVC status */ +#define LMI_CCITT_PVCSTAT 0x57 + +#define LMI_FULLREP 0x00 /* full report */ +#define LMI_INTEGRITY 0x01 /* link integrity report */ +#define LMI_SINGLE 0x02 /* single PVC report */ + +#define LMI_STATUS_ENQUIRY 0x75 +#define LMI_STATUS 0x7D /* reply */ + +#define LMI_REPT_LEN 1 /* report type element length */ +#define LMI_INTEG_LEN 2 /* link integrity element length */ + +#define LMI_CCITT_CISCO_LENGTH 13 /* LMI frame lengths */ +#define LMI_ANSI_LENGTH 14 + + +typedef struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned ea1: 1; + unsigned cr: 1; + unsigned dlcih: 6; + + unsigned ea2: 1; + unsigned de: 1; + unsigned becn: 1; + unsigned fecn: 1; + unsigned dlcil: 4; +#else + unsigned dlcih: 6; + unsigned cr: 1; + unsigned ea1: 1; + + unsigned dlcil: 4; + unsigned fecn: 1; + unsigned becn: 1; + unsigned de: 1; + unsigned ea2: 1; +#endif +}__attribute__ ((packed)) fr_hdr; + + +static inline u16 q922_to_dlci(u8 *hdr) +{ + return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4); +} + + + +static inline void dlci_to_q922(u8 *hdr, u16 dlci) +{ + hdr[0] = (dlci >> 2) & 0xFC; + hdr[1] = ((dlci << 4) & 0xF0) | 0x01; +} + + + +static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) +{ + pvc_device *pvc = hdlc->state.fr.first_pvc; + + while (pvc) { + if (pvc->dlci == dlci) + return pvc; + if (pvc->dlci > dlci) + return NULL; /* the listed is sorted */ + pvc = pvc->next; + } + + return NULL; +} + + +static inline pvc_device* add_pvc(struct net_device *dev, u16 dlci) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + pvc_device *pvc, **pvc_p = &hdlc->state.fr.first_pvc; + + while (*pvc_p) { + if ((*pvc_p)->dlci == dlci) + return *pvc_p; + if ((*pvc_p)->dlci > dlci) + break; /* the list is sorted */ + pvc_p = &(*pvc_p)->next; + } + + pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC); + if (!pvc) + return NULL; + + memset(pvc, 0, sizeof(pvc_device)); + pvc->dlci = dlci; + pvc->master = dev; + pvc->next = *pvc_p; /* Put it in the chain */ + *pvc_p = pvc; + return pvc; +} + + +static inline int pvc_is_used(pvc_device *pvc) +{ + return pvc->main != NULL || pvc->ether != NULL; +} + + +static inline void pvc_carrier(int on, pvc_device *pvc) +{ + if (on) { + if (pvc->main) + if (!netif_carrier_ok(pvc->main)) + netif_carrier_on(pvc->main); + if (pvc->ether) + if (!netif_carrier_ok(pvc->ether)) + netif_carrier_on(pvc->ether); + } else { + if (pvc->main) + if (netif_carrier_ok(pvc->main)) + netif_carrier_off(pvc->main); + if (pvc->ether) + if (netif_carrier_ok(pvc->ether)) + netif_carrier_off(pvc->ether); + } +} + + +static inline void delete_unused_pvcs(hdlc_device *hdlc) +{ + pvc_device **pvc_p = &hdlc->state.fr.first_pvc; + + while (*pvc_p) { + if (!pvc_is_used(*pvc_p)) { + pvc_device *pvc = *pvc_p; + *pvc_p = pvc->next; + kfree(pvc); + continue; + } + pvc_p = &(*pvc_p)->next; + } +} + + +static inline struct net_device** get_dev_p(pvc_device *pvc, int type) +{ + if (type == ARPHRD_ETHER) + return &pvc->ether; + else + return &pvc->main; +} + + +static int fr_hard_header(struct sk_buff **skb_p, u16 dlci) +{ + u16 head_len; + struct sk_buff *skb = *skb_p; + + switch (skb->protocol) { + case __constant_ntohs(NLPID_CCITT_ANSI_LMI): + head_len = 4; + skb_push(skb, head_len); + skb->data[3] = NLPID_CCITT_ANSI_LMI; + break; + + case __constant_ntohs(NLPID_CISCO_LMI): + head_len = 4; + skb_push(skb, head_len); + skb->data[3] = NLPID_CISCO_LMI; + break; + + case __constant_ntohs(ETH_P_IP): + head_len = 4; + skb_push(skb, head_len); + skb->data[3] = NLPID_IP; + break; + + case __constant_ntohs(ETH_P_IPV6): + head_len = 4; + skb_push(skb, head_len); + skb->data[3] = NLPID_IPV6; + break; + + case __constant_ntohs(ETH_P_802_3): + head_len = 10; + if (skb_headroom(skb) < head_len) { + struct sk_buff *skb2 = skb_realloc_headroom(skb, + head_len); + if (!skb2) + return -ENOBUFS; + dev_kfree_skb(skb); + skb = *skb_p = skb2; + } + skb_push(skb, head_len); + skb->data[3] = FR_PAD; + skb->data[4] = NLPID_SNAP; + skb->data[5] = FR_PAD; + skb->data[6] = 0x80; + skb->data[7] = 0xC2; + skb->data[8] = 0x00; + skb->data[9] = 0x07; /* bridged Ethernet frame w/out FCS */ + break; + + default: + head_len = 10; + skb_push(skb, head_len); + skb->data[3] = FR_PAD; + skb->data[4] = NLPID_SNAP; + skb->data[5] = FR_PAD; + skb->data[6] = FR_PAD; + skb->data[7] = FR_PAD; + *(u16*)(skb->data + 8) = skb->protocol; + } + + dlci_to_q922(skb->data, dlci); + skb->data[2] = FR_UI; + return 0; +} + + + +static int pvc_open(struct net_device *dev) +{ + pvc_device *pvc = dev_to_pvc(dev); + + if ((pvc->master->flags & IFF_UP) == 0) + return -EIO; /* Master must be UP in order to activate PVC */ + + if (pvc->open_count++ == 0) { + hdlc_device *hdlc = dev_to_hdlc(pvc->master); + if (hdlc->state.fr.settings.lmi == LMI_NONE) + pvc->state.active = hdlc->carrier; + + pvc_carrier(pvc->state.active, pvc); + hdlc->state.fr.dce_changed = 1; + } + return 0; +} + + + +static int pvc_close(struct net_device *dev) +{ + pvc_device *pvc = dev_to_pvc(dev); + + if (--pvc->open_count == 0) { + hdlc_device *hdlc = dev_to_hdlc(pvc->master); + if (hdlc->state.fr.settings.lmi == LMI_NONE) + pvc->state.active = 0; + + if (hdlc->state.fr.settings.dce) { + hdlc->state.fr.dce_changed = 1; + pvc->state.active = 0; + } + } + return 0; +} + + + +static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + pvc_device *pvc = dev_to_pvc(dev); + fr_proto_pvc_info info; + + if (ifr->ifr_settings.type == IF_GET_PROTO) { + if (dev->type == ARPHRD_ETHER) + ifr->ifr_settings.type = IF_PROTO_FR_ETH_PVC; + else + ifr->ifr_settings.type = IF_PROTO_FR_PVC; + + if (ifr->ifr_settings.size < sizeof(info)) { + /* data size wanted */ + ifr->ifr_settings.size = sizeof(info); + return -ENOBUFS; + } + + info.dlci = pvc->dlci; + memcpy(info.master, pvc->master->name, IFNAMSIZ); + if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info, + &info, sizeof(info))) + return -EFAULT; + return 0; + } + + return -EINVAL; +} + + +static inline struct net_device_stats *pvc_get_stats(struct net_device *dev) +{ + return netdev_priv(dev); +} + + + +static int pvc_xmit(struct sk_buff *skb, struct net_device *dev) +{ + pvc_device *pvc = dev_to_pvc(dev); + struct net_device_stats *stats = pvc_get_stats(dev); + + if (pvc->state.active) { + if (dev->type == ARPHRD_ETHER) { + int pad = ETH_ZLEN - skb->len; + if (pad > 0) { /* Pad the frame with zeros */ + int len = skb->len; + if (skb_tailroom(skb) < pad) + if (pskb_expand_head(skb, 0, pad, + GFP_ATOMIC)) { + stats->tx_dropped++; + dev_kfree_skb(skb); + return 0; + } + skb_put(skb, pad); + memset(skb->data + len, 0, pad); + } + skb->protocol = __constant_htons(ETH_P_802_3); + } + if (!fr_hard_header(&skb, pvc->dlci)) { + stats->tx_bytes += skb->len; + stats->tx_packets++; + if (pvc->state.fecn) /* TX Congestion counter */ + stats->tx_compressed++; + skb->dev = pvc->master; + dev_queue_xmit(skb); + return 0; + } + } + + stats->tx_dropped++; + dev_kfree_skb(skb); + return 0; +} + + + +static int pvc_change_mtu(struct net_device *dev, int new_mtu) +{ + if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU)) + return -EINVAL; + dev->mtu = new_mtu; + return 0; +} + + + +static inline void fr_log_dlci_active(pvc_device *pvc) +{ + printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n", + pvc->master->name, + pvc->dlci, + pvc->main ? pvc->main->name : "", + pvc->main && pvc->ether ? " " : "", + pvc->ether ? pvc->ether->name : "", + pvc->state.new ? " new" : "", + !pvc->state.exist ? "deleted" : + pvc->state.active ? "active" : "inactive"); +} + + + +static inline u8 fr_lmi_nextseq(u8 x) +{ + x++; + return x ? x : 1; +} + + + +static void fr_lmi_send(struct net_device *dev, int fullrep) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + struct sk_buff *skb; + pvc_device *pvc = hdlc->state.fr.first_pvc; + int lmi = hdlc->state.fr.settings.lmi; + int dce = hdlc->state.fr.settings.dce; + int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH; + int stat_len = (lmi == LMI_CISCO) ? 6 : 3; + u8 *data; + int i = 0; + + if (dce && fullrep) { + len += hdlc->state.fr.dce_pvc_count * (2 + stat_len); + if (len > HDLC_MAX_MRU) { + printk(KERN_WARNING "%s: Too many PVCs while sending " + "LMI full report\n", dev->name); + return; + } + } + + skb = dev_alloc_skb(len); + if (!skb) { + printk(KERN_WARNING "%s: Memory squeeze on fr_lmi_send()\n", + dev->name); + return; + } + memset(skb->data, 0, len); + skb_reserve(skb, 4); + if (lmi == LMI_CISCO) { + skb->protocol = __constant_htons(NLPID_CISCO_LMI); + fr_hard_header(&skb, LMI_CISCO_DLCI); + } else { + skb->protocol = __constant_htons(NLPID_CCITT_ANSI_LMI); + fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI); + } + data = skb->tail; + data[i++] = LMI_CALLREF; + data[i++] = dce ? LMI_STATUS : LMI_STATUS_ENQUIRY; + if (lmi == LMI_ANSI) + data[i++] = LMI_ANSI_LOCKSHIFT; + data[i++] = lmi == LMI_CCITT ? LMI_CCITT_REPTYPE : + LMI_ANSI_CISCO_REPTYPE; + data[i++] = LMI_REPT_LEN; + data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY; + data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE; + data[i++] = LMI_INTEG_LEN; + data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq); + data[i++] = hdlc->state.fr.rxseq; + + if (dce && fullrep) { + while (pvc) { + data[i++] = lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT : + LMI_ANSI_CISCO_PVCSTAT; + data[i++] = stat_len; + + /* LMI start/restart */ + if (hdlc->state.fr.reliable && !pvc->state.exist) { + pvc->state.exist = pvc->state.new = 1; + fr_log_dlci_active(pvc); + } + + /* ifconfig PVC up */ + if (pvc->open_count && !pvc->state.active && + pvc->state.exist && !pvc->state.new) { + pvc_carrier(1, pvc); + pvc->state.active = 1; + fr_log_dlci_active(pvc); + } + + if (lmi == LMI_CISCO) { + data[i] = pvc->dlci >> 8; + data[i + 1] = pvc->dlci & 0xFF; + } else { + data[i] = (pvc->dlci >> 4) & 0x3F; + data[i + 1] = ((pvc->dlci << 3) & 0x78) | 0x80; + data[i + 2] = 0x80; + } + + if (pvc->state.new) + data[i + 2] |= 0x08; + else if (pvc->state.active) + data[i + 2] |= 0x02; + + i += stat_len; + pvc = pvc->next; + } + } + + skb_put(skb, i); + skb->priority = TC_PRIO_CONTROL; + skb->dev = dev; + skb->nh.raw = skb->data; + + dev_queue_xmit(skb); +} + + + +static void fr_set_link_state(int reliable, struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + pvc_device *pvc = hdlc->state.fr.first_pvc; + + hdlc->state.fr.reliable = reliable; + if (reliable) { +#if 0 + if (!netif_carrier_ok(dev)) + netif_carrier_on(dev); +#endif + + hdlc->state.fr.n391cnt = 0; /* Request full status */ + hdlc->state.fr.dce_changed = 1; + + if (hdlc->state.fr.settings.lmi == LMI_NONE) { + while (pvc) { /* Activate all PVCs */ + pvc_carrier(1, pvc); + pvc->state.exist = pvc->state.active = 1; + pvc->state.new = 0; + pvc = pvc->next; + } + } + } else { +#if 0 + if (netif_carrier_ok(dev)) + netif_carrier_off(dev); +#endif + + while (pvc) { /* Deactivate all PVCs */ + pvc_carrier(0, pvc); + pvc->state.exist = pvc->state.active = 0; + pvc->state.new = 0; + if (!hdlc->state.fr.settings.dce) + pvc->state.bandwidth = 0; + pvc = pvc->next; + } + } +} + + + +static void fr_timer(unsigned long arg) +{ + struct net_device *dev = (struct net_device *)arg; + hdlc_device *hdlc = dev_to_hdlc(dev); + int i, cnt = 0, reliable; + u32 list; + + if (hdlc->state.fr.settings.dce) { + reliable = hdlc->state.fr.request && + time_before(jiffies, hdlc->state.fr.last_poll + + hdlc->state.fr.settings.t392 * HZ); + hdlc->state.fr.request = 0; + } else { + hdlc->state.fr.last_errors <<= 1; /* Shift the list */ + if (hdlc->state.fr.request) { + if (hdlc->state.fr.reliable) + printk(KERN_INFO "%s: No LMI status reply " + "received\n", dev->name); + hdlc->state.fr.last_errors |= 1; + } + + list = hdlc->state.fr.last_errors; + for (i = 0; i < hdlc->state.fr.settings.n393; i++, list >>= 1) + cnt += (list & 1); /* errors count */ + + reliable = (cnt < hdlc->state.fr.settings.n392); + } + + if (hdlc->state.fr.reliable != reliable) { + printk(KERN_INFO "%s: Link %sreliable\n", dev->name, + reliable ? "" : "un"); + fr_set_link_state(reliable, dev); + } + + if (hdlc->state.fr.settings.dce) + hdlc->state.fr.timer.expires = jiffies + + hdlc->state.fr.settings.t392 * HZ; + else { + if (hdlc->state.fr.n391cnt) + hdlc->state.fr.n391cnt--; + + fr_lmi_send(dev, hdlc->state.fr.n391cnt == 0); + + hdlc->state.fr.last_poll = jiffies; + hdlc->state.fr.request = 1; + hdlc->state.fr.timer.expires = jiffies + + hdlc->state.fr.settings.t391 * HZ; + } + + hdlc->state.fr.timer.function = fr_timer; + hdlc->state.fr.timer.data = arg; + add_timer(&hdlc->state.fr.timer); +} + + + +static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + pvc_device *pvc; + u8 rxseq, txseq; + int lmi = hdlc->state.fr.settings.lmi; + int dce = hdlc->state.fr.settings.dce; + int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i; + + if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH : + LMI_CCITT_CISCO_LENGTH)) { + printk(KERN_INFO "%s: Short LMI frame\n", dev->name); + return 1; + } + + if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI : + NLPID_CCITT_ANSI_LMI)) { + printk(KERN_INFO "%s: Received non-LMI frame with LMI" + " DLCI\n", dev->name); + return 1; + } + + if (skb->data[4] != LMI_CALLREF) { + printk(KERN_INFO "%s: Invalid LMI Call reference (0x%02X)\n", + dev->name, skb->data[4]); + return 1; + } + + if (skb->data[5] != (dce ? LMI_STATUS_ENQUIRY : LMI_STATUS)) { + printk(KERN_INFO "%s: Invalid LMI Message type (0x%02X)\n", + dev->name, skb->data[5]); + return 1; + } + + if (lmi == LMI_ANSI) { + if (skb->data[6] != LMI_ANSI_LOCKSHIFT) { + printk(KERN_INFO "%s: Not ANSI locking shift in LMI" + " message (0x%02X)\n", dev->name, skb->data[6]); + return 1; + } + i = 7; + } else + i = 6; + + if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_REPTYPE : + LMI_ANSI_CISCO_REPTYPE)) { + printk(KERN_INFO "%s: Not an LMI Report type IE (0x%02X)\n", + dev->name, skb->data[i]); + return 1; + } + + if (skb->data[++i] != LMI_REPT_LEN) { + printk(KERN_INFO "%s: Invalid LMI Report type IE length" + " (%u)\n", dev->name, skb->data[i]); + return 1; + } + + reptype = skb->data[++i]; + if (reptype != LMI_INTEGRITY && reptype != LMI_FULLREP) { + printk(KERN_INFO "%s: Unsupported LMI Report type (0x%02X)\n", + dev->name, reptype); + return 1; + } + + if (skb->data[++i] != (lmi == LMI_CCITT ? LMI_CCITT_ALIVE : + LMI_ANSI_CISCO_ALIVE)) { + printk(KERN_INFO "%s: Not an LMI Link integrity verification" + " IE (0x%02X)\n", dev->name, skb->data[i]); + return 1; + } + + if (skb->data[++i] != LMI_INTEG_LEN) { + printk(KERN_INFO "%s: Invalid LMI Link integrity verification" + " IE length (%u)\n", dev->name, skb->data[i]); + return 1; + } + i++; + + hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */ + rxseq = skb->data[i++]; /* Should confirm our sequence */ + + txseq = hdlc->state.fr.txseq; + + if (dce) + hdlc->state.fr.last_poll = jiffies; + + error = 0; + if (!hdlc->state.fr.reliable) + error = 1; + + if (rxseq == 0 || rxseq != txseq) { + hdlc->state.fr.n391cnt = 0; /* Ask for full report next time */ + error = 1; + } + + if (dce) { + if (hdlc->state.fr.fullrep_sent && !error) { +/* Stop sending full report - the last one has been confirmed by DTE */ + hdlc->state.fr.fullrep_sent = 0; + pvc = hdlc->state.fr.first_pvc; + while (pvc) { + if (pvc->state.new) { + pvc->state.new = 0; + +/* Tell DTE that new PVC is now active */ + hdlc->state.fr.dce_changed = 1; + } + pvc = pvc->next; + } + } + + if (hdlc->state.fr.dce_changed) { + reptype = LMI_FULLREP; + hdlc->state.fr.fullrep_sent = 1; + hdlc->state.fr.dce_changed = 0; + } + + hdlc->state.fr.request = 1; /* got request */ + fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0); + return 0; + } + + /* DTE */ + + hdlc->state.fr.request = 0; /* got response, no request pending */ + + if (error) + return 0; + + if (reptype != LMI_FULLREP) + return 0; + + pvc = hdlc->state.fr.first_pvc; + + while (pvc) { + pvc->state.deleted = 1; + pvc = pvc->next; + } + + no_ram = 0; + while (skb->len >= i + 2 + stat_len) { + u16 dlci; + u32 bw; + unsigned int active, new; + + if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT : + LMI_ANSI_CISCO_PVCSTAT)) { + printk(KERN_INFO "%s: Not an LMI PVC status IE" + " (0x%02X)\n", dev->name, skb->data[i]); + return 1; + } + + if (skb->data[++i] != stat_len) { + printk(KERN_INFO "%s: Invalid LMI PVC status IE length" + " (%u)\n", dev->name, skb->data[i]); + return 1; + } + i++; + + new = !! (skb->data[i + 2] & 0x08); + active = !! (skb->data[i + 2] & 0x02); + if (lmi == LMI_CISCO) { + dlci = (skb->data[i] << 8) | skb->data[i + 1]; + bw = (skb->data[i + 3] << 16) | + (skb->data[i + 4] << 8) | + (skb->data[i + 5]); + } else { + dlci = ((skb->data[i] & 0x3F) << 4) | + ((skb->data[i + 1] & 0x78) >> 3); + bw = 0; + } + + pvc = add_pvc(dev, dlci); + + if (!pvc && !no_ram) { + printk(KERN_WARNING + "%s: Memory squeeze on fr_lmi_recv()\n", + dev->name); + no_ram = 1; + } + + if (pvc) { + pvc->state.exist = 1; + pvc->state.deleted = 0; + if (active != pvc->state.active || + new != pvc->state.new || + bw != pvc->state.bandwidth || + !pvc->state.exist) { + pvc->state.new = new; + pvc->state.active = active; + pvc->state.bandwidth = bw; + pvc_carrier(active, pvc); + fr_log_dlci_active(pvc); + } + } + + i += stat_len; + } + + pvc = hdlc->state.fr.first_pvc; + + while (pvc) { + if (pvc->state.deleted && pvc->state.exist) { + pvc_carrier(0, pvc); + pvc->state.active = pvc->state.new = 0; + pvc->state.exist = 0; + pvc->state.bandwidth = 0; + fr_log_dlci_active(pvc); + } + pvc = pvc->next; + } + + /* Next full report after N391 polls */ + hdlc->state.fr.n391cnt = hdlc->state.fr.settings.n391; + + return 0; +} + + + +static int fr_rx(struct sk_buff *skb) +{ + struct net_device *ndev = skb->dev; + hdlc_device *hdlc = dev_to_hdlc(ndev); + fr_hdr *fh = (fr_hdr*)skb->data; + u8 *data = skb->data; + u16 dlci; + pvc_device *pvc; + struct net_device *dev = NULL; + + if (skb->len <= 4 || fh->ea1 || data[2] != FR_UI) + goto rx_error; + + dlci = q922_to_dlci(skb->data); + + if ((dlci == LMI_CCITT_ANSI_DLCI && + (hdlc->state.fr.settings.lmi == LMI_ANSI || + hdlc->state.fr.settings.lmi == LMI_CCITT)) || + (dlci == LMI_CISCO_DLCI && + hdlc->state.fr.settings.lmi == LMI_CISCO)) { + if (fr_lmi_recv(ndev, skb)) + goto rx_error; + dev_kfree_skb_any(skb); + return NET_RX_SUCCESS; + } + + pvc = find_pvc(hdlc, dlci); + if (!pvc) { +#ifdef DEBUG_PKT + printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n", + ndev->name, dlci); +#endif + dev_kfree_skb_any(skb); + return NET_RX_DROP; + } + + if (pvc->state.fecn != fh->fecn) { +#ifdef DEBUG_ECN + printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", ndev->name, + dlci, fh->fecn ? "N" : "FF"); +#endif + pvc->state.fecn ^= 1; + } + + if (pvc->state.becn != fh->becn) { +#ifdef DEBUG_ECN + printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", ndev->name, + dlci, fh->becn ? "N" : "FF"); +#endif + pvc->state.becn ^= 1; + } + + + if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { + hdlc->stats.rx_dropped++; + return NET_RX_DROP; + } + + if (data[3] == NLPID_IP) { + skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */ + dev = pvc->main; + skb->protocol = htons(ETH_P_IP); + + } else if (data[3] == NLPID_IPV6) { + skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */ + dev = pvc->main; + skb->protocol = htons(ETH_P_IPV6); + + } else if (skb->len > 10 && data[3] == FR_PAD && + data[4] == NLPID_SNAP && data[5] == FR_PAD) { + u16 oui = ntohs(*(u16*)(data + 6)); + u16 pid = ntohs(*(u16*)(data + 8)); + skb_pull(skb, 10); + + switch ((((u32)oui) << 16) | pid) { + case ETH_P_ARP: /* routed frame with SNAP */ + case ETH_P_IPX: + case ETH_P_IP: /* a long variant */ + case ETH_P_IPV6: + dev = pvc->main; + skb->protocol = htons(pid); + break; + + case 0x80C20007: /* bridged Ethernet frame */ + if ((dev = pvc->ether) != NULL) + skb->protocol = eth_type_trans(skb, dev); + break; + + default: + printk(KERN_INFO "%s: Unsupported protocol, OUI=%x " + "PID=%x\n", ndev->name, oui, pid); + dev_kfree_skb_any(skb); + return NET_RX_DROP; + } + } else { + printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x " + "length = %i\n", ndev->name, data[3], skb->len); + dev_kfree_skb_any(skb); + return NET_RX_DROP; + } + + if (dev) { + struct net_device_stats *stats = pvc_get_stats(dev); + stats->rx_packets++; /* PVC traffic */ + stats->rx_bytes += skb->len; + if (pvc->state.becn) + stats->rx_compressed++; + skb->dev = dev; + netif_rx(skb); + return NET_RX_SUCCESS; + } else { + dev_kfree_skb_any(skb); + return NET_RX_DROP; + } + + rx_error: + hdlc->stats.rx_errors++; /* Mark error */ + dev_kfree_skb_any(skb); + return NET_RX_DROP; +} + + + +static void fr_start(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); +#ifdef DEBUG_LINK + printk(KERN_DEBUG "fr_start\n"); +#endif + if (hdlc->state.fr.settings.lmi != LMI_NONE) { + hdlc->state.fr.reliable = 0; + hdlc->state.fr.dce_changed = 1; + hdlc->state.fr.request = 0; + hdlc->state.fr.fullrep_sent = 0; + hdlc->state.fr.last_errors = 0xFFFFFFFF; + hdlc->state.fr.n391cnt = 0; + hdlc->state.fr.txseq = hdlc->state.fr.rxseq = 0; + + init_timer(&hdlc->state.fr.timer); + /* First poll after 1 s */ + hdlc->state.fr.timer.expires = jiffies + HZ; + hdlc->state.fr.timer.function = fr_timer; + hdlc->state.fr.timer.data = (unsigned long)dev; + add_timer(&hdlc->state.fr.timer); + } else + fr_set_link_state(1, dev); +} + + + +static void fr_stop(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); +#ifdef DEBUG_LINK + printk(KERN_DEBUG "fr_stop\n"); +#endif + if (hdlc->state.fr.settings.lmi != LMI_NONE) + del_timer_sync(&hdlc->state.fr.timer); + fr_set_link_state(0, dev); +} + + + +static void fr_close(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + pvc_device *pvc = hdlc->state.fr.first_pvc; + + while (pvc) { /* Shutdown all PVCs for this FRAD */ + if (pvc->main) + dev_close(pvc->main); + if (pvc->ether) + dev_close(pvc->ether); + pvc = pvc->next; + } +} + +static void dlci_setup(struct net_device *dev) +{ + dev->type = ARPHRD_DLCI; + dev->flags = IFF_POINTOPOINT; + dev->hard_header_len = 10; + dev->addr_len = 2; +} + +static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type) +{ + hdlc_device *hdlc = dev_to_hdlc(master); + pvc_device *pvc = NULL; + struct net_device *dev; + int result, used; + char * prefix = "pvc%d"; + + if (type == ARPHRD_ETHER) + prefix = "pvceth%d"; + + if ((pvc = add_pvc(master, dlci)) == NULL) { + printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n", + master->name); + return -ENOBUFS; + } + + if (*get_dev_p(pvc, type)) + return -EEXIST; + + used = pvc_is_used(pvc); + + if (type == ARPHRD_ETHER) + dev = alloc_netdev(sizeof(struct net_device_stats), + "pvceth%d", ether_setup); + else + dev = alloc_netdev(sizeof(struct net_device_stats), + "pvc%d", dlci_setup); + + if (!dev) { + printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", + master->name); + delete_unused_pvcs(hdlc); + return -ENOBUFS; + } + + if (type == ARPHRD_ETHER) { + memcpy(dev->dev_addr, "\x00\x01", 2); + get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2); + } else { + *(u16*)dev->dev_addr = htons(dlci); + dlci_to_q922(dev->broadcast, dlci); + } + dev->hard_start_xmit = pvc_xmit; + dev->get_stats = pvc_get_stats; + dev->open = pvc_open; + dev->stop = pvc_close; + dev->do_ioctl = pvc_ioctl; + dev->change_mtu = pvc_change_mtu; + dev->mtu = HDLC_MAX_MTU; + dev->tx_queue_len = 0; + dev->priv = pvc; + + result = dev_alloc_name(dev, dev->name); + if (result < 0) { + free_netdev(dev); + delete_unused_pvcs(hdlc); + return result; + } + + if (register_netdevice(dev) != 0) { + free_netdev(dev); + delete_unused_pvcs(hdlc); + return -EIO; + } + + dev->destructor = free_netdev; + *get_dev_p(pvc, type) = dev; + if (!used) { + hdlc->state.fr.dce_changed = 1; + hdlc->state.fr.dce_pvc_count++; + } + return 0; +} + + + +static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type) +{ + pvc_device *pvc; + struct net_device *dev; + + if ((pvc = find_pvc(hdlc, dlci)) == NULL) + return -ENOENT; + + if ((dev = *get_dev_p(pvc, type)) == NULL) + return -ENOENT; + + if (dev->flags & IFF_UP) + return -EBUSY; /* PVC in use */ + + unregister_netdevice(dev); /* the destructor will free_netdev(dev) */ + *get_dev_p(pvc, type) = NULL; + + if (!pvc_is_used(pvc)) { + hdlc->state.fr.dce_pvc_count--; + hdlc->state.fr.dce_changed = 1; + } + delete_unused_pvcs(hdlc); + return 0; +} + + + +static void fr_destroy(hdlc_device *hdlc) +{ + pvc_device *pvc; + + pvc = hdlc->state.fr.first_pvc; + hdlc->state.fr.first_pvc = NULL; /* All PVCs destroyed */ + hdlc->state.fr.dce_pvc_count = 0; + hdlc->state.fr.dce_changed = 1; + + while (pvc) { + pvc_device *next = pvc->next; + /* destructors will free_netdev() main and ether */ + if (pvc->main) + unregister_netdevice(pvc->main); + + if (pvc->ether) + unregister_netdevice(pvc->ether); + + kfree(pvc); + pvc = next; + } +} + + + +int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr) +{ + fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr; + const size_t size = sizeof(fr_proto); + fr_proto new_settings; + hdlc_device *hdlc = dev_to_hdlc(dev); + fr_proto_pvc pvc; + int result; + + switch (ifr->ifr_settings.type) { + case IF_GET_PROTO: + ifr->ifr_settings.type = IF_PROTO_FR; + if (ifr->ifr_settings.size < size) { + ifr->ifr_settings.size = size; /* data size wanted */ + return -ENOBUFS; + } + if (copy_to_user(fr_s, &hdlc->state.fr.settings, size)) + return -EFAULT; + return 0; + + case IF_PROTO_FR: + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + + if(dev->flags & IFF_UP) + return -EBUSY; + + if (copy_from_user(&new_settings, fr_s, size)) + return -EFAULT; + + if (new_settings.lmi == LMI_DEFAULT) + new_settings.lmi = LMI_ANSI; + + if ((new_settings.lmi != LMI_NONE && + new_settings.lmi != LMI_ANSI && + new_settings.lmi != LMI_CCITT && + new_settings.lmi != LMI_CISCO) || + new_settings.t391 < 1 || + new_settings.t392 < 2 || + new_settings.n391 < 1 || + new_settings.n392 < 1 || + new_settings.n393 < new_settings.n392 || + new_settings.n393 > 32 || + (new_settings.dce != 0 && + new_settings.dce != 1)) + return -EINVAL; + + result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); + if (result) + return result; + + if (hdlc->proto.id != IF_PROTO_FR) { + hdlc_proto_detach(hdlc); + hdlc->state.fr.first_pvc = NULL; + hdlc->state.fr.dce_pvc_count = 0; + } + memcpy(&hdlc->state.fr.settings, &new_settings, size); + memset(&hdlc->proto, 0, sizeof(hdlc->proto)); + + hdlc->proto.close = fr_close; + hdlc->proto.start = fr_start; + hdlc->proto.stop = fr_stop; + hdlc->proto.detach = fr_destroy; + hdlc->proto.netif_rx = fr_rx; + hdlc->proto.id = IF_PROTO_FR; + dev->hard_start_xmit = hdlc->xmit; + dev->hard_header = NULL; + dev->type = ARPHRD_FRAD; + dev->flags = IFF_POINTOPOINT | IFF_NOARP; + dev->addr_len = 0; + return 0; + + case IF_PROTO_FR_ADD_PVC: + case IF_PROTO_FR_DEL_PVC: + case IF_PROTO_FR_ADD_ETH_PVC: + case IF_PROTO_FR_DEL_ETH_PVC: + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (copy_from_user(&pvc, ifr->ifr_settings.ifs_ifsu.fr_pvc, + sizeof(fr_proto_pvc))) + return -EFAULT; + + if (pvc.dlci <= 0 || pvc.dlci >= 1024) + return -EINVAL; /* Only 10 bits, DLCI 0 reserved */ + + if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC || + ifr->ifr_settings.type == IF_PROTO_FR_DEL_ETH_PVC) + result = ARPHRD_ETHER; /* bridged Ethernet device */ + else + result = ARPHRD_DLCI; + + if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC || + ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC) + return fr_add_pvc(dev, pvc.dlci, result); + else + return fr_del_pvc(hdlc, pvc.dlci, result); + } + + return -EINVAL; +} diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_generic.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_generic.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_generic.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_generic.c 2008-02-04 17:00:48.000000000 -0600 @@ -0,0 +1,355 @@ +/* + * Generic HDLC support routines for Linux + * + * Copyright (C) 1999 - 2005 Krzysztof Halasa + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * Currently supported: + * * raw IP-in-HDLC + * * Cisco HDLC + * * Frame Relay with ANSI or CCITT LMI (both user and network side) + * * PPP + * * X.25 + * + * Use sethdlc utility to set line parameters, protocol and PVCs + * + * How does it work: + * - proto.open(), close(), start(), stop() calls are serialized. + * The order is: open, [ start, stop ... ] close ... + * - proto.start() and stop() are called with spin_lock_irq held. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const char* version = "HDLC support module revision 1.18"; + +#undef DEBUG_LINK + + +static int hdlc_change_mtu(struct net_device *dev, int new_mtu) +{ + if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU)) + return -EINVAL; + dev->mtu = new_mtu; + return 0; +} + + + +static struct net_device_stats *hdlc_get_stats(struct net_device *dev) +{ + return hdlc_stats(dev); +} + + + +static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *p, struct net_device *orig_dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + if (hdlc->proto.netif_rx) + return hdlc->proto.netif_rx(skb); + + hdlc->stats.rx_dropped++; /* Shouldn't happen */ + dev_kfree_skb(skb); + return NET_RX_DROP; +} + + + +static void __hdlc_set_carrier_on(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + if (hdlc->proto.start) + return hdlc->proto.start(dev); +#if 0 +#ifdef DEBUG_LINK + if (netif_carrier_ok(dev)) + printk(KERN_ERR "hdlc_set_carrier_on(): already on\n"); +#endif + netif_carrier_on(dev); +#endif +} + + + +static void __hdlc_set_carrier_off(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + if (hdlc->proto.stop) + return hdlc->proto.stop(dev); + +#if 0 +#ifdef DEBUG_LINK + if (!netif_carrier_ok(dev)) + printk(KERN_ERR "hdlc_set_carrier_off(): already off\n"); +#endif + netif_carrier_off(dev); +#endif +} + + + +void hdlc_set_carrier(int on, struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + unsigned long flags; + on = on ? 1 : 0; + +#ifdef DEBUG_LINK + printk(KERN_DEBUG "hdlc_set_carrier %i\n", on); +#endif + + spin_lock_irqsave(&hdlc->state_lock, flags); + + if (hdlc->carrier == on) + goto carrier_exit; /* no change in DCD line level */ + +#ifdef DEBUG_LINK + printk(KERN_INFO "%s: carrier %s\n", dev->name, on ? "ON" : "off"); +#endif + hdlc->carrier = on; + + if (!hdlc->open) + goto carrier_exit; + + if (hdlc->carrier) { + printk(KERN_INFO "%s: Carrier detected\n", dev->name); + __hdlc_set_carrier_on(dev); + } else { + printk(KERN_INFO "%s: Carrier lost\n", dev->name); + __hdlc_set_carrier_off(dev); + } + +carrier_exit: + spin_unlock_irqrestore(&hdlc->state_lock, flags); +} + + + +/* Must be called by hardware driver when HDLC device is being opened */ +int hdlc_open(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); +#ifdef DEBUG_LINK + printk(KERN_DEBUG "hdlc_open() carrier %i open %i\n", + hdlc->carrier, hdlc->open); +#endif + + if (hdlc->proto.id == -1) + return -ENOSYS; /* no protocol attached */ + + if (hdlc->proto.open) { + int result = hdlc->proto.open(dev); + if (result) + return result; + } + + spin_lock_irq(&hdlc->state_lock); + + if (hdlc->carrier) { + printk(KERN_INFO "%s: Carrier detected\n", dev->name); + __hdlc_set_carrier_on(dev); + } else + printk(KERN_INFO "%s: No carrier\n", dev->name); + + hdlc->open = 1; + + spin_unlock_irq(&hdlc->state_lock); + return 0; +} + + + +/* Must be called by hardware driver when HDLC device is being closed */ +void hdlc_close(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); +#ifdef DEBUG_LINK + printk(KERN_DEBUG "hdlc_close() carrier %i open %i\n", + hdlc->carrier, hdlc->open); +#endif + + spin_lock_irq(&hdlc->state_lock); + + hdlc->open = 0; + if (hdlc->carrier) + __hdlc_set_carrier_off(dev); + + spin_unlock_irq(&hdlc->state_lock); + + if (hdlc->proto.close) + hdlc->proto.close(dev); +} + + + +#ifndef CONFIG_HDLC_RAW +#define hdlc_raw_ioctl(dev, ifr) -ENOSYS +#endif + +#ifndef CONFIG_HDLC_RAW_ETH +#define hdlc_raw_eth_ioctl(dev, ifr) -ENOSYS +#endif + +#ifndef CONFIG_HDLC_PPP +#define hdlc_ppp_ioctl(dev, ifr) -ENOSYS +#endif + +#ifndef CONFIG_HDLC_CISCO +#define hdlc_cisco_ioctl(dev, ifr) -ENOSYS +#endif + +#ifndef CONFIG_HDLC_FR +#define hdlc_fr_ioctl(dev, ifr) -ENOSYS +#endif + +#ifndef CONFIG_HDLC_X25 +#define hdlc_x25_ioctl(dev, ifr) -ENOSYS +#endif + + +int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + unsigned int proto; + + if (cmd != SIOCWANDEV) + return -EINVAL; + + switch(ifr->ifr_settings.type) { + case IF_PROTO_HDLC: + case IF_PROTO_HDLC_ETH: + case IF_PROTO_PPP: + case IF_PROTO_CISCO: + case IF_PROTO_FR: + case IF_PROTO_X25: + proto = ifr->ifr_settings.type; + break; + + default: + proto = hdlc->proto.id; + } + + switch(proto) { + case IF_PROTO_HDLC: return hdlc_raw_ioctl(dev, ifr); + case IF_PROTO_HDLC_ETH: return hdlc_raw_eth_ioctl(dev, ifr); + case IF_PROTO_PPP: return hdlc_ppp_ioctl(dev, ifr); + case IF_PROTO_CISCO: return hdlc_cisco_ioctl(dev, ifr); + case IF_PROTO_FR: return hdlc_fr_ioctl(dev, ifr); + case IF_PROTO_X25: return hdlc_x25_ioctl(dev, ifr); + default: return -EINVAL; + } +} + +static void hdlc_setup(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + + dev->get_stats = hdlc_get_stats; + dev->change_mtu = hdlc_change_mtu; + dev->mtu = HDLC_MAX_MTU; + + dev->type = ARPHRD_RAWHDLC; + dev->hard_header_len = 16; + + dev->flags = IFF_POINTOPOINT | IFF_NOARP; + + hdlc->proto.id = -1; + hdlc->proto.detach = NULL; + hdlc->carrier = 1; + hdlc->open = 0; + spin_lock_init(&hdlc->state_lock); +} + +struct net_device *alloc_hdlcdev(void *priv) +{ + struct net_device *dev; + dev = alloc_netdev(sizeof(hdlc_device), "hdlc%d", hdlc_setup); + if (dev) + dev_to_hdlc(dev)->priv = priv; + return dev; +} + +int register_hdlc_device(struct net_device *dev) +{ + int result = dev_alloc_name(dev, "hdlc%d"); + if (result < 0) + return result; + + result = register_netdev(dev); + if (result != 0) + return -EIO; + +#if 0 + if (netif_carrier_ok(dev)) + netif_carrier_off(dev); /* no carrier until DCD goes up */ +#endif + + return 0; +} + + + +void unregister_hdlc_device(struct net_device *dev) +{ + rtnl_lock(); + hdlc_proto_detach(dev_to_hdlc(dev)); + unregister_netdevice(dev); + rtnl_unlock(); +} + + + +MODULE_AUTHOR("Krzysztof Halasa "); +MODULE_DESCRIPTION("HDLC support module"); +MODULE_LICENSE("GPL v2"); + +EXPORT_SYMBOL(hdlc_open); +EXPORT_SYMBOL(hdlc_close); +EXPORT_SYMBOL(hdlc_set_carrier); +EXPORT_SYMBOL(hdlc_ioctl); +EXPORT_SYMBOL(alloc_hdlcdev); +EXPORT_SYMBOL(register_hdlc_device); +EXPORT_SYMBOL(unregister_hdlc_device); + +static struct packet_type hdlc_packet_type = { + .type = __constant_htons(ETH_P_HDLC), + .func = hdlc_rcv, +}; + + +static int __init hdlc_module_init(void) +{ + printk(KERN_INFO "%s\n", version); + dev_add_pack(&hdlc_packet_type); + return 0; +} + + + +static void __exit hdlc_module_exit(void) +{ + dev_remove_pack(&hdlc_packet_type); +} + + +module_init(hdlc_module_init); +module_exit(hdlc_module_exit); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_ppp.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_ppp.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_ppp.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_ppp.c 2008-02-04 17:00:48.000000000 -0600 @@ -0,0 +1,114 @@ +/* + * Generic HDLC support routines for Linux + * Point-to-point protocol support + * + * Copyright (C) 1999 - 2003 Krzysztof Halasa + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int ppp_open(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + void *old_ioctl; + int result; + + dev->priv = &hdlc->state.ppp.syncppp_ptr; + hdlc->state.ppp.syncppp_ptr = &hdlc->state.ppp.pppdev; + hdlc->state.ppp.pppdev.dev = dev; + + old_ioctl = dev->do_ioctl; + hdlc->state.ppp.old_change_mtu = dev->change_mtu; + sppp_attach(&hdlc->state.ppp.pppdev); + /* sppp_attach nukes them. We don't need syncppp's ioctl */ + dev->do_ioctl = old_ioctl; + hdlc->state.ppp.pppdev.sppp.pp_flags &= ~PP_CISCO; + dev->type = ARPHRD_PPP; + result = sppp_open(dev); + if (result) { + sppp_detach(dev); + return result; + } + + return 0; +} + + + +static void ppp_close(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + + sppp_close(dev); + sppp_detach(dev); + dev->rebuild_header = NULL; + dev->change_mtu = hdlc->state.ppp.old_change_mtu; + dev->mtu = HDLC_MAX_MTU; + dev->hard_header_len = 16; +} + + + +static __be16 ppp_type_trans(struct sk_buff *skb, struct net_device *dev) +{ + return __constant_htons(ETH_P_WAN_PPP); +} + + + +int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + int result; + + switch (ifr->ifr_settings.type) { + case IF_GET_PROTO: + ifr->ifr_settings.type = IF_PROTO_PPP; + return 0; /* return protocol only, no settable parameters */ + + case IF_PROTO_PPP: + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + + if(dev->flags & IFF_UP) + return -EBUSY; + + /* no settable parameters */ + + result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); + if (result) + return result; + + hdlc_proto_detach(hdlc); + memset(&hdlc->proto, 0, sizeof(hdlc->proto)); + + hdlc->proto.open = ppp_open; + hdlc->proto.close = ppp_close; + hdlc->proto.type_trans = ppp_type_trans; + hdlc->proto.id = IF_PROTO_PPP; + dev->hard_start_xmit = hdlc->xmit; + dev->hard_header = NULL; + dev->type = ARPHRD_PPP; + dev->addr_len = 0; + return 0; + } + + return -EINVAL; +} diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_raw.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_raw.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_raw.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_raw.c 2008-02-04 17:00:48.000000000 -0600 @@ -0,0 +1,89 @@ +/* + * Generic HDLC support routines for Linux + * HDLC support + * + * Copyright (C) 1999 - 2003 Krzysztof Halasa + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev) +{ + return __constant_htons(ETH_P_IP); +} + + + +int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr) +{ + raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; + const size_t size = sizeof(raw_hdlc_proto); + raw_hdlc_proto new_settings; + hdlc_device *hdlc = dev_to_hdlc(dev); + int result; + + switch (ifr->ifr_settings.type) { + case IF_GET_PROTO: + ifr->ifr_settings.type = IF_PROTO_HDLC; + if (ifr->ifr_settings.size < size) { + ifr->ifr_settings.size = size; /* data size wanted */ + return -ENOBUFS; + } + if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size)) + return -EFAULT; + return 0; + + case IF_PROTO_HDLC: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (dev->flags & IFF_UP) + return -EBUSY; + + if (copy_from_user(&new_settings, raw_s, size)) + return -EFAULT; + + if (new_settings.encoding == ENCODING_DEFAULT) + new_settings.encoding = ENCODING_NRZ; + + if (new_settings.parity == PARITY_DEFAULT) + new_settings.parity = PARITY_CRC16_PR1_CCITT; + + result = hdlc->attach(dev, new_settings.encoding, + new_settings.parity); + if (result) + return result; + + hdlc_proto_detach(hdlc); + memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size); + memset(&hdlc->proto, 0, sizeof(hdlc->proto)); + + hdlc->proto.type_trans = raw_type_trans; + hdlc->proto.id = IF_PROTO_HDLC; + dev->hard_start_xmit = hdlc->xmit; + dev->hard_header = NULL; + dev->type = ARPHRD_RAWHDLC; + dev->flags = IFF_POINTOPOINT | IFF_NOARP; + dev->addr_len = 0; + return 0; + } + + return -EINVAL; +} diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_raw_eth.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_raw_eth.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_raw_eth.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/hdlc_raw_eth.c 2008-02-04 17:00:48.000000000 -0600 @@ -0,0 +1,107 @@ +/* + * Generic HDLC support routines for Linux + * HDLC Ethernet emulation support + * + * Copyright (C) 2002-2003 Krzysztof Halasa + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int eth_tx(struct sk_buff *skb, struct net_device *dev) +{ + int pad = ETH_ZLEN - skb->len; + if (pad > 0) { /* Pad the frame with zeros */ + int len = skb->len; + if (skb_tailroom(skb) < pad) + if (pskb_expand_head(skb, 0, pad, GFP_ATOMIC)) { + hdlc_stats(dev)->tx_dropped++; + dev_kfree_skb(skb); + return 0; + } + skb_put(skb, pad); + memset(skb->data + len, 0, pad); + } + return dev_to_hdlc(dev)->xmit(skb, dev); +} + + +int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) +{ + raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; + const size_t size = sizeof(raw_hdlc_proto); + raw_hdlc_proto new_settings; + hdlc_device *hdlc = dev_to_hdlc(dev); + int result; + void *old_ch_mtu; + int old_qlen; + + switch (ifr->ifr_settings.type) { + case IF_GET_PROTO: + ifr->ifr_settings.type = IF_PROTO_HDLC_ETH; + if (ifr->ifr_settings.size < size) { + ifr->ifr_settings.size = size; /* data size wanted */ + return -ENOBUFS; + } + if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size)) + return -EFAULT; + return 0; + + case IF_PROTO_HDLC_ETH: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (dev->flags & IFF_UP) + return -EBUSY; + + if (copy_from_user(&new_settings, raw_s, size)) + return -EFAULT; + + if (new_settings.encoding == ENCODING_DEFAULT) + new_settings.encoding = ENCODING_NRZ; + + if (new_settings.parity == PARITY_DEFAULT) + new_settings.parity = PARITY_CRC16_PR1_CCITT; + + result = hdlc->attach(dev, new_settings.encoding, + new_settings.parity); + if (result) + return result; + + hdlc_proto_detach(hdlc); + memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size); + memset(&hdlc->proto, 0, sizeof(hdlc->proto)); + + hdlc->proto.type_trans = eth_type_trans; + hdlc->proto.id = IF_PROTO_HDLC_ETH; + dev->hard_start_xmit = eth_tx; + old_ch_mtu = dev->change_mtu; + old_qlen = dev->tx_queue_len; + ether_setup(dev); + dev->change_mtu = old_ch_mtu; + dev->tx_queue_len = old_qlen; + memcpy(dev->dev_addr, "\x00\x01", 2); + get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2); + return 0; + } + + return -EINVAL; +} diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/Makefile dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/Makefile --- dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/Makefile 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/Makefile 2008-02-04 17:00:48.000000000 -0600 @@ -0,0 +1,32 @@ +.EXPORT_ALL_VARIABLES: +MODULES= \ + hdlc_cisco hdlc_generic hdlc_raw syncppp \ + hdlc_fr hdlc_ppp hdlc_raw_eth + + +PWD=$(shell pwd) + +MODULESO:=$(MODULES:%=%.o) +MODULESKO:=$(MODULES:%=%.ko) +KMAKE = $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) +KMAKE_INST = $(KMAKE) \ + INSTALL_MOD_PATH=$(INSTALL_PREFIX) INSTALL_MOD_DIR=misc modules_install + +obj-m := $(MODULESO) +#obj-m:=hdlc_raw.o hdlc_cisco.o +#obj-m := hdlc_cisco.o hdlc_cisco.mod.o hdlc_fr.o hdlc_generic.o hdlc_ppp.o hdlc_raw.o hdlc_raw_eth.o hdlc_raw.mod.o hdlc_x25.o + +all: + @echo "You don't want to do make here. Do it from up above" + +clean: + $(KMAKE) clean + +install: $(MODULESKO) + $(KMAKE_INST) + +datamods: + @echo "To build: $(obj-m)" + @echo $(KSRC) + @if [ -z "$(KSRC)" -o ! -d "$(KSRC)" ]; then echo "You do not appear to have the sources for the $(KVERS) kernel installed."; exit 1 ; fi + $(KMAKE) modules diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/syncppp.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/syncppp.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/datamods/syncppp.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/datamods/syncppp.c 2008-06-20 17:40:11.000000000 -0500 @@ -0,0 +1,1484 @@ +/* + * NET3: A (fairly minimal) implementation of synchronous PPP for Linux + * as well as a CISCO HDLC implementation. See the copyright + * message below for the original source. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the license, or (at your option) any later version. + * + * Note however. This code is also used in a different form by FreeBSD. + * Therefore when making any non OS specific change please consider + * contributing it back to the original author under the terms + * below in addition. + * -- Alan + * + * Port for Linux-2.1 by Jan "Yenya" Kasprzak + */ + +/* + * Synchronous PPP/Cisco link level subroutines. + * Keepalive protocol implemented in both Cisco and PPP modes. + * + * Copyright (C) 1994 Cronyx Ltd. + * Author: Serge Vakulenko, + * + * This software is distributed with NO WARRANTIES, not even the implied + * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Authors grant any other persons or organisations permission to use + * or modify this software as long as this message is kept with the software, + * all derivative works or modified versions. + * + * Version 1.9, Wed Oct 4 18:58:15 MSK 1995 + * + * $Id: syncppp.c 4436 2008-06-20 22:40:11Z kpfleming $ + */ +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#define MAXALIVECNT 6 /* max. alive packets */ + +#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ +#define PPP_UI 0x03 /* Unnumbered Information */ +#define PPP_IP 0x0021 /* Internet Protocol */ +#define PPP_ISO 0x0023 /* ISO OSI Protocol */ +#define PPP_XNS 0x0025 /* Xerox NS Protocol */ +#define PPP_IPX 0x002b /* Novell IPX Protocol */ +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#define PPP_IPCP 0x8021 /* Internet Protocol Control Protocol */ + +#define LCP_CONF_REQ 1 /* PPP LCP configure request */ +#define LCP_CONF_ACK 2 /* PPP LCP configure acknowledge */ +#define LCP_CONF_NAK 3 /* PPP LCP configure negative ack */ +#define LCP_CONF_REJ 4 /* PPP LCP configure reject */ +#define LCP_TERM_REQ 5 /* PPP LCP terminate request */ +#define LCP_TERM_ACK 6 /* PPP LCP terminate acknowledge */ +#define LCP_CODE_REJ 7 /* PPP LCP code reject */ +#define LCP_PROTO_REJ 8 /* PPP LCP protocol reject */ +#define LCP_ECHO_REQ 9 /* PPP LCP echo request */ +#define LCP_ECHO_REPLY 10 /* PPP LCP echo reply */ +#define LCP_DISC_REQ 11 /* PPP LCP discard request */ + +#define LCP_OPT_MRU 1 /* maximum receive unit */ +#define LCP_OPT_ASYNC_MAP 2 /* async control character map */ +#define LCP_OPT_AUTH_PROTO 3 /* authentication protocol */ +#define LCP_OPT_QUAL_PROTO 4 /* quality protocol */ +#define LCP_OPT_MAGIC 5 /* magic number */ +#define LCP_OPT_RESERVED 6 /* reserved */ +#define LCP_OPT_PROTO_COMP 7 /* protocol field compression */ +#define LCP_OPT_ADDR_COMP 8 /* address/control field compression */ + +#define IPCP_CONF_REQ LCP_CONF_REQ /* PPP IPCP configure request */ +#define IPCP_CONF_ACK LCP_CONF_ACK /* PPP IPCP configure acknowledge */ +#define IPCP_CONF_NAK LCP_CONF_NAK /* PPP IPCP configure negative ack */ +#define IPCP_CONF_REJ LCP_CONF_REJ /* PPP IPCP configure reject */ +#define IPCP_TERM_REQ LCP_TERM_REQ /* PPP IPCP terminate request */ +#define IPCP_TERM_ACK LCP_TERM_ACK /* PPP IPCP terminate acknowledge */ +#define IPCP_CODE_REJ LCP_CODE_REJ /* PPP IPCP code reject */ + +#define CISCO_MULTICAST 0x8f /* Cisco multicast address */ +#define CISCO_UNICAST 0x0f /* Cisco unicast address */ +#define CISCO_KEEPALIVE 0x8035 /* Cisco keepalive protocol */ +#define CISCO_ADDR_REQ 0 /* Cisco address request */ +#define CISCO_ADDR_REPLY 1 /* Cisco address reply */ +#define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */ + +struct ppp_header { + u8 address; + u8 control; + u16 protocol; +}; +#define PPP_HEADER_LEN sizeof (struct ppp_header) + +struct lcp_header { + u8 type; + u8 ident; + u16 len; +}; +#define LCP_HEADER_LEN sizeof (struct lcp_header) + +struct cisco_packet { + u32 type; + u32 par1; + u32 par2; + u16 rel; + u16 time0; + u16 time1; +}; +#define CISCO_PACKET_LEN 18 +#define CISCO_BIG_PACKET_LEN 20 + +static struct sppp *spppq; +static struct timer_list sppp_keepalive_timer; +static DEFINE_SPINLOCK(spppq_lock); + +/* global xmit queue for sending packets while spinlock is held */ +static struct sk_buff_head tx_queue; + +static void sppp_keepalive (unsigned long dummy); +static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type, + u8 ident, u16 len, void *data); +static void sppp_cisco_send (struct sppp *sp, int type, long par1, long par2); +static void sppp_lcp_input (struct sppp *sp, struct sk_buff *m); +static void sppp_cisco_input (struct sppp *sp, struct sk_buff *m); +static void sppp_ipcp_input (struct sppp *sp, struct sk_buff *m); +static void sppp_lcp_open (struct sppp *sp); +static void sppp_ipcp_open (struct sppp *sp); +static int sppp_lcp_conf_parse_options (struct sppp *sp, struct lcp_header *h, + int len, u32 *magic); +static void sppp_cp_timeout (unsigned long arg); +static char *sppp_lcp_type_name (u8 type); +static char *sppp_ipcp_type_name (u8 type); +static void sppp_print_bytes (u8 *p, u16 len); + +static int debug; + +/* Flush global outgoing packet queue to dev_queue_xmit(). + * + * dev_queue_xmit() must be called with interrupts enabled + * which means it can't be called with spinlocks held. + * If a packet needs to be sent while a spinlock is held, + * then put the packet into tx_queue, and call sppp_flush_xmit() + * after spinlock is released. + */ +static void sppp_flush_xmit(void) +{ + struct sk_buff *skb; + while ((skb = skb_dequeue(&tx_queue)) != NULL) + dev_queue_xmit(skb); +} + +/* + * Interface down stub + */ + +static void if_down(struct net_device *dev) +{ + struct sppp *sp = (struct sppp *)sppp_of(dev); + + sp->pp_link_state=SPPP_LINK_DOWN; +} + +/* + * Timeout routine activations. + */ + +static void sppp_set_timeout(struct sppp *p,int s) +{ + if (! (p->pp_flags & PP_TIMO)) + { + init_timer(&p->pp_timer); + p->pp_timer.function=sppp_cp_timeout; + p->pp_timer.expires=jiffies+s*HZ; + p->pp_timer.data=(unsigned long)p; + p->pp_flags |= PP_TIMO; + add_timer(&p->pp_timer); + } +} + +static void sppp_clear_timeout(struct sppp *p) +{ + if (p->pp_flags & PP_TIMO) + { + del_timer(&p->pp_timer); + p->pp_flags &= ~PP_TIMO; + } +} + +/** + * sppp_input - receive and process a WAN PPP frame + * @skb: The buffer to process + * @dev: The device it arrived on + * + * This can be called directly by cards that do not have + * timing constraints but is normally called from the network layer + * after interrupt servicing to process frames queued via netif_rx(). + * + * We process the options in the card. If the frame is destined for + * the protocol stacks then it requeues the frame for the upper level + * protocol. If it is a control from it is processed and discarded + * here. + */ + +static void sppp_input (struct net_device *dev, struct sk_buff *skb) +{ + struct ppp_header *h; + struct sppp *sp = (struct sppp *)sppp_of(dev); + unsigned long flags; + + skb->dev=dev; + skb->mac.raw=skb->data; + + if (dev->flags & IFF_RUNNING) + { + /* Count received bytes, add FCS and one flag */ + sp->ibytes+= skb->len + 3; + sp->ipkts++; + } + + if (!pskb_may_pull(skb, PPP_HEADER_LEN)) { + /* Too small packet, drop it. */ + if (sp->pp_flags & PP_DEBUG) + printk (KERN_DEBUG "%s: input packet is too small, %d bytes\n", + dev->name, skb->len); + kfree_skb(skb); + return; + } + + /* Get PPP header. */ + h = (struct ppp_header *)skb->data; + skb_pull(skb,sizeof(struct ppp_header)); + + spin_lock_irqsave(&sp->lock, flags); + + switch (h->address) { + default: /* Invalid PPP packet. */ + goto invalid; + case PPP_ALLSTATIONS: + if (h->control != PPP_UI) + goto invalid; + if (sp->pp_flags & PP_CISCO) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: PPP packet in Cisco mode <0x%x 0x%x 0x%x>\n", + dev->name, + h->address, h->control, ntohs (h->protocol)); + goto drop; + } + switch (ntohs (h->protocol)) { + default: + if (sp->lcp.state == LCP_STATE_OPENED) + sppp_cp_send (sp, PPP_LCP, LCP_PROTO_REJ, + ++sp->pp_seq, skb->len + 2, + &h->protocol); + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid input protocol <0x%x 0x%x 0x%x>\n", + dev->name, + h->address, h->control, ntohs (h->protocol)); + goto drop; + case PPP_LCP: + sppp_lcp_input (sp, skb); + goto drop; + case PPP_IPCP: + if (sp->lcp.state == LCP_STATE_OPENED) + sppp_ipcp_input (sp, skb); + else + printk(KERN_DEBUG "IPCP when still waiting LCP finish.\n"); + goto drop; + case PPP_IP: + if (sp->ipcp.state == IPCP_STATE_OPENED) { + if(sp->pp_flags&PP_DEBUG) + printk(KERN_DEBUG "Yow an IP frame.\n"); + skb->protocol=htons(ETH_P_IP); + netif_rx(skb); + dev->last_rx = jiffies; + goto done; + } + break; +#ifdef IPX + case PPP_IPX: + /* IPX IPXCP not implemented yet */ + if (sp->lcp.state == LCP_STATE_OPENED) { + skb->protocol=htons(ETH_P_IPX); + netif_rx(skb); + dev->last_rx = jiffies; + goto done; + } + break; +#endif + } + break; + case CISCO_MULTICAST: + case CISCO_UNICAST: + /* Don't check the control field here (RFC 1547). */ + if (! (sp->pp_flags & PP_CISCO)) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: Cisco packet in PPP mode <0x%x 0x%x 0x%x>\n", + dev->name, + h->address, h->control, ntohs (h->protocol)); + goto drop; + } + switch (ntohs (h->protocol)) { + default: + goto invalid; + case CISCO_KEEPALIVE: + sppp_cisco_input (sp, skb); + goto drop; +#ifdef CONFIG_INET + case ETH_P_IP: + skb->protocol=htons(ETH_P_IP); + netif_rx(skb); + dev->last_rx = jiffies; + goto done; +#endif +#ifdef CONFIG_IPX + case ETH_P_IPX: + skb->protocol=htons(ETH_P_IPX); + netif_rx(skb); + dev->last_rx = jiffies; + goto done; +#endif + } + break; + } + goto drop; + +invalid: + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid input packet <0x%x 0x%x 0x%x>\n", + dev->name, h->address, h->control, ntohs (h->protocol)); +drop: + kfree_skb(skb); +done: + spin_unlock_irqrestore(&sp->lock, flags); + sppp_flush_xmit(); + return; +} + +/* + * Handle transmit packets. + */ + +static int sppp_hard_header(struct sk_buff *skb, struct net_device *dev, __u16 type, + void *daddr, void *saddr, unsigned int len) +{ + struct sppp *sp = (struct sppp *)sppp_of(dev); + struct ppp_header *h; + skb_push(skb,sizeof(struct ppp_header)); + h=(struct ppp_header *)skb->data; + if(sp->pp_flags&PP_CISCO) + { + h->address = CISCO_UNICAST; + h->control = 0; + } + else + { + h->address = PPP_ALLSTATIONS; + h->control = PPP_UI; + } + if(sp->pp_flags & PP_CISCO) + { + h->protocol = htons(type); + } + else switch(type) + { + case ETH_P_IP: + h->protocol = htons(PPP_IP); + break; + case ETH_P_IPX: + h->protocol = htons(PPP_IPX); + break; + } + return sizeof(struct ppp_header); +} + +static int sppp_rebuild_header(struct sk_buff *skb) +{ + return 0; +} + +/* + * Send keepalive packets, every 10 seconds. + */ + +static void sppp_keepalive (unsigned long dummy) +{ + struct sppp *sp; + unsigned long flags; + + spin_lock_irqsave(&spppq_lock, flags); + + for (sp=spppq; sp; sp=sp->pp_next) + { + struct net_device *dev = sp->pp_if; + + /* Keepalive mode disabled or channel down? */ + if (! (sp->pp_flags & PP_KEEPALIVE) || + ! (dev->flags & IFF_UP)) + continue; + + spin_lock(&sp->lock); + + /* No keepalive in PPP mode if LCP not opened yet. */ + if (! (sp->pp_flags & PP_CISCO) && + sp->lcp.state != LCP_STATE_OPENED) { + spin_unlock(&sp->lock); + continue; + } + + if (sp->pp_alivecnt == MAXALIVECNT) { + /* No keepalive packets got. Stop the interface. */ + printk (KERN_WARNING "%s: protocol down\n", dev->name); + if_down (dev); + if (! (sp->pp_flags & PP_CISCO)) { + /* Shut down the PPP link. */ + sp->lcp.magic = jiffies; + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + sppp_clear_timeout (sp); + /* Initiate negotiation. */ + sppp_lcp_open (sp); + } + } + if (sp->pp_alivecnt <= MAXALIVECNT) + ++sp->pp_alivecnt; + if (sp->pp_flags & PP_CISCO) + sppp_cisco_send (sp, CISCO_KEEPALIVE_REQ, ++sp->pp_seq, + sp->pp_rseq); + else if (sp->lcp.state == LCP_STATE_OPENED) { + long nmagic = htonl (sp->lcp.magic); + sp->lcp.echoid = ++sp->pp_seq; + sppp_cp_send (sp, PPP_LCP, LCP_ECHO_REQ, + sp->lcp.echoid, 4, &nmagic); + } + + spin_unlock(&sp->lock); + } + spin_unlock_irqrestore(&spppq_lock, flags); + sppp_flush_xmit(); + sppp_keepalive_timer.expires=jiffies+10*HZ; + add_timer(&sppp_keepalive_timer); +} + +/* + * Handle incoming PPP Link Control Protocol packets. + */ + +static void sppp_lcp_input (struct sppp *sp, struct sk_buff *skb) +{ + struct lcp_header *h; + struct net_device *dev = sp->pp_if; + int len = skb->len; + u8 *p, opt[6]; + u32 rmagic; + + if (!pskb_may_pull(skb, sizeof(struct lcp_header))) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid lcp packet length: %d bytes\n", + dev->name, len); + return; + } + h = (struct lcp_header *)skb->data; + skb_pull(skb,sizeof(struct lcp_header *)); + + if (sp->pp_flags & PP_DEBUG) + { + char state = '?'; + switch (sp->lcp.state) { + case LCP_STATE_CLOSED: state = 'C'; break; + case LCP_STATE_ACK_RCVD: state = 'R'; break; + case LCP_STATE_ACK_SENT: state = 'S'; break; + case LCP_STATE_OPENED: state = 'O'; break; + } + printk (KERN_WARNING "%s: lcp input(%c): %d bytes <%s id=%xh len=%xh", + dev->name, state, len, + sppp_lcp_type_name (h->type), h->ident, ntohs (h->len)); + if (len > 4) + sppp_print_bytes ((u8*) (h+1), len-4); + printk (">\n"); + } + if (len > ntohs (h->len)) + len = ntohs (h->len); + switch (h->type) { + default: + /* Unknown packet type -- send Code-Reject packet. */ + sppp_cp_send (sp, PPP_LCP, LCP_CODE_REJ, ++sp->pp_seq, + skb->len, h); + break; + case LCP_CONF_REQ: + if (len < 4) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_DEBUG"%s: invalid lcp configure request packet length: %d bytes\n", + dev->name, len); + break; + } + if (len>4 && !sppp_lcp_conf_parse_options (sp, h, len, &rmagic)) + goto badreq; + if (rmagic == sp->lcp.magic) { + /* Local and remote magics equal -- loopback? */ + if (sp->pp_loopcnt >= MAXALIVECNT*5) { + printk (KERN_WARNING "%s: loopback\n", + dev->name); + sp->pp_loopcnt = 0; + if (dev->flags & IFF_UP) { + if_down (dev); + } + } else if (sp->pp_flags & PP_DEBUG) + printk (KERN_DEBUG "%s: conf req: magic glitch\n", + dev->name); + ++sp->pp_loopcnt; + + /* MUST send Conf-Nack packet. */ + rmagic = ~sp->lcp.magic; + opt[0] = LCP_OPT_MAGIC; + opt[1] = sizeof (opt); + opt[2] = rmagic >> 24; + opt[3] = rmagic >> 16; + opt[4] = rmagic >> 8; + opt[5] = rmagic; + sppp_cp_send (sp, PPP_LCP, LCP_CONF_NAK, + h->ident, sizeof (opt), &opt); +badreq: + switch (sp->lcp.state) { + case LCP_STATE_OPENED: + /* Initiate renegotiation. */ + sppp_lcp_open (sp); + /* fall through... */ + case LCP_STATE_ACK_SENT: + /* Go to closed state. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + } + break; + } + /* Send Configure-Ack packet. */ + sp->pp_loopcnt = 0; + if (sp->lcp.state != LCP_STATE_OPENED) { + sppp_cp_send (sp, PPP_LCP, LCP_CONF_ACK, + h->ident, len-4, h+1); + } + /* Change the state. */ + switch (sp->lcp.state) { + case LCP_STATE_CLOSED: + sp->lcp.state = LCP_STATE_ACK_SENT; + break; + case LCP_STATE_ACK_RCVD: + sp->lcp.state = LCP_STATE_OPENED; + sppp_ipcp_open (sp); + break; + case LCP_STATE_OPENED: + /* Remote magic changed -- close session. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + /* Initiate renegotiation. */ + sppp_lcp_open (sp); + /* Send ACK after our REQ in attempt to break loop */ + sppp_cp_send (sp, PPP_LCP, LCP_CONF_ACK, + h->ident, len-4, h+1); + sp->lcp.state = LCP_STATE_ACK_SENT; + break; + } + break; + case LCP_CONF_ACK: + if (h->ident != sp->lcp.confid) + break; + sppp_clear_timeout (sp); + if ((sp->pp_link_state != SPPP_LINK_UP) && + (dev->flags & IFF_UP)) { + /* Coming out of loopback mode. */ + sp->pp_link_state=SPPP_LINK_UP; + printk (KERN_INFO "%s: protocol up\n", dev->name); + } + switch (sp->lcp.state) { + case LCP_STATE_CLOSED: + sp->lcp.state = LCP_STATE_ACK_RCVD; + sppp_set_timeout (sp, 5); + break; + case LCP_STATE_ACK_SENT: + sp->lcp.state = LCP_STATE_OPENED; + sppp_ipcp_open (sp); + break; + } + break; + case LCP_CONF_NAK: + if (h->ident != sp->lcp.confid) + break; + p = (u8*) (h+1); + if (len>=10 && p[0] == LCP_OPT_MAGIC && p[1] >= 4) { + rmagic = (u32)p[2] << 24 | + (u32)p[3] << 16 | p[4] << 8 | p[5]; + if (rmagic == ~sp->lcp.magic) { + int newmagic; + if (sp->pp_flags & PP_DEBUG) + printk (KERN_DEBUG "%s: conf nak: magic glitch\n", + dev->name); + get_random_bytes(&newmagic, sizeof(newmagic)); + sp->lcp.magic += newmagic; + } else + sp->lcp.magic = rmagic; + } + if (sp->lcp.state != LCP_STATE_ACK_SENT) { + /* Go to closed state. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + } + /* The link will be renegotiated after timeout, + * to avoid endless req-nack loop. */ + sppp_clear_timeout (sp); + sppp_set_timeout (sp, 2); + break; + case LCP_CONF_REJ: + if (h->ident != sp->lcp.confid) + break; + sppp_clear_timeout (sp); + /* Initiate renegotiation. */ + sppp_lcp_open (sp); + if (sp->lcp.state != LCP_STATE_ACK_SENT) { + /* Go to closed state. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + } + break; + case LCP_TERM_REQ: + sppp_clear_timeout (sp); + /* Send Terminate-Ack packet. */ + sppp_cp_send (sp, PPP_LCP, LCP_TERM_ACK, h->ident, 0, NULL); + /* Go to closed state. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + /* Initiate renegotiation. */ + sppp_lcp_open (sp); + break; + case LCP_TERM_ACK: + case LCP_CODE_REJ: + case LCP_PROTO_REJ: + /* Ignore for now. */ + break; + case LCP_DISC_REQ: + /* Discard the packet. */ + break; + case LCP_ECHO_REQ: + if (sp->lcp.state != LCP_STATE_OPENED) + break; + if (len < 8) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid lcp echo request packet length: %d bytes\n", + dev->name, len); + break; + } + if (ntohl (*(long*)(h+1)) == sp->lcp.magic) { + /* Line loopback mode detected. */ + printk (KERN_WARNING "%s: loopback\n", dev->name); + if_down (dev); + + /* Shut down the PPP link. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + sppp_clear_timeout (sp); + /* Initiate negotiation. */ + sppp_lcp_open (sp); + break; + } + *(long*)(h+1) = htonl (sp->lcp.magic); + sppp_cp_send (sp, PPP_LCP, LCP_ECHO_REPLY, h->ident, len-4, h+1); + break; + case LCP_ECHO_REPLY: + if (h->ident != sp->lcp.echoid) + break; + if (len < 8) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid lcp echo reply packet length: %d bytes\n", + dev->name, len); + break; + } + if (ntohl (*(long*)(h+1)) != sp->lcp.magic) + sp->pp_alivecnt = 0; + break; + } +} + +/* + * Handle incoming Cisco keepalive protocol packets. + */ + +static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb) +{ + struct cisco_packet *h; + struct net_device *dev = sp->pp_if; + + if (!pskb_may_pull(skb, sizeof(struct cisco_packet)) + || (skb->len != CISCO_PACKET_LEN + && skb->len != CISCO_BIG_PACKET_LEN)) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid cisco packet length: %d bytes\n", + dev->name, skb->len); + return; + } + h = (struct cisco_packet *)skb->data; + skb_pull(skb, sizeof(struct cisco_packet*)); + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: cisco input: %d bytes <%xh %xh %xh %xh %xh-%xh>\n", + dev->name, skb->len, + ntohl (h->type), h->par1, h->par2, h->rel, + h->time0, h->time1); + switch (ntohl (h->type)) { + default: + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: unknown cisco packet type: 0x%x\n", + dev->name, ntohl (h->type)); + break; + case CISCO_ADDR_REPLY: + /* Reply on address request, ignore */ + break; + case CISCO_KEEPALIVE_REQ: + sp->pp_alivecnt = 0; + sp->pp_rseq = ntohl (h->par1); + if (sp->pp_seq == sp->pp_rseq) { + /* Local and remote sequence numbers are equal. + * Probably, the line is in loopback mode. */ + int newseq; + if (sp->pp_loopcnt >= MAXALIVECNT) { + printk (KERN_WARNING "%s: loopback\n", + dev->name); + sp->pp_loopcnt = 0; + if (dev->flags & IFF_UP) { + if_down (dev); + } + } + ++sp->pp_loopcnt; + + /* Generate new local sequence number */ + get_random_bytes(&newseq, sizeof(newseq)); + sp->pp_seq ^= newseq; + break; + } + sp->pp_loopcnt = 0; + if (sp->pp_link_state==SPPP_LINK_DOWN && + (dev->flags & IFF_UP)) { + sp->pp_link_state=SPPP_LINK_UP; + printk (KERN_INFO "%s: protocol up\n", dev->name); + } + break; + case CISCO_ADDR_REQ: + /* Stolen from net/ipv4/devinet.c -- SIOCGIFADDR ioctl */ + { + struct in_device *in_dev; + struct in_ifaddr *ifa; + u32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */ +#ifdef CONFIG_INET + rcu_read_lock(); + if ((in_dev = __in_dev_get_rcu(dev)) != NULL) + { + for (ifa=in_dev->ifa_list; ifa != NULL; + ifa=ifa->ifa_next) { + if (strcmp(dev->name, ifa->ifa_label) == 0) + { + addr = ifa->ifa_local; + mask = ifa->ifa_mask; + break; + } + } + } + rcu_read_unlock(); +#endif + /* I hope both addr and mask are in the net order */ + sppp_cisco_send (sp, CISCO_ADDR_REPLY, addr, mask); + break; + } + } +} + + +/* + * Send PPP LCP packet. + */ + +static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type, + u8 ident, u16 len, void *data) +{ + struct ppp_header *h; + struct lcp_header *lh; + struct sk_buff *skb; + struct net_device *dev = sp->pp_if; + + skb=alloc_skb(dev->hard_header_len+PPP_HEADER_LEN+LCP_HEADER_LEN+len, + GFP_ATOMIC); + if (skb==NULL) + return; + + skb_reserve(skb,dev->hard_header_len); + + h = (struct ppp_header *)skb_put(skb, sizeof(struct ppp_header)); + h->address = PPP_ALLSTATIONS; /* broadcast address */ + h->control = PPP_UI; /* Unnumbered Info */ + h->protocol = htons (proto); /* Link Control Protocol */ + + lh = (struct lcp_header *)skb_put(skb, sizeof(struct lcp_header)); + lh->type = type; + lh->ident = ident; + lh->len = htons (LCP_HEADER_LEN + len); + + if (len) + memcpy(skb_put(skb,len),data, len); + + if (sp->pp_flags & PP_DEBUG) { + printk (KERN_WARNING "%s: %s output <%s id=%xh len=%xh", + dev->name, + proto==PPP_LCP ? "lcp" : "ipcp", + proto==PPP_LCP ? sppp_lcp_type_name (lh->type) : + sppp_ipcp_type_name (lh->type), lh->ident, + ntohs (lh->len)); + if (len) + sppp_print_bytes ((u8*) (lh+1), len); + printk (">\n"); + } + sp->obytes += skb->len; + /* Control is high priority so it doesn't get queued behind data */ + skb->priority=TC_PRIO_CONTROL; + skb->dev = dev; + skb_queue_tail(&tx_queue, skb); +} + +/* + * Send Cisco keepalive packet. + */ + +static void sppp_cisco_send (struct sppp *sp, int type, long par1, long par2) +{ + struct ppp_header *h; + struct cisco_packet *ch; + struct sk_buff *skb; + struct net_device *dev = sp->pp_if; + u32 t = jiffies * 1000/HZ; + + skb=alloc_skb(dev->hard_header_len+PPP_HEADER_LEN+CISCO_PACKET_LEN, + GFP_ATOMIC); + + if(skb==NULL) + return; + + skb_reserve(skb, dev->hard_header_len); + h = (struct ppp_header *)skb_put (skb, sizeof(struct ppp_header)); + h->address = CISCO_MULTICAST; + h->control = 0; + h->protocol = htons (CISCO_KEEPALIVE); + + ch = (struct cisco_packet*)skb_put(skb, CISCO_PACKET_LEN); + ch->type = htonl (type); + ch->par1 = htonl (par1); + ch->par2 = htonl (par2); + ch->rel = -1; + ch->time0 = htons ((u16) (t >> 16)); + ch->time1 = htons ((u16) t); + + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: cisco output: <%xh %xh %xh %xh %xh-%xh>\n", + dev->name, ntohl (ch->type), ch->par1, + ch->par2, ch->rel, ch->time0, ch->time1); + sp->obytes += skb->len; + skb->priority=TC_PRIO_CONTROL; + skb->dev = dev; + skb_queue_tail(&tx_queue, skb); +} + +/** + * sppp_close - close down a synchronous PPP or Cisco HDLC link + * @dev: The network device to drop the link of + * + * This drops the logical interface to the channel. It is not + * done politely as we assume we will also be dropping DTR. Any + * timeouts are killed. + */ + +int sppp_close (struct net_device *dev) +{ + struct sppp *sp = (struct sppp *)sppp_of(dev); + unsigned long flags; + + spin_lock_irqsave(&sp->lock, flags); + sp->pp_link_state = SPPP_LINK_DOWN; + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + sppp_clear_timeout (sp); + spin_unlock_irqrestore(&sp->lock, flags); + + return 0; +} + +EXPORT_SYMBOL(sppp_close); + +/** + * sppp_open - open a synchronous PPP or Cisco HDLC link + * @dev: Network device to activate + * + * Close down any existing synchronous session and commence + * from scratch. In the PPP case this means negotiating LCP/IPCP + * and friends, while for Cisco HDLC we simply need to start sending + * keepalives + */ + +int sppp_open (struct net_device *dev) +{ + struct sppp *sp = (struct sppp *)sppp_of(dev); + unsigned long flags; + + sppp_close(dev); + + spin_lock_irqsave(&sp->lock, flags); + if (!(sp->pp_flags & PP_CISCO)) { + sppp_lcp_open (sp); + } + sp->pp_link_state = SPPP_LINK_DOWN; + spin_unlock_irqrestore(&sp->lock, flags); + sppp_flush_xmit(); + + return 0; +} + +EXPORT_SYMBOL(sppp_open); + +/** + * sppp_reopen - notify of physical link loss + * @dev: Device that lost the link + * + * This function informs the synchronous protocol code that + * the underlying link died (for example a carrier drop on X.21) + * + * We increment the magic numbers to ensure that if the other end + * failed to notice we will correctly start a new session. It happens + * do to the nature of telco circuits is that you can lose carrier on + * one endonly. + * + * Having done this we go back to negotiating. This function may + * be called from an interrupt context. + */ + +int sppp_reopen (struct net_device *dev) +{ + struct sppp *sp = (struct sppp *)sppp_of(dev); + unsigned long flags; + + sppp_close(dev); + + spin_lock_irqsave(&sp->lock, flags); + if (!(sp->pp_flags & PP_CISCO)) + { + sp->lcp.magic = jiffies; + ++sp->pp_seq; + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + /* Give it a moment for the line to settle then go */ + sppp_set_timeout (sp, 1); + } + sp->pp_link_state=SPPP_LINK_DOWN; + spin_unlock_irqrestore(&sp->lock, flags); + + return 0; +} + +EXPORT_SYMBOL(sppp_reopen); + +/** + * sppp_change_mtu - Change the link MTU + * @dev: Device to change MTU on + * @new_mtu: New MTU + * + * Change the MTU on the link. This can only be called with + * the link down. It returns an error if the link is up or + * the mtu is out of range. + */ + +static int sppp_change_mtu(struct net_device *dev, int new_mtu) +{ + if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP)) + return -EINVAL; + dev->mtu=new_mtu; + return 0; +} + +/** + * sppp_do_ioctl - Ioctl handler for ppp/hdlc + * @dev: Device subject to ioctl + * @ifr: Interface request block from the user + * @cmd: Command that is being issued + * + * This function handles the ioctls that may be issued by the user + * to control the settings of a PPP/HDLC link. It does both busy + * and security checks. This function is intended to be wrapped by + * callers who wish to add additional ioctl calls of their own. + */ + +int sppp_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct sppp *sp = (struct sppp *)sppp_of(dev); + + if(dev->flags&IFF_UP) + return -EBUSY; + + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + + switch(cmd) + { + case SPPPIOCCISCO: + sp->pp_flags|=PP_CISCO; + dev->type = ARPHRD_HDLC; + break; + case SPPPIOCPPP: + sp->pp_flags&=~PP_CISCO; + dev->type = ARPHRD_PPP; + break; + case SPPPIOCDEBUG: + sp->pp_flags&=~PP_DEBUG; + if(ifr->ifr_flags) + sp->pp_flags|=PP_DEBUG; + break; + case SPPPIOCGFLAGS: + if(copy_to_user(ifr->ifr_data, &sp->pp_flags, sizeof(sp->pp_flags))) + return -EFAULT; + break; + case SPPPIOCSFLAGS: + if(copy_from_user(&sp->pp_flags, ifr->ifr_data, sizeof(sp->pp_flags))) + return -EFAULT; + break; + default: + return -EINVAL; + } + return 0; +} + +EXPORT_SYMBOL(sppp_do_ioctl); + +/** + * sppp_attach - attach synchronous PPP/HDLC to a device + * @pd: PPP device to initialise + * + * This initialises the PPP/HDLC support on an interface. At the + * time of calling the dev element must point to the network device + * that this interface is attached to. The interface should not yet + * be registered. + */ + +void sppp_attach(struct ppp_device *pd) +{ + struct net_device *dev = pd->dev; + struct sppp *sp = &pd->sppp; + unsigned long flags; + + /* Make sure embedding is safe for sppp_of */ + BUG_ON(sppp_of(dev) != sp); + + spin_lock_irqsave(&spppq_lock, flags); + /* Initialize keepalive handler. */ + if (! spppq) + { + init_timer(&sppp_keepalive_timer); + sppp_keepalive_timer.expires=jiffies+10*HZ; + sppp_keepalive_timer.function=sppp_keepalive; + add_timer(&sppp_keepalive_timer); + } + /* Insert new entry into the keepalive list. */ + sp->pp_next = spppq; + spppq = sp; + spin_unlock_irqrestore(&spppq_lock, flags); + + sp->pp_loopcnt = 0; + sp->pp_alivecnt = 0; + sp->pp_seq = 0; + sp->pp_rseq = 0; + sp->pp_flags = PP_KEEPALIVE|PP_CISCO|debug;/*PP_DEBUG;*/ + sp->lcp.magic = 0; + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + sp->pp_if = dev; + spin_lock_init(&sp->lock); + + /* + * Device specific setup. All but interrupt handler and + * hard_start_xmit. + */ + + dev->hard_header = sppp_hard_header; + dev->rebuild_header = sppp_rebuild_header; + dev->tx_queue_len = 10; + dev->type = ARPHRD_HDLC; + dev->addr_len = 0; + dev->hard_header_len = sizeof(struct ppp_header); + dev->mtu = PPP_MTU; + /* + * These 4 are callers but MUST also call sppp_ functions + */ + dev->do_ioctl = sppp_do_ioctl; +#if 0 + dev->get_stats = NULL; /* Let the driver override these */ + dev->open = sppp_open; + dev->stop = sppp_close; +#endif + dev->change_mtu = sppp_change_mtu; + dev->hard_header_cache = NULL; + dev->header_cache_update = NULL; + dev->flags = IFF_MULTICAST|IFF_POINTOPOINT|IFF_NOARP; +} + +EXPORT_SYMBOL(sppp_attach); + +/** + * sppp_detach - release PPP resources from a device + * @dev: Network device to release + * + * Stop and free up any PPP/HDLC resources used by this + * interface. This must be called before the device is + * freed. + */ + +void sppp_detach (struct net_device *dev) +{ + struct sppp **q, *p, *sp = (struct sppp *)sppp_of(dev); + unsigned long flags; + + spin_lock_irqsave(&spppq_lock, flags); + /* Remove the entry from the keepalive list. */ + for (q = &spppq; (p = *q); q = &p->pp_next) + if (p == sp) { + *q = p->pp_next; + break; + } + + /* Stop keepalive handler. */ + if (! spppq) + del_timer(&sppp_keepalive_timer); + sppp_clear_timeout (sp); + spin_unlock_irqrestore(&spppq_lock, flags); +} + +EXPORT_SYMBOL(sppp_detach); + +/* + * Analyze the LCP Configure-Request options list + * for the presence of unknown options. + * If the request contains unknown options, build and + * send Configure-reject packet, containing only unknown options. + */ +static int +sppp_lcp_conf_parse_options (struct sppp *sp, struct lcp_header *h, + int len, u32 *magic) +{ + u8 *buf, *r, *p; + int rlen; + + len -= 4; + buf = r = kmalloc (len, GFP_ATOMIC); + if (! buf) + return (0); + + p = (void*) (h+1); + for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) { + switch (*p) { + case LCP_OPT_MAGIC: + /* Magic number -- extract. */ + if (len >= 6 && p[1] == 6) { + *magic = (u32)p[2] << 24 | + (u32)p[3] << 16 | p[4] << 8 | p[5]; + continue; + } + break; + case LCP_OPT_ASYNC_MAP: + /* Async control character map -- check to be zero. */ + if (len >= 6 && p[1] == 6 && ! p[2] && ! p[3] && + ! p[4] && ! p[5]) + continue; + break; + case LCP_OPT_MRU: + /* Maximum receive unit -- always OK. */ + continue; + default: + /* Others not supported. */ + break; + } + /* Add the option to rejected list. */ + memcpy(r, p, p[1]); + r += p[1]; + rlen += p[1]; + } + if (rlen) + sppp_cp_send (sp, PPP_LCP, LCP_CONF_REJ, h->ident, rlen, buf); + kfree(buf); + return (rlen == 0); +} + +static void sppp_ipcp_input (struct sppp *sp, struct sk_buff *skb) +{ + struct lcp_header *h; + struct net_device *dev = sp->pp_if; + int len = skb->len; + + if (!pskb_may_pull(skb, sizeof(struct lcp_header))) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid ipcp packet length: %d bytes\n", + dev->name, len); + return; + } + h = (struct lcp_header *)skb->data; + skb_pull(skb,sizeof(struct lcp_header)); + if (sp->pp_flags & PP_DEBUG) { + printk (KERN_WARNING "%s: ipcp input: %d bytes <%s id=%xh len=%xh", + dev->name, len, + sppp_ipcp_type_name (h->type), h->ident, ntohs (h->len)); + if (len > 4) + sppp_print_bytes ((u8*) (h+1), len-4); + printk (">\n"); + } + if (len > ntohs (h->len)) + len = ntohs (h->len); + switch (h->type) { + default: + /* Unknown packet type -- send Code-Reject packet. */ + sppp_cp_send (sp, PPP_IPCP, IPCP_CODE_REJ, ++sp->pp_seq, len, h); + break; + case IPCP_CONF_REQ: + if (len < 4) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid ipcp configure request packet length: %d bytes\n", + dev->name, len); + return; + } + if (len > 4) { + sppp_cp_send (sp, PPP_IPCP, LCP_CONF_REJ, h->ident, + len-4, h+1); + + switch (sp->ipcp.state) { + case IPCP_STATE_OPENED: + /* Initiate renegotiation. */ + sppp_ipcp_open (sp); + /* fall through... */ + case IPCP_STATE_ACK_SENT: + /* Go to closed state. */ + sp->ipcp.state = IPCP_STATE_CLOSED; + } + } else { + /* Send Configure-Ack packet. */ + sppp_cp_send (sp, PPP_IPCP, IPCP_CONF_ACK, h->ident, + 0, NULL); + /* Change the state. */ + if (sp->ipcp.state == IPCP_STATE_ACK_RCVD) + sp->ipcp.state = IPCP_STATE_OPENED; + else + sp->ipcp.state = IPCP_STATE_ACK_SENT; + } + break; + case IPCP_CONF_ACK: + if (h->ident != sp->ipcp.confid) + break; + sppp_clear_timeout (sp); + switch (sp->ipcp.state) { + case IPCP_STATE_CLOSED: + sp->ipcp.state = IPCP_STATE_ACK_RCVD; + sppp_set_timeout (sp, 5); + break; + case IPCP_STATE_ACK_SENT: + sp->ipcp.state = IPCP_STATE_OPENED; + break; + } + break; + case IPCP_CONF_NAK: + case IPCP_CONF_REJ: + if (h->ident != sp->ipcp.confid) + break; + sppp_clear_timeout (sp); + /* Initiate renegotiation. */ + sppp_ipcp_open (sp); + if (sp->ipcp.state != IPCP_STATE_ACK_SENT) + /* Go to closed state. */ + sp->ipcp.state = IPCP_STATE_CLOSED; + break; + case IPCP_TERM_REQ: + /* Send Terminate-Ack packet. */ + sppp_cp_send (sp, PPP_IPCP, IPCP_TERM_ACK, h->ident, 0, NULL); + /* Go to closed state. */ + sp->ipcp.state = IPCP_STATE_CLOSED; + /* Initiate renegotiation. */ + sppp_ipcp_open (sp); + break; + case IPCP_TERM_ACK: + /* Ignore for now. */ + case IPCP_CODE_REJ: + /* Ignore for now. */ + break; + } +} + +static void sppp_lcp_open (struct sppp *sp) +{ + char opt[6]; + + if (! sp->lcp.magic) + sp->lcp.magic = jiffies; + opt[0] = LCP_OPT_MAGIC; + opt[1] = sizeof (opt); + opt[2] = sp->lcp.magic >> 24; + opt[3] = sp->lcp.magic >> 16; + opt[4] = sp->lcp.magic >> 8; + opt[5] = sp->lcp.magic; + sp->lcp.confid = ++sp->pp_seq; + sppp_cp_send (sp, PPP_LCP, LCP_CONF_REQ, sp->lcp.confid, + sizeof (opt), &opt); + sppp_set_timeout (sp, 2); +} + +static void sppp_ipcp_open (struct sppp *sp) +{ + sp->ipcp.confid = ++sp->pp_seq; + sppp_cp_send (sp, PPP_IPCP, IPCP_CONF_REQ, sp->ipcp.confid, 0, NULL); + sppp_set_timeout (sp, 2); +} + +/* + * Process PPP control protocol timeouts. + */ + +static void sppp_cp_timeout (unsigned long arg) +{ + struct sppp *sp = (struct sppp*) arg; + unsigned long flags; + + spin_lock_irqsave(&sp->lock, flags); + + sp->pp_flags &= ~PP_TIMO; + if (! (sp->pp_if->flags & IFF_UP) || (sp->pp_flags & PP_CISCO)) { + spin_unlock_irqrestore(&sp->lock, flags); + return; + } + switch (sp->lcp.state) { + case LCP_STATE_CLOSED: + /* No ACK for Configure-Request, retry. */ + sppp_lcp_open (sp); + break; + case LCP_STATE_ACK_RCVD: + /* ACK got, but no Configure-Request for peer, retry. */ + sppp_lcp_open (sp); + sp->lcp.state = LCP_STATE_CLOSED; + break; + case LCP_STATE_ACK_SENT: + /* ACK sent but no ACK for Configure-Request, retry. */ + sppp_lcp_open (sp); + break; + case LCP_STATE_OPENED: + /* LCP is already OK, try IPCP. */ + switch (sp->ipcp.state) { + case IPCP_STATE_CLOSED: + /* No ACK for Configure-Request, retry. */ + sppp_ipcp_open (sp); + break; + case IPCP_STATE_ACK_RCVD: + /* ACK got, but no Configure-Request for peer, retry. */ + sppp_ipcp_open (sp); + sp->ipcp.state = IPCP_STATE_CLOSED; + break; + case IPCP_STATE_ACK_SENT: + /* ACK sent but no ACK for Configure-Request, retry. */ + sppp_ipcp_open (sp); + break; + case IPCP_STATE_OPENED: + /* IPCP is OK. */ + break; + } + break; + } + spin_unlock_irqrestore(&sp->lock, flags); + sppp_flush_xmit(); +} + +static char *sppp_lcp_type_name (u8 type) +{ + static char buf [8]; + switch (type) { + case LCP_CONF_REQ: return ("conf-req"); + case LCP_CONF_ACK: return ("conf-ack"); + case LCP_CONF_NAK: return ("conf-nack"); + case LCP_CONF_REJ: return ("conf-rej"); + case LCP_TERM_REQ: return ("term-req"); + case LCP_TERM_ACK: return ("term-ack"); + case LCP_CODE_REJ: return ("code-rej"); + case LCP_PROTO_REJ: return ("proto-rej"); + case LCP_ECHO_REQ: return ("echo-req"); + case LCP_ECHO_REPLY: return ("echo-reply"); + case LCP_DISC_REQ: return ("discard-req"); + } + sprintf (buf, "%xh", type); + return (buf); +} + +static char *sppp_ipcp_type_name (u8 type) +{ + static char buf [8]; + switch (type) { + case IPCP_CONF_REQ: return ("conf-req"); + case IPCP_CONF_ACK: return ("conf-ack"); + case IPCP_CONF_NAK: return ("conf-nack"); + case IPCP_CONF_REJ: return ("conf-rej"); + case IPCP_TERM_REQ: return ("term-req"); + case IPCP_TERM_ACK: return ("term-ack"); + case IPCP_CODE_REJ: return ("code-rej"); + } + sprintf (buf, "%xh", type); + return (buf); +} + +static void sppp_print_bytes (u_char *p, u16 len) +{ + printk (" %x", *p++); + while (--len > 0) + printk ("-%x", *p++); +} + +/** + * sppp_rcv - receive and process a WAN PPP frame + * @skb: The buffer to process + * @dev: The device it arrived on + * @p: Unused + * @orig_dev: Unused + * + * Protocol glue. This drives the deferred processing mode the poorer + * cards use. This can be called directly by cards that do not have + * timing constraints but is normally called from the network layer + * after interrupt servicing to process frames queued via netif_rx. + */ + +static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p, struct net_device *orig_dev) +{ + if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) + return NET_RX_DROP; + sppp_input(dev,skb); + return 0; +} + +static struct packet_type sppp_packet_type = { + .type = __constant_htons(ETH_P_WAN_PPP), + .func = sppp_rcv, +}; + +static char banner[] __initdata = + KERN_INFO "Cronyx Ltd, Synchronous PPP and CISCO HDLC (c) 1994\n" + KERN_INFO "Linux port (c) 1998 Building Number Three Ltd & " + "Jan \"Yenya\" Kasprzak.\n"; + +static int __init sync_ppp_init(void) +{ + if(debug) + debug=PP_DEBUG; + printk(banner); + skb_queue_head_init(&tx_queue); + dev_add_pack(&sppp_packet_type); + return 0; +} + + +static void __exit sync_ppp_cleanup(void) +{ + dev_remove_pack(&sppp_packet_type); +} + +module_init(sync_ppp_init); +module_exit(sync_ppp_cleanup); +module_param(debug, int, 0); +MODULE_LICENSE("GPL v2"); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/digits.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/digits.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/digits.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/digits.h 2008-08-05 18:56:00.000000000 -0500 @@ -0,0 +1,47 @@ +/* + * DAHDI Telephony + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#ifndef _DIGITS_H +#define _DIGITS_H + +#define DEFAULT_DTMF_LENGTH 100 * DAHDI_CHUNKSIZE +#define DEFAULT_MFR1_LENGTH 68 * DAHDI_CHUNKSIZE +#define DEFAULT_MFR2_LENGTH 100 * DAHDI_CHUNKSIZE +#define PAUSE_LENGTH 500 * DAHDI_CHUNKSIZE + +/* At the end of silence, the tone stops */ +static struct dahdi_tone dtmf_silence = { + .tonesamples = DEFAULT_DTMF_LENGTH, +}; + +/* At the end of silence, the tone stops */ +static struct dahdi_tone mfr1_silence = { + .tonesamples = DEFAULT_MFR1_LENGTH, +}; + +/* At the end of silence, the tone stops */ +static struct dahdi_tone mfr2_silence = { + .tonesamples = DEFAULT_MFR2_LENGTH, +}; + +/* A pause in the dialing */ +static struct dahdi_tone tone_pause = { + .tonesamples = PAUSE_LENGTH, +}; + +#endif diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/ecdis.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/ecdis.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/ecdis.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/ecdis.h 2009-04-29 13:24:04.000000000 -0500 @@ -0,0 +1,103 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * ec_disable_detector.h - A detector which should eventually meet the + * G.164/G.165 requirements for detecting the + * 2100Hz echo cancellor disable tone. + * + * Written by Steve Underwood + * + * Copyright (C) 2001 Steve Underwood + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include "biquad.h" + +#define FALSE 0 +#define TRUE (!FALSE) + +static inline void echo_can_disable_detector_init (echo_can_disable_detector_state_t *det) +{ + /* Elliptic notch */ + /* This is actually centred at 2095Hz, but gets the balance we want, due + to the asymmetric walls of the notch */ + biquad2_init (&det->notch, + (int32_t) (-0.7600000*32768.0), + (int32_t) (-0.1183852*32768.0), + (int32_t) (-0.5104039*32768.0), + (int32_t) ( 0.1567596*32768.0), + (int32_t) ( 1.0000000*32768.0)); + + det->channel_level = 0; + det->notch_level = 0; + det->tone_present = FALSE; + det->tone_cycle_duration = 0; + det->good_cycles = 0; + det->hit = 0; +} +/*- End of function --------------------------------------------------------*/ + +static inline int echo_can_disable_detector_update (echo_can_disable_detector_state_t *det, + int16_t amp) +{ + int16_t notched; + + notched = biquad2 (&det->notch, amp); + /* Estimate the overall energy in the channel, and the energy in + the notch (i.e. overall channel energy - tone energy => noise). + Use abs instead of multiply for speed (is it really faster?). + Damp the overall energy a little more for a stable result. + Damp the notch energy a little less, so we don't damp out the + blip every time the phase reverses */ + det->channel_level += ((abs(amp) - det->channel_level) >> 5); + det->notch_level += ((abs(notched) - det->notch_level) >> 4); + if (det->channel_level >= 70) { + /* There is adequate energy in the channel. Is it mostly at 2100Hz? */ + if (det->notch_level*6 < det->channel_level) { + det->tone_cycle_duration++; + /* The notch says yes, so we have the tone. */ + if (!det->tone_present) { + /* Do we get a kick every 450+-25ms? */ + if ((det->tone_cycle_duration >= (425 * 8)) && + (det->tone_cycle_duration <= (475 * 8))) { + /* It's ANS/PR (CED with polarity reversals), so wait + for at least three cycles before returning a hit. */ + det->good_cycles++; + if (det->good_cycles > 2) + det->hit = TRUE; + } + det->tone_cycle_duration = 0; + det->tone_present = TRUE; + } else if (det->tone_cycle_duration >= 600 * 8) { + /* It's ANS (CED without polarity reversals) + so return a hit. */ + det->hit = TRUE; + } + } else { + det->tone_present = FALSE; + } + } else { + det->tone_present = FALSE; + det->tone_cycle_duration = 0; + det->good_cycles = 0; + } + + return det->hit; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/fir.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/fir.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/fir.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/fir.h 2008-08-05 18:56:00.000000000 -0500 @@ -0,0 +1,129 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * fir.h - General telephony FIR routines + * + * Written by Steve Underwood + * + * Copyright (C) 2002 Steve Underwood + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#if !defined(_FIR_H_) +#define _FIR_H_ + +typedef struct +{ + int taps; + int curr_pos; + int16_t *coeffs; + int16_t *history; +} fir16_state_t; + +typedef struct +{ + int taps; + int curr_pos; + int32_t *coeffs; + int16_t *history; +} fir32_state_t; + +static inline void fir16_create (fir16_state_t *fir, + int16_t *coeffs, + int taps) +{ + fir->taps = taps; + fir->curr_pos = taps - 1; + fir->coeffs = coeffs; + fir->history = kmalloc(taps*sizeof (int16_t), GFP_KERNEL); + if (fir->history) + memset (fir->history, '\0', taps*sizeof (int16_t)); +} +/*- End of function --------------------------------------------------------*/ + +static inline void fir16_free (fir16_state_t *fir) +{ + kfree(fir->history); +} +/*- End of function --------------------------------------------------------*/ + +static inline int16_t fir16 (fir16_state_t *fir, int16_t sample) +{ + int i; + int offset1; + int offset2; + int32_t y; + + fir->history[fir->curr_pos] = sample; + offset2 = fir->curr_pos + 1; + offset1 = fir->taps - offset2; + y = 0; + for (i = fir->taps - 1; i >= offset1; i--) + y += fir->coeffs[i]*fir->history[i - offset1]; + for ( ; i >= 0; i--) + y += fir->coeffs[i]*fir->history[i + offset2]; + if (fir->curr_pos <= 0) + fir->curr_pos = fir->taps; + fir->curr_pos--; + return y >> 15; +} +/*- End of function --------------------------------------------------------*/ + +static inline void fir32_create (fir32_state_t *fir, + int32_t *coeffs, + int taps) +{ + fir->taps = taps; + fir->curr_pos = taps - 1; + fir->coeffs = coeffs; + fir->history = kmalloc(taps*sizeof (int16_t), GFP_KERNEL); + if (fir->history) + memset (fir->history, '\0', taps*sizeof (int16_t)); +} +/*- End of function --------------------------------------------------------*/ + +static inline void fir32_free (fir32_state_t *fir) +{ + kfree(fir->history); +} +/*- End of function --------------------------------------------------------*/ + +static inline int16_t fir32 (fir32_state_t *fir, int16_t sample) +{ + int i; + int offset1; + int offset2; + int32_t y; + + fir->history[fir->curr_pos] = sample; + offset2 = fir->curr_pos + 1; + offset1 = fir->taps - offset2; + y = 0; + for (i = fir->taps - 1; i >= offset1; i--) + y += fir->coeffs[i]*fir->history[i - offset1]; + for ( ; i >= 0; i--) + y += fir->coeffs[i]*fir->history[i + offset2]; + if (fir->curr_pos <= 0) + fir->curr_pos = fir->taps; + fir->curr_pos--; + return y >> 15; +} +/*- End of function --------------------------------------------------------*/ + +#endif +/*- End of file ------------------------------------------------------------*/ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/firmware/Makefile dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/firmware/Makefile --- dahdi-linux-2.2.1-rc2/drivers/dahdi/firmware/Makefile 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/firmware/Makefile 2009-11-09 13:32:45.000000000 -0600 @@ -0,0 +1,154 @@ +# +# DAHDI +# +# Makefile for firmware downloading/installation +# +# Copyright (C) 2007-2009, Digium, Inc. +# +# Joshua Colp +# +# This program is free software, distributed under the terms of +# the GNU General Public License +# + +.PHONY: dist-clean clean all uninstall have_download install object-build hotplug-install hotplug-dirs hotplug-uninstall make_firmware_object firmware-loaders + +OCT6114_064_VERSION:=1.05.01 +OCT6114_128_VERSION:=1.05.01 +TC400M_VERSION:=MR6.12 +VPMADT032_VERSION:=1.20.0 + +FIRMWARE_URL:=http://downloads.digium.com/pub/telephony/firmware/releases + +ALL_FIRMWARE=FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-TC400M + +# Firmware files should use the naming convention: dahdi-fw--- or dahdi-fw-- +# First example: dahdi-fw-oct6114-064-1.05.01 +# This means this is version 1.05.01 of the oct6114-064 firmware +# Second example: dahdi-fw-tc400m-MR5.6 +# This means this is version MR5.6 of the tc400m firmware + +# Build a list of firmware package filenames we need +FIRMWARE:=$(ALL_FIRMWARE:FIRMWARE-OCT6114-064=dahdi-fw-oct6114-064-$(OCT6114_064_VERSION).tar.gz) +FIRMWARE:=$(FIRMWARE:FIRMWARE-OCT6114-128=dahdi-fw-oct6114-128-$(OCT6114_128_VERSION).tar.gz) +FIRMWARE:=$(FIRMWARE:FIRMWARE-TC400M=dahdi-fw-tc400m-$(TC400M_VERSION).tar.gz) + +FWLOADERS:=dahdi-fwload-vpmadt032-$(VPMADT032_VERSION).tar.gz + +# Build a list of object files if hotplug will not be used +OBJECT_FILES:=$(ALL_FIRMWARE:FIRMWARE-OCT6114-064=dahdi-fw-oct6114-064.o) +OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-OCT6114-128=dahdi-fw-oct6114-128.o) +OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-TC400M=dahdi-fw-tc400m.o) + +# Force usage of wget, for now +DOWNLOAD=wget +WGET=wget + +# If "fetch" is used, --continue is not a valid option. +ifeq ($(WGET),wget) +WGET_ARGS:=--continue +endif + +all: $(FIRMWARE) + +# Clean up any downloaded/extracted firmware packages +dist-clean: clean + rm -f dahdi-fw-*.bin + rm -f dahdi-fw-*.tar.gz + rm -f dahdi-fwload-*.tar.gz + rm -f make_firmware_object + +# Clean up anything we built +clean: + rm -f dahdi-fw-*.o + +# Download and extract firmware tarballs +dahdi-fw-%.tar.gz: + @if ( [ "$(HOTPLUG_FIRMWARE)" = "no" ] ) || ( [ -d $(DESTDIR)/usr/lib/hotplug/firmware ] && ! [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.$(subst .tar.gz,,$*) ] ) || ( [ -d $(DESTDIR)/lib/firmware ] && ! [ -f $(DESTDIR)/lib/firmware/.$(subst .tar.gz,,$*) ] ); then \ + echo "Attempting to download $@"; \ + if test ! -f $@; then $(DOWNLOAD) $(WGET_ARGS) $(FIRMWARE_URL)/$@; fi; \ + if test ! -f $@; then exit 1; fi; \ + (cat $@ | gzip -d | tar -xof -) \ + fi + +firmware-loaders: $(FWLOADERS) + +.PHONY: dahdi-fwload-vpmadt032-$(VPMADT032_VERSION).tar.gz +dahdi-fwload-vpmadt032-$(VPMADT032_VERSION).tar.gz: + @if test ! -f $@; then echo "Attempting to download $@"; $(DOWNLOAD) $(WGET_ARGS) $(FIRMWARE_URL)/$@; fi; \ + if test ! -f $@; then exit 1; fi; \ + (cd ../../..; cat drivers/dahdi/firmware/$@ | gzip -d | tar -xof -) + +# Create object files suitable for linking against +object-build: $(FIRMWARE) $(OBJECT_FILES) + +$(DESTDIR)/usr/lib/hotplug/firmware $(DESTDIR)/lib/firmware: + mkdir -p $@ + +# Install all downloaded firmware images for hotplug usage +hotplug-install: $(DESTDIR)/usr/lib/hotplug/firmware $(DESTDIR)/lib/firmware $(FIRMWARE) +ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-064-$(OCT6114_064_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-064-$(OCT6114_064_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes) + @echo "Installing dahdi-fw-oct6114-064.bin to hotplug firmware directories" + @install -m 644 dahdi-fw-oct6114-064.bin $(DESTDIR)/usr/lib/hotplug/firmware + @rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-064-* + @touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-064-$(OCT6114_064_VERSION) + @install -m 644 dahdi-fw-oct6114-064.bin $(DESTDIR)/lib/firmware + @rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-064-* + @touch $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-064-$(OCT6114_064_VERSION) +else + @echo "Firmware dahdi-fw-oct6114-064.bin is already installed with required version $(OCT6114_064_VERSION)" +endif +ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-128-$(OCT6114_128_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-128-$(OCT6114_128_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes) + @echo "Installing dahdi-fw-oct6114-128.bin to hotplug firmware directories" + @install -m 644 dahdi-fw-oct6114-128.bin $(DESTDIR)/usr/lib/hotplug/firmware + @rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-128-* + @touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-128-$(OCT6114_128_VERSION) + @install -m 644 dahdi-fw-oct6114-128.bin $(DESTDIR)/lib/firmware + @rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-128-* + @touch $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-128-$(OCT6114_128_VERSION) +else + @echo "Firmware dahdi-fw-oct6114-128.bin is already installed with required version $(OCT6114_128_VERSION)" +endif +ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-tc400m-$(TC400M_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-tc400m-$(TC400M_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes) + @echo "Installing dahdi-fw-tc400m.bin to hotplug firmware directories" + @install -m 644 dahdi-fw-tc400m.bin $(DESTDIR)/usr/lib/hotplug/firmware + @rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-tc400m-* + @touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-tc400m-$(TC400M_VERSION) + @install -m 644 dahdi-fw-tc400m.bin $(DESTDIR)/lib/firmware + @rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-tc400m-* + @touch $(DESTDIR)/lib/firmware/.dahdi-fw-tc400m-$(TC400M_VERSION) +else + @echo "Firmware dahdi-fw-tc400m.bin is already installed with required version $(TC400M_VERSION)" +endif + +# Uninstall any installed dahdi firmware images from hotplug firmware directories +hotplug-uninstall: + if [ -d $(DESTDIR)/usr/lib/hotplug/firmware ]; then \ + rm -f $(DESTDIR)/usr/lib/hotplug/firmware/dahdi-fw-*.bin; \ + rm -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw*; \ + fi + if [ -d $(DESTDIR)/lib/firmware ]; then \ + rm -f $(DESTDIR)/lib/firmware/dahdi-fw-*.bin; \ + rm -f $(DESTDIR)/lib/firmware/.dahdi-fw*; \ + fi + +make_firmware_object: make_firmware_object.in ../dahdi-base.o + @export BFDNAME=`LANG=C objdump -f ../dahdi-base.o | grep -e "dahdi-base.o:" | sed "s/.*file format \(.*\)/\1/"`; \ + export BFDARCH=`LANG=C objdump -f ../dahdi-base.o | grep -e "architecture:" | sed "s/.*ture: \(.*\),.*/\1/"`; \ + sed -e s/BFDNAME/$${BFDNAME}/ -e s/BFDARCH/$${BFDARCH}/ $< > $@ + @chmod +x $@ + +# Build object file of an oct6114 064 firmware image for linking +dahdi-fw-oct6114-064.o: dahdi-fw-oct6114-064-$(OCT6114_064_VERSION).tar.gz dahdi-fw-oct6114-064.bin make_firmware_object + @echo Making firmware object file for dahdi-fw-oct6114-064.bin + ./make_firmware_object dahdi-fw-oct6114-064.bin $@ + +# Build object file of an oct6114 128 firmware image for linking +dahdi-fw-oct6114-128.o: dahdi-fw-oct6114-128-$(OCT6114_128_VERSION).tar.gz dahdi-fw-oct6114-128.bin make_firmware_object + @echo Making firmware object file for dahdi-fw-oct6114-128.bin + ./make_firmware_object dahdi-fw-oct6114-128.bin $@ + +# Build object file of a TC400M firmware image for linking +dahdi-fw-tc400m.o: dahdi-fw-tc400m-$(TC400M_VERSION).tar.gz dahdi-fw-tc400m.bin make_firmware_object + @echo Making firmware object file for dahdi-fw-tc400m.bin + ./make_firmware_object dahdi-fw-tc400m.bin $@ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/firmware/make_firmware_object.in dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/firmware/make_firmware_object.in --- dahdi-linux-2.2.1-rc2/drivers/dahdi/firmware/make_firmware_object.in 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/firmware/make_firmware_object.in 2008-06-17 17:09:22.000000000 -0500 @@ -0,0 +1,8 @@ +#!/bin/sh -e + +# make an object file from a raw binary firmware file +# arguments: +# 1 - firmware file +# 2 - output file + +objcopy -I binary ${1} -B BFDARCH -O BFDNAME ${2} --rename-section .data=.rodata,alloc,load,data,contents,readonly diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/fxo_modes.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/fxo_modes.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/fxo_modes.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/fxo_modes.h 2010-01-09 21:29:01.959619081 -0600 @@ -0,0 +1,678 @@ +/* + * FXO port mode settings for various regions + * + * Copyright (C) 2008 Digium, Inc. + * + * extracted from wctdm.c by + * Kevin P. Fleming + * + * All rights reserved. + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#ifndef _FXO_MODES_H +#define _FXO_MODES_H + +static struct fxo_mode { + char *name; + int ohs; + int ohs2; + int rz; + int rt; + int ilim; + int dcv; + int mini; + int acim; + int ring_osc; + int ring_x; + unsigned int battdebounce; /* in milliseconds */ + unsigned int battalarm; /* in milliseconds */ + unsigned int battthresh; /* unknown units */ +} fxo_modes[] = +{ + /* US, Canada */ + { .name = "FCC", + .rt = 1, + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + /* (CNET) Special "FCC" zones for frequency-selective ringers */ + { .name = "FCC17", + .rt = 1, + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + .acim = 0x2, + .ring_osc = 0x7f4c, /* 16.67 Hz */ + }, + { .name = "FCC25", + .rt = 1, + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + .acim = 0x2, + .ring_osc = 0x7e6c, + }, + { .name = "FCC30", + .rt = 1, + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + .acim = 0x2, + .ring_osc = 0x7dbb, + }, + { .name = "FCC33", + .rt = 1, + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + .acim = 0x2, + .ring_osc = 0x7d34, /* 33.33 Hz */ + }, + { .name = "FCC40", + .rt = 1, + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + .acim = 0x2, + .ring_osc = 0x7bfa, + }, + { .name = "FCC42", + .rt = 1, + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + .acim = 0x2, + .ring_osc = 0x7b91, + }, + { .name = "FCC50", + .rt = 1, + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + .acim = 0x2, + .ring_osc = 0x79bc, + }, + { .name = "FCC54", + .rt = 1, + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + .acim = 0x2, + .ring_osc = 0x78b3, + }, + { .name = "FCC60", + .rt = 1, + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + .acim = 0x2, + .ring_osc = 0x7702, + }, + { .name = "FCC67", + .rt = 1, + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + .acim = 0x2, + .ring_osc = 0x74ef, /* 66.66 Hz */ + }, + /* Austria, Belgium, Denmark, Finland, France, Germany, + Greece, Iceland, Ireland, Italy, Luxembourg, Netherlands, + Norway, Portugal, Spain, Sweden, Switzerland, and UK */ + { .name = "TBR21", + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .ring_osc = 0x7e6c, + .ring_x = 0x023a, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "ARGENTINA", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "AUSTRALIA", + .ohs = 1, + .mini = 0x3, + .acim = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "AUSTRIA", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "BAHRAIN", + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "BELGIUM", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "BRAZIL", + .mini = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "BULGARIA", + .ilim = 1, + .dcv = 0x3, + .mini = 0x0, + .acim = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "CANADA", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "CHILE", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "CHINA", + .mini = 0x3, + .acim = 0xf, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "COLOMBIA", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "CROATIA", + .ilim = 1, + .dcv = 0x3, + .mini = 0, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "CYPRUS", + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "CZECH", + .ilim = 1, + .dcv = 0x3, + .mini = 0, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "DENMARK", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "ECUADOR", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "EGYPT", + .mini = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "ELSALVADOR", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "FINLAND", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "FRANCE", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .mini = 0, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "GERMANY", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "GREECE", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "GUAM", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "HONGKONG", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "HUNGARY", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "ICELAND", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "INDIA", + .dcv = 0x3, + .acim = 0x4, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "INDONESIA", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "IRELAND", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "ISRAEL", + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "ITALY", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "JAPAN", + .mini = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "JORDAN", + .mini = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "KAZAKHSTAN", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "KUWAIT", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "LATVIA", + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "LEBANON", + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "LUXEMBOURG", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "MACAO", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + /* Current loop >= 20ma */ + { .name = "MALAYSIA", + .mini = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "MALTA", + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "MEXICO", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "MOROCCO", + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "NETHERLANDS", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "NEWZEALAND", + .dcv = 0x3, + .acim = 0x4, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "NIGERIA", + .ilim = 0x1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "NORWAY", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "OMAN", + .mini = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "PAKISTAN", + .mini = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "PERU", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "PHILIPPINES", + .mini = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "POLAND", + .rz = 1, + .rt = 1, + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "PORTUGAL", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "ROMANIA", + .dcv = 3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "RUSSIA", + .mini = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "SAUDIARABIA", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "SINGAPORE", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "SLOVAKIA", + .dcv = 0x3, + .acim = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "SLOVENIA", + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "SOUTHAFRICA", + .ohs = 1, + .rz = 1, + .dcv = 0x3, + .acim = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "SOUTHKOREA", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "SPAIN", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "SWEDEN", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "SWITZERLAND", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x2, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "SYRIA", + .mini = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "TAIWAN", + .mini = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "THAILAND", + .mini = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "UAE", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "UK", + .ohs2 = 1, + .ilim = 1, + .dcv = 0x3, + .acim = 0x5, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "USA", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, + { .name = "YEMEN", + .dcv = 0x3, + .battdebounce = 64, + .battalarm = 1000, + .battthresh = 3, + }, +}; + +#endif /* _FXO_MODES_H */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/hpec/dahdi_echocan_hpec.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/hpec/dahdi_echocan_hpec.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/hpec/dahdi_echocan_hpec.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/hpec/dahdi_echocan_hpec.c 2009-11-09 13:32:45.000000000 -0600 @@ -0,0 +1,222 @@ +/* + * DAHDI Telephony Interface to Digium High-Performance Echo Canceller + * + * Copyright (C) 2006-2008 Digium, Inc. + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +static int debug; + +#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args) +#define debug_printk(level, fmt, args...) if (debug >= level) printk(KERN_DEBUG "%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args) + +#include "hpec_user.h" +#include "hpec.h" + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec); +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec); +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, __u32 size); +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val); + +static const struct dahdi_echocan_factory my_factory = { + .name = "HPEC", + .owner = THIS_MODULE, + .echocan_create = echo_can_create, +}; + +static const struct dahdi_echocan_features my_features = { + .NLP_automatic = 1, + .CED_tx_detect = 1, + .CED_rx_detect = 1, +}; + +static const struct dahdi_echocan_ops my_ops = { + .name = "HPEC", + .echocan_free = echo_can_free, + .echocan_process = echo_can_process, + .echocan_traintap = echo_can_traintap, +}; + +struct ec_pvt { + struct hpec_state *hpec; + struct dahdi_echocan_state dahdi; +}; + +#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi) + +static int __attribute__((regparm(0), format(printf, 1, 2))) logger(const char *format, ...) +{ + int res; + va_list args; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9) + va_start(args, format); + res = vprintk(format, args); + va_end(args); +#else + char buf[256]; + + va_start(args, format); + res = vsnprintf(buf, sizeof(buf), format, args); + va_end(args); + printk(KERN_INFO "%s" buf); +#endif + + return res; +} + +static void *memalloc(size_t len) +{ + return kmalloc(len, GFP_KERNEL); +} + +static void memfree(void *ptr) +{ + kfree(ptr); +} + +static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + hpec_channel_free(pvt->hpec); + kfree(pvt); +} + +static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, __u32 size) +{ + struct ec_pvt *pvt = dahdi_to_pvt(ec); + + hpec_channel_update(pvt->hpec, isig, iref); +} + +DECLARE_MUTEX(license_lock); + +static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec) +{ + struct ec_pvt *pvt; + + if (ecp->param_count > 0) { + printk(KERN_WARNING "HPEC does not support parameters; failing request\n"); + return -EINVAL; + } + + pvt = kzalloc(sizeof(*pvt), GFP_KERNEL); + if (!pvt) + return -ENOMEM; + + pvt->dahdi.ops = &my_ops; + pvt->dahdi.features = my_features; + + if (down_interruptible(&license_lock)) + return -ENOTTY; + + pvt->hpec = hpec_channel_alloc(ecp->tap_length); + + up(&license_lock); + + if (!pvt->hpec) { + kfree(pvt); + *ec = NULL; + return -ENOTTY; + } else { + *ec = &pvt->dahdi; + return 0; + } +} + +static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val) +{ + return 1; +} + +static int hpec_license_ioctl(unsigned int cmd, unsigned long data) +{ + struct hpec_challenge challenge; + struct hpec_license license; + int result = 0; + + switch (cmd) { + case DAHDI_EC_LICENSE_CHALLENGE: + if (down_interruptible(&license_lock)) + return -EINTR; + memset(&challenge, 0, sizeof(challenge)); + if (hpec_license_challenge(&challenge)) + result = -ENODEV; + if (!result && copy_to_user((unsigned char *) data, &challenge, sizeof(challenge))) + result = -EFAULT; + up(&license_lock); + return result; + case DAHDI_EC_LICENSE_RESPONSE: + if (down_interruptible(&license_lock)) + return -EINTR; + if (copy_from_user(&license, (unsigned char *) data, sizeof(license))) + result = -EFAULT; + if (!result && hpec_license_check(&license)) + result = -EACCES; + up(&license_lock); + return result; + default: + return -ENOSYS; + } +} + +static int __init mod_init(void) +{ + if (dahdi_register_echocan_factory(&my_factory)) { + module_printk(KERN_ERR, "could not register with DAHDI core\n"); + + return -EPERM; + } + + module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", my_factory.name); + + hpec_init(logger, debug, DAHDI_CHUNKSIZE, memalloc, memfree); + + dahdi_set_hpec_ioctl(hpec_license_ioctl); + + return 0; +} + +static void __exit mod_exit(void) +{ + dahdi_unregister_echocan_factory(&my_factory); + + dahdi_set_hpec_ioctl(NULL); + + hpec_shutdown(); +} + +module_param(debug, int, S_IRUGO | S_IWUSR); + +MODULE_DESCRIPTION("DAHDI High Performance Echo Canceller"); +MODULE_AUTHOR("Kevin P. Fleming "); +MODULE_LICENSE("Digium Commercial"); + +module_init(mod_init); +module_exit(mod_exit); diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/hpec/hpec.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/hpec/hpec.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/hpec/hpec.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/hpec/hpec.h 2009-04-29 13:24:04.000000000 -0500 @@ -0,0 +1,46 @@ +/* + * DAHDI Telephony Interface to Digium High-Performance Echo Canceller + * + * Copyright (C) 2006 Digium, Inc. + * + * All rights reserved. + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#if !defined(_HPEC_H) +#define _HPEC_H + +struct hpec_state; + +void __attribute__((regparm(0))) hpec_init(int __attribute__((regparm(0), format(printf, 1, 2))) (*logger)(const char *format, ...), + unsigned int debug, + unsigned int chunk_size, + void * (*memalloc)(size_t len), + void (*memfree)(void *ptr)); + +void __attribute__((regparm(0))) hpec_shutdown(void); + +int __attribute__((regparm(0))) hpec_license_challenge(struct hpec_challenge *challenge); + +int __attribute__((regparm(0))) hpec_license_check(struct hpec_license *license); + +struct hpec_state __attribute__((regparm(0))) *hpec_channel_alloc(unsigned int len); + +void __attribute__((regparm(0))) hpec_channel_free(struct hpec_state *channel); + +void __attribute__((regparm(0))) hpec_channel_update(struct hpec_state *channel, short *isig, const short *iref); + +#endif /* !defined(_HPEC_H) */ + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/hpec/hpec_user.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/hpec/hpec_user.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/hpec/hpec_user.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/hpec/hpec_user.h 2008-08-06 10:05:25.000000000 -0500 @@ -0,0 +1,39 @@ +/* + * DAHDI Telephony Interface to Digium High-Performance Echo Canceller + * + * Copyright (C) 2006 Digium, Inc. + * + * All rights reserved. + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#if !defined(_HPEC_USER_H) +#define _HPEC_USER_H + +struct hpec_challenge { + __u8 challenge[16]; +}; + +struct hpec_license { + __u32 numchannels; + __u8 userinfo[256]; + __u8 response[16]; +}; + +#define DAHDI_EC_LICENSE_CHALLENGE _IOR(DAHDI_CODE, 60, struct hpec_challenge) +#define DAHDI_EC_LICENSE_RESPONSE _IOW(DAHDI_CODE, 61, struct hpec_license) + +#endif /* !defined(_HPEC_USER_H) */ + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/Kbuild dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/Kbuild --- dahdi-linux-2.2.1-rc2/drivers/dahdi/Kbuild 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/Kbuild 2010-01-09 21:29:01.959619081 -0600 @@ -0,0 +1,136 @@ +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI) += dahdi.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DUMMY) += dahdi_dummy.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC) += dahdi_dynamic.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_LOC) += dahdi_dynamic_loc.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETH) += dahdi_dynamic_eth.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TRANSCODE) += dahdi_transcode.o + +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT4XXP) += wct4xxp/ +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTC4XXP) += wctc4xxp/ +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM24XXP) += wctdm24xxp/ +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE12XP) += wcte12xp/ +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM) += wctdm.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VOICEBUS) += voicebus/ +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCB4XXP) += wcb4xxp/ + +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT1XXP) += wct1xxp.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE11XP) += wcte11xp.o + +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCFXO) += wcfxo.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TOR2) += tor2.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_PCIRADIO) += pciradio.o + +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_XPP) += xpp/ + +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_JPAH) += dahdi_echocan_jpah.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_STEVE) += dahdi_echocan_sec.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_STEVE2) += dahdi_echocan_sec2.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_KB1) += dahdi_echocan_kb1.o +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_MG2) += dahdi_echocan_mg2.o + +obj-m += $(DAHDI_MODULES_EXTRA) + +# Only enable this if you think you know what you're doing. This is not +# supported yet: +obj-m += dahdi_echocan_oslec.o +# +# A quick and dirty way to build OSLEC, if you happened to place it +# yourself in the dahdi source tree. This is experimental. See README +# regarding OSLEC. +obj-m += ../staging/echo/echo.o + +CFLAGS_MODULE += -I$(DAHDI_INCLUDE) -I$(src) + +ifndef HOTPLUG_FIRMWARE +ifneq (,$(filter y m,$(CONFIG_FW_LOADER))) +HOTPLUG_FIRMWARE := yes +else +HOTPLUG_FIRMWARE := no +endif +export HOTPLUG_FIRMWARE +endif + +# fix typo present in CentOS and RHEL 2.6.9 kernels +BAD_KERNELS_VERS := 22 34 34.0.1 34.0.2 +BAD_KERNELS := $(foreach ver,$(BAD_KERNELS_VERS),2.6.9-$(ver).EL 2.6.9-$(ver).ELsmp) +ifneq (,$(filter $(KVERS),$(BAD_KERNELS))) +EXTRA_CFLAGS+=-Drw_lock_t=rwlock_t +endif + +# A number of Fedora 10 (9 also?) kernels backported hrtimer to 2.6.27 +# as part of an ALSA backport. TODO: Any better way to detect that? +ifeq (1,$(shell fgrep -q ' hrtimer_set_expires' include/linux/hrtimer.h 2>/dev/null && echo 1)) +EXTRA_CFLAGS+=-DHAVE_HRTIMER_ACCESSORS=1 +endif + +dahdi-objs := dahdi-base.o + +############################################################################### +# Find appropriate ARCH value for VPMADT032 and HPEC binary modules +############################################################################### + +ifeq ($(ARCH),i386) + DAHDI_ARCH=x86_32 +else + ifeq ($(ARCH),x86_64) + DAHDI_ARCH=x86_64 + else + ifeq ($(ARCH),x86) + ifeq ($(CONFIG_X86_32),y) + DAHDI_ARCH=x86_32 + else + DAHDI_ARCH=x86_64 + endif + else +$(warning CPU Architecture '$(ARCH)' does not support VPMADT032 or HPEC. Skipping.) + endif + endif +endif + +############################################################################### +# VPMADT032 Loader +############################################################################### + +dahdi_vpmadt032_loader-objs := vpmadt032_loader/dahdi_vpmadt032_loader.o + +ifneq ($(DAHDI_ARCH),) + ifneq ($(wildcard $(src)/vpmadt032_loader/vpmadt032_$(DAHDI_ARCH).o_shipped),) + VPMADT032_LOADER_PRESENT=yes + dahdi_vpmadt032_loader-objs += vpmadt032_loader/vpmadt032_$(DAHDI_ARCH).o + obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VPMADT032_LOADER) += dahdi_vpmadt032_loader.o + endif +endif + +############################################################################### +# HPEC Support +############################################################################### + +dahdi_echocan_hpec-objs := hpec/dahdi_echocan_hpec.o +CFLAGS_dahdi_echocan_hpec.o := -I$(src)/hpec + +ifneq ($(DAHDI_ARCH),) + ifneq ($(wildcard $(src)/hpec/hpec_$(DAHDI_ARCH).o_shipped),) + HPEC_PRESENT=yes + dahdi_echocan_hpec-objs += hpec/hpec_$(DAHDI_ARCH).o + endif +endif + +ifeq ($(HPEC_PRESENT),yes) +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_HPEC) += dahdi_echocan_hpec.o +endif + +$(obj)/pciradio.o: $(obj)/radfw.h +$(obj)/tor2.o: $(obj)/tor2fw.h + +hostprogs-y := $(obj)/makefw + +$(obj)/tor2fw.h: $(src)/tormenta2.rbt $(obj)/makefw + $(obj)/makefw $< tor2fw > $@ + +$(obj)/radfw.h: $(src)/pciradio.rbt $(obj)/makefw + $(obj)/makefw $< radfw > $@ + +$(obj)/makefw: $(src)/makefw.c + $(HOSTCC) -o $@ $^ + +clean-files := radfw.h tor2fw.h diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/Kconfig dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/Kconfig --- dahdi-linux-2.2.1-rc2/drivers/dahdi/Kconfig 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/Kconfig 2009-04-29 12:48:39.000000000 -0500 @@ -0,0 +1,281 @@ +# +# DAHDI configuration +# + +menuconfig DAHDI + tristate "DAHDI support" + select CRC_CCITT + default m + ---help--- + DAHDI basic infrastructure. + + To compile this driver as a module, choose M here: the + module will be called dahdi. + + If unsure, say Y. + +config DAHDI_ECHOCAN + tristate "DADHI Echo Cancelers (software)" + depends on DAHDI + default DAHDI + +config DAHDI_ECHOCAN_MG2 + tristate "DADHI MG2 Echo Canceler" + depends on DAHDI_ECHOCAN + default DAHDI_ECHOCAN + ---help--- + To compile this driver as a module, choose M here: the + module will be called dahdi_echocancel_mg2. + + If unsure, say Y. + +config DAHDI_ECHOCAN_KB1 + tristate "DADHI KB1 Echo Canceler" + depends on DAHDI_ECHOCAN + default DAHDI_ECHOCAN + ---help--- + To compile this driver as a module, choose M here: the + module will be called dahdi_echocancel_kb1. + + If unsure, say Y. + +config DAHDI_ECHOCAN_SEC + tristate "DADHI SEC Echo Canceler" + depends on DAHDI_ECHOCAN + default DAHDI_ECHOCAN + ---help--- + To compile this driver as a module, choose M here: the + module will be called dahdi_echocancel_sec. + + If unsure, say Y. + +config DAHDI_ECHOCAN_SEC2 + tristate "DADHI SEC2 Echo Canceler" + depends on DAHDI_ECHOCAN + default DAHDI_ECHOCAN + ---help--- + To compile this driver as a module, choose M here: the + module will be called dahdi_echocancel_sec2. + + If unsure, say Y. + +config DAHDI_ECHOCAN_HPEC + tristate "DADHI HPEC Echo Canceler" + depends on DAHDI_ECHOCAN + default DAHDI_ECHOCAN + ---help--- + To compile this driver as a module, choose M here: the + module will be called dahdi_echocancel_hpec. + + If unsure, say Y. + +config DAHDI_WCTDM + tristate "Digium Wildcard TDM400P Support" + depends on DAHDI && PCI + default DAHDI + ---help--- + This driver provides support for the Digium Wildcard TDM400P. + + To compile this driver as a module, choose M here: the + module will be called wctdm. + + If unsure, say Y. + +config DAHDI_WCT4XXP + tristate "Digium Wildcard dual- and quad-T1/E1/J1 Support" + depends on DAHDI && PCI + default DAHDI + ---help--- + This driver provides support for the following Digium + Wildcard products: + + * TE205/206/207/210/211/212P (PCI/PCI-X) + * TE220 (PCI-E) + * TE405/406/407/410/411/412P (PCI/PCI-X) + * TE420 (PCI-E) + + To compile this driver as a module, choose M here: the + module will be called wct4xxp. + + If unsure, say Y. + +config DAHDI_TRANSCODE + tristate "DAHDI transcoding support" + depends on DAHDI + default DAHDI + ---help--- + DAHDI transcoding infrastructure. + + To compile this driver as a module, choose M here: the + module will be called dahdi_transcode. + + If unsure, say Y. + +config DAHDI_WCTC4XXP + tristate "Digium Wildcard TC400B Support" + depends on DAHDI_TRANSCODE && PCI + default DAHDI + ---help--- + This driver provides support for the Digium Wildcard TC400B. + + To compile this driver as a module, choose M here: the + module will be called wctc4xxp. + + If unsure, say Y. + +config DAHDI_VOICEBUS + tristate "VoiceBus(tm) Interface Library" + depends on PCI + default DAHDI + ---help--- + This driver provides the common interface for telephony cards that + use the VoiceBus(tm) interface. It also contains common supporting + libraries for the VPMADT032 hardware echo cancelation module that + is available for the VoiceBus cards. + + To compile this driver as a module, choose M here: the module will + be called voicebus. + + If unsure, say Y. + +config DAHDI_WCTDM24XXP + tristate "Digium Wildcard VoiceBus analog card Support" + depends on DAHDI && DAHDI_VOICEBUS + default DAHDI + ---help--- + This driver provides support for the following Digium + Wildcard products: + + * TDM410P (PCI/PCI-X) + * AEX410 (PCI-E) + * TDM800P (PCI/PCI-X) + * AEX800 (PCI-E) + * TDM2400P (PCI/PCI-X) + * AEX2400 (PCI-E) + + To compile this driver as a module, choose M here: the + module will be called wctdm24xxp. + + If unsure, say Y. + +config DAHDI_WCTE12XP + tristate "Digium Wildcard VoiceBus digital card Support" + depends on DAHDI && DAHDI_VOICEBUS + default DAHDI + ---help--- + This driver provides support for the following Digium + Wildcard products: + + * TE120P (PCI/PCI-X) + * TE121 (PCI/PCI-X) + * TE122 (PCI-E) + + To compile this driver as a module, choose M here: the + module will be called wcte12xp. + + If unsure, say Y. + +config DAHDI_PCIRADIO + tristate "PCI Radio Support" + depends on DAHDI && PCI + default DAHDI + ---help--- + To compile this driver as a module, choose M here: the + module will be called pciradio. + + If unsure, say Y. + +config DAHDI_DUMMY + tristate "Dummy (no hardware) Timing Support" + depends on DAHDI + default DAHDI + ---help--- + This module provides timing support for applications that + use DAHDI conference mixing services, pseudo channels or + for other purposes. + + To compile this driver as a module, choose M here: the + module will be called dahdi_dummy. + + If unsure, say Y. + +config DAHDI_DYNAMIC + tristate "Dynamic (virtual) Span Support" + depends on DAHDI + default DAHDI + ---help--- + This module provides support for virtual spans, which are + emulated or provided using various technologies. + + To compile this driver as a module, choose M here: the + module will be called dahdi_dynamic. + + If unsure, say Y. + +config DAHDI_DYNAMIC_ETH + tristate "Ethernet (TDMoE) Span Support" + depends on DAHDI && DAHDI_DYNAMIC + default DAHDI + ---help--- + This module provides support for spans over Ethernet, + using the TDMoE protocol. + + To compile this driver as a module, choose M here: the + module will be called dahdi_dynamic_eth. + + If unsure, say Y. + +config DAHDI_DYNAMIC_LOC + tristate "Local (loopback) Span Support" + depends on DAHDI && DAHDI_DYNAMIC + default DAHDI + ---help--- + This module provides support for spans in the local system, + primarily used for looping and monitoring other spans. + + To compile this driver as a module, choose M here: the + module will be called dahdi_dynamic_loc. + + If unsure, say Y. + +config DAHDI_TOR2 + tristate "Tormenta2 quad-port T1/E1 Support" + depends on DAHDI && PCI + default DAHDI + ---help--- + To compile this driver as a module, choose M here: the + module will be called tor2. + + If unsure, say Y. + +config DAHDI_WCFXO + tristate "Digium Wildcard X100P Support" + depends on DAHDI && PCI + default DAHDI + ---help--- + To compile this driver as a module, choose M here: the + module will be called wcfxo. + + If unsure, say Y. + +config DAHDI_WCT1XXP + tristate "Digium Wildcard T100P Support" + depends on DAHDI && PCI + default DAHDI + ---help--- + To compile this driver as a module, choose M here: the + module will be called wct1xxp. + + If unsure, say Y. + +config DAHDI_WCTE11XP + tristate "Digium Wildcard TE110P Support" + depends on DAHDI && PCI + default DAHDI + ---help--- + To compile this driver as a module, choose M here: the + module will be called wcte11xp. + + If unsure, say Y. + +source "drivers/dahdi/xpp/Kconfig" diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/Makefile dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/Makefile --- dahdi-linux-2.2.1-rc2/drivers/dahdi/Makefile 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/Makefile 2008-06-17 15:22:36.000000000 -0500 @@ -0,0 +1,6 @@ +ifdef KBUILD_EXTMOD +# We only get here on kernels 2.6.0-2.6.9 . +# For newer kernels, Kbuild will be included directly by the kernel +# build system. +include $(src)/Kbuild +endif diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/makefw.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/makefw.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/makefw.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/makefw.c 2008-08-06 16:07:48.000000000 -0500 @@ -0,0 +1,84 @@ +/* Xilinx firmware convertor program. + * + * Written by Jim Dixon . + * + * Copyright (C) 2001 Jim Dixon / Zapata Telephony. + * Copyright (C) 2001-2008 Digium, Inc. + * + * All rights reserved. + * + */ + +/* + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2 as published by the + * Free Software Foundation. See the LICENSE file included with + * this program for more details. + */ + +#include +#include +#include + +#define SWATH 12 + +int main(int argc, char *argv[]) +{ +FILE *fp; +int i,j,nbytes; +unsigned char c; +char buf[300]; + + if (argc < 3) + { + puts("Usage... makefw filename.rbt array_name"); + exit(1); + } + + fp = fopen(argv[1],"r"); + if (!fp) + { + perror("bit file open"); + exit(1); + } + nbytes = 0; + printf("static unsigned char %s[] = {\n",argv[2]); + i = 0; + while(fgets(buf,sizeof(buf) - 1,fp)) + { + if (!buf[0]) continue; + if (buf[strlen(buf) - 1] < ' ') buf[strlen(buf) - 1] = 0; + if (!buf[0]) continue; + if (buf[strlen(buf) - 1] < ' ') buf[strlen(buf) - 1] = 0; + if (!buf[0]) continue; + if (strlen(buf) < 32) continue; + if ((buf[0] != '0') && (buf[0] != '1')) continue; + c = 0; + for(j = 0; buf[j]; j++) + { + if (buf[j] > '0') c |= 1 << (j & 7); + if ((j & 7) == 7) + { + nbytes++; + if (i) printf(","); + printf("0x%02x",c); + if (i++ == SWATH) { + printf(",\n"); + i = 0; + } + c = 0; + } + } + } + printf("\n};\n\n"); + fprintf(stderr,"Loaded %d bytes from file\n",nbytes); + fclose(fp); + exit(0); +} + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/bt/octapi_bt0.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/bt/octapi_bt0.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/bt/octapi_bt0.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/bt/octapi_bt0.c 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,1217 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_bt0.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to manage a binary tree of variable max size. Library is + made to use one block of contiguous memory to manage the tree. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 18 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#include "apilib/octapi_bt0.h" +#include "octapi_bt0_private.h" + + + +#if !SKIP_OctApiBt0GetSize +UINT32 OctApiBt0GetSize(UINT32 number_of_items,UINT32 key_size, UINT32 data_size, UINT32 * b_size) +{ + if ((key_size % 4) != 0) return(OCTAPI_BT0_KEY_SIZE_NOT_MUTLIPLE_OF_UINT32); + if ((data_size % 4) != 0) return(OCTAPI_BT0_DATA_SIZE_NOT_MUTLIPLE_OF_UINT32); + + *b_size = 0; + *b_size += sizeof(OCTAPI_BT0); + *b_size += sizeof(OCTAPI_BT0_NODE) * number_of_items; + *b_size += key_size * number_of_items; + *b_size += data_size * number_of_items; + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0Init +UINT32 OctApiBt0Init(void ** b,UINT32 number_of_items,UINT32 key_size, UINT32 data_size) +{ + UINT32 i; + OCTAPI_BT0 * bb; + + /* Check input parameters.*/ + if ((key_size % 4) != 0) return(OCTAPI_BT0_KEY_SIZE_NOT_MUTLIPLE_OF_UINT32); + if ((data_size % 4) != 0) return(OCTAPI_BT0_DATA_SIZE_NOT_MUTLIPLE_OF_UINT32); + + /* If b is not already allocated.*/ + if (*b == NULL) return(OCTAPI_BT0_MALLOC_FAILED); + + bb = (OCTAPI_BT0 *)(*b); + + /* Initialize the tree to an empty one!*/ + bb->root_link.node_number = 0xFFFFFFFF; + bb->root_link.depth = 0; + + /* Initialize tree parameters.*/ + bb->number_of_items = number_of_items; + bb->key_size = key_size / 4; + bb->data_size = data_size / 4; + + /* Initialize the next free node pointer.*/ + if (number_of_items != 0) + bb->next_free_node = 0; + else + bb->next_free_node = 0xFFFFFFFF; + + /* Setup the arrays.*/ + OctApiBt0CorrectPointers(bb); + + /* Initialize the Nodes to unused!*/ + for(i=0;inode[i].next_free_node = i + 1; + } + + /* Last empty node points to invalid node.*/ + bb->node[number_of_items-1].next_free_node = 0xFFFFFFFF; + + bb->invalid_value = 0xFFFFFFFF; + bb->no_smaller_key = OCTAPI_BT0_NO_SMALLER_KEY; + + return(GENERIC_OK); +} +#endif + + +#if !SKIP_OctApiBt0CorrectPointers +void OctApiBt0CorrectPointers(OCTAPI_BT0 * bb) +{ + bb->node = (OCTAPI_BT0_NODE *)(((BYTE *)bb) + sizeof(OCTAPI_BT0)); + bb->key = (UINT32 *)(((BYTE *)bb->node) + (sizeof(OCTAPI_BT0_NODE) * bb->number_of_items)); + bb->data = (UINT32 *)(((BYTE *)bb->key) + (sizeof(UINT32) * bb->number_of_items * bb->key_size)); +} +#endif + + +#if !SKIP_OctApiBt0AddNode +UINT32 OctApiBt0AddNode(void * b,void * key,void ** data) +{ + OCTAPI_BT0 * bb; + OCTAPI_BT0_NODE * new_node; + UINT32 * lkey; + UINT32 * nkey; + UINT32 i; + UINT32 new_node_number; + UINT32 result; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Check that there is at least one block left.*/ + if (bb->next_free_node == 0xFFFFFFFF) return(OCTAPI_BT0_NO_NODES_AVAILABLE); + + /* Seize the node!*/ + new_node_number = bb->next_free_node; + new_node = &(bb->node[new_node_number]); + bb->next_free_node = new_node->next_free_node; + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Find the first UINT32 of the key.*/ + nkey = &(bb->key[bb->key_size * new_node_number]); + + /* Copy the key.*/ + for(i=0;ikey_size;i++) + nkey[i] = lkey[i]; + + /* Attempt to place the node. Only a "multiple hit" will cause an error.*/ + result = OctApiBt0AddNode2(bb,&(bb->root_link), lkey, new_node_number); + if (result != GENERIC_OK) + { + /* This attempt failed. Refree the node!*/ + bb->next_free_node = new_node_number; + + /* Return the error code.*/ + return(result); + } + + /* Return the address of the data to the user.*/ + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * new_node_number])); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0AddNode2 +UINT32 OctApiBt0AddNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 new_node_number) +{ + UINT32 result; + + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. Here, we shall place the new node.*/ + { + bb->node[new_node_number].l[0].node_number = 0xFFFFFFFF; + bb->node[new_node_number].l[0].depth = 0; + bb->node[new_node_number].l[1].node_number = 0xFFFFFFFF; + bb->node[new_node_number].l[1].depth = 0; + + /* OCTAPI_BT0_LINK to parent!*/ + link->node_number = new_node_number; + link->depth = 1; /* We are a leaf, last OCTAPI_BT0_LINK depth is 1.*/ + + return(GENERIC_OK); + } + else /* Current node is used, check for a match and a direction.*/ + { + OCTAPI_BT0_NODE * this_node; + UINT32 compare; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + result = OctApiBt0AddNode2(bb,&(this_node->l[0]), lkey, new_node_number); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + result = OctApiBt0AddNode2(bb,&(this_node->l[1]), lkey, new_node_number); + if (result != GENERIC_OK) return(result); + } + else + { + return(OCTAPI_BT0_KEY_ALREADY_IN_TREE); + } + + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); + } +} +#endif + + +#if !SKIP_OctApiBt0AddNode3 +UINT32 OctApiBt0AddNode3(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 *p_new_node_number) +{ + UINT32 result; + + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. Here, we shall place the new node.*/ + { + if ( *p_new_node_number == 0xFFFFFFFF ) + return(OCTAPI_BT0_NO_NODES_AVAILABLE); + + bb->node[*p_new_node_number].l[0].node_number = 0xFFFFFFFF; + bb->node[*p_new_node_number].l[0].depth = 0; + bb->node[*p_new_node_number].l[1].node_number = 0xFFFFFFFF; + bb->node[*p_new_node_number].l[1].depth = 0; + + /* OCTAPI_BT0_LINK to parent!*/ + link->node_number = *p_new_node_number; + link->depth = 1; /* We are a leaf, last OCTAPI_BT0_LINK depth is 1.*/ + + return(GENERIC_OK); + } + else /* Current node is used, check for a match and a direction.*/ + { + OCTAPI_BT0_NODE * this_node; + UINT32 compare; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + result = OctApiBt0AddNode3(bb,&(this_node->l[0]), lkey, p_new_node_number); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + result = OctApiBt0AddNode3(bb,&(this_node->l[1]), lkey, p_new_node_number); + if (result != GENERIC_OK) return(result); + } + else + { + *p_new_node_number = link->node_number; + return(OCTAPI_BT0_KEY_ALREADY_IN_TREE); + } + + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); + } +} +#endif + +/* state +0 -> first call to the function. +1 -> recursive call.*/ +#if !SKIP_OctApiBt0AddNode4 +UINT32 OctApiBt0AddNode4(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 *p_new_node_number, UINT32 *p_prev_node_number, UINT32 state ) +{ + UINT32 result; + UINT32 *nkey; + UINT32 *okey; + + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. Here, we shall place the new node.*/ + { + bb->node[*p_new_node_number].l[0].node_number = 0xFFFFFFFF; + bb->node[*p_new_node_number].l[0].depth = 0; + bb->node[*p_new_node_number].l[1].node_number = 0xFFFFFFFF; + bb->node[*p_new_node_number].l[1].depth = 0; + + /* OCTAPI_BT0_LINK to parent!*/ + link->node_number = *p_new_node_number; + link->depth = 1; /* We are a leaf, last OCTAPI_BT0_LINK depth is 1.*/ + + if ( state == 0 ) + *p_prev_node_number = 0xFFFFFFFF; + + return(GENERIC_OK); + } + else /* Current node is used, check for a match and a direction.*/ + { + OCTAPI_BT0_NODE * this_node; + UINT32 compare; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + if ( state == 0 ) + *p_prev_node_number = OCTAPI_BT0_NO_SMALLER_KEY; + + if ( *p_prev_node_number != OCTAPI_BT0_NO_SMALLER_KEY ) + { + /* Check if the key is the smallest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key smaller then the old small one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + } + + result = OctApiBt0AddNode4(bb,&(this_node->l[0]), lkey, p_new_node_number, p_prev_node_number, 1); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + if ( state == 0 ) + *p_prev_node_number = link->node_number; + else + { + if ( *p_prev_node_number == OCTAPI_BT0_NO_SMALLER_KEY ) + *p_prev_node_number = link->node_number; + else + { + /* Check if the key is the smallest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key smaller then the old small one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + } + } + + result = OctApiBt0AddNode4(bb,&(this_node->l[1]), lkey, p_new_node_number, p_prev_node_number, 1); + if (result != GENERIC_OK) return(result); + } + else + { + *p_new_node_number = link->node_number; + return(OCTAPI_BT0_KEY_ALREADY_IN_TREE); + } + + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); + } +} +#endif + +#if !SKIP_OctApiBt0KeyCompare +UINT32 OctApiBt0KeyCompare(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey) +{ + UINT32 * nkey; + UINT32 i; + + /* Find the first UINT32 of the key.*/ + nkey = &(bb->key[bb->key_size * link->node_number]); + + for(i=0;ikey_size;i++) + { + if (lkey[i] < nkey[i]) + return(OCTAPI_BT0_LKEY_SMALLER); + else if (lkey[i] > nkey[i]) + return(OCTAPI_BT0_LKEY_LARGER); + } + + return(OCTAPI_BT0_LKEY_EQUAL); +} +#endif + + +#if !SKIP_OctApiBt0UpdateLinkDepth +void OctApiBt0UpdateLinkDepth(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link) +{ + OCTAPI_BT0_NODE * this_node; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + if (this_node->l[0].depth > this_node->l[1].depth) + link->depth = this_node->l[0].depth + 1; + else + link->depth = this_node->l[1].depth + 1; +} +#endif + +#if !SKIP_OctApiBt0Rebalance +void OctApiBt0Rebalance(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * root_link) +{ + if (bb->node[root_link->node_number].l[0].depth > (bb->node[root_link->node_number].l[1].depth + 1)) /* Heavy to the left.*/ + { + /* Check if the right child of the heavy child node is causing a problem.*/ + /* If so, do a left rotate in order to make the left most child the longer one.*/ + { + OCTAPI_BT0_LINK * heavy_link; + heavy_link = &(bb->node[root_link->node_number].l[0]); + + if (bb->node[heavy_link->node_number].l[1].depth > bb->node[heavy_link->node_number].l[0].depth) + { + OctApiBt0ExternalHeavy(bb,heavy_link); + } + } + + /* Ready to do super rotation!*/ + { + OCTAPI_BT0_LINK init_root_link; + OCTAPI_BT0_LINK init_heavy_link; + OCTAPI_BT0_LINK init_leaf_tree[3]; + + /* Save pertinent initial OCTAPI_BT0_LINK information.*/ + init_root_link = *root_link; + init_heavy_link = bb->node[root_link->node_number].l[0]; + init_leaf_tree[2] = bb->node[root_link->node_number].l[1]; + init_leaf_tree[0] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[0]; + init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[1]; + + /* Restructure the tree.*/ + *root_link = init_heavy_link; + bb->node[init_heavy_link.node_number].l[1] = init_root_link; + bb->node[init_root_link.node_number].l[0] = init_leaf_tree[1]; + + /* Reconstruct the depth of the branches.*/ + OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[1])); + OctApiBt0UpdateLinkDepth(bb,root_link); + } + } + else if (bb->node[root_link->node_number].l[1].depth > (bb->node[root_link->node_number].l[0].depth + 1)) /* Heavy to the right.*/ + { + /* Check if the right child of the heavy child node is causing a problem.*/ + /* If so, do a left rotate in order to make the left most child the longer one.*/ + { + OCTAPI_BT0_LINK * heavy_link; + heavy_link = &(bb->node[root_link->node_number].l[1]); + + if (bb->node[heavy_link->node_number].l[0].depth > bb->node[heavy_link->node_number].l[1].depth) + { + OctApiBt0ExternalHeavy(bb,heavy_link); + } + } + + /* Ready to do super rotation!*/ + { + OCTAPI_BT0_LINK init_root_link; + OCTAPI_BT0_LINK init_heavy_link; + OCTAPI_BT0_LINK init_leaf_tree[3]; + + /* Save pertinent initial OCTAPI_BT0_LINK information.*/ + init_root_link = *root_link; + init_heavy_link = bb->node[root_link->node_number].l[1]; + init_leaf_tree[2] = bb->node[root_link->node_number].l[0]; + init_leaf_tree[0] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[1]; + init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[0]; + + /* Restructure the tree.*/ + *root_link = init_heavy_link; + bb->node[init_heavy_link.node_number].l[0] = init_root_link; + bb->node[init_root_link.node_number].l[1] = init_leaf_tree[1]; + + /* Reconstruct the depth of the branches.*/ + OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[0])); + OctApiBt0UpdateLinkDepth(bb,root_link); + } + } +} +#endif + +/* This function does a rotation towards the outside of the tree*/ +/* in order to keep the heavy branches towards the outside.*/ +#if !SKIP_OctApiBt0ExternalHeavy +void OctApiBt0ExternalHeavy(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * root_link) +{ + if (bb->node[root_link->node_number].l[1].depth > bb->node[root_link->node_number].l[0].depth) /* Exterior of tree is towards the left.*/ + { + OCTAPI_BT0_LINK init_root_link; + OCTAPI_BT0_LINK init_heavy_link; + OCTAPI_BT0_LINK init_leaf_tree[3]; + + /* Save pertinent initial OCTAPI_BT0_LINK information.*/ + init_root_link = *root_link; + init_leaf_tree[0] = bb->node[root_link->node_number].l[0]; + init_heavy_link = bb->node[root_link->node_number].l[1]; + init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[0]; + init_leaf_tree[2] = bb->node[bb->node[root_link->node_number].l[1].node_number].l[1]; + + /* Restructure the tree.*/ + *root_link = init_heavy_link; + bb->node[init_heavy_link.node_number].l[0] = init_root_link; + bb->node[init_root_link.node_number].l[1] = init_leaf_tree[1]; + + /* Reconstruct the depth of the branches.*/ + OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[0])); + OctApiBt0UpdateLinkDepth(bb,root_link); + } + else if (bb->node[root_link->node_number].l[0].depth > bb->node[root_link->node_number].l[1].depth) /* Exterior of tree is towards the right.*/ + { + OCTAPI_BT0_LINK init_root_link; + OCTAPI_BT0_LINK init_heavy_link; + OCTAPI_BT0_LINK init_leaf_tree[3]; + + /* Save pertinent initial OCTAPI_BT0_LINK information.*/ + init_root_link = *root_link; + init_leaf_tree[0] = bb->node[root_link->node_number].l[1]; + init_heavy_link = bb->node[root_link->node_number].l[0]; + init_leaf_tree[1] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[1]; + init_leaf_tree[2] = bb->node[bb->node[root_link->node_number].l[0].node_number].l[0]; + + /* Restructure the tree.*/ + *root_link = init_heavy_link; + bb->node[init_heavy_link.node_number].l[1] = init_root_link; + bb->node[init_root_link.node_number].l[0] = init_leaf_tree[1]; + + /* Reconstruct the depth of the branches.*/ + OctApiBt0UpdateLinkDepth(bb,&(bb->node[root_link->node_number].l[1])); + OctApiBt0UpdateLinkDepth(bb,root_link); + } +} +#endif + + +/* State:*/ +/* 0 = seeking node to be removed.*/ +/* 1 = node found, left branch taken.*/ +/* 2 = node found, right branch taken.*/ +#if !SKIP_OctApiBt0RemoveNode2 +UINT32 OctApiBt0RemoveNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link) +{ + UINT32 result; + OCTAPI_BT0_NODE * this_node; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + if (state == 0) + { + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. The node we were looking for does not exist.*/ + { + return(OCTAPI_BT0_KEY_NOT_IN_TREE); + } + else /* Current node is used, check for a match and a direction.*/ + { + UINT32 compare; + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, 0, NULL); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, 0, NULL); + if (result != GENERIC_OK) return(result); + } + else + { + link_to_removed_node = link; + + /* Keep on going down to find a replacement node.*/ + if (bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) + { + /* Doe! No tree left! WHAT TO DO? */ + /* Just delete the current node. That's it.*/ + + /* Release the current node (restore free node link-list)*/ + bb->node[link->node_number].next_free_node = bb->next_free_node; + bb->next_free_node = link->node_number; + + link->node_number = 0xFFFFFFFF; + link->depth = 0; + + return(GENERIC_OK); + } + else if (bb->node[link->node_number].l[0].node_number != 0xFFFFFFFF) /* Left node is present. Go left, then permanently right.*/ + { + OCTAPI_BT0_NODE * removed_node_pnt; + removed_node_pnt = &(bb->node[link->node_number]); + + result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[0]), lkey, link_to_removed_node, 1, link); + if (result != GENERIC_OK) return(result); + + /* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/ + /* but is about to be discarded! Save it quickly!*/ + /* bb->node[link->node_number].l[0] = removed_node_pnt->l[0];*/ + } + else /* Right node is present. Go right, then permanently left.*/ + { + OCTAPI_BT0_NODE * removed_node_pnt; + removed_node_pnt = &(bb->node[link->node_number]); + + result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[1]), lkey, link_to_removed_node, 2, link); + if (result != GENERIC_OK) return(result); + + /* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/ + /* but is about to be discarded! Save it quickly!*/ + /* bb->node[link->node_number].l[1] = removed_node_pnt->l[1];*/ + } + } + } + } + else + { + /* Left side, Right-most node found! OR*/ + /* Right side, Left-most node found!*/ + if ((state == 1 && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) || + (state == 2 && bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF)) + { + OCTAPI_BT0_LINK init_chosen_link; + + /* Release the current node (restore free node link-list)*/ + bb->node[link_to_removed_node->node_number].next_free_node = bb->next_free_node; + bb->next_free_node = link_to_removed_node->node_number; + + /* Save the link to the chosen node, because it is about to be deleted.*/ + init_chosen_link = *link; + + /* Remove this node, and allow the tree to go on:*/ + { + OCTAPI_BT0_LINK init_child_link[2]; + + init_child_link[0] = bb->node[link->node_number].l[0]; + init_child_link[1] = bb->node[link->node_number].l[1]; + + if (state == 1) + *link = init_child_link[0]; + else + *link = init_child_link[1]; + } + + /* Replace the removed node by this node.*/ + { + OCTAPI_BT0_LINK init_removed_child_link[2]; + + init_removed_child_link[0] = bb->node[link_to_removed_node->node_number].l[0]; + init_removed_child_link[1] = bb->node[link_to_removed_node->node_number].l[1]; + + *link_to_removed_node = init_chosen_link; + bb->node[init_chosen_link.node_number].l[0] = init_removed_child_link[0]; + bb->node[init_chosen_link.node_number].l[1] = init_removed_child_link[1]; + } + + return(GENERIC_OK); + } + else + { + /* Keep on going, we have not found the center most node yet!*/ + if (state == 1) + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, state, NULL); + if (result != GENERIC_OK) return(result); + + /* Refresh the link if our link is volatile.*/ + if (volatile_grandparent_link != NULL) + { + link = &(bb->node[volatile_grandparent_link->node_number].l[0]); + } + } + else + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, state, NULL); + if (result != GENERIC_OK) return(result); + + /* Refresh the link if our link is volatile.*/ + if (volatile_grandparent_link != NULL) + { + link = &(bb->node[volatile_grandparent_link->node_number].l[1]); + } + } + } + } + + /* We may have messed up the tree. So patch it!*/ + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); +} +#endif + + +/* State:*/ +/* 0 = seeking node to be removed.*/ +/* 1 = node found, left branch taken.*/ +/* 2 = node found, right branch taken.*/ +#if !SKIP_OctApiBt0RemoveNode3 +UINT32 OctApiBt0RemoveNode3(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link, UINT32 *p_prev_node_number ) +{ + UINT32 result; + UINT32 *nkey; + UINT32 *okey; + OCTAPI_BT0_NODE * this_node; + + /* Get a pointer to this node.*/ + this_node = &(bb->node[link->node_number]); + + if (state == 0) + { + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. The node we were looking for does not exist.*/ + { + return(OCTAPI_BT0_KEY_NOT_IN_TREE); + } + else /* Current node is used, check for a match and a direction.*/ + { + UINT32 compare; + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + /* Check if the key is the biggest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key bigger then the old one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, 0, NULL); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + /* Check if the key is the biggest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key bigger then the old one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, 0, NULL); + if (result != GENERIC_OK) return(result); + } + else + { + link_to_removed_node = link; + + /* Keep on going down to find a replacement node.*/ + if (bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) + { + /* Doe! No tree left! WHAT TO DO? */ + /* Just delete the current node. That's it.*/ + + /* Release the current node (restore free node link-list)*/ + bb->node[link->node_number].next_free_node = bb->next_free_node; + bb->next_free_node = link->node_number; + + link->node_number = 0xFFFFFFFF; + link->depth = 0; + + return(GENERIC_OK); + } + else if (bb->node[link->node_number].l[0].node_number != 0xFFFFFFFF) /* Left node is present. Go left, then permanently right.*/ + { + OCTAPI_BT0_NODE * removed_node_pnt; + removed_node_pnt = &(bb->node[link->node_number]); + + result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[0]), lkey, link_to_removed_node, 1, link); + if (result != GENERIC_OK) return(result); + + /* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/ + /* but is about to be discarded! Save it quickly!*/ + /* bb->node[link->node_number].l[0] = removed_node_pnt->l[0];*/ + } + else /* Right node is present. Go right, then permanently left.*/ + { + OCTAPI_BT0_NODE * removed_node_pnt; + removed_node_pnt = &(bb->node[link->node_number]); + + result = OctApiBt0RemoveNode2(bb,&(removed_node_pnt->l[1]), lkey, link_to_removed_node, 2, link); + if (result != GENERIC_OK) return(result); + + /* Caution! Once we are here, the link->node_pnt->l[0] has been modified,*/ + /* but is about to be discarded! Save it quickly!*/ + /* bb->node[link->node_number].l[1] = removed_node_pnt->l[1];*/ + } + } + } + } + else + { + /* Check if the key is the biggest one encountered yet.*/ + okey = &(bb->key[bb->key_size * (*p_prev_node_number)]); + nkey = &(bb->key[bb->key_size * link->node_number]); + /* If the node is key bigger then the old one, change the value.*/ + if ( *nkey > *okey ) + { + if ( *nkey < *lkey ) + *p_prev_node_number = link->node_number; + } + + /* Left side, Right-most node found! OR*/ + /* Right side, Left-most node found!*/ + if ((state == 1 && bb->node[link->node_number].l[1].node_number == 0xFFFFFFFF) || + (state == 2 && bb->node[link->node_number].l[0].node_number == 0xFFFFFFFF)) + { + OCTAPI_BT0_LINK init_chosen_link; + + /* Release the current node (restore free node link-list)*/ + bb->node[link_to_removed_node->node_number].next_free_node = bb->next_free_node; + bb->next_free_node = link_to_removed_node->node_number; + + /* Save the link to the chosen node, because it is about to be deleted.*/ + init_chosen_link = *link; + + /* Remove this node, and allow the tree to go on:*/ + { + OCTAPI_BT0_LINK init_child_link[2]; + + init_child_link[0] = bb->node[link->node_number].l[0]; + init_child_link[1] = bb->node[link->node_number].l[1]; + + if (state == 1) + *link = init_child_link[0]; + else + *link = init_child_link[1]; + } + + /* Replace the removed node by this node.*/ + { + OCTAPI_BT0_LINK init_removed_child_link[2]; + + init_removed_child_link[0] = bb->node[link_to_removed_node->node_number].l[0]; + init_removed_child_link[1] = bb->node[link_to_removed_node->node_number].l[1]; + + *link_to_removed_node = init_chosen_link; + bb->node[init_chosen_link.node_number].l[0] = init_removed_child_link[0]; + bb->node[init_chosen_link.node_number].l[1] = init_removed_child_link[1]; + } + + return(GENERIC_OK); + } + else + { + /* Keep on going, we have not found the center most node yet!*/ + if (state == 1) + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[1]), lkey, link_to_removed_node, state, NULL); + if (result != GENERIC_OK) return(result); + + /* Refresh the link if our link is volatile.*/ + if (volatile_grandparent_link != NULL) + { + link = &(bb->node[volatile_grandparent_link->node_number].l[0]); + } + } + else + { + result = OctApiBt0RemoveNode2(bb,&(bb->node[link->node_number].l[0]), lkey, link_to_removed_node, state, NULL); + if (result != GENERIC_OK) return(result); + + /* Refresh the link if our link is volatile.*/ + if (volatile_grandparent_link != NULL) + { + link = &(bb->node[volatile_grandparent_link->node_number].l[1]); + } + } + } + } + + /* We may have messed up the tree. So patch it!*/ + /* Check if this node is unbalanced by 2. If so, rebalance it:*/ + if (this_node->l[0].depth > (this_node->l[1].depth + 1) || + this_node->l[1].depth > (this_node->l[0].depth + 1)) + { + OctApiBt0Rebalance(bb,link); + } + + /* Always update the OCTAPI_BT0_LINK depth before exiting.*/ + OctApiBt0UpdateLinkDepth(bb,link); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0RemoveNode +UINT32 OctApiBt0RemoveNode(void * b,void * key) +{ + OCTAPI_BT0 * bb; + UINT32 result; + UINT32 * lkey; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Attempt to remove the node. Only a "no hit" will cause an error.*/ + result = OctApiBt0RemoveNode2(bb,&(bb->root_link), lkey, NULL, 0, NULL); + if (result != GENERIC_OK) return(result); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0QueryNode2 +UINT32 OctApiBt0QueryNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 * node_number) +{ + UINT32 result; + + if (link->node_number == 0xFFFFFFFF) /* We have an empty node. The node we were looking for does not exist.*/ + { + return(OCTAPI_BT0_KEY_NOT_IN_TREE); + } + else /* Current node is used, check for a match and a direction.*/ + { + UINT32 compare; + + /* Compare this node to the lkey.*/ + compare = OctApiBt0KeyCompare(bb,link,lkey); + + if (compare == OCTAPI_BT0_LKEY_SMALLER) /* Go left.*/ + { + result = OctApiBt0QueryNode2(bb,&(bb->node[link->node_number].l[0]), lkey, node_number); + if (result != GENERIC_OK) return(result); + } + else if (compare == OCTAPI_BT0_LKEY_LARGER) /* Go right.*/ + { + result = OctApiBt0QueryNode2(bb,&(bb->node[link->node_number].l[1]), lkey, node_number); + if (result != GENERIC_OK) return(result); + } + else + { + /* A match!*/ + *node_number = link->node_number; + } + } + + return(GENERIC_OK); +} +#endif + + +#if !SKIP_OctApiBt0QueryNode +UINT32 OctApiBt0QueryNode(void * b,void * key,void ** data) +{ + OCTAPI_BT0 * bb; + UINT32 node_number; + UINT32 result; + UINT32 * lkey; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Get the node number.*/ + result = OctApiBt0QueryNode2(bb,&(bb->root_link),lkey,&node_number); + if (result != GENERIC_OK) return(result); + + /* Return the address of the data to the user.*/ + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * node_number])); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0GetFirstNode +UINT32 OctApiBt0GetFirstNode(void * b,void ** key, void ** data) +{ + OCTAPI_BT0 * bb; + OCTAPI_BT0_NODE * node; + UINT32 node_number; + UINT32 * lkey; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Check if there are any keys present in the tree. */ + if (bb->root_link.node_number == 0xFFFFFFFF) return OCTAPI_BT0_NO_NODES_AVAILABLE; + + node_number = bb->root_link.node_number; + node = &bb->node[node_number]; + + /* Make our way down to the left-most node. */ + while (node->l[0].node_number != 0xFFFFFFFF) + { + node_number = node->l[0].node_number; + node = &bb->node[node_number]; + } + + /* Return the address of the data to the user.*/ + if ( bb->key_size > 0 ) + *key = (void *)(&(bb->key[bb->key_size * node_number])); + + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * node_number])); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiBt0FindOrAddNode +UINT32 OctApiBt0FindOrAddNode(void * b,void * key,void ** data, UINT32 *fnct_result) +{ + OCTAPI_BT0 * bb; + OCTAPI_BT0_NODE * new_node; + UINT32 * lkey; + UINT32 * nkey; + UINT32 i; + UINT32 new_node_number; + UINT32 temp_node_number = 0; + UINT32 result; + UINT32 tree_already_full = FALSE; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Seize the node!*/ + new_node_number = bb->next_free_node; + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Check that there is at least one block left.*/ + if (bb->next_free_node != 0xFFFFFFFF) + { + + temp_node_number = new_node_number; + new_node = &(bb->node[new_node_number]); + bb->next_free_node = new_node->next_free_node; + + /* Find the first UINT32 of the key.*/ + nkey = &(bb->key[bb->key_size * new_node_number]); + + /* Copy the key.*/ + for(i=0;ikey_size;i++) + nkey[i] = lkey[i]; + } + else + tree_already_full = TRUE; /* Signal that the tree was already full when the function was called.*/ + + /* Attempt to place the node. Only a "multiple hit" will cause an error.*/ + result = OctApiBt0AddNode3(bb,&(bb->root_link), lkey, &new_node_number); + switch( result ) + { + case GENERIC_OK: + *fnct_result = OCTAPI0_BT0_NODE_ADDDED; + break; + case OCTAPI_BT0_KEY_ALREADY_IN_TREE: + *fnct_result = OCTAPI0_BT0_NODE_FOUND; + /* This attempt did not add a new node. Refree the node!*/ + if ( tree_already_full == FALSE ) + bb->next_free_node = temp_node_number; + result = GENERIC_OK; + break; + default: + break; + } + + if (result != GENERIC_OK) + { + /* This attempt failed. Refree the node!*/ + if ( tree_already_full == FALSE ) + bb->next_free_node = new_node_number; + + /* Return the error code.*/ + return(result); + } + + /* Return the address of the data to the user.*/ + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * new_node_number])); + + return(GENERIC_OK); +} +#endif + + +#if !SKIP_OctApiBt0AddNodeReportPrevNodeData +UINT32 OctApiBt0AddNodeReportPrevNodeData(void * b,void * key,void ** data, void ** prev_data, PUINT32 fnct_result ) +{ + OCTAPI_BT0 * bb; + OCTAPI_BT0_NODE * new_node; + UINT32 * lkey; + UINT32 * nkey; + UINT32 i; + UINT32 new_node_number; + UINT32 temp_node_number; + UINT32 prev_node_number; + UINT32 result; + + /* Load all!*/ + bb = (OCTAPI_BT0 *)(b); + OctApiBt0CorrectPointers(bb); + + /* Check that there is at least one block left.*/ + if (bb->next_free_node == 0xFFFFFFFF) return(OCTAPI_BT0_NO_NODES_AVAILABLE); + + /* Seize the node!*/ + new_node_number = bb->next_free_node; + temp_node_number = new_node_number; + new_node = &(bb->node[new_node_number]); + bb->next_free_node = new_node->next_free_node; + + /* Set the previous node value */ + prev_node_number = 0xFFFFFFFF; + + /* Register in the key and the data.*/ + lkey = ((UINT32 *)key); + + /* Find the first UINT32 of the key.*/ + nkey = &(bb->key[bb->key_size * new_node_number]); + + /* Copy the key.*/ + for(i=0;ikey_size;i++) + nkey[i] = lkey[i]; + + /* Attempt to place the node. Only a "multiple hit" will cause an error.*/ + result = OctApiBt0AddNode4(bb,&(bb->root_link), lkey, &new_node_number, &prev_node_number, 0); + switch( result ) + { + case GENERIC_OK: + *fnct_result = OCTAPI0_BT0_NODE_ADDDED; + break; + case OCTAPI_BT0_KEY_ALREADY_IN_TREE: + *fnct_result = OCTAPI0_BT0_NODE_FOUND; + /* This attempt did not add a new node. Refree the node!*/ + bb->next_free_node = temp_node_number; + result = GENERIC_OK; + break; + default: + break; + } + + if (result != GENERIC_OK) + { + /* This attempt failed. Refree the node!*/ + bb->next_free_node = new_node_number; + + /* Return the error code.*/ + return(result); + } + + /* Return the address of the data to the user.*/ + if ( bb->data_size > 0 ) + *data = (void *)(&(bb->data[bb->data_size * new_node_number])); + + if ( bb->data_size > 0 ) + { + if ( (prev_node_number != 0xFFFFFFFF) && + (prev_node_number != OCTAPI_BT0_NO_SMALLER_KEY) && + (*fnct_result == OCTAPI0_BT0_NODE_ADDDED)) + *prev_data = ( void* )(&(bb->data[bb->data_size * prev_node_number])); + else if ( prev_node_number == 0xFFFFFFFF ) + *prev_data = ( void* )(&bb->invalid_value); + else if ( prev_node_number == OCTAPI_BT0_NO_SMALLER_KEY ) + *prev_data = ( void* )(&bb->no_smaller_key); + } + + return(GENERIC_OK); +} +#endif + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/bt/octapi_bt0_private.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/bt/octapi_bt0_private.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/bt/octapi_bt0_private.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/bt/octapi_bt0_private.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,93 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_bt0_private.h + +Copyright (c) 2001 Octasic Inc. All rights reserved. + +Description: + + Library used to manage a binary tree of variable max size. Library is + made to use one block of contiguous memory to manage the tree. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_BT0_PRIVATE_H__ +#define __OCTAPI_BT0_PRIVATE_H__ + + + +#include "octdef.h" + +#define OCTAPI_BT0_LKEY_LARGER 0x0 +#define OCTAPI_BT0_LKEY_SMALLER 0x1 +#define OCTAPI_BT0_LKEY_EQUAL 0x2 + +typedef struct __OCTAPI_BT0_LINK__ +{ + UINT32 node_number; + UINT32 depth; +} OCTAPI_BT0_LINK; + +typedef struct __OCTAPI_BT0_NODE__ +{ + UINT32 next_free_node; /* Number of the next node in the free node link-list.*/ + OCTAPI_BT0_LINK l[2]; /* 0 = left link; 1 = right link.*/ +} OCTAPI_BT0_NODE; + + +typedef struct __OCTAPI_BT0__ +{ + UINT32 number_of_items; /* Number of items on total that can be allocated in the tree.*/ + UINT32 key_size; /* Size is in UINT32s*/ + UINT32 data_size; /* Size is in UINT32s*/ + + /* Empty node linked-list:*/ + UINT32 next_free_node; /* 0xFFFFFFFF means that no nodes are free.*/ + + /* Tree as such:*/ + OCTAPI_BT0_NODE * node; /* Array of nodes (number_of_items in size).*/ + + /* Tree root:*/ + OCTAPI_BT0_LINK root_link; + + /* Associated key structure*/ + UINT32 * key; /* Array of keys associated to NODEs.*/ + + /* Associated data structure.*/ + UINT32 * data; /* Array of data associated to NODEs.*/ + + UINT32 invalid_value; + UINT32 no_smaller_key; + +} OCTAPI_BT0; + +void OctApiBt0CorrectPointers( OCTAPI_BT0 * bb ); +UINT32 OctApiBt0AddNode2( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey, UINT32 new_node_number ); +UINT32 OctApiBt0AddNode3( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey, UINT32 *p_new_node_number ); +UINT32 OctApiBt0AddNode4(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 *p_new_node_number, UINT32 *p_prev_node_number, UINT32 state ); +UINT32 OctApiBt0KeyCompare( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey ); +void OctApiBt0UpdateLinkDepth( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link ); +void OctApiBt0Rebalance( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * root_link ); +void OctApiBt0ExternalHeavy( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * root_link ); +UINT32 OctApiBt0RemoveNode2( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link ); + + + +#endif /*__OCTAPI_BT0_PRIVATE_H__*/ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/largmath/octapi_largmath.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/largmath/octapi_largmath.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/largmath/octapi_largmath.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/largmath/octapi_largmath.c 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,628 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_largmath.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to perform arithmetic on integer values of an integer multiple + of 32-bits. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#include "apilib/octapi_largmath.h" + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmAdd. +| +| Description: This function adds 2 numbers, a and b. Number a is +| (alen + 1) * 32 bits long; b is (blen + 1) * 32 bits long. The +| result is (zlen + 1) * 32 bits long. It the function succeeds it returns +| GENERIC_OK, else GENERIC_ERROR. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| alen USHORT The length of array a, minus 1 (0 - 99). +| *b UINT32 The array containing the second number. +| blen USHORT The length of array b, minus 1 (0 - 99). +| *z UINT32 The array containing the resulting number. +| zlen USHORT The length of array z, minus 1 (0 - 99). +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmAdd +UINT32 OctApiLmAdd(UINT32 * a,USHORT alen,UINT32 * b,USHORT blen,UINT32 * z, USHORT zlen) +{ + USHORT i; + UINT32 temp; + UINT32 carry=0; + UINT32 aprim; + UINT32 bprim; + + /* Check for array lengths.*/ + if (alen > zlen || blen > zlen) return(OCTAPI_LM_ARRAY_SIZE_MISMATCH); + + for(i=0;i<=zlen;i++) + { + if (i <= alen) aprim = *(a+i); else aprim = 0; + if (i <= blen) bprim = *(b+i); else bprim = 0; + temp = aprim + bprim + carry; + + /* Calculate carry for next time.*/ + if (carry == 0) + if (temp < aprim) carry = 1; else carry = 0; + else + if (temp <= aprim) carry = 1; else carry = 0; + + /* Write new value.*/ + *(z+i) = temp; + } + + /* Check for overflow.*/ + if (carry == 1) return(OCTAPI_LM_OVERFLOW); + + /* All is well.*/ + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmSubtract. +| +| Description: This function subtracts 2 numbers, a and b. Number a is +| (alen + 1) * 32 bits long; b is (blen + 1) * 32 bits long. The result +| is (zlen + 1) * 32 bits long. It the function succeeds it returns +| GENERIC_OK, else GENERIC_ERROR. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| alen USHORT The length of array a, minus 1 (0 - 99). +| *bneg UINT32 The array containing the second number. +| blen USHORT The length of array b, minus 1 (0 - 99). +| *z UINT32 The array containing the resulting number. +| zlen USHORT The length of array z, minus 1 (0 - 99). +| *neg USHORT Indicates if the result is negative +| (TRUE/FALSE). +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmSubtract +UINT32 OctApiLmSubtract(UINT32 * a,USHORT alen,UINT32 * bneg,USHORT blen,UINT32 * z,USHORT zlen,USHORT * neg) +{ + USHORT i; + UINT32 temp; + UINT32 carry=1; + UINT32 aprim; + UINT32 bprim; + + /* Check for array lengths.*/ + if (alen > zlen || blen > zlen) return(OCTAPI_LM_ARRAY_SIZE_MISMATCH); + + for(i=0;i<=zlen;i++) + { + if (i <= alen) aprim = *(a+i); else aprim = 0; + if (i <= blen) bprim = ~(*(bneg+i)); else bprim = 0xFFFFFFFF; + temp = aprim + bprim + carry; + + /* Calculate carry for next time.*/ + if (carry == 0) + if (temp < aprim) carry = 1; else carry = 0; + else + if (temp <= aprim) carry = 1; else carry = 0; + + /* Write new value.*/ + *(z+i) = temp; + } + + /* Check for overflow, which means negative number!*/ + if (carry == 0) + { + /* Number is not of right neg. Invert and add one to correct neg.*/ + for(i=0;i<=zlen;i++) + *(z+i) = ~(*(z+i)); + + temp = 1; + OctApiLmAdd(&temp,0,z,zlen,z,zlen); + + *neg = TRUE; + return(GENERIC_OK); + } + + /* Result is positive.*/ + *neg = FALSE; + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmCompare. +| +| Description: This function compares two numbers (arrays) of equal lengths. +| Number a is (alen + 1) * 32 bits long; b is (blen + 1) * 32 bits long. The result +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| alen USHORT The length of array a, minus 1 (0 - 99). +| *b UINT32 The array containing the second number. +| blen USHORT The length of array b, minus 1 (0 - 99). +| *neg USHORT Result of compare. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmCompare +UINT32 OctApiLmCompare(UINT32 * a,USHORT alen,UINT32 * bneg,USHORT blen,USHORT * neg) +{ + USHORT i; + UINT32 temp; + UINT32 carry=1; + UINT32 aprim; + UINT32 bprim; + UINT32 zlen; + + /* Set zlen to alen or blen (which ever is longer)*/ + if (alen < blen) + zlen = blen; + else + zlen = alen; + + for(i=0;i<=zlen;i++) + { + if (i <= alen) aprim = *(a+i); else aprim = 0; + if (i <= blen) bprim = ~(*(bneg+i)); else bprim = 0xFFFFFFFF; + temp = aprim + bprim + carry; + + /* Calculate carry for next time.*/ + if (carry == 0) + if (temp < aprim) carry = 1; else carry = 0; + else + if (temp <= aprim) carry = 1; else carry = 0; + } + + /* Check for overflow, which means negative number!*/ + if (carry == 0) + { + *neg = TRUE; + return(GENERIC_OK); + } + + /* Result is positive.*/ + *neg = FALSE; + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmSubtract. +| +| Description: This function multiplies 2 numbers, a and b. Number a and +| b are both (ablen + 1) * 32 bits long. The result is twice as +| long. If the functions succeeds if returns GENERIC_OK, +| else GENERIC_ERROR. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| *b UINT32 The array containing the second number. +| ablen USHORT The length of arrays a and b, minus 1 (0 - 99). +| *z UINT32 The array containing the resulting number. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmMultiply +UINT32 OctApiLmMultiply(UINT32 * a,UINT32 * b,USHORT ablen,UINT32 * z) +{ + USHORT i,j,k; + USHORT nos; + UINT32 lownum; + UINT32 highnum; + USHORT longnumi; + USHORT longnumj; + USHORT indentw,indentl; + + + /* Caculate number of shorts in a and b.*/ + nos = (USHORT)((ablen+1) * 2); + + /* Clear answer word.*/ + for(i=0;i OCTAPI_LM_MAX_OPTIMIZE_MUL) + optimizea = FALSE; + if(*b > OCTAPI_LM_MAX_OPTIMIZE_MUL) + optimizeb = FALSE; + + if(optimizea == TRUE) + { + for(l = 0; l < *a; l++) + OctApiLmAdd(z, (USHORT)(nos-1), b, ablen, z, (USHORT)(nos-1)); + return(GENERIC_OK); + } + + if(optimizeb == TRUE) + { + for(l = 0; l < *b; l++) + OctApiLmAdd(z, (USHORT)(nos-1), a, ablen, z, (USHORT)(nos-1)); + return(GENERIC_OK); + } + } + + for(i=0;i>16; /* Odd word. Upper part of long.*/ + + for(j=0;j>16; /* Odd word. Upper part of long.*/ + + /* Find the word indent of the answer. 0 = no indent. 1 = one word indent.*/ + indentw = (USHORT)( j+i ); + indentl = (USHORT)( indentw / 2 ); + + /* Multiply both numbers.*/ + product = highnum * lownum; + + /* After multiplying both numbers, add result to end result.*/ + if ((indentw % 2) == 0) /* Even word boundary, addition in one shot!*/ + { + UINT32 carry=0; + UINT32 temp; + UINT32 addme; + + for(k=indentl;k>16; + else addme = 0; + + temp = *(z+k) + addme + carry; + + /* Calculate carry for next time.*/ + if (carry == 0) + if (temp < addme) carry = 1; else carry = 0; + else + if (temp <= addme) carry = 1; else carry = 0; + + /* Set value.*/ + *(z+k) = temp; + } + + /* Carry should always be 0.*/ + if (carry == 1) return(GENERIC_ERROR); + } + } + } + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmDivide. +| +| Description: This function divides the number n by the number d. The +| quotient is placed in q and the remainder in r. The arrays +| n, d, q and r are all of the same length, namely (ndqrlen + 1). +| If the functions succeeds if returns GENERIC_OK, else +| GENERIC_ERROR. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *a UINT32 The array containing the first number. +| *b UINT32 The array containing the second number. +| ablen USHORT The length of arrays a and b, minus 1 (0 - 99). +| *z UINT32 The array containing the resulting number. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmDivide +UINT32 OctApiLmDivide(UINT32 * n,UINT32 * d,UINT32 * q,UINT32 * r,USHORT ndqrlen) +{ + /* Proceedure for division:*/ + /* r = n*/ + /* q = 0*/ + /* shift = initial_denominator_shift (for upper '1's to be in same bit position).*/ + /* d <<= shift;*/ + /* Start loop:*/ + /* compare r and d*/ + /* if r > d then*/ + /* r -= d;*/ + /* write a '1' to bit "shift" of array q.*/ + /* end if;*/ + /* if shift == 0 then*/ + /* return;*/ + /* else*/ + /* shift--;*/ + /* d>>=1;*/ + /* goto "Start loop:"*/ + /* end if;*/ + + UINT32 i; + UINT32 result; + USHORT shift,n_msb,d_msb; + USHORT neg; + USHORT ConditionFlag = TRUE; + + /* r = n*/ + for(i=0;i<=ndqrlen;i++) + *(r+i) = *(n+i); + + /* q = 0*/ + for(i=0;i<=ndqrlen;i++) + *(q+i) = 0; + + /* shift = initial_denominator_shift (for upper '1's to be in same bit position).*/ + result = OctApiLmGetMsb(d,ndqrlen,&d_msb); + if (result != GENERIC_OK) return(result); + + result = OctApiLmGetMsb(n,ndqrlen,&n_msb); + if (result != GENERIC_OK) return(result); + + if (d_msb == 0xFFFF) /* Division by 0.*/ + return(OCTAPI_LM_DIVISION_BY_ZERO); + + if (n_msb == 0xFFFF) /* 0/n, returns 0 R 0.*/ + return(GENERIC_OK); + + if (n_msb < d_msb) /* x/y, where x is smaller than y, returns 0 R x.*/ + return(GENERIC_OK); + + shift = (USHORT)( n_msb - d_msb ); + + /* Shift d to match n highest bit position.*/ + result = OctApiLmShiftn(d,ndqrlen,TRUE,shift); + if (result != GENERIC_OK) return(result); + + /* Start loop:*/ + while( ConditionFlag == TRUE ) + { + /* compare r and d*/ + result = OctApiLmCompare(r,ndqrlen,d,ndqrlen,&neg); + if (result != GENERIC_OK) return(result); + + if (neg == FALSE) /* Subtraction can be done(do it).*/ + { + /* r -= d;*/ + result = OctApiLmSubtract(r,ndqrlen,d,ndqrlen,r,ndqrlen,&neg); + if (result != GENERIC_OK) return(result); + + /* write a '1' to bit "shift" of array q.*/ + *(q+(shift/32)) |= (UINT32)0x1 << (shift%32); + } + + /* if shift == 0 then*/ + /* return;*/ + if (shift == 0) return(GENERIC_OK); + + /* shift--;*/ + /* d>>=1;*/ + /* goto "Start loop:"*/ + shift--; + OctApiLmShiftRight1(d,ndqrlen); + } + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: octapi_lm_shifright1. +| +| Description: The function is for internal use only. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| N/A. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmShiftRight1 +UINT32 OctApiLmShiftRight1(UINT32 * a,USHORT alen) +{ + UINT32 i; + + /* Start with lower long and move up by one long each time,*/ + /* shifting each long to the right by one bit. The upper bit*/ + /* of the next long will have to be concatenated each time a*/ + /* loop is executed. For the last long, leave the highest bit*/ + /* intact.*/ + for(i=0;i>=1; /* Shift long by one to the right.*/ + *(a+i)|=*(a+i+1)<<31; + } + *(a+alen)>>=1; /* Shift last long, leaving it's highest bit at 0.*/ + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmShiftn. +| +| Description: The function is for internal use only. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| N/A. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmShiftn +UINT32 OctApiLmShiftn(UINT32 * a,USHORT alen,USHORT shiftleft,USHORT shiftn) +{ + UINT32 i; + USHORT long_offset; + USHORT bit_offset; + + long_offset = (USHORT)( shiftn / 32 ); + bit_offset = (USHORT)( shiftn % 32 ); + + if (shiftleft == TRUE) /* Shift left.*/ + { + for(i=alen;i<=alen;i--) + { + /* Fill upper bits of long.*/ + if (i >= long_offset) + *(a+i) = *(a+i-long_offset) << bit_offset; + else + *(a+i) = 0; + + /* Fill lower bits of long.*/ + if (i > long_offset && bit_offset != 0) + *(a+i) |= *(a+i-long_offset-1) >> (32-bit_offset); + } + } + else /* Shift right.*/ + { + for(i=0;i<=alen;i++) + { + /* Fill lower bits of long.*/ + if ((alen-i) >= long_offset) + *(a+i) = *(a+i+long_offset) >> bit_offset; + else + *(a+i) = 0; + + /* Fill upper bits of long.*/ + if ((alen-i) > long_offset && bit_offset != 0) + *(a+i) |= *(a+i+long_offset+1) << (32-bit_offset); + + } + } + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLmGetMsb. +| +| Description: The function is for internal use only. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| N/A. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLmGetMsb +UINT32 OctApiLmGetMsb(UINT32 * a,USHORT alen,USHORT * msb_pos) +{ + UINT32 i,j; + UINT32 x; + + for(i=alen;i<=alen;i--) + { + if (*(a+i) == 0) continue; + + x = *(a+i); + for(j=31;j<=31;j--) + { + /* Test for bit being '1'.*/ + if ((x & 0x80000000) != 0) + { + *msb_pos=(USHORT)(j+(32*i)); + return(GENERIC_OK); + } + + /* Shift bit one bit position, and try again.*/ + x<<=1; + } + } + + /* MSB not found.*/ + *msb_pos = 0xFFFF; + + return(GENERIC_OK); +} +#endif diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/llman/octapi_llman.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/llman/octapi_llman.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/llman/octapi_llman.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/llman/octapi_llman.c 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,2787 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_llman.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to manage allocation tables and linked lists. The library is + made such that only a block of contiguous memory is needed for the + management of the linked list/allocation table. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 22 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#include "octapi_llman_private.h" +#include "apilib/octapi_llman.h" +#include "apilib/octapi_largmath.h" + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocGetSize. +| +| Description: This function determines the amount of memory needed to +| manage the allocation of a fixed amount of resources. +| The memory is measured in bytes. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocGetSize +UINT32 OctapiLlmAllocGetSize(UINT32 number_of_items,UINT32 * l_size) +{ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + *l_size = (sizeof(LLM_ALLOC)) + (number_of_items * sizeof(UINT32)); + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocInit. +| +| Description: This function intializes the LLM_ALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| **l void The memory used by the LLM_ALLOC structure. +| number_of_items UINT32 The number of resources to be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocInit +UINT32 OctapiLlmAllocInit(void ** l,UINT32 number_of_items) +{ + LLM_ALLOC* ls; + UINT32 i; + + /* Check the number of items required.*/ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + /* If no memory has been allocated yet:*/ + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)(*l); + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + ls->number_of_items = number_of_items; + + /* Linked list links all structures in ascending order.*/ + for(i=0;ilinked_list[i] = i+1; + } + + ls->linked_list[number_of_items - 1] = 0xFFFFFFFF; /* Invalid link.*/ + + /* Next avail is 0.*/ + ls->next_avail_num = 0; + + /* Number of allocated items is null.*/ + ls->allocated_items = 0; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocInfo. +| +| Description: This function returns the number of free and allocated +| block in the LLMAN list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *allocated_items UINT32 Number of allocated items. +| *available_items UINT32 Number of available items. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocInfo +UINT32 OctapiLlmAllocInfo(void * l,UINT32 * allocated_items,UINT32 * available_items) +{ + LLM_ALLOC* ls; + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)l; + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + *allocated_items = ls->allocated_items; + *available_items = ls->number_of_items - ls->allocated_items; + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocInfo. +| +| Description: This function allocates the resource indicated by blocknum. +| If the resource can be allocated then GENERIC_OK is returned. +| Else an error. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *block_num UINT32 The resource to be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocAlloc +UINT32 OctapiLlmAllocAlloc(void * l,UINT32 * blocknum) +{ + LLM_ALLOC* ls; + UINT32 allocated_block; + UINT32* node; + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)l; + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + /* Get next available block number.*/ + allocated_block = ls->next_avail_num; + + /* Check if block is invalid.*/ + if (allocated_block == 0xFFFFFFFF) + { + /* Make blocknum NULL.*/ + *blocknum = 0xFFFFFFFF; + + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + } + + node = &ls->linked_list[allocated_block]; + + /* Copy next block number.*/ + ls->next_avail_num = *node; + + /* Tag as used the current block number.*/ + *node = 0xFFFFFFFE; + + /* Return proper block number.*/ + *blocknum = allocated_block; + + /* Update block usage number.*/ + ls->allocated_items++; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctapiLlmAllocDealloc. +| +| Description: This function deallocates the resource indicated by blocknum. +| If the resource is not already allocated an error is returned. +| Else GENERIC_OK is returned. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| block_num UINT32 The resource to be deallocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctapiLlmAllocDealloc +UINT32 OctapiLlmAllocDealloc(void * l,UINT32 blocknum) +{ + LLM_ALLOC* ls; + UINT32* node; + + /* Build the structure before starting.*/ + ls = (LLM_ALLOC *)l; + ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC)); + + /* Check for null item pointer.*/ + if (blocknum == 0xFFFFFFFF) return(GENERIC_OK); + + /* Check if blocknum is within specified item range.*/ + if (blocknum >= ls->number_of_items) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + + node = &ls->linked_list[blocknum]; + + /* Check if block is really used as of now.*/ + if (*node != 0xFFFFFFFE) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Add link to list.*/ + *node = ls->next_avail_num; + + /* Point to returned block.*/ + ls->next_avail_num = blocknum; + + /* Update block usage number.*/ + ls->allocated_items--; + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocGetSize. +| +| Description: This function determines the amount of memory needed to +| manage the allocation of a fixed amount of resources. +| The memory is measured in bytes. +| +| This version is a time manage version of llman. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocGetSize +UINT32 OctApiTllmAllocGetSize(UINT32 number_of_items,UINT32 * l_size) +{ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + *l_size = (sizeof(TLLM_ALLOC)) + (number_of_items * sizeof(TLLM_ALLOC_NODE)); + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocInit. +| +| Description: This function intializes the TLLM_ALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| **l void The memory used by the LLM_ALLOC structure. +| number_of_items UINT32 The number of resources to be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocInit +UINT32 OctApiTllmAllocInit(void ** l,UINT32 number_of_items) +{ + TLLM_ALLOC* ls; + UINT32 i; + + /* Check the number of items required.*/ + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + + /* If no memory has been allocated yet.*/ + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)(*l); + ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC)); + + ls->number_of_items = number_of_items; + + /* Linked list links all structures in ascending order.*/ + for(i=0;ilinked_list[i].value = i+1; + } + + ls->linked_list[number_of_items - 1].value = 0xFFFFFFFF; /* Invalid link.*/ + + /* Next avail is 0.*/ + ls->next_avail_num = 0; + + /* Number of allocated items is null.*/ + ls->allocated_items = 0; + + /* Set the number of timeout entry.*/ + ls->number_of_timeout = 0; + + /* Next timeout is 0.*/ + ls->next_timeout_num = 0xFFFFFFFF; + ls->last_timeout_num = 0xFFFFFFFF; + + /* Set the known time to 0.*/ + ls->last_known_time[ 0 ] = 0; + ls->last_known_time[ 1 ] = 0; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocInfo. +| +| Description: This function returns the number of free and allocated +| block in the TLLMAN list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *allocated_items UINT32 Number of allocated items. +| *available_items UINT32 Number of available items. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocInfo +UINT32 OctApiTllmAllocInfo(void * l,UINT32 * allocated_items,UINT32 * available_items) +{ + TLLM_ALLOC* ls; + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)l; + *allocated_items = ls->allocated_items; + *available_items = ls->number_of_items - ls->allocated_items; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocAlloc. +| +| Description: This function allocates the resource indicated by blocknum. +| If the resource can be allocated then GENERIC_OK is returned. +| Else an error. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| *block_num UINT32 The resource to be allocated. +| *current_time UINT32 +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocAlloc +UINT32 OctApiTllmAllocAlloc(void * l,UINT32 * blocknum, UINT32 *current_time) +{ + TLLM_ALLOC* ls; + UINT32 allocated_block; + TLLM_ALLOC_NODE* node; + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)l; + ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC)); + + if ( ls->allocated_items == ls->number_of_items && + ls->next_timeout_num != 0xFFFFFFFF ) + { + UINT32 l_ulResult; + l_ulResult = OctApiTllmCheckTimeoutList( ls, current_time ); + if ( l_ulResult != GENERIC_OK ) + return l_ulResult; + } + + /* Get next available block number.*/ + allocated_block = ls->next_avail_num; + + /* Check if block is invalid.*/ + if (allocated_block == 0xFFFFFFFF) + { + /* Make blocknum NULL.*/ + *blocknum = 0xFFFFFFFF; + + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + } + + node = &ls->linked_list[allocated_block]; + + /* Copy next block number.*/ + ls->next_avail_num = node->value; + + /* Tag as used the current block number.*/ + node->value = 0xFFFFFFFE; + + /* Return proper block number.*/ + *blocknum = allocated_block; + + /* Update block usage number.*/ + ls->allocated_items++; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmAllocDealloc. +| +| Description: This function deallocates the resource indicated by blocknum. +| If the resource is not already allocated an error is returned. +| Else GENERIC_OK is returned. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_ALLOC structure. +| block_num UINT32 The resource to be deallocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmAllocDealloc +UINT32 OctApiTllmAllocDealloc(void * l,UINT32 blocknum, UINT32 timeout_value, UINT32 current_time[2]) +{ + TLLM_ALLOC* ls; + TLLM_ALLOC_NODE* node; + UINT32 l_ulResult; + + /* Build the structure before starting.*/ + ls = (TLLM_ALLOC *)l; + ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC)); + + /* Check for null item pointer.*/ + if (blocknum == 0xFFFFFFFF) return(GENERIC_OK); + + /* Check if blocknum is within specified item range.*/ + if (blocknum >= ls->number_of_items) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + + if ( ls->next_timeout_num != 0xFFFFFFFF ) + { + l_ulResult = OctApiTllmCheckTimeoutList( ls, current_time ); + if ( l_ulResult != GENERIC_OK ) + return l_ulResult; + } + + node = &ls->linked_list[blocknum]; + + /* Check if block is really used as of now.*/ + if (node->value != 0xFFFFFFFE) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Add link to timeout list.*/ + if ( ls->last_timeout_num != 0xFFFFFFFF ) + { + TLLM_ALLOC_NODE* last_node; + + /* insert the node at the end of the list.*/ + node->value = 0xFFFFFFFF; + last_node = &ls->linked_list[ ls->last_timeout_num ]; + last_node->value = blocknum; + } + else + { + /* The node is alone in the list.*/ + node->value = 0xFFFFFFFF; + ls->next_timeout_num = blocknum; + } + + ls->last_timeout_num = blocknum; + ls->number_of_timeout++; + + /* Set the timeout time of the node.*/ + l_ulResult = OctApiLmAdd( current_time, 1, &timeout_value, 0, node->timeout, 1 ); + if (l_ulResult != GENERIC_OK) + return(l_ulResult); + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiTllmCheckTimeoutList. +| +| Description: This function will verify if the timeout time +| of all the node present in the timeout list are bigger +| then the current time. If so the node will be returned +| ot the free node list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *ls TLLM_ALLOC The memory used by the TLLM_ALLOC structure. +| current_time UINT32[2] The current time in msec. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiTllmCheckTimeoutList +UINT32 OctApiTllmCheckTimeoutList(TLLM_ALLOC *ls, UINT32 current_time[2]) +{ + UINT32 result; + UINT32 fConditionFlag = TRUE; + + /* Free-up any pending memory before trying the allocation:*/ + if ((ls->last_known_time[0] != current_time[0] || + ls->last_known_time[1] != current_time[1]) && + (current_time[1] != 0 || current_time[0] != 0)) /* Time has changed.*/ + { + TLLM_ALLOC_NODE *pcurrent_node; + UINT32 current_num; + USHORT neg; + + /* Remember time for next time!*/ + ls->last_known_time[0] = current_time[0]; + ls->last_known_time[1] = current_time[1]; + + + while ( fConditionFlag == TRUE ) + { + /* Get a node from the timeout list.*/ + pcurrent_node = &ls->linked_list[ ls->next_timeout_num ]; + current_num = ls->next_timeout_num; + + /* Check if first node has timeout.*/ + result = OctApiLmCompare(current_time,1,pcurrent_node->timeout ,1,&neg); + if (result != GENERIC_OK) return(result); + + /* if the timeout tiem was exceeded, set the block as free.*/ + if ( neg == FALSE ) + { + /* set the next node pointer.*/ + ls->next_timeout_num = pcurrent_node->value; + ls->number_of_timeout--; + + /* reset the last pointer of the timeout list.*/ + if ( ls->number_of_timeout == 0 ) + ls->last_timeout_num = 0xFFFFFFFF; + + /* return the node the free list.*/ + pcurrent_node->value = ls->next_avail_num; + ls->next_avail_num = current_num; + ls->allocated_items--; + } + else /* node not in timeout */ + { + fConditionFlag = FALSE; + break; + } + + if ( ls->next_timeout_num == 0xFFFFFFFF ) + { + fConditionFlag = FALSE; + break; /* end of timeout list.*/ + } + } + } + + return(GENERIC_OK); +} +#endif +/**************************************** llm_alloc section **********************************************/ + + + + + + + +/**************************************** llm_list section **********************************************/ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListGetSize +| +| Description: This function determines the amount of memory needed by +| the LLM_LIST structure to manage the allocation of +| number_of_items number of resources. The memory is +| measured in bytes. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListGetSize +UINT32 OctApiLlmListGetSize(UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size,UINT32 * l_size) +{ + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + *l_size = sizeof(LLM_LIST) + (number_of_lists * sizeof(LLM_LIST_HEAD)) + head_alloc_size + (number_of_items * (sizeof(LLM_LIST_ITEM) + user_info_size_roundup - 4)); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiLlmListGetItemPointer +LLM_LIST_ITEM * OctApiLlmListGetItemPointer(LLM_LIST * ls, UINT32 item_number) +{ + return (LLM_LIST_ITEM *) (((BYTE *)ls->li) + (ls->item_size * item_number)) ; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListInit. +| +| Description: This function intializes the LLM_TALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListInit +UINT32 OctApiLlmListInit(void ** l,UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size) +{ + LLM_LIST* ls; + LLM_LIST_ITEM* item; + UINT32 i; + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + UINT32 total_lists; + BYTE* lsbyte; + + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + /* Get the size of the Alloc structure used to manage head of list structures.*/ + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize parameters in the structure.*/ + ls->head_alloc_size = head_alloc_size; + ls->user_info_bytes = user_info_size; + ls->user_info_size = user_info_size_roundup; + ls->total_items = number_of_items; + ls->assigned_items = 0; + ls->total_lists = number_of_lists; + ls->assigned_lists = 0; + ls->next_empty_item = 0; + ls->item_size = sizeof(LLM_LIST_ITEM) + user_info_size_roundup - 4; + + /* Complete the build!*/ + ls = (LLM_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize the head of queue Alloc structure.*/ + result = OctapiLlmAllocInit(&(ls->list_head_alloc),number_of_lists); + if(result != GENERIC_OK) return(result); + + /* Initialize the linked list of the items:*/ + for(i=0; ili + ls->item_size * i); + + if (i == (number_of_items - 1)) + item->forward_link = 0xFFFFFFFF; + else + item->forward_link = i + 1; + } + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListInfo. +| +| Description: This function returns the status of the LLM_LIST structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *allocated_lists UINT32 The number of linked_lists allocated. +| *free_lists UINT32 The number of linked_lists still free. +| *allocated_items UINT32 The number of items allocated to lists. +| *free_items UINT32 The number of items still free. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListInfo +UINT32 OctApiLlmListInfo(void * l,UINT32 * allocated_lists,UINT32 * allocated_items, + UINT32 * free_lists,UINT32 * free_items) +{ + LLM_LIST* ls; + BYTE* lsbyte; + UINT32 total_lists; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + *allocated_items = ls->assigned_items; + *free_items = ls->total_items - ls->assigned_items; + + *allocated_lists = ls->assigned_lists; + *free_lists = ls->total_lists - ls->assigned_lists; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListCreate. +| +| Description: This function creates a linked list. The target which is +| allocated the newly created list can request additions +| or removals from the list later on. To target identifies +| its list with the returned list handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the new list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListCreate +UINT32 OctApiLlmListCreate(void * l,UINT32 * list_handle) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + UINT32 blocknum; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + /* Get a list using the list head alloc structure.*/ + result = OctapiLlmAllocAlloc(ls->list_head_alloc, &blocknum); + if (result != GENERIC_OK) return(result); + + /* The handle is the block number.*/ + *list_handle = blocknum; + + /* Initialize the list head structure.*/ + lh = &ls->lh[blocknum]; + lh->list_length = 0; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + + ls->assigned_lists++; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListDelete. +| +| Description: This function deletes the linked list indicated by the +| handle list_handle. Any items which are still allocated +| to the list are first deallocated. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListDelete +UINT32 OctApiLlmListDelete(void * l,UINT32 list_handle) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (ls->lh[list_handle].list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Release internal list header handle...*/ + result = OctapiLlmAllocDealloc(ls->list_head_alloc,list_handle); + if (result != GENERIC_OK) return(result); + + lh = &ls->lh[list_handle]; + + /* Deallocate all items in the list!*/ + if (lh->list_length != 0) + { + LLM_LIST_ITEM * item; + + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer); + + /* Release the items using only the links.*/ + item->forward_link = ls->next_empty_item; + ls->next_empty_item = lh->head_pointer; + + /* Remove items from item counter.*/ + ls->assigned_items -= lh->list_length; + } + + lh->list_length = 0xFFFFFFFF; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + + ls->assigned_lists--; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListLength. +| +| Description: This function returns the number of items allocated to the +| list indicated by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| list_handle UINT32 The handle to the list. +| *number_of_items UINT32 The number of items in the list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListLength +UINT32 OctApiLlmListLength(void * l,UINT32 list_handle, UINT32 * number_of_items_in_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + UINT32 total_lists; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + *number_of_items_in_list = lh->list_length; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListItemData +| +| Description: This function returns a pointer to the user data associated +| with an item. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| list_handle UINT32 The handle to the list. +| item_number UINT32 The number of the list node in question. +| **item_data_pnt void The pointer to the user data, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListItemData +UINT32 OctApiLlmListItemData(void * l,UINT32 list_handle,UINT32 item_number,void ** item_data_pnt) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item; + UINT32 cur_list_pnt; + UINT32 cur_list_num; + UINT32 total_lists; + UINT32 list_length; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + list_length = lh->list_length; + + *item_data_pnt = NULL; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + if (list_length <= item_number) return(OCTAPI_LLM_ELEMENT_NOT_FOUND); + + /* Determine where the search will start.*/ + if (list_length == (item_number + 1)) /* Last item in list:*/ + { + cur_list_pnt = lh->tail_pointer; + cur_list_num = item_number; + } + else if (lh->cache_item_number <= item_number) /* Start at cache:*/ + { + cur_list_pnt = lh->cache_item_pointer; + cur_list_num = lh->cache_item_number; + } + else /* Start at beginning:*/ + { + cur_list_pnt = lh->head_pointer; + cur_list_num = 0; + } + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + + if (cur_list_num == item_number) /* Item number found.*/ + { + /* Write new cache entry.*/ + lh->cache_item_pointer = cur_list_pnt; + lh->cache_item_number = cur_list_num; + + /* Get item info.*/ + *item_data_pnt = (void *)item->user_info; + + return(GENERIC_OK); + } + else if(item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + cur_list_pnt = item->forward_link; + } + + cur_list_num++; + } + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListInsertItem. +| +| Description: This function allocates a node to the linked list specified +| by the handle list_handle. The position of the new item +| can be specified. A position of 0xFFFFFFFF means append to the +| list( use the OCTAPI_LLM_LIST_APPEND define for clarity); +| a position of 0 mean insert at the begining of the list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListInsertItem +UINT32 OctApiLlmListInsertItem(void * l,UINT32 list_handle,UINT32 item_number,void ** item_data_pnt) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* free_item; + UINT32 free_item_pnt; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + *item_data_pnt = NULL; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + if (lh->list_length < item_number && item_number != 0xFFFFFFFF) + return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (ls->next_empty_item == 0xFFFFFFFF) return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + + /* Get a free item from the free item list!*/ + free_item_pnt = ls->next_empty_item; + free_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * free_item_pnt); + ls->next_empty_item = free_item->forward_link; + + if (item_number == 0xFFFFFFFF) + item_number = lh->list_length; + + if (lh->list_length == 0) /* First item and only item:*/ + { + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + lh->head_pointer = free_item_pnt; + } + else if (item_number == 0) /* First item and but list not empty:*/ + { + free_item->forward_link = lh->head_pointer; + lh->head_pointer = free_item_pnt; + } + else if (item_number == lh->list_length) /* Append:*/ + { + LLM_LIST_ITEM * last_item; + last_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer); + + last_item->forward_link = free_item_pnt; + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + } + else /* Insert:*/ + { + LLM_LIST_ITEM * last_item = NULL; + LLM_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_num; + + if (lh->cache_item_number < item_number) /* Start at cache:*/ + { + cur_list_pnt = lh->cache_item_pointer; + cur_list_num = lh->cache_item_number; + } + else /* Start at beginning:*/ + { + cur_list_pnt = lh->head_pointer; + cur_list_num = 0; + } + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + + if (cur_list_num == item_number) /* Item number found.*/ + { + if (last_list_pnt == 0xFFFFFFFF) return(OCTAPI_LLM_INTERNAL_ERROR1); + + free_item->forward_link = cur_list_pnt; + last_item->forward_link = free_item_pnt; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + cur_list_num++; + } + } + + /* Increase the list length.*/ + lh->list_length++; + ls->assigned_items++; + *item_data_pnt = (void *)free_item->user_info; + + /* Write new cache entry.*/ + lh->cache_item_pointer = free_item_pnt; + lh->cache_item_number = item_number; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListCreateFull. +| +| Description: This function allocates the desired number of nodes to +| the linked list specified by the handle list_handle. +| The position of the new item can be specified. A +| position of 0xFFFFFFFF means append to the list (use the +| OCTAPI_LLM_LIST_APPEND define for clarity); a position +| of 0 means insert at the begining of the list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListCreateFull +UINT32 OctApiLlmListCreateFull(void* l, UINT32 list_length, UINT32* plist_handle) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* free_item; + LLM_LIST_ITEM* last_item = NULL; + UINT32 free_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 list_handle; + UINT32 list_length_m1; + UINT32 next_empty_item; + UINT32 result; + UINT32 i; + BYTE* lsbyte; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure another list can be created.*/ + if (ls->assigned_lists == ls->total_lists) + return(OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED); + + /* Make sure there are enough free nodes to fill the new list.*/ + if (list_length > (ls->total_items - ls->assigned_items)) + return(OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Create list (i.e. get a list using the list head alloc structure.*/ + result = OctapiLlmAllocAlloc(ls->list_head_alloc, &list_handle); + if (result != GENERIC_OK) return(result); + + /* Initialize the list head structure.*/ + lh = &ls->lh[list_handle]; + lh->list_length = 0; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + + ls->assigned_lists++; + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Add the number of requested nodes to the list.*/ + lh = &ls->lh[list_handle]; + list_length_m1 = list_length - 1; + next_empty_item = ls->next_empty_item; + + for (i=0; ili + ls->item_size * free_item_pnt); + next_empty_item = free_item->forward_link; + + /* Branch according to whether the node is the first in list, last, or in + the middle.*/ + if (i == 0) + { + /* First item.*/ + free_item->forward_link = 0xFFFFFFFF; + lh->head_pointer = free_item_pnt; + lh->tail_pointer = free_item_pnt; + } + else if (i == list_length_m1) + { + /* Last item.*/ + last_item->forward_link = free_item_pnt; + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + } + else + { + /* Node somewhere in the middle.*/ + last_item->forward_link = free_item_pnt; + } + + /* Store pointer to free item as pointer to last item (for next iteration).*/ + last_item = free_item; + } + + /* Store new value of next_empty_item.*/ + ls->next_empty_item = next_empty_item; + + /* Write new cache entry.*/ + lh->cache_item_pointer = free_item_pnt; + lh->cache_item_number = list_length_m1; + + /* Set the list length.*/ + lh->list_length = list_length; + ls->assigned_items += list_length; + + /* Return pointer to new list.*/ + *plist_handle = list_handle; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListAppendItems. +| +| Description: This function allocates the desired number of nodes to +| the linked list specified by the handle list_handle. +| The position of the new item can be specified. A +| position of 0xFFFFFFFF means append to the list (use the +| OCTAPI_LLM_LIST_APPEND define for clarity); a position +| of 0 means insert at the begining of the list. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListAppendItems +UINT32 OctApiLlmListAppendItems(void* l, UINT32 list_handle, UINT32 num_items) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item_list; + LLM_LIST_ITEM* curr_item = NULL; + LLM_LIST_ITEM* free_item; + UINT32 curr_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 next_empty_item; + UINT32 item_size; + UINT32 i; + BYTE* lsbyte; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure there is at least one item.*/ + if (num_items == 0) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure there are enough free nodes.*/ + if (num_items > (ls->total_items - ls->assigned_items)) + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Get pointer to list structure.*/ + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Add the number of requested nodes to the list.*/ + item_list = ls->li; + item_size = ls->item_size; + next_empty_item = ls->next_empty_item; + + for (i=0; ihead_pointer == 0xFFFFFFFF) + { + /* Current and next items are one and the same!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Set new head and tail pointers.*/ + lh->head_pointer = next_empty_item; + lh->tail_pointer = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next item.*/ + next_empty_item = curr_item->forward_link; + + /* Set first item to be only item in list.*/ + curr_item->forward_link = 0xFFFFFFFF; + } + else + { + /* Get a free item from the free item list!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * lh->tail_pointer); + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + } + else + { + /* Update pointers to current item and free item.*/ + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + } + + /* Terminate list.*/ + if ( curr_item != NULL ) + curr_item->forward_link = 0xFFFFFFFF; + + /* Update llman structure variables.*/ + ls->next_empty_item = next_empty_item; + ls->assigned_items += num_items; + + /* Update list variables.*/ + lh->list_length += num_items; + lh->cache_item_pointer = curr_item_pnt; + lh->cache_item_number = lh->list_length - 1; + lh->tail_pointer = curr_item_pnt; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListAppendAndSetItems. +| +| Description: +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListAppendAndSetItems +UINT32 OctApiLlmListAppendAndSetItems(void* l, UINT32 list_handle, UINT32 num_items, void* data_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item_list; + LLM_LIST_ITEM* curr_item = NULL; + LLM_LIST_ITEM* free_item; + UINT32 curr_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 next_empty_item; + UINT32 user_info_bytes; + UINT32 item_size; + UINT32 i; + BYTE* lsbyte; + void* data_item; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure there is at least one item.*/ + if (num_items == 0) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure there are enough free nodes.*/ + if (num_items > (ls->total_items - ls->assigned_items)) + return(OCTAPI_LLM_NO_STRUCTURES_LEFT); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Get pointer to list structure.*/ + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Add the number of requested nodes to the list.*/ + item_list = ls->li; + user_info_bytes = ls->user_info_bytes; + item_size = ls->item_size; + next_empty_item = ls->next_empty_item; + data_item = data_list; + + for (i=0; ihead_pointer == 0xFFFFFFFF) + { + /* Current and next items are one and the same!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Set new head and tail pointers.*/ + lh->head_pointer = next_empty_item; + lh->tail_pointer = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next item.*/ + next_empty_item = curr_item->forward_link; + + /* Set first item to be only item in list.*/ + curr_item->forward_link = 0xFFFFFFFF; + } + else + { + /* Get a free item from the free item list!*/ + curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * lh->tail_pointer); + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + } + else + { + /* Update pointers to current item and free item.*/ + free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item); + + /* Have current item point to next empty item.*/ + curr_item->forward_link = next_empty_item; + + /* Update current item pnt.*/ + curr_item_pnt = next_empty_item; + + /* Update next_empty_item.*/ + next_empty_item = free_item->forward_link; + + /* Update pointers to current item and free item.*/ + curr_item = free_item; + } + + /* Copy data to new item.*/ + OctApiLlmMemCpy(curr_item->user_info, data_item, user_info_bytes); + + /* Update data_item pointer for next iteration (item).*/ + data_item = (void *)((BYTE *)data_item + user_info_bytes); + } + + + /* Terminate list.*/ + if ( curr_item != NULL ) + curr_item->forward_link = 0xFFFFFFFF; + + /* Update llman structure variables.*/ + ls->next_empty_item = next_empty_item; + ls->assigned_items += num_items; + + /* Update list variables.*/ + lh->list_length += num_items; + lh->cache_item_pointer = curr_item_pnt; + lh->cache_item_number = lh->list_length - 1; + lh->tail_pointer = curr_item_pnt; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListSetItems. +| +| Description: This function takes a start entry (0 to length - 1), +| a pointer to a list of data (each item of list is the +| size of one data unit, specified at init), and the +| length of the data list. From this, the data will be +| copied from the data list to the linked list, from +| entry start_entry to (start_entry + data_length - 1). +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListSetItems +UINT32 OctApiLlmListSetItems(void* l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, void* pdata_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item = NULL; + UINT32 total_lists; + UINT32 item_pnt = 0xFFFFFFFF; + UINT32 i, j; + BYTE* lsbyte; + void* pdata_item = NULL; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure the start_entry is within limits.*/ + if (start_item >= lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure the end_entry is within limits.*/ + lh = &ls->lh[list_handle]; + if ((start_item + data_length) > lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Set the data of each node.*/ + for (i=0; icache_item_number + 1)) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->cache_item_pointer); + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + else + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->head_pointer); + item_pnt = lh->head_pointer; + for (j=0; jforward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + } + + pdata_item = (void *)((BYTE *)pdata_list + (i * ls->user_info_bytes)); + } + else + { + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + + pdata_item = (void *)((BYTE *)pdata_item + ls->user_info_bytes); + } + + /* Set the value of the item's user data.*/ + OctApiLlmMemCpy(item->user_info, pdata_item, ls->user_info_bytes); + } + + /* Write new cache entry.*/ + lh->cache_item_pointer = item_pnt; + lh->cache_item_number = start_item + data_length - 1; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListCopyData. +| +| Description: This function takes a start entry (0 to length - 1), +| a pointer to a list of data (each item of list is the +| size of one data unit, specified at init), and the +| length of the data list. From this, the data will be +| copied from the linked list to the data list, from +| entry start_entry of the linked list to +| (start_entry + data_length - 1). +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListCopyData +UINT32 OctApiLlmListCopyData(void* l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, void* pdata_list) +{ + LLM_LIST* ls; + LLM_LIST_HEAD* lh; + LLM_LIST_ITEM* item = NULL; + UINT32 item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 i, j; + BYTE* lsbyte; + void* pdata_item = NULL; + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Build the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Make sure list handle is valid.*/ + if (list_handle >= ls->total_lists) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + lh = &ls->lh[list_handle]; + if (lh->list_length == 0xFFFFFFFF) + return(OCTAPI_LLM_INVALID_LIST_HANDLE); + + /* Make sure the start_entry is within limits.*/ + if (start_item >= lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + + /* Make sure the end_entry is within limits.*/ + lh = &ls->lh[list_handle]; + if ((start_item + data_length) > lh->list_length) + return(OCTAPI_LLM_INVALID_PARAMETER); + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + + + + /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ + /* Set the data of each node.*/ + for (i=0; icache_item_number + 1)) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->cache_item_pointer); + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + else + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->head_pointer); + for (j=0; jforward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + } + } + + pdata_item = (void *)((BYTE *)pdata_list + (i * ls->user_info_bytes)); + } + else + { + item_pnt = item->forward_link; + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt); + + pdata_item = (void *)((BYTE *)pdata_item + ls->user_info_bytes); + } + + /* Set the value of the item's user data.*/ + OctApiLlmMemCpy(pdata_item, item->user_info, ls->user_info_bytes); + } + + /* Write new cache entry.*/ + lh->cache_item_pointer = item_pnt; + lh->cache_item_number = start_item + data_length - 1; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListRemoveItem. +| +| Description: This function deallocates a node of the linked list specified +| by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| list_handle UINT32 The handle to the list. +| item_number UINT32 The number of the item to be removed. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmListRemoveItem +UINT32 OctApiLlmListRemoveItem(void * l,UINT32 list_handle,UINT32 item_number) +{ + LLM_LIST* ls; + LLM_LIST_ITEM* freed_item = NULL; + LLM_LIST_HEAD* lh; + UINT32 freed_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD))); + ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE); + if (lh->list_length <= item_number) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE); + + if (item_number == 0 && lh->list_length == 1)/* First item and only item:*/ + { + freed_item_pnt = lh->head_pointer; + freed_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt); + + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + + lh->cache_item_number = 0xFFFFFFFF; + lh->cache_item_pointer = 0xFFFFFFFF; + } + else if (item_number == 0) /* First item and but list not empty:*/ + { + freed_item_pnt = ls->lh[list_handle].head_pointer; + freed_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt); + + lh->head_pointer = freed_item->forward_link; + + lh->cache_item_number = 0; + lh->cache_item_pointer = freed_item->forward_link; + } + else /* Discard non-first item! (Caution: this could be the last item!)*/ + { + LLM_LIST_ITEM * last_item = NULL; + LLM_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_num; + + if (lh->cache_item_number < item_number) /* Start at cache:*/ + { + cur_list_pnt = lh->cache_item_pointer; + cur_list_num = lh->cache_item_number; + } + else /* Start at beginning:*/ + { + cur_list_pnt = lh->head_pointer; + cur_list_num = 0; + } + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while( fConditionFlag == TRUE ) + { + item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + + if (cur_list_num == item_number) /* Item number found.*/ + { + if (last_list_pnt == 0xFFFFFFFF) return(OCTAPI_LLM_INTERNAL_ERROR1); + + if ((item_number + 1) == lh->list_length) + { + lh->tail_pointer = last_list_pnt; + last_item->forward_link = 0xFFFFFFFF; + } + else + { + last_item->forward_link = item->forward_link; + } + freed_item_pnt = cur_list_pnt; + freed_item = item; + + /* Reset cache entry.*/ + lh->cache_item_pointer = last_list_pnt; + lh->cache_item_number = cur_list_num - 1; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + cur_list_num++; + } + } + + /* Decrease the list length.*/ + lh->list_length--; + ls->assigned_items--; + + /* Return free block to free block list:*/ + freed_item->forward_link = ls->next_empty_item; + ls->next_empty_item = freed_item_pnt; + + return(GENERIC_OK); +} +#endif + +/**************************************** llm2 function section *****************************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListGetSize +| +| Description: This function determines the amount of memory needed by +| the LLM2_LIST structure to manage the allocation of +| number_of_items number of resources. The memory is +| measured in bytes. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| *l_size UINT32 UINT32 The amount of memory needed, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListGetSize +UINT32 OctApiLlm2ListGetSize(UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size,UINT32 * l_size) +{ + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + *l_size = sizeof(LLM2_LIST) + (number_of_lists * sizeof(LLM2_LIST_HEAD)) + head_alloc_size + (number_of_items * (sizeof(LLM2_LIST_ITEM) + user_info_size_roundup - 4)); + + return(GENERIC_OK); +} +#endif + +#if !SKIP_OctApiLlm2ListGetItemPointer +LLM2_LIST_ITEM * OctApiLlm2ListGetItemPointer(LLM2_LIST * ls, UINT32 item_number) +{ + return (LLM2_LIST_ITEM *) (((BYTE *)ls->li) + (ls->item_size * item_number)) ; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListInit. +| +| Description: This function intializes the LLM2_TALLOC structure. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| number_of_items UINT32 The number of resources to be allocated +| amongst all linked-lists. +| number_of_lists UINT32 The maximum number of linked-lists that +| can be allocated. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListInit +UINT32 OctApiLlm2ListInit(void ** l,UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size) +{ + LLM2_LIST* ls; + LLM2_LIST_ITEM* item; + UINT32 i; + UINT32 head_alloc_size; + UINT32 result; + UINT32 user_info_size_roundup; + UINT32 total_lists; + BYTE* lsbyte; + + + if (number_of_items == 0) return(GENERIC_BAD_PARAM); + if (number_of_lists == 0) return(GENERIC_BAD_PARAM); + if (user_info_size == 0) return(GENERIC_BAD_PARAM); + + user_info_size_roundup = ((user_info_size + 3) / 4) * 4; + + /* Get the size of the Alloc structure used to manage head of list structures.*/ + result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size); + if(result != GENERIC_OK) return(result); + + if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED); + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize parameters in the structure.*/ + ls->head_alloc_size = head_alloc_size; + ls->user_info_bytes = user_info_size; + ls->user_info_size = user_info_size_roundup; + ls->total_items = number_of_items; + ls->assigned_items = 0; + ls->total_lists = number_of_lists; + ls->assigned_lists = 0; + ls->next_empty_item = 0; + ls->item_size = sizeof(LLM2_LIST_ITEM) + user_info_size_roundup - 4; + + /* Complete the build!*/ + ls = (LLM2_LIST *)(*l); + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + /* Initialize the head of queue Alloc structure.*/ + result = OctapiLlmAllocInit(&(ls->list_head_alloc),number_of_lists); + if(result != GENERIC_OK) return(result); + + /* Initialize the linked list of the items:*/ + for(i=0; ili + ls->item_size * i); + + if (i == (number_of_items - 1)) + item->forward_link = 0xFFFFFFFF; + else + item->forward_link = i + 1; + } + + return(GENERIC_OK); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListCreate. +| +| Description: This function creates a linked list. The target which is +| allocated the newly created list can request additions +| or removals from the list later on. To target identifies +| its list with the returned list handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM_LIST structure. +| *list_handle UINT32 The handle to the new list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListCreate +UINT32 OctApiLlm2ListCreate(void * l,UINT32 * list_handle) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + UINT32 blocknum; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + /* Get a list using the list head alloc structure.*/ + result = OctapiLlmAllocAlloc(ls->list_head_alloc, &blocknum); + if (result != GENERIC_OK) return(result); + + /* The handle is the block number.*/ + *list_handle = blocknum; + + /* Initialize the list head structure.*/ + lh = &ls->lh[blocknum]; + lh->list_length = 0; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + + ls->assigned_lists++; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListDelete. +| +| Description: This function deletes the linked list indicated by the +| handle list_handle. Any items which are still allocated +| to the list are first deallocated. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| *list_handle UINT32 The handle to the list. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListDelete +UINT32 OctApiLlm2ListDelete(void * l,UINT32 list_handle) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + UINT32 total_lists; + UINT32 result; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (ls->lh[list_handle].list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + /* Release internal list header handle...*/ + result = OctapiLlmAllocDealloc(ls->list_head_alloc,list_handle); + if (result != GENERIC_OK) return(result); + + lh = &ls->lh[list_handle]; + + /* Deallocate all items in the list!*/ + if (lh->list_length != 0) + { + LLM2_LIST_ITEM * item; + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer); + + /* Release the items using only the links.*/ + item->forward_link = ls->next_empty_item; + ls->next_empty_item = lh->head_pointer; + + /* Remove items from item counter.*/ + ls->assigned_items -= lh->list_length; + } + + lh->list_length = 0xFFFFFFFF; + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + + ls->assigned_lists--; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmListLength. +| +| Description: This function returns the number of items allocated to the +| list indicated by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| list_handle UINT32 The handle to the list. +| *number_of_items UINT32 The number of items in the list, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListLength +UINT32 OctApiLlm2ListLength(void * l,UINT32 list_handle, UINT32 * number_of_items_in_list) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + UINT32 total_lists; + BYTE* lsbyte; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + *number_of_items_in_list = lh->list_length; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListItemData +| +| Description: This function returns a pointer to the user data associated +| with an item. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| list_handle UINT32 The handle to the list. +| item_number UINT32 The number of the list node in question. +| **item_data_pnt void The pointer to the user data, returned. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListItemData +UINT32 OctApiLlm2ListItemData(void * l,UINT32 list_handle,UINT32 item_key,void ** item_data_pnt, PUINT32 item_number_pnt) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + LLM2_LIST_ITEM* item; + UINT32 cur_list_pnt; + UINT32 cur_list_key = 0xFFFFFFFF; + UINT32 total_lists; + UINT32 list_length; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + list_length = lh->list_length; + + *item_data_pnt = NULL; + *item_number_pnt = 0; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + /* Determine where the search will start.*/ + /* Start at beginning:*/ + cur_list_pnt = lh->head_pointer; + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + if (cur_list_key == item_key) /* Item key found.*/ + { + /* Get item info.*/ + *item_data_pnt = (void *)item->user_info; + + return(GENERIC_OK); + } + else if(item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM2_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + cur_list_pnt = item->forward_link; + } + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + (*item_number_pnt)++; + } + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListInsertItem. +| +| Description: This function allocates a node to the linked list specified +| by the handle list_handle. The position of the new item +| will be defined based on the key value. All entry are inserted +| in the list in incremental Key value. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| *list_handle UINT32 The handle to the list. +| **item_data void Address of the user data space for this item. +| **prev_item_data void Address of the user data space for the previous item. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListInsertItem +UINT32 OctApiLlm2ListInsertItem(void * l,UINT32 list_handle,UINT32 item_key,void ** item_data_pnt, void ** prev_item_data_pnt, void ** prev_prev_item_data_pnt, PUINT32 insert_status_pnt ) +{ + LLM2_LIST* ls; + LLM2_LIST_HEAD* lh; + LLM2_LIST_ITEM* free_item; + UINT32 free_item_pnt; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 ulPassCount = 0; + UINT32 fConditionFlag = TRUE; + + /* Set the status of the insertion.*/ + *insert_status_pnt = OCTAPI_LLM2_INSERT_ERROR; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + *item_data_pnt = NULL; + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + if (ls->next_empty_item == 0xFFFFFFFF) return(OCTAPI_LLM2_NO_STRUCTURES_LEFT); + + /* Get a free item from the free item list!*/ + free_item_pnt = ls->next_empty_item; + free_item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * free_item_pnt); + free_item->key = item_key; + ls->next_empty_item = free_item->forward_link; + + if (lh->list_length == 0) /* First item and only item:*/ + { + free_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = free_item_pnt; + lh->head_pointer = free_item_pnt; + *insert_status_pnt = OCTAPI_LLM2_INSERT_FIRST_NODE; + + /* There is no previous node information to return.*/ + *prev_item_data_pnt = NULL; + *prev_prev_item_data_pnt = NULL; + } + else /* Insert:*/ + { + LLM2_LIST_ITEM * last_last_item = NULL; + LLM2_LIST_ITEM * last_item = NULL; + LLM2_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_key = 0xFFFFFFFF; + + /* Start at beginning:*/ + cur_list_pnt = lh->head_pointer; + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while ( fConditionFlag == TRUE ) + { + /* Increment the pass count to determine if the addition will happen next to last.*/ + ulPassCount++; + + if (cur_list_key >= item_key) /* Item new node between the last and the curent. */ + { + if (last_list_pnt == 0xFFFFFFFF) /* Must insert at the head of the list.*/ + { + free_item->forward_link = cur_list_pnt; + lh->head_pointer = free_item_pnt; + } + else /* Standard insertion.*/ + { + free_item->forward_link = cur_list_pnt; + last_item->forward_link = free_item_pnt; + } + + /* Check if the entry was made before the last one.*/ + if ( ulPassCount == lh->list_length ) + *insert_status_pnt = OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE; + else + *insert_status_pnt = OCTAPI_LLM2_INSERT_LIST_NODE; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found, must insert at the end.*/ + { + free_item->forward_link = 0xFFFFFFFF; + item->forward_link = free_item_pnt; + lh->tail_pointer = free_item_pnt; + + *insert_status_pnt = OCTAPI_LLM2_INSERT_LAST_NODE; + + fConditionFlag = FALSE; + break; + } + else /* Item was not found, but continue searching.*/ + { + last_last_item = last_item; + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + } + + /* Return the previous node if possible.*/ + if ( *insert_status_pnt == OCTAPI_LLM2_INSERT_LIST_NODE || + *insert_status_pnt == OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE ) + { + if ( last_item != NULL ) + *prev_item_data_pnt = (void *)last_item->user_info; + + if ( last_last_item != NULL ) + *prev_prev_item_data_pnt = (void *)last_last_item->user_info; + else + *prev_prev_item_data_pnt = NULL; + } + else + { + *prev_item_data_pnt = (void *)item->user_info; + + if ( ( last_last_item != NULL ) && ( last_item != NULL ) ) + *prev_prev_item_data_pnt = (void *)last_item->user_info; + else + *prev_prev_item_data_pnt = NULL; + } + } + + /* Increase the list length.*/ + lh->list_length++; + ls->assigned_items++; + *item_data_pnt = (void *)free_item->user_info; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlm2ListRemoveItem. +| +| Description: This function deallocates a node of the linked list specified +| by the handle list_handle. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *l void The memory used by the LLM2_LIST structure. +| list_handle UINT32 The handle to the list. +| item_key UINT32 The key of the item to be removed. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlm2ListRemoveItem +UINT32 OctApiLlm2ListRemoveItem(void * l,UINT32 list_handle,UINT32 item_key, PUINT32 prev_item_key_pnt, PUINT32 prev_prev_item_key_pnt, PUINT32 remove_status_pnt ) +{ + LLM2_LIST* ls; + LLM2_LIST_ITEM* freed_item = NULL; + LLM2_LIST_HEAD* lh; + UINT32 freed_item_pnt = 0xFFFFFFFF; + UINT32 total_lists; + BYTE* lsbyte; + UINT32 fConditionFlag = TRUE; + UINT32 ulPassCount = 0; + + /* Built the structure based on the base address:*/ + ls = (LLM2_LIST *)l; + lsbyte = (BYTE *)ls; + total_lists = ls->total_lists; + + /* Set the status of the removal to error as a default value.*/ + *remove_status_pnt = OCTAPI_LLM2_REMOVE_ERROR; + + ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST)); + ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD))); + ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size); + + lh = &ls->lh[list_handle]; + + if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE); + if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE); + + if (lh->list_length == 1)/* First item and only item if he matches.*/ + { + freed_item_pnt = lh->head_pointer; + freed_item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt); + + if ( freed_item->key == item_key ) + { + lh->head_pointer = 0xFFFFFFFF; + lh->tail_pointer = 0xFFFFFFFF; + } + else + return(OCTAPI_LLM2_INTERNAL_ERROR1); + + /* Indicate that there was no node prior to the one removed.*/ + *prev_item_key_pnt = 0xFFFFFFFF; + *prev_prev_item_key_pnt = 0xFFFFFFFF; + *remove_status_pnt = OCTAPI_LLM2_REMOVE_FIRST_NODE; + } + else /* Discard non-first item! (Caution: this could be the last item!)*/ + { + LLM2_LIST_ITEM * last_last_item = NULL; + LLM2_LIST_ITEM * last_item = NULL; + LLM2_LIST_ITEM * item; + UINT32 last_list_pnt; + UINT32 cur_list_pnt; + UINT32 cur_list_key; + + /* Start at beginning:*/ + cur_list_pnt = lh->head_pointer; + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + + last_list_pnt = 0xFFFFFFFF; + + /* Start search from cur_list_pnt and cur_list_num.*/ + while( fConditionFlag == TRUE ) + { + ulPassCount++; + if (cur_list_key == item_key) /* Item number found.*/ + { + if (last_list_pnt == 0xFFFFFFFF) /* First item in the list.*/ + { + lh->head_pointer = item->forward_link; + *remove_status_pnt = OCTAPI_LLM2_REMOVE_FIRST_NODE; + } + else if ( item->forward_link == 0xFFFFFFFF) /* Last item of the list.*/ + { + last_item->forward_link = 0xFFFFFFFF; + lh->tail_pointer = last_list_pnt; + *remove_status_pnt = OCTAPI_LLM2_REMOVE_LAST_NODE; + } + else + { + last_item->forward_link = item->forward_link; + + if ( ulPassCount == ( lh->list_length - 1 ) ) + *remove_status_pnt = OCTAPI_LLM2_REMOVE_BEFORE_LAST_NODE; + else + *remove_status_pnt = OCTAPI_LLM2_REMOVE_LIST_NODE; + } + + freed_item_pnt = cur_list_pnt; + freed_item = item; + + fConditionFlag = FALSE; + break; + } + else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/ + { + return(OCTAPI_LLM2_INTERNAL_ERROR0); + } + else /* Item was not found, but continue searching.*/ + { + last_last_item = last_item; + last_item = item; + last_list_pnt = cur_list_pnt; + cur_list_pnt = item->forward_link; + } + + item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt); + cur_list_key = item->key; + } + + /* Return the key of the node before the node removed if possible.*/ + if ( last_list_pnt == 0xFFFFFFFF ) + *prev_item_key_pnt = 0xFFFFFFFF; + else if ( last_item != NULL ) + *prev_item_key_pnt = last_item->key; + + /* Return the key of the node before before the node removed if possible.*/ + if ( last_last_item == NULL ) + *prev_prev_item_key_pnt = 0xFFFFFFFF; + else + *prev_prev_item_key_pnt = last_last_item->key; + + } + + /* Decrease the list length.*/ + lh->list_length--; + ls->assigned_items--; + + /* Return free block to free block list:*/ + freed_item->forward_link = ls->next_empty_item; + ls->next_empty_item = freed_item_pnt; + + return(GENERIC_OK); +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ +| API UTILITIES +| +| Function: OctApiLlmMemCpy. +| +| Description: This function copies data from a source to a destination. +| +| ----------------------------------------------------------------------- +| | Variable | Type | Description +| ----------------------------------------------------------------------- +| *f_pvDestination VOID The destination where to copy the data. +| *f_pvSource VOID The source where to copy the data from. +| f_ulSize UINT32 The number of bytes to copy. +| +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OctApiLlmMemCpy +VOID * OctApiLlmMemCpy( VOID *f_pvDestination, const VOID * f_pvSource, UINT32 f_ulSize ) +{ + CHAR * pbyDst; + const CHAR * pbySrc; + UINT32 * f_pulAlignedDst; + const UINT32 * f_pulAlignedSrc; + + pbyDst = (CHAR *)f_pvDestination; + pbySrc = (const CHAR *)f_pvSource; + + /* + * If the size is small, or either SRC or DST is unaligned, + * then punt into the byte copy loop. This should be rare. + */ + if ( ( f_ulSize < sizeof(UINT32) ) + || ( ( (unsigned long)( pbySrc ) & ( sizeof(UINT32) - 1 ) ) | ( (unsigned long)( pbyDst ) & ( sizeof(UINT32) - 1 ) ) ) ) + { + while ( f_ulSize-- ) + *pbyDst++ = *pbySrc++; + return f_pvDestination; + } + + f_pulAlignedDst = (UINT32 *)pbyDst; + f_pulAlignedSrc = (const UINT32 *)pbySrc; + + /* Copy 4X long words at a time if possible. */ + while ( f_ulSize >= 4 * sizeof(UINT32) ) + { + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + f_ulSize -= 4 * sizeof(UINT32); + } + + /* Copy one long word at a time if possible. */ + while ( f_ulSize >= sizeof(UINT32) ) + { + *f_pulAlignedDst++ = *f_pulAlignedSrc++; + f_ulSize -= sizeof(UINT32); + } + + /* Pick up any residual with a byte copier. */ + pbyDst = (CHAR *)f_pulAlignedDst; + pbySrc = (const CHAR *)f_pulAlignedSrc; + while ( f_ulSize-- ) + *pbyDst++ = *pbySrc++; + + return f_pvDestination; +} +#endif + +/**************************************** llm_list section **********************************************/ + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/llman/octapi_llman_private.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/llman/octapi_llman_private.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/llman/octapi_llman_private.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/apilib/llman/octapi_llman_private.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,206 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_llman_private.h + +Copyright (c) 2001 Octasic Inc. All rights reserved. + +Description: + + Library used to manage allocation tables and linked lists. The library is + made such that only a block of contiguous memory is needed for the + management of the linked list/allocation table. + + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 13 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_LLMAN_PRIVATE_H__ +#define __OCTAPI_LLMAN_PRIVATE_H__ + +#include "octdef.h" + + +/**************************************** llm_alloc section **********************************************/ + + +/* Most basic linked list model. + LLM_STR contains a list of "number_of_items" that + are each "unassigned" or "assigned". When requesting + a new element, llm_alloc must choose an "unassigned" + element. An element that is deallocated will be last + to be allocated. +*/ + +typedef struct _LLM_ALLOC +{ + UINT32 *linked_list; /* Each item is either used (0xFFFFFFFE)*/ + /* or unused (pointer to next unused item, 0xFFFFFFFF means last item reached).*/ + UINT32 next_avail_num; /* Points to the next available item in linked list. (0xFFFFFFFF means none available)*/ + UINT32 number_of_items; /* Total number of items in linked list.*/ + UINT32 allocated_items; /* Allocated items in linked list.*/ + +} LLM_ALLOC; + +typedef struct _TLLM_ALLOC_NODE_ +{ + UINT32 value; /* Each item is either used (0xFFFFFFFE)*/ + /* or unused (pointer to next unused item, 0xFFFFFFFF means last item reached).*/ + UINT32 timeout[2]; /* Timeout value that must be exceeded for the node to be considered free again.*/ + +} TLLM_ALLOC_NODE; + + +typedef struct _TLLM_ALLOC_ +{ + TLLM_ALLOC_NODE *linked_list; /* List of nodes used by the link list.*/ + + UINT32 next_avail_num; /* Points to the next available item in linked list. (0xFFFFFFFF means none available)*/ + UINT32 number_of_items; /* Total number of items in linked list.*/ + UINT32 allocated_items; /* Allocated items in linked list.*/ + + UINT32 number_of_timeout; /* Number of block currently in timeout.*/ + UINT32 next_timeout_num; /* Points to the next block currently in timeout.*/ + UINT32 last_timeout_num; /* Last node of the timeout list.*/ + + UINT32 last_known_time[2]; /* last known time.*/ + +} TLLM_ALLOC; + +/* +void octapi_llm_alloc_build_structure(void *l, LLM_ALLOC ** ls); +*/ +/**************************************** llm_alloc section **********************************************/ + + + +/**************************************** llm_list section **********************************************/ +/* This section contains memory structures and functions used + to maintain a variable number of lists (FIFOs) that each + have a variable amount of items. A total amount of items + can be assigned through-out all the lists. Each item in + each list contains a UINT32 specified by the software using + the lists. Each used item in the list is accessible through + it's position in the list. */ + +typedef struct _LLM_LIST_HEAD +{ + UINT32 list_length; /* Current number of items in the list.*/ + /* 0xFFFFFFFF means that the list is not used.*/ + UINT32 head_pointer; /* Number of the item in the item pool that is the first of this list.*/ + /* 0xFFFFFFFF indicates end-of-list link.*/ + UINT32 tail_pointer; /* Number of the item in the item pool that is the last of this list.*/ + + /* Item cache (pointer within the list of the last accessed item):*/ + UINT32 cache_item_number; /* Number of the last accessed item in the list. 0xFFFFFFFF indicates invalid cache.*/ + UINT32 cache_item_pointer; /* Number of the last accessed item in the item pool.*/ +} LLM_LIST_HEAD; + +typedef struct _LLM_LIST_ITEM +{ + UINT32 forward_link; /* Number of the item in the item pool that is next in this list.*/ + /* 0xFFFFFFFF indicates end-of-list link.*/ + + /* User item info (variable size)*/ + UINT32 user_info[1]; +} LLM_LIST_ITEM; + +typedef struct _LLM_LIST +{ + UINT32 user_info_bytes; /* In bytes, size of the user info in a single item.*/ + UINT32 user_info_size; /* In bytes, size of the user info in a single item.*/ + UINT32 item_size; + + UINT32 head_alloc_size; + UINT32 total_items; + UINT32 assigned_items; + + UINT32 total_lists; + UINT32 assigned_lists; + + UINT32 next_empty_item; /* Contains a pointer to the next empty item in the*/ + /* item pool.*/ + + /* Table of all the possible list heads:*/ + LLM_LIST_HEAD * lh; + void * list_head_alloc; /* LLM_ALLOC structure used for list head allocation!*/ + + /* Table of the list items:*/ + LLM_LIST_ITEM * li; +} LLM_LIST; + + +/**********************************************************************************/ +/* These structures are are used by the Llm2 functions to creates lists of ordered + items based on a key given by the user when a new node is inserted in a list. */ +typedef struct _LLM2_LIST_HEAD +{ + UINT32 list_length; /* Current number of items in the list.*/ + /* 0xFFFFFFFF means that the list is not used.*/ + UINT32 head_pointer; /* Number of the item in the item pool that is the first of this list.*/ + /* 0xFFFFFFFF indicates end-of-list link.*/ + UINT32 tail_pointer; /* Number of the item in the item pool that is the last of this list.*/ + +} LLM2_LIST_HEAD; + +typedef struct _LLM2_LIST_ITEM +{ + UINT32 forward_link; /* Number of the item in the item pool that is next in this list.*/ + /* 0xFFFFFFFF indicates end-of-list link.*/ + UINT32 key; /* Key used to order the entries.*/ + + /* User item info (variable size)*/ + UINT32 user_info[1]; +} LLM2_LIST_ITEM; + +typedef struct _LLM2_LIST +{ + UINT32 user_info_bytes; /* In bytes, size of the user info in a single item.*/ + UINT32 user_info_size; /* In bytes, size of the user info in a single item.*/ + UINT32 item_size; + + UINT32 head_alloc_size; + UINT32 total_items; + UINT32 assigned_items; + + UINT32 total_lists; + UINT32 assigned_lists; + + UINT32 next_empty_item; /* Contains a pointer to the next empty item in the*/ + /* item pool.*/ + + /* Table of all the possible list heads:*/ + LLM2_LIST_HEAD * lh; + void * list_head_alloc; /* LLM_ALLOC structure used for list head allocation!*/ + + /* Table of the list items:*/ + LLM2_LIST_ITEM * li; +} LLM2_LIST; + +/*void octapi_llm_list_build_structure(void *l, LLM_LIST ** ls);*/ +LLM_LIST_ITEM * OctApiLlmListGetItemPointer( LLM_LIST * ls, UINT32 item_number ); +LLM2_LIST_ITEM * OctApiLlm2ListGetItemPointer( LLM2_LIST * ls, UINT32 item_number ); +UINT32 OctApiTllmCheckTimeoutList( TLLM_ALLOC *ls, UINT32 current_time[2] ); +VOID * OctApiLlmMemCpy( VOID *f_pvDestination, const VOID * f_pvSource, UINT32 f_ulSize ); +/**************************************** llm_list section **********************************************/ + + + + + +#endif /*__OCTAPI_LLMAN_PRIVATE_H__*/ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/get_discards dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/get_discards --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/get_discards 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/get_discards 2006-08-25 19:06:38.000000000 -0500 @@ -0,0 +1,51 @@ +#!/usr/bin/php + + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/apilib/octapi_bt0.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/apilib/octapi_bt0.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/apilib/octapi_bt0.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/apilib/octapi_bt0.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,75 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_bt0.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to manage a binary tree of variable max size. Library is + made to use one block of contiguous memory to manage the tree. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_BT0_H__ +#define __OCTAPI_BT0_H__ + +#include "octdef.h" + +#define OCTAPI_BT0_BASE 0xFFFF0000 +#define OCTAPI_BT0_KEY_SIZE_NOT_MUTLIPLE_OF_UINT32 OCTAPI_BT0_BASE+0x0001 +#define OCTAPI_BT0_DATA_SIZE_NOT_MUTLIPLE_OF_UINT32 OCTAPI_BT0_BASE+0x0002 +#define OCTAPI_BT0_MALLOC_FAILED OCTAPI_BT0_BASE+0x0003 +#define OCTAPI_BT0_NO_NODES_AVAILABLE OCTAPI_BT0_BASE+0x0004 +#define OCTAPI_BT0_KEY_ALREADY_IN_TREE OCTAPI_BT0_BASE+0x0005 +#define OCTAPI_BT0_KEY_NOT_IN_TREE OCTAPI_BT0_BASE+0x0006 + +/* Possible result for Find Or Add function. */ +#define OCTAPI0_BT0_NODE_FOUND 0 +#define OCTAPI0_BT0_NODE_ADDDED 1 + +#define OCTAPI_BT0_NO_SMALLER_KEY 0xAAAAAAAA + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define octapi_bt0_get_size( number_of_items, key_size, data_size, b_size ) OctApiBt0GetSize( (UINT32) number_of_items,(UINT32) key_size, (UINT32) data_size, (PUINT32) b_size ) +#define octapi_bt0_init( b, number_of_items, key_size, data_size ) OctApiBt0Init( (void **) b,(UINT32) number_of_items,(UINT32) key_size, (UINT32) data_size ) +#define octapi_bt0_add_node( b, key, data ) OctApiBt0AddNode( (void *) b,(void *) key,(void **) data ) +#define octapi_bt0_remove_node( b, key ) OctApiBt0RemoveNode( (void *) b,(void *) key ) +#define octapi_bt0_query_node( b, key, data ) OctApiBt0QueryNode( (void *) b,(void *) key,(void **) data ) +#define octapi_bt0_get_first_node( b, key, data ) OctApiBt0GetFirstNode( (void *) b,(void **) key, (void **) data ) + +UINT32 OctApiBt0GetSize( UINT32 number_of_items, UINT32 key_size, UINT32 data_size, UINT32 * b_size ); +UINT32 OctApiBt0Init( void ** b, UINT32 number_of_items, UINT32 key_size, UINT32 data_size ); +UINT32 OctApiBt0AddNode( void * b, void * key, void ** data ); +UINT32 OctApiBt0RemoveNode( void * b, void * key ); +UINT32 OctApiBt0QueryNode( void * b, void * key, void ** data ); +UINT32 OctApiBt0GetFirstNode( void * b, void ** key, void ** data ); +UINT32 OctApiBt0FindOrAddNode( void * b, void * key, void ** data, UINT32 *fnct_result ); + +UINT32 OctApiBt0AddNodeReportPrevNodeData( void * b, void * key, void ** data, void ** prev_data, UINT32 *fnct_result ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /*__OCTAPI_BT0_H__*/ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/apilib/octapi_largmath.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/apilib/octapi_largmath.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/apilib/octapi_largmath.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/apilib/octapi_largmath.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,69 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_largmath.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to perform arithmetic on integer values of an integer multiple + of 32-bits. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_LARGMATH_H__ +#define __OCTAPI_LARGMATH_H__ + +#include "octdef.h" + +#define OCTAPI_LM_DIVISION_BY_ZERO 0xFFFF +#define OCTAPI_LM_OVERFLOW 0xFFFE +#define OCTAPI_LM_ARRAY_SIZE_MISMATCH 0xFFFD + +#define OCTAPI_LM_MAX_OPTIMIZE_MUL 10 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define octapi_lm_add( a, alen, b, blen, z, zlen ) OctApiLmAdd( (PUINT32) a, (USHORT) alen, (PUINT32) b, (USHORT) blen, (PUINT32) z, (USHORT) zlen ) +#define octapi_lm_subtract( a, alen, bneg, blen, z, zlen, neg ) OctApiLmSubtract( (PUINT32) a, (USHORT) alen, (PUINT32) bneg, (USHORT) blen, (PUINT32) z, (USHORT) zlen, (USHORT*) neg ) +#define octapi_lm_compare( a, alen, bneg, blen, neg ) OctApiLmCompare( (PUINT32) a, (USHORT) alen, (PUINT32) bneg, (USHORT) blen, (USHORT*) neg ) +#define octapi_lm_multiply( a, b, ablen, z ) OctApiLmMultiply( (PUINT32) a, (PUINT32) b, (USHORT) ablen, (PUINT32) z ) +#define octapi_lm_divide( n, d, q, r, ndqrlen ) OctApiLmDivide( (PUINT32) n, (PUINT32) d, (PUINT32) q, (PUINT32) r, (USHORT) ndqrlen ) +#define octapi_lm_shiftright1( a, alen ) OctApiLmShiftRight1( (PUINT32) a, (USHORT) alen ) +#define octapi_lm_shiftn( a, alen, shiftleft, shiftn ) OctApiLmShiftn( (PUINT32) a, (USHORT) alen, (USHORT) shiftleft, (USHORT) shiftn ) +#define octapi_lm_getmsb( a, alen, msb_pos ) OctApiLmGetMsb( (PUINT32) a, (USHORT) alen, (USHORT*) msb_pos ) + + +UINT32 OctApiLmAdd( PUINT32 a, USHORT alen, PUINT32 b, USHORT blen, PUINT32 z, USHORT zlen ); +UINT32 OctApiLmSubtract( PUINT32 a, USHORT alen, PUINT32 bneg, USHORT blen, PUINT32 z, USHORT zlen, PUSHORT neg ); +UINT32 OctApiLmCompare( PUINT32 a, USHORT alen, PUINT32 bneg, USHORT blen, PUSHORT neg ); +UINT32 OctApiLmMultiply( PUINT32 a, PUINT32 b, USHORT ablen, PUINT32 z ); +UINT32 OctApiLmDivide( PUINT32 n, PUINT32 d, PUINT32 q, PUINT32 r, USHORT ndqrlen ); +UINT32 OctApiLmShiftRight1( PUINT32 a, USHORT alen ); +UINT32 OctApiLmShiftn( PUINT32 a, USHORT alen, USHORT shiftleft, USHORT shiftn ); +UINT32 OctApiLmGetMsb( PUINT32 a, USHORT alen, PUSHORT msb_pos ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __OCTAPI_LARGMATH_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/apilib/octapi_llman.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/apilib/octapi_llman.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/apilib/octapi_llman.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/apilib/octapi_llman.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,142 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octapi_llman.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Library used to manage allocation tables and linked lists. The library is + made such that only a block of contiguous memory is needed for the + management of the linked list/allocation table. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 8 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTAPI_LLMAN_H__ +#define __OCTAPI_LLMAN_H__ + +#include "octdef.h" + +/* Error defines. */ +#define OCTAPI_LLM_MEMORY_NOT_ALLOCATED 0xFFFFFFFF +#define OCTAPI_LLM_NO_STRUCTURES_LEFT 0xFFFFFFFE +#define OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE 0xFFFFFFFD +#define OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED 0xFFFFFFFC +#define OCTAPI_LLM_ELEMENT_NOT_FOUND 0xFFFFFFFB +#define OCTAPI_LLM_LIST_EMPTY 0xFFFFFFFA +#define OCTAPI_LLM_INVALID_LIST_HANDLE 0xFFFFFFF9 +#define OCTAPI_LLM_TREE_NODE_ABSENT 0xFFFFFFF8 +#define OCTAPI_LLM_INTERNAL_ERROR0 0xFFFFFFF7 +#define OCTAPI_LLM_INTERNAL_ERROR1 0xFFFFFFF6 +#define OCTAPI_LLM_INVALID_PARAMETER 0xFFFFFFF5 + +#define OCTAPI_LLM2_MEMORY_NOT_ALLOCATED 0xFEFFFFFF +#define OCTAPI_LLM2_NO_STRUCTURES_LEFT 0xFEFFFFFE +#define OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE 0xFEFFFFFD +#define OCTAPI_LLM2_ELEMENT_ALREADY_ASSIGNED 0xFEFFFFFC +#define OCTAPI_LLM2_ELEMENT_NOT_FOUND 0xFEFFFFFB +#define OCTAPI_LLM2_LIST_EMPTY 0xFEFFFFFA +#define OCTAPI_LLM2_INVALID_LIST_HANDLE 0xFEFFFFF9 +#define OCTAPI_LLM2_TREE_NODE_ABSENT 0xFEFFFFF8 +#define OCTAPI_LLM2_INTERNAL_ERROR0 0xFEFFFFF7 +#define OCTAPI_LLM2_INTERNAL_ERROR1 0xFEFFFFF6 +#define OCTAPI_LLM2_INVALID_PARAMETER 0xFEFFFFF5 + +/* Other defines. */ +#define OCTAPI_LLM_LIST_APPEND 0xFFFFFFFF +#define OCTAPI_LLM2_INSERT_ERROR 0xFFFFFFFF +#define OCTAPI_LLM2_INSERT_FIRST_NODE 0xFFFF0000 +#define OCTAPI_LLM2_INSERT_LIST_NODE 0xFFFF0001 +#define OCTAPI_LLM2_INSERT_LAST_NODE 0xFFFF0002 +#define OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE 0xFFFF0003 +#define OCTAPI_LLM2_REMOVE_ERROR 0xFFFFFFFF +#define OCTAPI_LLM2_REMOVE_FIRST_NODE 0xFFFF0004 +#define OCTAPI_LLM2_REMOVE_LIST_NODE 0xFFFF0005 +#define OCTAPI_LLM2_REMOVE_LAST_NODE 0xFFFF0006 +#define OCTAPI_LLM2_REMOVE_BEFORE_LAST_NODE 0xFFFF0007 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define octapi_llm_alloc_get_size( number_of_items, l_size ) OctapiLlmAllocGetSize( (UINT32) number_of_items,(PUINT32) l_size ) +#define octapi_llm_alloc_init( l, number_of_items ) OctapiLlmAllocInit( (PVOID*) l,(UINT32) number_of_items ) +#define octapi_llm_alloc_info( l, allocated_items, available_items ) OctapiLlmAllocInfo( (PVOID) l, (PUINT32) allocated_items, (PUINT32) available_items ) +#define octapi_llm_alloc_alloc( l, blocknum ) OctapiLlmAllocAlloc( (PVOID) l, (PUINT32) blocknum ) +#define octapi_llm_alloc_dealloc( l, blocknum ) OctapiLlmAllocDealloc( (PVOID) l,(UINT32) blocknum ) +#define octapi_llm_list_get_size( number_of_items, number_of_lists, user_info_size, l_size ) OctApiLlmListGetSize( (UINT32) number_of_items,(UINT32) number_of_lists,(UINT32) user_info_size,(PUINT32) l_size ) +#define octapi_llm_list_init( l, number_of_items, number_of_lists, user_info_size ) OctApiLlmListInit( (PVOID*) l,(UINT32) number_of_items,(UINT32) number_of_lists,(UINT32) user_info_size ) +#define octapi_llm_list_info( l, allocated_lists, allocated_items, free_lists, free_items ) OctApiLlmListInfo( (PVOID) l,(PUINT32) allocated_lists,(PUINT32) allocated_items,(PUINT32) free_lists,(PUINT32) free_items ) +#define octapi_llm_list_create( l, list_handle ) OctApiLlmListCreate( (PVOID) l,(PUINT32) list_handle ) +#define octapi_llm_list_create_full( l, list_length, plist_handle ) OctApiLlmListCreateFull( (PVOID) l, (UINT32) list_length, (PUINT32) plist_handle ) +#define octapi_llm_list_append_items( l, list_handle, num_items ) OctApiLlmListAppendItems( (PVOID) l, (UINT32) list_handle, (UINT32) num_items ) +#define octapi_llm_list_append_and_set_items( l, list_handle, num_items, data_list ) OctApiLlmListAppendAndSetItems( (PVOID) l, (UINT32) list_handle, (UINT32) num_items, (PVOID) data_list ) +#define octapi_llm_list_delete( l, list_handle ) OctApiLlmListDelete( (PVOID) l,(UINT32) list_handle ) +#define octapi_llm_list_length( l, list_handle, number_of_items_in_list ) OctApiLlmListLength( (PVOID) l,(UINT32) list_handle, (PUINT32) number_of_items_in_list ) +#define octapi_llm_list_insert_item( l, list_handle, item_number, item_data_pnt ) OctApiLlmListInsertItem( (PVOID) l,(UINT32) list_handle,(UINT32) item_number,(PVOID*) item_data_pnt ) +#define octapi_llm_list_remove_item( l, list_handle, item_number ) OctApiLlmListRemoveItem( (PVOID) l,(UINT32) list_handle,(UINT32) item_number ) +#define octapi_llm_list_item_data( l, list_handle, item_number, item_data_pnt ) OctApiLlmListItemData( (PVOID) l,(UINT32) list_handle,(UINT32) item_number,(PVOID*) item_data_pnt ) +#define octapi_llm_list_copy_data( l, list_handle, start_item, data_length, pdata_list ) OctApiLlmListCopyData( (PVOID) l, (UINT32) list_handle, (UINT32) start_item, (UINT32) data_length, (PVOID) pdata_list ) +#define octapi_llm_list_set_items( l, list_handle, start_item, data_length, pdata_list ) OctApiLlmListSetItems( (PVOID) l, (UINT32) list_handle, (UINT32) start_item, (UINT32) data_length, (PVOID) pdata_list ) + +/* Alloc man. */ +UINT32 OctapiLlmAllocGetSize( UINT32 number_of_items,PUINT32 l_size ); +UINT32 OctapiLlmAllocInit( PVOID* l,UINT32 number_of_items ); +UINT32 OctapiLlmAllocInfo( PVOID l, PUINT32 allocated_items, PUINT32 available_items ); +UINT32 OctapiLlmAllocAlloc( PVOID l, PUINT32 blocknum ); +UINT32 OctapiLlmAllocDealloc( PVOID l,UINT32 blocknum ); + +/* Time managed alloc man. */ +UINT32 OctApiTllmAllocGetSize( UINT32 number_of_items, PUINT32 l_size ); +UINT32 OctApiTllmAllocInit( PVOID* l, UINT32 number_of_items ); +UINT32 OctApiTllmAllocInfo( PVOID l, PUINT32 allocated_items, PUINT32 available_items ); +UINT32 OctApiTllmAllocAlloc( PVOID l, PUINT32 blocknum, UINT32 current_time[2] ); +UINT32 OctApiTllmAllocDealloc( PVOID l, UINT32 blocknum, UINT32 timeout_value, UINT32 current_time[2] ); + +/* List man. */ +UINT32 OctApiLlmListGetSize( UINT32 number_of_items, UINT32 number_of_lists, UINT32 user_info_size, PUINT32 l_size ); +UINT32 OctApiLlmListInit( PVOID* l, UINT32 number_of_items, UINT32 number_of_lists, UINT32 user_info_size ); +UINT32 OctApiLlmListInfo( PVOID l, PUINT32 allocated_lists, PUINT32 allocated_items, PUINT32 free_lists, PUINT32 free_items ); +UINT32 OctApiLlmListCreate( PVOID l, PUINT32 list_handle ); +UINT32 OctApiLlmListCreateFull( PVOID l, UINT32 list_length, UINT32* plist_handle ); +UINT32 OctApiLlmListAppendItems( PVOID l, UINT32 list_handle, UINT32 num_items ); +UINT32 OctApiLlmListAppendAndSetItems( PVOID l, UINT32 list_handle, UINT32 num_items, PVOID data_list ); +UINT32 OctApiLlmListDelete( PVOID l, UINT32 list_handle ); +UINT32 OctApiLlmListLength( PVOID l, UINT32 list_handle, PUINT32 number_of_items_in_list ); +UINT32 OctApiLlmListInsertItem( PVOID l, UINT32 list_handle, UINT32 item_number, PVOID* item_data_pnt ); +UINT32 OctApiLlmListRemoveItem( PVOID l, UINT32 list_handle, UINT32 item_number ); +UINT32 OctApiLlmListItemData( PVOID l, UINT32 list_handle, UINT32 item_number, PVOID* item_data_pnt ); +UINT32 OctApiLlmListCopyData( PVOID l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, PVOID pdata_list ); +UINT32 OctApiLlmListSetItems( PVOID l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, PVOID pdata_list ); + +/* Second list manager using a key to order info in the list. */ +UINT32 OctApiLlm2ListGetSize( UINT32 number_of_items, UINT32 number_of_lists, UINT32 user_info_size, PUINT32 l_size ); +UINT32 OctApiLlm2ListInit( PVOID* l,UINT32 number_of_items, UINT32 number_of_lists, UINT32 user_info_size ); +UINT32 OctApiLlm2ListCreate( PVOID l, PUINT32 list_handle ); +UINT32 OctApiLlm2ListLength( PVOID l, UINT32 list_handle, PUINT32 number_of_items_in_list ); +UINT32 OctApiLlm2ListInsertItem(void * l, UINT32 list_handle, UINT32 item_key, void ** item_data_pnt, void ** prev_item_data_pnt, void ** prev_prev_item_data_pnt, PUINT32 insert_status_pnt ); +UINT32 OctApiLlm2ListRemoveItem(void * l, UINT32 list_handle, UINT32 item_key, PUINT32 prev_item_key_pnt, PUINT32 prev_prev_item_key_pnt, PUINT32 remove_status_pnt ); +UINT32 OctApiLlm2ListItemData( PVOID l, UINT32 list_handle, UINT32 item_key, PVOID* item_data_pnt, PUINT32 item_number ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __OCTAPI_LLMAN_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/digium_unused.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/digium_unused.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/digium_unused.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/digium_unused.h 2007-01-18 15:06:01.000000000 -0600 @@ -0,0 +1,297 @@ +/* Define macros here to suppress functions from the API being built */ + +#if 1 + +#define SKIP_Oct6100AdpcmChanOpenDef 1 +#define SKIP_Oct6100AdpcmChanOpen 1 +#define SKIP_Oct6100AdpcmChanCloseDef 1 +#define SKIP_Oct6100AdpcmChanClose 1 +#define SKIP_Oct6100AdpcmChanOpenSer 1 +#define SKIP_Oct6100ApiCheckAdpcmChanParams 1 +#define SKIP_Oct6100ApiReserveAdpcmChanResources 1 +#define SKIP_Oct6100ApiWriteAdpcmChanStructs 1 +#define SKIP_Oct6100ApiUpdateAdpcmChanEntry 1 +#define SKIP_Oct6100AdpcmChanCloseSer 1 +#define SKIP_Oct6100ApiAssertAdpcmChanParams 1 +#define SKIP_Oct6100ApiInvalidateAdpcmChanStructs 1 +#define SKIP_Oct6100ApiReleaseAdpcmChanResources 1 +#define SKIP_Oct6100ApiReserveAdpcmChanEntry 1 +#define SKIP_Oct6100ApiReleaseAdpcmChanEntry 1 +#define SKIP_Oct6100ChannelCloseDef 1 +#define SKIP_Oct6100ChannelClose 1 +#define SKIP_Oct6100ChannelCreateBiDirDef 1 +#define SKIP_Oct6100ChannelCreateBiDir 1 +#define SKIP_Oct6100ChannelDestroyBiDirDef 1 +#define SKIP_Oct6100ChannelDestroyBiDir 1 +#define SKIP_Oct6100ChannelBroadcastTsstAddDef 1 +#define SKIP_Oct6100ChannelBroadcastTsstAdd 1 +#define SKIP_Oct6100ChannelBroadcastTsstRemove 1 +#define SKIP_Oct6100ChannelGetStatsDef 1 +#define SKIP_Oct6100ChannelGetStats 1 +#define SKIP_Oct6100ChannelMuteDef 1 +#define SKIP_Oct6100ChannelMute 1 +#define SKIP_Oct6100ChannelUnMuteDef 1 +#define SKIP_Oct6100ChannelUnMute 1 +#define SKIP_Oct6100ChannelCloseSer 1 +#define SKIP_Oct6100ApiAssertChannelParams 1 +#define SKIP_Oct6100ApiInvalidateChannelStructs 1 +#define SKIP_Oct6100ApiReleaseChannelResources 1 +#define SKIP_Oct6100ChannelBroadcastTsstAddSer 1 +#define SKIP_Oct6100ApiCheckChanTsstAddParams 1 +#define SKIP_Oct6100ApiReserveTsstAddResources 1 +#define SKIP_Oct6100ApiWriteTsstAddStructs 1 +#define SKIP_Oct6100ApiUpdateTsstAddChanEntry 1 +#define SKIP_Oct6100ApiChannelGetStatsSer 1 +#define SKIP_Oct6100ApiReserveBiDirChanEntry 1 +#define SKIP_Oct6100ApiReleaseBiDirChanEntry 1 +#define SKIP_Oct6100ApiRetrieveNlpConfDword 1 +#define SKIP_Oct6100ApiSaveNlpConfDword 1 +#define SKIP_Oct6100ChannelCreateBiDirSer 1 +#define SKIP_Oct6100ApiCheckChannelCreateBiDirParams 1 +#define SKIP_Oct6100ApiReserveChannelCreateBiDirResources 1 +#define SKIP_Oct6100ApiWriteChannelCreateBiDirStructs 1 +#define SKIP_Oct6100ApiUpdateBiDirChannelEntry 1 +#define SKIP_Oct6100ChannelDestroyBiDirSer 1 +#define SKIP_Oct6100ApiAssertDestroyBiDirChanParams 1 +#define SKIP_Oct6100ApiInvalidateBiDirChannelStructs 1 +#define SKIP_Oct6100ApiReleaseBiDirChannelResources 1 +#define SKIP_Oct6100ApiOctFloatToDbEnergyByte 1 +#define SKIP_Oct6100ApiOctFloatToDbEnergyHalf 1 +#define SKIP_Oct6100ChannelMuteSer 1 +#define SKIP_Oct6100ApiAssertChannelMuteParams 1 +#define SKIP_Oct6100ChannelUnMuteSer 1 +#define SKIP_Oct6100ApiAssertChannelUnMuteParams 1 +#define SKIP_Oct6100ApiMuteSinWithFeatures 1 +#define SKIP_Oct6100ApiMuteChannelPorts 1 +#define SKIP_Oct6100CreateLocalInstanceDef 1 +#define SKIP_Oct6100CreateLocalInstance 1 +#define SKIP_Oct6100DestroyLocalInstanceDef 1 +#define SKIP_Oct6100DestroyLocalInstance 1 +#define SKIP_Oct6100GetHwRevisionDef 1 +#define SKIP_Oct6100GetHwRevision 1 +#define SKIP_Oct6100FreeResourcesDef 1 +#define SKIP_Oct6100FreeResources 1 +#define SKIP_Oct6100ProductionBistDef 1 +#define SKIP_Oct6100ProductionBist 1 +#define SKIP_Oct6100ApiGetVersionDef 1 +#define SKIP_Oct6100ApiGetVersion 1 +#define SKIP_Oct6100FreeResourcesSer 1 +#define SKIP_Oct6100ProductionBistSer 1 +#define SKIP_Oct6100ChipGetStatsDef 1 +#define SKIP_Oct6100ChipGetStats 1 +#define SKIP_Oct6100ChipGetImageInfoDef 1 +#define SKIP_Oct6100ChipGetImageInfo 1 +#define SKIP_Oct6100ChipGetStatsSer 1 +#define SKIP_Oct6100ConfBridgeOpenDef 1 +#define SKIP_Oct6100ConfBridgeOpen 1 +#define SKIP_Oct6100ConfBridgeClose 1 +#define SKIP_Oct6100ConfBridgeChanAddDef 1 +#define SKIP_Oct6100ConfBridgeChanAdd 1 +#define SKIP_Oct6100ConfBridgeChanRemove 1 +#define SKIP_Oct6100ConfBridgeChanMuteDef 1 +#define SKIP_Oct6100ConfBridgeChanMute 1 +#define SKIP_Oct6100ConfBridgeChanUnMuteDef 1 +#define SKIP_Oct6100ConfBridgeChanUnMute 1 +#define SKIP_Oct6100ConfBridgeDominantSpeakerSetDef 1 +#define SKIP_Oct6100ConfBridgeDominantSpeakerSet 1 +#define SKIP_Oct6100ConfBridgeMaskChangeDef 1 +#define SKIP_Oct6100ConfBridgeMaskChange 1 +#define SKIP_Oct6100ConfBridgeGetStatsDef 1 +#define SKIP_Oct6100ConfBridgeGetStats 1 +#define SKIP_Oct6100ConfBridgeOpenSer 1 +#define SKIP_Oct6100ApiCheckBridgeParams 1 +#define SKIP_Oct6100ApiReserveBridgeResources 1 +#define SKIP_Oct6100ApiUpdateBridgeEntry 1 +#define SKIP_Oct6100ConfBridgeChanAddSer 1 +#define SKIP_Oct6100ApiCheckBridgeAddParams 1 +#define SKIP_Oct6100ApiReserveBridgeAddResources 1 +#define SKIP_Oct6100ApiBridgeEventAdd 1 +#define SKIP_Oct6100ApiBridgeAddParticipantToChannel 1 +#define SKIP_Oct6100ConfBridgeChanMuteSer 1 +#define SKIP_Oct6100ApiCheckBridgeMuteParams 1 +#define SKIP_Oct6100ApiUpdateBridgeMuteResources 1 +#define SKIP_Oct6100ConfBridgeChanUnMuteSer 1 +#define SKIP_Oct6100ApiCheckBridgeUnMuteParams 1 +#define SKIP_Oct6100ApiUpdateBridgeUnMuteResources 1 +#define SKIP_Oct6100ConfBridgeDominantSpeakerSetSer 1 +#define SKIP_Oct6100ApiCheckBridgeDominantSpeakerParams 1 +#define SKIP_Oct6100ApiUpdateBridgeDominantSpeakerResources 1 +#define SKIP_Oct6100ConfBridgeMaskChangeSer 1 +#define SKIP_Oct6100ApiCheckBridgeMaskChangeParams 1 +#define SKIP_Oct6100ApiUpdateMaskModifyResources 1 +#define SKIP_Oct6100ApiBridgeUpdateMask 1 +#define SKIP_Oct6100ConfBridgeGetStatsSer 1 +#define SKIP_Oct6100ApiReserveBridgeEntry 1 +#define SKIP_Oct6100ApiReserveFlexConfParticipantEntry 1 +#define SKIP_Oct6100DebugSelectChannelDef 1 +#define SKIP_Oct6100DebugSelectChannel 1 +#define SKIP_Oct6100DebugGetDataDef 1 +#define SKIP_Oct6100DebugGetData 1 +#define SKIP_Oct6100DebugSelectChannelSer 1 +#define SKIP_Oct6100DebugGetDataSer 1 +#define SKIP_Oct6100BufferPlayoutGetEventDef 1 +#define SKIP_Oct6100BufferPlayoutGetEvent 1 +#define SKIP_Oct6100BufferPlayoutGetEventSer 1 +#define SKIP_Oct6100InterruptConfigureDef 1 +#define SKIP_Oct6100InterruptConfigure 1 +#define SKIP_Oct6100ApiReserveBufferPlayoutMemoryNode 1 +#define SKIP_Oct6100ApiReleaseBufferPlayoutMemoryNode 1 +#define SKIP_Oct6100ApiReserveBufferPlayoutMemory 1 +#define SKIP_Oct6100ApiReleaseBufferPlayoutMemory 1 +#define SKIP_Oct6100ApiCreateFeatureMask 1 +#define SKIP_Oct6100MixerCopyEventCreateDef 1 +#define SKIP_Oct6100MixerCopyEventCreate 1 +#define SKIP_Oct6100MixerCopyEventDestroyDef 1 +#define SKIP_Oct6100MixerCopyEventDestroy 1 +#define SKIP_Oct6100MixerCopyEventCreateSer 1 +#define SKIP_Oct6100ApiCheckCopyEventCreateParams 1 +#define SKIP_Oct6100ApiReserveCopyEventCreateResources 1 +#define SKIP_Oct6100ApiWriteCopyEventCreateStructs 1 +#define SKIP_Oct6100ApiUpdateCopyEventCreateEntry 1 +#define SKIP_Oct6100MixerCopyEventDestroySer 1 +#define SKIP_Oct6100ApiAssertCopyEventDestroyParams 1 +#define SKIP_Oct6100ApiInvalidateCopyEventStructs 1 +#define SKIP_Oct6100ApiReleaseCopyEventResources 1 +#define SKIP_Oct6100ApiReserveCopyEventEntry 1 +#define SKIP_Oct6100ApiReleaseCopyEventEntry 1 +#define SKIP_Oct6100PhasingTsstOpenDef 1 +#define SKIP_Oct6100PhasingTsstOpen 1 +#define SKIP_Oct6100PhasingTsstCloseDef 1 +#define SKIP_Oct6100PhasingTsstClose 1 +#define SKIP_Oct6100PhasingTsstOpenSer 1 +#define SKIP_Oct6100ApiCheckPhasingParams 1 +#define SKIP_Oct6100ApiReservePhasingResources 1 +#define SKIP_Oct6100ApiWritePhasingStructs 1 +#define SKIP_Oct6100ApiUpdatePhasingEntry 1 +#define SKIP_Oct6100PhasingTsstCloseSer 1 +#define SKIP_Oct6100ApiAssertPhasingParams 1 +#define SKIP_Oct6100ApiInvalidatePhasingStructs 1 +#define SKIP_Oct6100ApiReleasePhasingResources 1 +#define SKIP_Oct6100ApiReservePhasingEntry 1 +#define SKIP_Oct6100ApiReleasePhasingEntry 1 +#define SKIP_Oct6100BufferPlayoutLoadDef 1 +#define SKIP_Oct6100BufferPlayoutLoad 1 +#define SKIP_Oct6100BufferPlayoutLoadBlockInitDef 1 +#define SKIP_Oct6100BufferPlayoutLoadBlockInit 1 +#define SKIP_Oct6100BufferPlayoutLoadBlockDef 1 +#define SKIP_Oct6100BufferPlayoutLoadBlock 1 +#define SKIP_Oct6100BufferPlayoutUnloadDef 1 +#define SKIP_Oct6100BufferPlayoutUnload 1 +#define SKIP_Oct6100BufferPlayoutAddDef 1 +#define SKIP_Oct6100BufferPlayoutAdd 1 +#define SKIP_Oct6100BufferPlayoutStartDef 1 +#define SKIP_Oct6100BufferPlayoutStart 1 +#define SKIP_Oct6100BufferPlayoutStop 1 +#define SKIP_Oct6100BufferLoadSer 1 +#define SKIP_Oct6100BufferLoadBlockInitSer 1 +#define SKIP_Oct6100BufferLoadBlockSer 1 +#define SKIP_Oct6100ApiCheckBufferParams 1 +#define SKIP_Oct6100ApiCheckBufferLoadBlockParams 1 +#define SKIP_Oct6100ApiReserveBufferResources 1 +#define SKIP_Oct6100ApiWriteBufferInMemory 1 +#define SKIP_Oct6100ApiUpdateBufferEntry 1 +#define SKIP_Oct6100BufferUnloadSer 1 +#define SKIP_Oct6100ApiAssertBufferParams 1 +#define SKIP_Oct6100ApiReleaseBufferResources 1 +#define SKIP_Oct6100BufferPlayoutAddSer 1 +#define SKIP_Oct6100ApiCheckPlayoutAddParams 1 +#define SKIP_Oct6100ApiWriteBufferAddStructs 1 +#define SKIP_Oct6100BufferPlayoutStartSer 1 +#define SKIP_Oct6100ApiCheckPlayoutStartParams 1 +#define SKIP_Oct6100ApiWriteChanPlayoutStructs 1 +#define SKIP_Oct6100ApiReserveBufPlayoutListEntry 1 +#define SKIP_Oct6100ApiReleaseBufPlayoutListEntry 1 +#define SKIP_Oct6100RemoteDebugDef 1 +#define SKIP_Oct6100RemoteDebug 1 +#define SKIP_Oct6100ApiCheckEndianDetectField 1 +#define SKIP_Oct6100ApiCalculateChecksum 1 +#define SKIP_Oct6100ApiFormResponsePkt 1 +#define SKIP_Oct6100ApiCheckPktCommands 1 +#define SKIP_Oct6100ApiExecutePktCommands 1 +#define SKIP_Oct6100ApiCheckSessionNum 1 +#define SKIP_Oct6100ApiRpcReadWord 1 +#define SKIP_Oct6100ApiRpcReadBurst 1 +#define SKIP_Oct6100ApiRpcReadArray 1 +#define SKIP_Oct6100ApiRpcWriteWord 1 +#define SKIP_Oct6100ApiRpcWriteSmear 1 +#define SKIP_Oct6100ApiRpcWriteBurst 1 +#define SKIP_Oct6100ApiRpcSetHotChannel 1 +#define SKIP_Oct6100ApiRpcGetDebugChanIndex 1 +#define SKIP_Oct6100ApiRpcDisconnect 1 +#define SKIP_Oct6100ToneDetectionDisable 1 +#define SKIP_Oct6100TsiCnctOpenDef 1 +#define SKIP_Oct6100TsiCnctOpen 1 +#define SKIP_Oct6100TsiCnctCloseDef 1 +#define SKIP_Oct6100TsiCnctClose 1 +#define SKIP_Oct6100TsiCnctOpenSer 1 +#define SKIP_Oct6100ApiCheckTsiParams 1 +#define SKIP_Oct6100ApiReserveTsiResources 1 +#define SKIP_Oct6100ApiWriteTsiStructs 1 +#define SKIP_Oct6100ApiUpdateTsiEntry 1 +#define SKIP_Oct6100TsiCnctCloseSer 1 +#define SKIP_Oct6100ApiAssertTsiParams 1 +#define SKIP_Oct6100ApiInvalidateTsiStructs 1 +#define SKIP_Oct6100ApiReleaseTsiResources 1 +#define SKIP_Oct6100ApiReserveTsiCnctEntry 1 +#define SKIP_Oct6100ApiReleaseTsiCnctEntry 1 +#define SKIP_Oct6100UserDriverWriteOs 1 +#define SKIP_Oct6100UserDriverWriteSmearOs 1 +#define SKIP_Oct6100UserDriverWriteBurstOs 1 +#define SKIP_Oct6100UserDriverReadOs 1 +#define SKIP_Oct6100UserDriverReadBurstOs 1 +#define SKIP_OctApiBt0AddNode 1 +#define SKIP_OctApiBt0AddNode2 1 +#define SKIP_OctApiBt0AddNode3 1 +#define SKIP_OctApiBt0AddNode4 1 +#define SKIP_OctApiBt0KeyCompare 1 +#define SKIP_OctApiBt0UpdateLinkDepth 1 +#define SKIP_OctApiBt0Rebalance 1 +#define SKIP_OctApiBt0ExternalHeavy 1 +#define SKIP_OctApiBt0RemoveNode2 1 +#define SKIP_OctApiBt0RemoveNode3 1 +#define SKIP_OctApiBt0RemoveNode 1 +#define SKIP_OctApiBt0QueryNode2 1 +#define SKIP_OctApiBt0QueryNode 1 +#define SKIP_OctApiBt0GetFirstNode 1 +#define SKIP_OctApiBt0FindOrAddNode 1 +#define SKIP_OctApiBt0AddNodeReportPrevNodeData 1 +#define SKIP_OctApiLmCompare 1 +#define SKIP_OctApiLmMultiply 1 +#define SKIP_OctApiLmDivide 1 +#define SKIP_OctApiLmShiftRight1 1 +#define SKIP_OctApiLmShiftn 1 +#define SKIP_OctApiLmGetMsb 1 +#define SKIP_OctApiTllmAllocGetSize 1 +#define SKIP_OctApiTllmAllocInit 1 +#define SKIP_OctApiTllmAllocInfo 1 +#define SKIP_OctApiTllmAllocAlloc 1 +#define SKIP_OctApiTllmAllocDealloc 1 +#define SKIP_OctApiTllmCheckTimeoutList 1 +#define SKIP_OctApiLlmListGetSize 1 +#define SKIP_OctApiLlmListGetItemPointer 1 +#define SKIP_OctApiLlmListInit 1 +#define SKIP_OctApiLlmListInfo 1 +#define SKIP_OctApiLlmListCreate 1 +#define SKIP_OctApiLlmListDelete 1 +#define SKIP_OctApiLlmListLength 1 +#define SKIP_OctApiLlmListItemData 1 +#define SKIP_OctApiLlmListInsertItem 1 +#define SKIP_OctApiLlmListCreateFull 1 +#define SKIP_OctApiLlmListAppendItems 1 +#define SKIP_OctApiLlmListAppendAndSetItems 1 +#define SKIP_OctApiLlmListSetItems 1 +#define SKIP_OctApiLlmListCopyData 1 +#define SKIP_OctApiLlmListRemoveItem 1 +#define SKIP_OctApiLlm2ListGetSize 1 +#define SKIP_OctApiLlm2ListGetItemPointer 1 +#define SKIP_OctApiLlm2ListInit 1 +#define SKIP_OctApiLlm2ListCreate 1 +#define SKIP_OctApiLlm2ListDelete 1 +#define SKIP_OctApiLlm2ListLength 1 +#define SKIP_OctApiLlm2ListItemData 1 +#define SKIP_OctApiLlm2ListInsertItem 1 +#define SKIP_OctApiLlm2ListRemoveItem 1 +#define SKIP_OctApiLlmMemCpy 1 + +#endif + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_adpcm_chan_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_adpcm_chan_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_adpcm_chan_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_adpcm_chan_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,74 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_adpcm_chan_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_adpcm_chan.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_adpcm_chan_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_ADPCM_CHAN_INST_H__ +#define __OCT6100_ADPCM_CHAN_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_ADPCM_CHAN_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* TSI chariot memory entry. */ + UINT16 usTsiMemIndex; + + /* ADPCM memory entry. */ + UINT16 usAdpcmMemIndex; + + /* Input and output timeslot information. */ + UINT16 usInputTimeslot; + UINT16 usInputStream; + UINT8 byInputNumTssts; + UINT8 byInputPcmLaw; + + UINT16 usOutputTimeslot; + UINT16 usOutputStream; + UINT8 byOutputNumTssts; + UINT8 byOutputPcmLaw; + + /* Internal info for quick access to structures associated to this TSI cnct. */ + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + +} tOCT6100_API_ADPCM_CHAN, *tPOCT6100_API_ADPCM_CHAN; + +#endif /* __OCT6100_ADPCM_CHAN_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_adpcm_chan_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_adpcm_chan_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_adpcm_chan_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_adpcm_chan_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,90 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_adpcm_chan_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_adpcm_chan.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_adpcm_chan_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 5 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_ADPCM_CHAN_PUB_H__ +#define __OCT6100_ADPCM_CHAN_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_ADPCM_CHAN_OPEN_ +{ + PUINT32 pulChanHndl; + + UINT32 ulInputTimeslot; + UINT32 ulInputStream; + UINT32 ulInputNumTssts; + UINT32 ulInputPcmLaw; + + UINT32 ulOutputTimeslot; + UINT32 ulOutputStream; + UINT32 ulOutputNumTssts; + UINT32 ulOutputPcmLaw; + + UINT32 ulChanMode; /* Encoding or decoding. */ + + UINT32 ulEncodingRate; + UINT32 ulDecodingRate; + + UINT32 ulAdpcmNibblePosition; + +} tOCT6100_ADPCM_CHAN_OPEN, *tPOCT6100_ADPCM_CHAN_OPEN; + +typedef struct _OCT6100_ADPCM_CHAN_CLOSE_ +{ + UINT32 ulChanHndl; + +} tOCT6100_ADPCM_CHAN_CLOSE, *tPOCT6100_ADPCM_CHAN_CLOSE; + + +/************************** FUNCTION PROTOTYPES *****************************/ + + +UINT32 Oct6100AdpcmChanOpenDef( + OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ); +UINT32 Oct6100AdpcmChanOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ); + +UINT32 Oct6100AdpcmChanCloseDef( + OUT tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ); +UINT32 Oct6100AdpcmChanClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ); + +#endif /* __OCT6100_ADPCM_CHAN_PUB_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_api.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_api.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_api.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_api.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,84 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_api.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Header file containing all definitions used throughout the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 23 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_API_H__ +#define __OCT6100_API_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100_defines.h" +#include "oct6100_errors.h" + +#include "oct6100_apiud.h" +#include "oct6100_tlv_inst.h" +#include "oct6100_chip_stats_inst.h" +#include "oct6100_tsi_cnct_inst.h" +#include "oct6100_mixer_inst.h" +#include "oct6100_events_inst.h" +#include "oct6100_tone_detection_inst.h" +#include "oct6100_conf_bridge_inst.h" +#include "oct6100_playout_buf_inst.h" + +#include "oct6100_adpcm_chan_inst.h" +#include "oct6100_phasing_tsst_inst.h" +#include "oct6100_channel_inst.h" +#include "oct6100_interrupts_inst.h" +#include "oct6100_remote_debug_inst.h" +#include "oct6100_debug_inst.h" +#include "oct6100_chip_open_inst.h" +#include "oct6100_api_inst.h" + +#include "oct6100_interrupts_pub.h" +#include "oct6100_tsi_cnct_pub.h" +#include "oct6100_events_pub.h" +#include "oct6100_tone_detection_pub.h" +#include "oct6100_mixer_pub.h" +#include "oct6100_conf_bridge_pub.h" +#include "oct6100_playout_buf_pub.h" + +#include "oct6100_channel_pub.h" +#include "oct6100_remote_debug_pub.h" +#include "oct6100_debug_pub.h" +#include "oct6100_chip_open_pub.h" +#include "oct6100_chip_stats_pub.h" +#include "oct6100_adpcm_chan_pub.h" +#include "oct6100_phasing_tsst_pub.h" + +#ifdef __cplusplus +} +#endif + +#endif /* __OCT6100_API_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_api_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_api_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_api_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_api_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,138 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_api_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing the definition of the API instance structure. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 40 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_API_INST_H__ +#define __OCT6100_API_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_SHARED_INFO_ +{ + /* Local copy of chip configuration structure. */ + tOCT6100_API_CHIP_CONFIG ChipConfig; + + /* Miscellaneous calculations and mapping of static structures in external memory. */ + tOCT6100_API_MISCELLANEOUS MiscVars; + tOCT6100_API_MEMORY_MAP MemoryMap; + + /* Error stats structure. */ + tOCT6100_API_CHIP_ERROR_STATS ErrorStats; + tOCT6100_API_CHIP_STATS ChipStats; + + /* Mixer information. */ + tOCT6100_API_MIXER MixerInfo; + + /* Image breakdown information. */ + tOCT6100_API_IMAGE_REGION ImageRegion[ cOCT6100_MAX_IMAGE_REGION ]; + tOCT6100_API_IMAGE_INFO ImageInfo; + + /* Configuration and management of interrupts. */ + tOCT6100_API_INTRPT_CONFIG IntrptConfig; + tOCT6100_API_INTRPT_MANAGE IntrptManage; + /* Remote debugging. */ + tOCT6100_API_REMOTE_DEBUG_INFO RemoteDebugInfo; + /* Chip debugging information. */ + tOCT6100_API_DEBUG DebugInfo; + + /* Management variables of software and hardware buffers. */ + tOCT6100_API_SOFT_BUFS SoftBufs; + + /* Caller buffer playout memory management structure. */ + tOCT6100_API_BUFFER_PLAYOUT_MALLOC_INFO PlayoutInfo; + + + + UINT32 ulChannelListOfst; + UINT32 ulChannelAllocOfst; + + UINT32 ulConversionMemoryAllocOfst; + + UINT32 ulTsiMemoryAllocOfst; + UINT32 ulExtraTsiMemoryAllocOfst; + UINT32 ulEchoMemoryAllocOfst; + + UINT32 ulTsstAllocOfst; + UINT32 ulTsstListOfst; + UINT32 ulTsstListAllocOfst; + + UINT32 ulTsiCnctListOfst; + UINT32 ulTsiCnctAllocOfst; + + UINT32 ulMixerEventListOfst; + UINT32 ulMixerEventAllocOfst; + + UINT32 ulCopyEventListOfst; + UINT32 ulCopyEventAllocOfst; + + UINT32 ulBiDirChannelListOfst; + UINT32 ulBiDirChannelAllocOfst; + + UINT32 ulConfBridgeListOfst; + UINT32 ulConfBridgeAllocOfst; + + UINT32 ulFlexConfParticipantListOfst; + UINT32 ulFlexConfParticipantAllocOfst; + + UINT32 ulPlayoutBufListOfst; + UINT32 ulPlayoutBufAllocOfst; + UINT32 ulPlayoutBufMemoryNodeListOfst; + + + + UINT32 ulAdpcmChanListOfst; + UINT32 ulAdpcmChanAllocOfst; + + UINT32 ulPhasingTsstListOfst; + UINT32 ulPhasingTsstAllocOfst; + +} tOCT6100_SHARED_INFO, *tPOCT6100_SHARED_INFO; + +typedef struct _OCT6100_INSTANCE_API_ +{ + /* Pointer to portion of API instance structure shared amongst all processes. */ + tPOCT6100_SHARED_INFO pSharedInfo; + + /* Pointer to user-supplied, process context structure. The structure is + a parameter to all user-supplied functions. */ + PVOID pProcessContext; + + /* Handles to all serialization objects used by the API. */ + tOCT6100_USER_SERIAL_OBJECT ulApiSerObj; + + +} tOCT6100_INSTANCE_API, *tPOCT6100_INSTANCE_API; + +#endif /* __OCT6100_API_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_apimi.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_apimi.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_apimi.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_apimi.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,69 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_apimi.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the declaration of all functions exported from the + APIMI block. The APIMI block contains only one function: + Oct6100InterruptMask. + The function is used to mask out the interrupt pin of the chip. This + function is used when a deferred procedure call treats the interrupt (new + interrupts must not be generated until the signalled interrupt is treated). + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_APIMI_H__ +#define __OCT6100_APIMI_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_INTERRUPT_MASK_ +{ + UINT32 ulUserChipIndex; + PVOID pProcessContext; + + +} tOCT6100_INTERRUPT_MASK, *tPOCT6100_INTERRUPT_MASK; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100InterruptMaskDef( + OUT tPOCT6100_INTERRUPT_MASK f_pInterruptMask ); +UINT32 Oct6100InterruptMask( + IN tPOCT6100_INTERRUPT_MASK f_pInterruptMask ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __OCT6100_APIMI_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_apiud.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_apiud.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_apiud.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_apiud.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,312 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_apiud.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Header file containing the definitions and prototypes that are to be + completed by the user. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 16 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_APIUD_H__ +#define __OCT6100_APIUD_H__ + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +/***************************** DEFINES *************************************/ + + +/* Determines the maximum length of a burst of reads/writes. This value must + be in the range 8 - 1024. This value obtains best performance if set to + a power of 2 (i.e. 2^n). */ +#define cOCT6100_MAX_RW_ACCESSES 32 + +/* The define used to specify that the Oct6100SeizeSerializeObject function + is not to return until the specified serialization object has been seized. */ +#define cOCT6100_WAIT_INFINITELY 0xFFFFFFFF + + +/* Compile option: enabling this compile option inserts code to check every + call to a user provided function to make sure the function parameters + are not changed, as required by the API specification. */ +#define cOCT6100_USER_FUNCTION_CHECK + + + +#define cOCT6100_GET_TIME_FAILED_0 0xFFFF0000 +#define cOCT6100_GET_TIME_FAILED_1 0xFFFF0001 +#define cOCT6100_GET_TIME_FAILED_2 0xFFFF0002 +#define cOCT6100_GET_TIME_FAILED_3 0xFFFF0003 +#define cOCT6100_GET_TIME_FAILED_4 0xFFFF0004 + +#define cOCT6100_CREATE_SERIAL_FAILED_0 0xFFFF0010 +#define cOCT6100_CREATE_SERIAL_FAILED_1 0xFFFF0011 +#define cOCT6100_CREATE_SERIAL_FAILED_2 0xFFFF0012 +#define cOCT6100_CREATE_SERIAL_FAILED_3 0xFFFF0013 +#define cOCT6100_CREATE_SERIAL_FAILED_4 0xFFFF0014 + +#define cOCT6100_DESTROY_SERIAL_FAILED_0 0xFFFF0020 +#define cOCT6100_DESTROY_SERIAL_FAILED_1 0xFFFF0021 +#define cOCT6100_DESTROY_SERIAL_FAILED_2 0xFFFF0022 +#define cOCT6100_DESTROY_SERIAL_FAILED_3 0xFFFF0023 +#define cOCT6100_DESTROY_SERIAL_FAILED_4 0xFFFF0024 + +#define cOCT6100_INVALID_SERIAL_HANDLE_0 0xFFFF0030 +#define cOCT6100_INVALID_SERIAL_HANDLE_1 0xFFFF0031 +#define cOCT6100_INVALID_SERIAL_HANDLE_2 0xFFFF0032 +#define cOCT6100_INVALID_SERIAL_HANDLE_3 0xFFFF0033 +#define cOCT6100_INVALID_SERIAL_HANDLE_4 0xFFFF0034 + +#define cOCT6100_RELEASE_SERIAL_FAILED_0 0xFFFF0040 +#define cOCT6100_RELEASE_SERIAL_FAILED_1 0xFFFF0041 +#define cOCT6100_RELEASE_SERIAL_FAILED_2 0xFFFF0042 +#define cOCT6100_RELEASE_SERIAL_FAILED_3 0xFFFF0043 +#define cOCT6100_RELEASE_SERIAL_FAILED_4 0xFFFF0044 + +#define cOCT6100_SEIZE_SERIAL_FAILED_0 0xFFFF0050 +#define cOCT6100_SEIZE_SERIAL_FAILED_1 0xFFFF0051 +#define cOCT6100_SEIZE_SERIAL_FAILED_2 0xFFFF0052 +#define cOCT6100_SEIZE_SERIAL_FAILED_3 0xFFFF0053 +#define cOCT6100_SEIZE_SERIAL_FAILED_4 0xFFFF0054 + +#define cOCT6100_DRIVER_WRITE_FAILED_0 0xFFFF0060 +#define cOCT6100_DRIVER_WRITE_FAILED_1 0xFFFF0061 +#define cOCT6100_DRIVER_WRITE_FAILED_2 0xFFFF0062 +#define cOCT6100_DRIVER_WRITE_FAILED_3 0xFFFF0063 +#define cOCT6100_DRIVER_WRITE_FAILED_4 0xFFFF0064 + +#define cOCT6100_DRIVER_WSMEAR_FAILED_0 0xFFFF0070 +#define cOCT6100_DRIVER_WSMEAR_FAILED_1 0xFFFF0071 +#define cOCT6100_DRIVER_WSMEAR_FAILED_2 0xFFFF0072 +#define cOCT6100_DRIVER_WSMEAR_FAILED_3 0xFFFF0073 +#define cOCT6100_DRIVER_WSMEAR_FAILED_4 0xFFFF0074 + +#define cOCT6100_DRIVER_WBURST_FAILED_0 0xFFFF0080 +#define cOCT6100_DRIVER_WBURST_FAILED_1 0xFFFF0081 +#define cOCT6100_DRIVER_WBURST_FAILED_2 0xFFFF0082 +#define cOCT6100_DRIVER_WBURST_FAILED_3 0xFFFF0083 +#define cOCT6100_DRIVER_WBURST_FAILED_4 0xFFFF0084 + +#define cOCT6100_DRIVER_READ_FAILED_0 0xFFFF0090 +#define cOCT6100_DRIVER_READ_FAILED_1 0xFFFF0091 +#define cOCT6100_DRIVER_READ_FAILED_2 0xFFFF0092 +#define cOCT6100_DRIVER_READ_FAILED_3 0xFFFF0093 +#define cOCT6100_DRIVER_READ_FAILED_4 0xFFFF0094 + +#define cOCT6100_DRIVER_RBURST_FAILED_0 0xFFFF00A0 +#define cOCT6100_DRIVER_RBURST_FAILED_1 0xFFFF00A1 +#define cOCT6100_DRIVER_RBURST_FAILED_2 0xFFFF00A2 +#define cOCT6100_DRIVER_RBURST_FAILED_3 0xFFFF00A3 +#define cOCT6100_DRIVER_RBURST_FAILED_4 0xFFFF00A4 + + + + + +/***************************** TYPES ***************************************/ + +/*Change this type if your platform uses 64bits semaphores/locks */ +typedef UINT32 tOCT6100_USER_SERIAL_OBJECT; + +typedef struct _OCT6100_GET_TIME_ +{ + PVOID pProcessContext; + UINT32 aulWallTimeUs[ 2 ]; + +} tOCT6100_GET_TIME, *tPOCT6100_GET_TIME; + + + + + +typedef struct _OCT6100_CREATE_SERIALIZE_OBJECT_ +{ + PVOID pProcessContext; + PSZ pszSerialObjName; + tOCT6100_USER_SERIAL_OBJECT ulSerialObjHndl; + +} tOCT6100_CREATE_SERIALIZE_OBJECT, *tPOCT6100_CREATE_SERIALIZE_OBJECT; + + +typedef struct _OCT6100_DESTROY_SERIALIZE_OBJECT_ +{ + PVOID pProcessContext; + tOCT6100_USER_SERIAL_OBJECT ulSerialObjHndl; + +} tOCT6100_DESTROY_SERIALIZE_OBJECT, *tPOCT6100_DESTROY_SERIALIZE_OBJECT; + + +typedef struct _OCT6100_SEIZE_SERIALIZE_OBJECT_ +{ + PVOID pProcessContext; + tOCT6100_USER_SERIAL_OBJECT ulSerialObjHndl; + UINT32 ulTryTimeMs; + +} tOCT6100_SEIZE_SERIALIZE_OBJECT, *tPOCT6100_SEIZE_SERIALIZE_OBJECT; + + +typedef struct _OCT6100_RELEASE_SERIALIZE_OBJECT_ +{ + PVOID pProcessContext; + tOCT6100_USER_SERIAL_OBJECT ulSerialObjHndl; + +} tOCT6100_RELEASE_SERIALIZE_OBJECT, *tPOCT6100_RELEASE_SERIALIZE_OBJECT; + + +typedef struct _OCT6100_WRITE_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulWriteAddress; + UINT16 usWriteData; + +} tOCT6100_WRITE_PARAMS, *tPOCT6100_WRITE_PARAMS; + + +typedef struct _OCT6100_WRITE_SMEAR_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulWriteAddress; + UINT32 ulWriteLength; + UINT16 usWriteData; + +} tOCT6100_WRITE_SMEAR_PARAMS, *tPOCT6100_WRITE_SMEAR_PARAMS; + + +typedef struct _OCT6100_WRITE_BURST_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulWriteAddress; + UINT32 ulWriteLength; + PUINT16 pusWriteData; + +} tOCT6100_WRITE_BURST_PARAMS, *tPOCT6100_WRITE_BURST_PARAMS; + + +typedef struct _OCT6100_READ_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulReadAddress; + PUINT16 pusReadData; + +} tOCT6100_READ_PARAMS, *tPOCT6100_READ_PARAMS; + + +typedef struct _OCT6100_READ_BURST_PARAMS_ +{ + PVOID pProcessContext; + + UINT32 ulUserChipId; + UINT32 ulReadAddress; + UINT32 ulReadLength; + PUINT16 pusReadData; + +} tOCT6100_READ_BURST_PARAMS, *tPOCT6100_READ_BURST_PARAMS; + + + + + + + + +/************************** FUNCTION PROTOTYPES *****************************/ + +/* Time function. */ +UINT32 Oct6100UserGetTime( + IN OUT tPOCT6100_GET_TIME f_pTime ); + + + +/* Memory management functions. */ +UINT32 Oct6100UserMemSet( + IN PVOID f_pAddress, + IN UINT32 f_ulPattern, + IN UINT32 f_ulLength ); + +UINT32 Oct6100UserMemCopy( + IN PVOID f_pDestination, + IN const void *f_pSource, + IN UINT32 f_ulLength ); + +/* Serialization functions. */ +UINT32 Oct6100UserCreateSerializeObject( + IN OUT tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate); + +UINT32 Oct6100UserDestroySerializeObject( + IN tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy); + +UINT32 Oct6100UserSeizeSerializeObject( + IN tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize); + +UINT32 Oct6100UserReleaseSerializeObject( + IN tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease); + +/* Read/Write functions.*/ +UINT32 Oct6100UserDriverWriteApi( + IN tPOCT6100_WRITE_PARAMS f_pWriteParams ); + +UINT32 Oct6100UserDriverWriteOs( + IN tPOCT6100_WRITE_PARAMS f_pWriteParams ); + +UINT32 Oct6100UserDriverWriteSmearApi( + IN tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams ); + +UINT32 Oct6100UserDriverWriteSmearOs( + IN tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams ); + +UINT32 Oct6100UserDriverWriteBurstApi( + IN tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams ); + +UINT32 Oct6100UserDriverWriteBurstOs( + IN tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams ); + +UINT32 Oct6100UserDriverReadApi( + IN OUT tPOCT6100_READ_PARAMS f_pReadParams ); + +UINT32 Oct6100UserDriverReadOs( + IN OUT tPOCT6100_READ_PARAMS f_pReadParams ); + +UINT32 Oct6100UserDriverReadBurstApi( + IN OUT tPOCT6100_READ_BURST_PARAMS f_pBurstParams ); + +UINT32 Oct6100UserDriverReadBurstOs( + IN OUT tPOCT6100_READ_BURST_PARAMS f_pBurstParams ); + + + + + + + +#endif /* __OCT6100_APIUD_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_channel_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_channel_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_channel_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_channel_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,389 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_channel_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_channel.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_channel_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 90 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHANNEL_INST_H__ +#define __OCT6100_CHANNEL_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_CHANNEL_TDM_ +{ + /* Laws. */ + UINT8 byRinPcmLaw; + UINT8 bySinPcmLaw; + UINT8 byRoutPcmLaw; + UINT8 bySoutPcmLaw; + + /* RIN port. */ + UINT16 usRinTimeslot; + UINT16 usRinStream; + + /* SIN port. */ + UINT16 usSinTimeslot; + UINT16 usSinStream; + + /* ROUT port. */ + UINT16 usRoutTimeslot; + UINT16 usRoutStream; + + /* SOUT port. */ + UINT16 usSoutTimeslot; + UINT16 usSoutStream; + + /* ROUT broadcast info. */ + UINT16 usRoutBrdcastTsstFirstEntry; + UINT16 usRoutBrdcastTsstNumEntry; + + /* SOUT broadcast info. */ + UINT16 usSoutBrdcastTsstFirstEntry; + UINT16 usSoutBrdcastTsstNumEntry; + + UINT8 byRinNumTssts; + UINT8 bySinNumTssts; + UINT8 byRoutNumTssts; + UINT8 bySoutNumTssts; + +} tOCT6100_API_CHANNEL_TDM, *tPOCT6100_API_CHANNEL_TDM; + +typedef struct _OCT6100_API_CHANNEL_VQE_ +{ + UINT8 fEnableNlp; + UINT8 fEnableTailDisplacement; + UINT16 usTailDisplacement; + UINT16 usTailLength; + + UINT8 fSinDcOffsetRemoval; + UINT8 fRinDcOffsetRemoval; + UINT8 fRinLevelControl; + UINT8 fSoutLevelControl; + + UINT8 fRinAutomaticLevelControl; + UINT8 fSoutAutomaticLevelControl; + OCT_INT8 chRinAutomaticLevelControlTargetDb; + OCT_INT8 chSoutAutomaticLevelControlTargetDb; + + UINT8 fRinHighLevelCompensation; + OCT_INT8 chRinHighLevelCompensationThresholdDb; + + UINT8 bySoutAutomaticListenerEnhancementGainDb; + UINT8 fSoutNaturalListenerEnhancement; + + UINT8 fSoutAdaptiveNoiseReduction; + UINT8 fDtmfToneRemoval; + UINT8 fAcousticEcho; + UINT8 byComfortNoiseMode; + + UINT8 byNonLinearityBehaviorA; + UINT8 byNonLinearityBehaviorB; + OCT_INT8 chRinLevelControlGainDb; + OCT_INT8 chSoutLevelControlGainDb; + + OCT_INT8 chDefaultErlDb; + OCT_INT8 chAecDefaultErlDb; + + UINT8 fRoutNoiseReduction; + OCT_INT8 chRoutNoiseReductionLevelGainDb; + OCT_INT8 chAnrSnrEnhancementDb; + + UINT8 fEnableMusicProtection; + UINT8 fIdleCodeDetection; + + UINT8 byAnrVoiceNoiseSegregation; + UINT8 bySoutNaturalListenerEnhancementGainDb; + + UINT16 usToneDisablerVqeActivationDelay; + UINT16 usAecTailLength; + + UINT8 byDoubleTalkBehavior; + UINT8 fSoutNoiseBleaching; + + + + UINT8 fSoutConferencingNoiseReduction; + + + +} tOCT6100_API_CHANNEL_VQE, *tPOCT6100_API_CHANNEL_VQE; + +typedef struct _OCT6100_API_CHANNEL_CODEC_ +{ + UINT8 byAdpcmNibblePosition; + UINT8 fEnableSilenceSuppression; + + UINT8 byEncoderPort; + UINT8 byEncodingRate; + + UINT8 byDecoderPort; + UINT8 byDecodingRate; + + UINT8 byPhase; + UINT8 byPhasingType; + +} tOCT6100_API_CHANNEL_CODEC, *tPOCT6100_API_CHANNEL_CODEC; + +typedef struct _OCT6100_API_CHANNEL_ +{ + /*=======================================================================*/ + /* Channel configuration. */ + + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* Is this a bidirectionnal channel? */ + UINT8 fBiDirChannel; + + /* Enable tone disabler? */ + UINT8 fEnableToneDisabler; + + /* TSI chariot memory entry for the Rin/Rout stream. */ + UINT16 usRinRoutTsiMemIndex; + + /* TSI chariot memory entry for the Sin/Sout stream. */ + UINT16 usSinSoutTsiMemIndex; + + /* Additional TSI entry used to temporarily store the SIN signal. */ + UINT16 usExtraSinTsiMemIndex; + UINT16 usExtraSinTsiDependencyCnt; + + /* Additional TSI entry used to temporarily store the RIN signal. */ + UINT16 usExtraRinTsiMemIndex; + UINT16 usExtraRinTsiDependencyCnt; + + /* Conversion chariot memory entry. */ + UINT16 usRinRoutConversionMemIndex; + UINT16 usSinSoutConversionMemIndex; + + /* TSST control memory entry. */ + UINT16 usRinTsstIndex; + UINT16 usSinTsstIndex; + UINT16 usRoutTsstIndex; + UINT16 usSoutTsstIndex; + + /* SSPX memory entry. */ + UINT16 usEchoMemIndex; + + /* Active mixer events count to test for last event. */ + UINT16 usMixerEventCnt; + + /* User channel ID, transparently passed to the user. */ + UINT32 ulUserChanId; + + /* Copy events. */ + UINT16 usSinCopyEventIndex; + UINT16 usSoutCopyEventIndex; + + /* Silence events. */ + UINT16 usRinSilenceEventIndex; + UINT16 usSinSilenceEventIndex; + + /* TDM configuration. */ + tOCT6100_API_CHANNEL_TDM TdmConfig; + + /* VQE configuration. */ + tOCT6100_API_CHANNEL_VQE VqeConfig; + + /* Current echo operation mode. */ + UINT8 byEchoOperationMode; + + /* Currently muted ports. */ + UINT16 usMutedPorts; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Statistics section. */ + + INT16 sComfortNoiseLevel; + + UINT16 usCurrentEchoDelay; + UINT16 usMaxEchoDelay; + + UINT16 usNumEchoPathChanges; + UINT16 usNumEchoPathChangesOfst; + + INT16 sCurrentERL; + INT16 sCurrentERLE; + + INT16 sMaxERL; + INT16 sMaxERLE; + + INT16 sRinLevel; + INT16 sSinLevel; + + INT16 sRinAppliedGain; + INT16 sSoutAppliedGain; + + UINT8 byToneDisablerStatus; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Bridge information. */ + + UINT16 usBridgeIndex; + + UINT8 fMute; + UINT8 fTap; + UINT8 fBeingTapped; + UINT8 fCopyEventCreated; + + UINT16 usLoadEventIndex; + UINT16 usSubStoreEventIndex; + + UINT16 usFlexConfParticipantIndex; + UINT16 usTapBridgeIndex; + UINT16 usTapChanIndex; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Buffer playout information. */ + + UINT32 ulRinBufWritePtr; + UINT32 ulRinBufSkipPtr; + + UINT8 fSoutBufPlaying; + UINT8 fRinBufPlaying; + + UINT8 fRinBufPlayoutNotifyOnStop; + UINT8 fRinBufPlayoutRepeatUsed; + + UINT32 ulSoutBufWritePtr; + UINT32 ulSoutBufSkipPtr; + + UINT8 fSoutBufPlayoutNotifyOnStop; + UINT8 fSoutBufPlayoutRepeatUsed; + + UINT8 fRinHardStop; + UINT8 fSoutHardStop; + + UINT32 ulRinUserBufPlayoutEventId; + UINT32 ulSoutUserBufPlayoutEventId; + + UINT8 byRinPlayoutStopEventType; + UINT8 bySoutPlayoutStopEventType; + + UINT8 fRinBufAdded; + UINT8 fSoutBufAdded; + + UINT8 fBufPlayoutActive; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Copy events information. */ + + /* Number of copy events created. */ + UINT16 usCopyEventCnt; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Extended tone detection info. */ + + /* Enable extended tone detection. */ + UINT8 fEnableExtToneDetection; + + UINT16 usExtToneChanIndex; + UINT16 usExtToneMixerIndex; + UINT16 usExtToneTsiIndex; + + /* Mode of operation of the channel based on the extended tone detection configuration. */ + UINT32 ulExtToneChanMode; + + /*=======================================================================*/ + + /* Tone detection state. */ + /* This array is configured as follow. */ + /* Index 0 contain event 0 to 31 and Index 1 contains event 32 - 55 */ + UINT32 aulToneConf[ 2 ]; + UINT32 ulLastSSToneDetected; + UINT32 ulLastSSToneTimestamp; + + /*=======================================================================*/ + + + /*=======================================================================*/ + + /* Index of the phasing TSST */ + UINT16 usPhasingTsstIndex; + + /* State of the codec structure associated to this channel. */ + UINT8 fSinSoutCodecActive; + UINT8 fRinRoutCodecActive; + + /* Codec configuration. */ + tOCT6100_API_CHANNEL_CODEC CodecConfig; + + /*=======================================================================*/ + + + + + + + + /* Nlp Conf Dword, index 0 contains the dword where the dword is located. and + index 1 is the actual value of the dword.*/ + UINT32 aulNlpConfDword[ cOCT6100_MAX_NLP_CONF_DWORD ][ 2 ]; + +} tOCT6100_API_CHANNEL, *tPOCT6100_API_CHANNEL; + +typedef struct _OCT6100_API_BIDIR_CHANNEL_ +{ + UINT16 usFirstChanIndex; + UINT16 usSecondChanIndex; + + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + + +} tOCT6100_API_BIDIR_CHANNEL, *tPOCT6100_API_BIDIR_CHANNEL; + +#endif /* __OCT6100_CHANNEL_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_channel_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_channel_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_channel_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_channel_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,547 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_channel_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_channel.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_channel_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 84 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHANNEL_PUB_H__ +#define __OCT6100_CHANNEL_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +/* Channel open structures. */ +typedef struct _OCT6100_CHANNEL_OPEN_TDM_ +{ + UINT32 ulRinNumTssts; + UINT32 ulSinNumTssts; + UINT32 ulRoutNumTssts; + UINT32 ulSoutNumTssts; + + UINT32 ulSinTimeslot; + UINT32 ulSinStream; + UINT32 ulSinPcmLaw; + + UINT32 ulSoutTimeslot; + UINT32 ulSoutStream; + UINT32 ulSoutPcmLaw; + + UINT32 ulRinTimeslot; + UINT32 ulRinStream; + UINT32 ulRinPcmLaw; + + UINT32 ulRoutTimeslot; + UINT32 ulRoutStream; + UINT32 ulRoutPcmLaw; + +} tOCT6100_CHANNEL_OPEN_TDM, *tPOCT6100_CHANNEL_OPEN_TDM; + +typedef struct _OCT6100_CHANNEL_OPEN_VQE_ +{ + BOOL fEnableNlp; + BOOL fEnableTailDisplacement; + UINT32 ulTailDisplacement; + UINT32 ulTailLength; + + BOOL fSinDcOffsetRemoval; + BOOL fRinDcOffsetRemoval; + BOOL fRinLevelControl; + BOOL fSoutLevelControl; + BOOL fRinAutomaticLevelControl; + BOOL fSoutAutomaticLevelControl; + BOOL fRinHighLevelCompensation; + BOOL fAcousticEcho; + BOOL fSoutAdaptiveNoiseReduction; + BOOL fDtmfToneRemoval; + + BOOL fSoutNoiseBleaching; + BOOL fSoutConferencingNoiseReduction; + + UINT32 ulComfortNoiseMode; + UINT32 ulNonLinearityBehaviorA; + UINT32 ulNonLinearityBehaviorB; + + INT32 lRinLevelControlGainDb; + INT32 lSoutLevelControlGainDb; + INT32 lRinAutomaticLevelControlTargetDb; + INT32 lSoutAutomaticLevelControlTargetDb; + INT32 lRinHighLevelCompensationThresholdDb; + INT32 lDefaultErlDb; + INT32 lAecDefaultErlDb; + UINT32 ulAecTailLength; + UINT32 ulSoutAutomaticListenerEnhancementGainDb; + UINT32 ulSoutNaturalListenerEnhancementGainDb; + BOOL fSoutNaturalListenerEnhancement; + BOOL fRoutNoiseReduction; + INT32 lRoutNoiseReductionLevelGainDb; + INT32 lAnrSnrEnhancementDb; + UINT32 ulAnrVoiceNoiseSegregation; + UINT32 ulDoubleTalkBehavior; + + UINT32 ulToneDisablerVqeActivationDelay; + + BOOL fEnableMusicProtection; + BOOL fIdleCodeDetection; + + + +} tOCT6100_CHANNEL_OPEN_VQE, *tPOCT6100_CHANNEL_OPEN_VQE; + +typedef struct _OCT6100_CHANNEL_OPEN_CODEC_ +{ + UINT32 ulAdpcmNibblePosition; + + UINT32 ulEncoderPort; + UINT32 ulEncodingRate; + + UINT32 ulDecoderPort; + UINT32 ulDecodingRate; + + BOOL fEnableSilenceSuppression; + UINT32 ulPhase; + UINT32 ulPhasingType; + UINT32 ulPhasingTsstHndl; + +} tOCT6100_CHANNEL_OPEN_CODEC, *tPOCT6100_CHANNEL_OPEN_CODEC; + +typedef struct _OCT6100_CHANNEL_OPEN_ +{ + PUINT32 pulChannelHndl; + UINT32 ulUserChanId; + + UINT32 ulEchoOperationMode; + + BOOL fEnableToneDisabler; + + BOOL fEnableExtToneDetection; + + tOCT6100_CHANNEL_OPEN_TDM TdmConfig; + tOCT6100_CHANNEL_OPEN_VQE VqeConfig; + tOCT6100_CHANNEL_OPEN_CODEC CodecConfig; + + + +} tOCT6100_CHANNEL_OPEN, *tPOCT6100_CHANNEL_OPEN; + +/* Channel close structure. */ +typedef struct _OCT6100_CHANNEL_CLOSE_ +{ + UINT32 ulChannelHndl; + +} tOCT6100_CHANNEL_CLOSE, *tPOCT6100_CHANNEL_CLOSE; + +/* Channel modify structures. */ +typedef struct _OCT6100_CHANNEL_MODIFY_TDM_ +{ + UINT32 ulRinNumTssts; + UINT32 ulSinNumTssts; + UINT32 ulRoutNumTssts; + UINT32 ulSoutNumTssts; + + UINT32 ulSinTimeslot; + UINT32 ulSinStream; + UINT32 ulSinPcmLaw; + + UINT32 ulSoutTimeslot; + UINT32 ulSoutStream; + UINT32 ulSoutPcmLaw; + + UINT32 ulRinTimeslot; + UINT32 ulRinStream; + UINT32 ulRinPcmLaw; + + UINT32 ulRoutTimeslot; + UINT32 ulRoutStream; + UINT32 ulRoutPcmLaw; + +} tOCT6100_CHANNEL_MODIFY_TDM, *tPOCT6100_CHANNEL_MODIFY_TDM; + +typedef struct _OCT6100_CHANNEL_MODIFY_VQE_ +{ + BOOL fEnableNlp; + BOOL fEnableTailDisplacement; + UINT32 ulTailDisplacement; + + BOOL fSinDcOffsetRemoval; + BOOL fRinDcOffsetRemoval; + BOOL fRinLevelControl; + BOOL fSoutLevelControl; + BOOL fRinAutomaticLevelControl; + BOOL fSoutAutomaticLevelControl; + BOOL fRinHighLevelCompensation; + BOOL fAcousticEcho; + BOOL fSoutAdaptiveNoiseReduction; + BOOL fDtmfToneRemoval; + + BOOL fSoutConferencingNoiseReduction; + BOOL fSoutNoiseBleaching; + + UINT32 ulNonLinearityBehaviorA; + UINT32 ulNonLinearityBehaviorB; + UINT32 ulComfortNoiseMode; + + INT32 lRinLevelControlGainDb; + INT32 lSoutLevelControlGainDb; + INT32 lRinAutomaticLevelControlTargetDb; + INT32 lSoutAutomaticLevelControlTargetDb; + INT32 lRinHighLevelCompensationThresholdDb; + INT32 lDefaultErlDb; + INT32 lAecDefaultErlDb; + UINT32 ulAecTailLength; + UINT32 ulSoutAutomaticListenerEnhancementGainDb; + UINT32 ulSoutNaturalListenerEnhancementGainDb; + BOOL fSoutNaturalListenerEnhancement; + BOOL fRoutNoiseReduction; + INT32 lRoutNoiseReductionLevelGainDb; + INT32 lAnrSnrEnhancementDb; + UINT32 ulAnrVoiceNoiseSegregation; + UINT32 ulDoubleTalkBehavior; + + UINT32 ulToneDisablerVqeActivationDelay; + + BOOL fEnableMusicProtection; + BOOL fIdleCodeDetection; + + + +} tOCT6100_CHANNEL_MODIFY_VQE, *tPOCT6100_CHANNEL_MODIFY_VQE; + +typedef struct _OCT6100_CHANNEL_MODIFY_CODEC_ +{ + UINT32 ulEncoderPort; + UINT32 ulEncodingRate; + + UINT32 ulDecoderPort; + UINT32 ulDecodingRate; + + BOOL fEnableSilenceSuppression; + UINT32 ulPhase; + UINT32 ulPhasingType; + UINT32 ulPhasingTsstHndl; + +} tOCT6100_CHANNEL_MODIFY_CODEC, *tPOCT6100_CHANNEL_MODIFY_CODEC; + +typedef struct _OCT6100_CHANNEL_MODIFY_ +{ + UINT32 ulChannelHndl; + UINT32 ulUserChanId; + UINT32 ulEchoOperationMode; + + BOOL fEnableToneDisabler; + + BOOL fApplyToAllChannels; + + BOOL fDisableToneDetection; + BOOL fStopBufferPlayout; + BOOL fRemoveConfBridgeParticipant; + BOOL fRemoveBroadcastTssts; + + BOOL fTdmConfigModified; /* TRUE/FALSE */ + BOOL fVqeConfigModified; /* TRUE/FALSE */ + BOOL fCodecConfigModified; /* TRUE/FALSE */ + + + tOCT6100_CHANNEL_MODIFY_TDM TdmConfig; + tOCT6100_CHANNEL_MODIFY_VQE VqeConfig; + tOCT6100_CHANNEL_MODIFY_CODEC CodecConfig; + +} tOCT6100_CHANNEL_MODIFY, *tPOCT6100_CHANNEL_MODIFY; + +typedef struct _OCT6100_CHANNEL_BROADCAST_TSST_ADD_ +{ + UINT32 ulChannelHndl; + + UINT32 ulPort; + UINT32 ulTimeslot; + UINT32 ulStream; + +} tOCT6100_CHANNEL_BROADCAST_TSST_ADD, *tPOCT6100_CHANNEL_BROADCAST_TSST_ADD; + +typedef struct _OCT6100_CHANNEL_BROADCAST_TSST_REMOVE_ +{ + UINT32 ulChannelHndl; + + UINT32 ulPort; + UINT32 ulTimeslot; + UINT32 ulStream; + + BOOL fRemoveAll; + +} tOCT6100_CHANNEL_BROADCAST_TSST_REMOVE, *tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE; + +/* Channel open structures.*/ +typedef struct _OCT6100_CHANNEL_STATS_TDM_ +{ + UINT32 ulMaxBroadcastTssts; + UINT32 ulNumRoutBroadcastTssts; + BOOL fMoreRoutBroadcastTssts; + UINT32 ulNumSoutBroadcastTssts; + BOOL fMoreSoutBroadcastTssts; + + UINT32 ulSinNumTssts; + UINT32 ulSoutNumTssts; + UINT32 ulRinNumTssts; + UINT32 ulRoutNumTssts; + + UINT32 ulSinTimeslot; + UINT32 ulSinStream; + UINT32 ulSinPcmLaw; + + UINT32 ulSoutTimeslot; + UINT32 ulSoutStream; + UINT32 ulSoutPcmLaw; + + PUINT32 pulSoutBroadcastTimeslot; + PUINT32 pulSoutBroadcastStream; + + UINT32 ulRinTimeslot; + UINT32 ulRinStream; + UINT32 ulRinPcmLaw; + + UINT32 ulRoutTimeslot; + UINT32 ulRoutStream; + UINT32 ulRoutPcmLaw; + + PUINT32 pulRoutBroadcastTimeslot; + PUINT32 pulRoutBroadcastStream; + +} tOCT6100_CHANNEL_STATS_TDM, *tPOCT6100_CHANNEL_STATS_TDM; + +typedef struct _OCT6100_CHANNEL_STATS_VQE_ +{ + BOOL fEnableNlp; + BOOL fEnableTailDisplacement; + UINT32 ulTailDisplacement; + UINT32 ulTailLength; + + BOOL fSinDcOffsetRemoval; + BOOL fRinDcOffsetRemoval; + BOOL fRinLevelControl; + BOOL fSoutLevelControl; + BOOL fRinAutomaticLevelControl; + BOOL fSoutAutomaticLevelControl; + BOOL fRinHighLevelCompensation; + BOOL fAcousticEcho; + BOOL fSoutAdaptiveNoiseReduction; + BOOL fDtmfToneRemoval; + + BOOL fSoutConferencingNoiseReduction; + BOOL fSoutNoiseBleaching; + + UINT32 ulComfortNoiseMode; + UINT32 ulNonLinearityBehaviorA; + UINT32 ulNonLinearityBehaviorB; + + INT32 lRinLevelControlGainDb; + INT32 lSoutLevelControlGainDb; + INT32 lRinAutomaticLevelControlTargetDb; + INT32 lSoutAutomaticLevelControlTargetDb; + INT32 lRinHighLevelCompensationThresholdDb; + INT32 lDefaultErlDb; + INT32 lAecDefaultErlDb; + UINT32 ulAecTailLength; + UINT32 ulSoutAutomaticListenerEnhancementGainDb; + UINT32 ulSoutNaturalListenerEnhancementGainDb; + BOOL fSoutNaturalListenerEnhancement; + BOOL fRoutNoiseReduction; + INT32 lRoutNoiseReductionLevelGainDb; + INT32 lAnrSnrEnhancementDb; + UINT32 ulAnrVoiceNoiseSegregation; + UINT32 ulDoubleTalkBehavior; + + UINT32 ulToneDisablerVqeActivationDelay; + + BOOL fEnableMusicProtection; + BOOL fIdleCodeDetection; + + + +} tOCT6100_CHANNEL_STATS_VQE, *tPOCT6100_CHANNEL_STATS_VQE; + +typedef struct _OCT6100_CHANNEL_STATS_CODEC_ +{ + UINT32 ulAdpcmNibblePosition; + + UINT32 ulEncoderPort; + UINT32 ulEncodingRate; + + UINT32 ulDecoderPort; + UINT32 ulDecodingRate; + + BOOL fEnableSilenceSuppression; + UINT32 ulPhase; + UINT32 ulPhasingType; + UINT32 ulPhasingTsstHndl; + +} tOCT6100_CHANNEL_STATS_CODEC, *tPOCT6100_CHANNEL_STATS_CODEC; + +typedef struct _OCT6100_CHANNEL_STATS_ +{ + BOOL fResetStats; + + UINT32 ulChannelHndl; + UINT32 ulUserChanId; + + UINT32 ulEchoOperationMode; + BOOL fEnableToneDisabler; + + UINT32 ulMutePortsMask; + BOOL fEnableExtToneDetection; + + tOCT6100_CHANNEL_STATS_TDM TdmConfig; + tOCT6100_CHANNEL_STATS_VQE VqeConfig; + tOCT6100_CHANNEL_STATS_CODEC CodecConfig; + + /* Real stats. */ + UINT32 ulNumEchoPathChanges; + UINT32 ulToneDisablerStatus; + + INT32 lCurrentERL; + INT32 lCurrentERLE; + UINT32 ulCurrentEchoDelay; + + INT32 lMaxERL; + INT32 lMaxERLE; + UINT32 ulMaxEchoDelay; + + INT32 lRinLevel; + INT32 lSinLevel; + INT32 lRinAppliedGain; + INT32 lSoutAppliedGain; + INT32 lComfortNoiseLevel; + + BOOL fEchoCancellerConverged; + BOOL fSinVoiceDetected; + + + +} tOCT6100_CHANNEL_STATS, *tPOCT6100_CHANNEL_STATS; + +typedef struct _OCT6100_CHANNEL_CREATE_BIDIR_ +{ + PUINT32 pulBiDirChannelHndl; + + UINT32 ulFirstChannelHndl; + UINT32 ulSecondChannelHndl; + + + +} tOCT6100_CHANNEL_CREATE_BIDIR, *tPOCT6100_CHANNEL_CREATE_BIDIR; + +typedef struct _OCT6100_CHANNEL_DESTROY_BIDIR_ +{ + UINT32 ulBiDirChannelHndl; + +} tOCT6100_CHANNEL_DESTROY_BIDIR, *tPOCT6100_CHANNEL_DESTROY_BIDIR; + +typedef struct _OCT6100_CHANNEL_MUTE_ +{ + UINT32 ulChannelHndl; + UINT32 ulPortMask; + +} tOCT6100_CHANNEL_MUTE, *tPOCT6100_CHANNEL_MUTE; + +typedef struct _OCT6100_CHANNEL_UNMUTE_ +{ + UINT32 ulChannelHndl; + UINT32 ulPortMask; + +} tOCT6100_CHANNEL_UNMUTE, *tPOCT6100_CHANNEL_UNMUTE; + + +/************************** FUNCTION PROTOTYPES *****************************/ + + +UINT32 Oct6100ChannelOpenDef( + OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ); +UINT32 Oct6100ChannelOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ); + +UINT32 Oct6100ChannelCloseDef( + OUT tPOCT6100_CHANNEL_CLOSE f_pChannelClose ); +UINT32 Oct6100ChannelClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_CLOSE f_pChannelClose ); + +UINT32 Oct6100ChannelModifyDef( + OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ); +UINT32 Oct6100ChannelModify( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ); + +UINT32 Oct6100ChannelBroadcastTsstAddDef( + OUT tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd ); +UINT32 Oct6100ChannelBroadcastTsstAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd ); + +UINT32 Oct6100ChannelBroadcastTsstRemoveDef( + OUT tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove ); +UINT32 Oct6100ChannelBroadcastTsstRemove( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove ); + +UINT32 Oct6100ChannelGetStatsDef( + OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ); +UINT32 Oct6100ChannelGetStats( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ); + +UINT32 Oct6100ChannelCreateBiDirDef( + OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ); +UINT32 Oct6100ChannelCreateBiDir( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ); + +UINT32 Oct6100ChannelDestroyBiDirDef( + OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ); +UINT32 Oct6100ChannelDestroyBiDir( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ); + +UINT32 Oct6100ChannelMuteDef( + OUT tPOCT6100_CHANNEL_MUTE f_pChannelMute ); +UINT32 Oct6100ChannelMute( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MUTE f_pChannelMute ); + +UINT32 Oct6100ChannelUnMuteDef( + OUT tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ); +UINT32 Oct6100ChannelUnMute( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ); + +#endif /* __OCT6100_CHANNEL_PUB_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_open_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_open_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_open_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_open_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,517 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_open_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_chip_open.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_chip_open_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 122 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_OPEN_INST_H__ +#define __OCT6100_CHIP_OPEN_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_CHIP_CONFIG_ +{ + UINT32 ulUserChipId; + PVOID pProcessContext; + + unsigned char const *pbyImageFile; /* Byte pointer to the image file to be uploaded into the chip. */ + UINT32 ulImageSize; /* Size of the image file (in bytes). */ + + UINT32 ulMemClkFreq; + UINT32 ulUpclkFreq; /* 33.33 or 66.66 MHz. */ + UINT8 fEnableMemClkOut; /* TRUE/FALSE */ + + UINT8 fMultiProcessSystem; + + UINT8 byMemoryType; /* SDRAM or DDR */ + UINT8 byNumMemoryChips; /* Number of memory chips present. */ + UINT32 ulMemoryChipSize; /* The size of the memory chips. */ + + UINT16 usMaxRwAccesses; + UINT16 usTailDisplacement; + + /* Resource allocation parameters. */ + UINT16 usMaxChannels; + UINT16 usMaxBiDirChannels; + + UINT32 aulTdmStreamFreqs[ cOCT6100_TDM_STREAM_MAX_GROUPS ]; + + UINT8 byMaxTdmStreams; + UINT8 byTdmSampling; + + UINT8 fEnableFastH100Mode; + UINT8 fEnableAcousticEcho; /* Acoustic echo enabled. */ + + UINT16 ausTimestampTimeslots[ 4 ]; + UINT16 ausTimestampStreams[ 4 ]; + + UINT8 fUseSynchTimestamp; + + /* Debug feature used to record stream information from a channel.*/ + UINT8 fEnableChannelRecording; + + UINT16 usMaxRemoteDebugSessions; + + UINT8 byInterruptPolarity; + + UINT16 usMaxTsiCncts; + + UINT8 fEnableExtToneDetection; + UINT8 fEnable2100StopEvent; + + + UINT16 usMaxConfBridges; + UINT16 usMaxFlexibleConfParticipants; + UINT16 usMaxPlayoutBuffers; + + /* Playout event software buffer size. */ + UINT32 ulSoftBufPlayoutEventsBufSize; + + /* Soft buffer size. */ + UINT32 ulSoftToneEventsBufSize; + + UINT16 usMaxPhasingTssts; + UINT16 usMaxAdpcmChannels; + + + + + + UINT8 fEnableProductionBist; + UINT32 ulProductionBistMode; + UINT32 ulNumProductionBistLoops; + +} tOCT6100_API_CHIP_CONFIG, *tPOCT6100_API_CHIP_CONFIG; + + +typedef struct _OCT6100_API_MISCELLANEOUS_ +{ + /* Total size of external memories. */ + UINT32 ulTotalMemSize; + + UINT32 ulH100SlaveMode; + + /* Mclk frequency generated by the chip. */ + UINT32 ulMclkFreq; + + /* Array of UINT32s used to perform a burst of writes (avoids having to + allocate on the stack. The size of this array MUST NOT CHANGE (it's + used everywhere). */ + UINT16 ausSuperArray[ cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ]; + UINT16 ausSuperArray1[ cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ]; + UINT16 ausSuperArray2[ cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ]; + + /* Chip ID and revision.*/ + UINT16 usChipId; + UINT16 usChipRevision; + + /* Lsu CPU access variables.*/ + UINT16 usCpuLsuWritePtr; + UINT16 usCodepoint; + + /* Max number of channel supported.*/ + UINT16 usMaxNumberOfChannels; + UINT16 usMaxH100Speed; + UINT16 usTdmClkBoundary; + + UINT16 usNumBridgesOpened; + UINT16 usFirstBridge; + + + + + +} tOCT6100_API_MISCELLANEOUS, *tPOCT6100_API_MISCELLANEOUS; + +typedef struct _OCT6100_API_MEMORY_MAP_ +{ + /*-----------------------------------------------------------------------------*/ + /* Structure contained in external memory. */ + + /* Memory mapping filled using TLV information from the chip. */ + + /* Main channel memory. */ + UINT32 ulChanMainMemBase; + UINT32 ulChanMainMemSize; + + UINT32 ulChanMainIoMemOfst; + + UINT32 ulChanMainRinCBMemOfst; + UINT32 ulChanMainRinCBMemSize; + UINT32 ulChanMainSinCBMemOfst; + UINT32 ulChanMainSinCBMemSize; + UINT32 ulChanMainSoutCBMemOfst; + UINT32 ulChanMainSoutCBMemSize; + + /* Free memory base address. */ + UINT32 ulFreeMemBaseAddress; + + /* Root channel config offset. */ + UINT32 ulChanRootConfOfst; + + /* Playout buffer info. */ + UINT32 ulChanMainRinPlayoutMemOfst; + UINT32 ulChanMainRinPlayoutMemSize; + UINT32 ulChanMainSoutPlayoutMemOfst; + UINT32 ulChanMainSoutPlayoutMemSize; + + /* Channel Stats location */ + UINT32 ulChanMainIoStatsOfst; + UINT32 ulChanMainIoStatsSize; + + /* Buffer playout fields. */ + tOCT6100_TLV_OFFSET PlayoutRinWritePtrOfst; + tOCT6100_TLV_OFFSET PlayoutRinIgnoreSkipCleanOfst; + tOCT6100_TLV_OFFSET PlayoutRinSkipPtrOfst; + tOCT6100_TLV_OFFSET PlayoutSoutWritePtrOfst; + tOCT6100_TLV_OFFSET PlayoutSoutIgnoreSkipCleanOfst; + tOCT6100_TLV_OFFSET PlayoutSoutSkipPtrOfst; + tOCT6100_TLV_OFFSET PlayoutRinReadPtrOfst; + tOCT6100_TLV_OFFSET PlayoutSoutReadPtrOfst; + tOCT6100_TLV_OFFSET PlayoutRinHardSkipOfst; + tOCT6100_TLV_OFFSET PlayoutSoutHardSkipOfst; + + /* Adaptive noise reduction. */ + tOCT6100_TLV_OFFSET AdaptiveNoiseReductionOfst; + + /* DC offset removal. */ + tOCT6100_TLV_OFFSET RinDcOffsetRemovalOfst; + tOCT6100_TLV_OFFSET SinDcOffsetRemovalOfst; + + /* Level control. */ + tOCT6100_TLV_OFFSET RinLevelControlOfst; + tOCT6100_TLV_OFFSET SoutLevelControlOfst; + + /* Auto level control. */ + tOCT6100_TLV_OFFSET RinAutoLevelControlTargetOfst; + tOCT6100_TLV_OFFSET SoutAutoLevelControlTargetOfst; + + /* High level compensation. */ + tOCT6100_TLV_OFFSET RinHighLevelCompensationThresholdOfst; + tOCT6100_TLV_OFFSET SoutHighLevelCompensationThresholdOfst; + + /* Auto level control and high level compensation status. */ + tOCT6100_TLV_OFFSET AlcHlcStatusOfst; + + /* Confort Noise Mode. */ + tOCT6100_TLV_OFFSET ComfortNoiseModeOfst; + + /* NLP control field. */ + tOCT6100_TLV_OFFSET NlpControlFieldOfst; + + /* VAD control field offset.*/ + tOCT6100_TLV_OFFSET VadControlFieldOfst; + + /* NLP Trivial field offset. */ + tOCT6100_TLV_OFFSET NlpTrivialFieldOfst; + + /* Acoustic echo field offset. */ + tOCT6100_TLV_OFFSET AecFieldOfst; + + /* Acoustic echo default ERL field offset. */ + tOCT6100_TLV_OFFSET AecDefaultErlFieldOfst; + + /* Non-linearity behavior A and B field offset. */ + tOCT6100_TLV_OFFSET PcmLeakFieldOfst; + tOCT6100_TLV_OFFSET NlpConvCapFieldOfst; + + /* Default ERL field offset. */ + tOCT6100_TLV_OFFSET DefaultErlFieldOfst; + + /* Tone Removal field offset.*/ + tOCT6100_TLV_OFFSET ToneRemovalFieldOfst; + + + + /* Channel config fields offset. */ + tOCT6100_TLV_OFFSET ChanMainIoMaxEchoPointOfst; + tOCT6100_TLV_OFFSET TailDisplEnableOfst; + + /* Pouch fields offset. */ + tOCT6100_TLV_OFFSET PouchBootInstructionOfst; + tOCT6100_TLV_OFFSET PouchBootResultOfst; + tOCT6100_TLV_OFFSET PouchTailDisplOfst; + + /* 2100 Hz Auto disabling fields offset. */ + tOCT6100_TLV_OFFSET ToneDisablerControlOfst; + + /* Conferencing dominant speaker field offset. */ + tOCT6100_TLV_OFFSET DominantSpeakerFieldOfst; + + /* Conferencing noise reduction field offset. */ + tOCT6100_TLV_OFFSET ConferencingNoiseReductionOfst; + + /* Per channel tail displacement field offset. */ + tOCT6100_TLV_OFFSET PerChanTailDisplacementFieldOfst; + + /* Per channel tail length field offset. */ + tOCT6100_TLV_OFFSET PerChanTailLengthFieldOfst; + + /* AF control/echo cancellation bypass. */ + tOCT6100_TLV_OFFSET AftControlOfst; + + /* Voice detected stat field offset. */ + tOCT6100_TLV_OFFSET SinVoiceDetectedStatOfst; + + /* Rin currently applied gain field offset. */ + tOCT6100_TLV_OFFSET RinAppliedGainStatOfst; + + /* Sout currently applied gain field offset. */ + tOCT6100_TLV_OFFSET SoutAppliedGainStatOfst; + + /* Adaptive listener enhancement field offset. */ + tOCT6100_TLV_OFFSET AdaptiveAleOfst; + + /* Rin NR field offset. */ + tOCT6100_TLV_OFFSET RinAnrOfst; + + /* Rin NR value field offset. */ + tOCT6100_TLV_OFFSET RinAnrValOfst; + + /* Sin Mute field offset. */ + tOCT6100_TLV_OFFSET SinMuteOfst; + + /* Rin Mute field offset. */ + tOCT6100_TLV_OFFSET RinMuteOfst; + + /* Sout ANR SNR enhancement offset. */ + tOCT6100_TLV_OFFSET AnrSnrEnhancementOfst; + + /* Sout ANR voice-noise segregation offset. */ + tOCT6100_TLV_OFFSET AnrVoiceNoiseSegregationOfst; + + /* Tone disabler VQE activation delay offset. */ + tOCT6100_TLV_OFFSET ToneDisablerVqeActivationDelayOfst; + + /* AF tail displacement value configuration offset. */ + tOCT6100_TLV_OFFSET AfTailDisplacementFieldOfst; + + /* Pouch counter field offset. */ + tOCT6100_TLV_OFFSET PouchCounterFieldOfst; + + /* Acoustic echo tail length. */ + tOCT6100_TLV_OFFSET AecTailLengthFieldOfst; + + /* Is ISR called field offset. */ + tOCT6100_TLV_OFFSET IsIsrCalledFieldOfst; + + /* Music protection enable field offset. */ + tOCT6100_TLV_OFFSET MusicProtectionFieldOfst; + + /* Rin port energy level statistics field offset. */ + tOCT6100_TLV_OFFSET RinEnergyStatFieldOfst; + + /* Sout port energy level statistics field offset. */ + tOCT6100_TLV_OFFSET SoutEnergyStatFieldOfst; + + /* Double talk behavior field offset. */ + tOCT6100_TLV_OFFSET DoubleTalkBehaviorFieldOfst; + + /* Idle code detection field offset. */ + tOCT6100_TLV_OFFSET IdleCodeDetectionFieldOfst; + + /* TSI memory mapping information.*/ + UINT32 ulNumTsiEntries; + + /*-----------------------------------------------------------------------------*/ + +} tOCT6100_API_MEMORY_MAP, *tPOCT6100_API_MEMORY_MAP; + +typedef struct _OCT6100_API_SOFT_BUFS_ +{ + /* To avoid compilation errors. */ + UINT32 ulDummyVariable; + + /* Tone events buffer pointers. */ + UINT32 ulToneEventBufferWritePtr; + UINT32 ulToneEventBufferReadPtr; + UINT32 ulToneEventBufferSize; + UINT32 ulToneEventBufferMemOfst; + UINT32 ulToneEventBufferOverflowCnt; + + /* Playout events buffer pointers. */ + UINT32 ulBufPlayoutEventBufferWritePtr; + UINT32 ulBufPlayoutEventBufferReadPtr; + UINT32 ulBufPlayoutEventBufferSize; + UINT32 ulBufPlayoutEventBufferMemOfst; + UINT32 ulBufPlayoutEventBufferOverflowCnt; + +} tOCT6100_API_SOFT_BUFS, *tPOCT6100_API_SOFT_BUFS; + +typedef struct _OCT6100_API_IMAGE_REGION_ +{ + UINT32 ulPart1Size; + UINT32 ulPart2Size; + UINT32 ulClockInfo; + + UINT32 ulReserved; + + UINT32 ulPart1BaseAddress; + UINT32 ulPart2BaseAddress; + +} tOCT6100_API_IMAGE_REGION, *tPOCT6100_API_IMAGE_REGION; + +typedef struct _OCT6100_API_IMAGE_INFO_ +{ + UINT8 fBufferPlayout; + UINT8 fAdaptiveNoiseReduction; + UINT8 fRinDcOffsetRemoval; + UINT8 fSinDcOffsetRemoval; + + UINT8 fRinAutoLevelControl; + UINT8 fSoutAutoLevelControl; + UINT8 fRinHighLevelCompensation; + UINT8 fSoutHighLevelCompensation; + + UINT8 fAlcHlcStatus; + UINT8 fComfortNoise; + UINT8 fNlpControl; + UINT8 fSilenceSuppression; + + UINT8 fToneDisabler; + UINT8 fTailDisplacement; + UINT8 fPerChannelTailDisplacement; + UINT8 fAcousticEcho; + + UINT8 fAecEnabled; + UINT8 fToneRemoval; + UINT8 fDefaultErl; + UINT8 fMaxEchoPoint; + + UINT8 fNonLinearityBehaviorA; + UINT8 fNonLinearityBehaviorB; + UINT8 fAecDefaultErl; + UINT8 fAdpcm; + + UINT8 fConferencing; + UINT8 fConferencingNoiseReduction; + UINT8 fMusicProtection; + UINT8 fDominantSpeakerEnabled; + + UINT8 fAftControl; + UINT8 fSinVoiceDetectedStat; + UINT8 fRinAppliedGainStat; + UINT8 fSoutAppliedGainStat; + + UINT8 fListenerEnhancement; + UINT8 fRoutNoiseReduction; + UINT8 fRoutNoiseReductionLevel; + UINT8 fRinMute; + UINT8 fSinMute; + + UINT8 fAnrSnrEnhancement; + UINT8 fAnrVoiceNoiseSegregation; + UINT8 fRinBufferPlayoutHardSkip; + UINT8 fSoutBufferPlayoutHardSkip; + + UINT16 usMaxNumberOfChannels; + UINT8 fPerChannelTailLength; + UINT8 fToneDisablerVqeActivationDelay; + + UINT32 ulToneProfileNumber; + + UINT16 usMaxTailDisplacement; + UINT16 usMaxTailLength; + + UINT8 byNumToneDetectors; + UINT8 byMaxNumberPlayoutEvents; + + UINT8 fAfTailDisplacement; + UINT8 fAecTailLength; + + UINT8 fMusicProtectionConfiguration; + UINT8 byImageType; + + UINT8 fBufferPlayoutSkipInEvents; + UINT8 fSoutNoiseBleaching; + + UINT8 fRinEnergyStat; + UINT8 fSoutEnergyStat; + + UINT8 fDoubleTalkBehavior; + UINT8 fDoubleTalkBehaviorFieldOfst; + + UINT8 fIdleCodeDetection; + UINT8 fIdleCodeDetectionConfiguration; + + UINT8 fSinLevel; + + + + UINT8 szVersionNumber[ cOCT6100_VERSION_NUMBER_MAX_SIZE ]; + UINT32 ulBuildId; + + tOCT6100_TLV_TONE_INFO aToneInfo[ cOCT6100_MAX_TONE_EVENT ]; + +} tOCT6100_API_IMAGE_INFO, *tPOCT6100_API_IMAGE_INFO; + +typedef struct _OCT6100_API_MIXER_ +{ + /* Pointer to the various event region. */ + UINT16 usFirstSoutCopyEventPtr; + UINT16 usLastSoutCopyEventPtr; + + UINT16 usFirstBridgeEventPtr; + UINT16 usLastBridgeEventPtr; + + UINT16 usFirstSinCopyEventPtr; + UINT16 usLastSinCopyEventPtr; + + /* Recording event info. */ + UINT16 usRecordCopyEventIndex; + UINT16 usRecordSinEventIndex; + +} tOCT6100_API_MIXER, tPOCT6100_API_MIXER; + + +typedef struct _OCT6100_API_BUFFER_PLAYOUT_MALLOC_INFO_ +{ + /* Next node to be checked for free memory. */ + UINT32 ulRovingNode; + + /* First unused node in the unused list. */ + UINT32 ulFirstUnusedNode; + + /* Last unused node in the unused list. */ + UINT32 ulLastUnusedNode; + + /* Count of unused nodes. */ + UINT32 ulUnusedNodeCnt; + +} tOCT6100_API_BUFFER_PLAYOUT_MALLOC_INFO, *tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_INFO; + + + + +#endif /* __OCT6100_CHIP_OPEN_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_open_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_open_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_open_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_open_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,241 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_open_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_chip_open.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_chip_open_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 54 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_OPEN_PUB_H__ +#define __OCT6100_CHIP_OPEN_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_CHIP_OPEN_ +{ + UINT32 ulUserChipId; + BOOL fMultiProcessSystem; + PVOID pProcessContext; + + UINT32 ulMaxRwAccesses; + + unsigned char const *pbyImageFile; /* Byte pointer to the image file to be uploaded into the chip. */ + UINT32 ulImageSize; /* Size of the image file (in bytes). */ + + UINT32 ulMemClkFreq; /* 10 - 133.3 MHz. */ + UINT32 ulUpclkFreq; /* 1 - 66.6 MHz. */ + BOOL fEnableMemClkOut; + + UINT32 ulMemoryType; /* SDRAM or DDR type external memory. */ + UINT32 ulNumMemoryChips; /* Number of memory chips present. */ + UINT32 ulMemoryChipSize; /* The size of the memory chips. */ + + UINT32 ulTailDisplacement; /* Tail displacement supported by the chip. */ + + BOOL fEnableAcousticEcho;/* Acoustic echo cancellation enabled. */ + + /* Resource allocation parameters. */ + UINT32 ulMaxChannels; + UINT32 ulMaxTsiCncts; + UINT32 ulMaxBiDirChannels; + UINT32 ulMaxConfBridges; + UINT32 ulMaxFlexibleConfParticipants; + UINT32 ulMaxPlayoutBuffers; + + + UINT32 ulMaxPhasingTssts; + UINT32 ulMaxAdpcmChannels; + BOOL fUseSynchTimestamp; + UINT32 aulTimestampTimeslots[ 4 ]; + UINT32 aulTimestampStreams[ 4 ]; + UINT32 ulInterruptPolarity; + tOCT6100_INTERRUPT_CONFIGURE InterruptConfig; + + UINT32 aulTdmStreamFreqs[ cOCT6100_TDM_STREAM_MAX_GROUPS ]; + UINT32 ulMaxTdmStreams; + UINT32 ulTdmSampling; + + BOOL fEnableFastH100Mode; + + UINT32 ulSoftToneEventsBufSize; /* In events. */ + BOOL fEnableExtToneDetection; + BOOL fEnable2100StopEvent; + + + UINT32 ulSoftBufferPlayoutEventsBufSize; /* In events. */ + UINT32 ulMaxRemoteDebugSessions; + + BOOL fEnableChannelRecording; + + BOOL fEnableProductionBist; + UINT32 ulProductionBistMode; + UINT32 ulNumProductionBistLoops; + +} tOCT6100_CHIP_OPEN, *tPOCT6100_CHIP_OPEN; + +typedef struct _OCT6100_GET_INSTANCE_SIZE_ +{ + UINT32 ulApiInstanceSize; + +} tOCT6100_GET_INSTANCE_SIZE, *tPOCT6100_GET_INSTANCE_SIZE; + +typedef struct _OCT6100_CHIP_CLOSE_ +{ + UINT32 ulDummyVariable; + +} tOCT6100_CHIP_CLOSE, *tPOCT6100_CHIP_CLOSE; + +typedef struct _OCT6100_CREATE_LOCAL_INSTANCE_ +{ + tPOCT6100_INSTANCE_API pApiInstShared; + tPOCT6100_INSTANCE_API pApiInstLocal; + PVOID pProcessContext; + UINT32 ulUserChipId; + +} tOCT6100_CREATE_LOCAL_INSTANCE, *tPOCT6100_CREATE_LOCAL_INSTANCE; + +typedef struct _OCT6100_DESTROY_LOCAL_INSTANCE_ +{ + UINT32 ulDummy; + +} tOCT6100_DESTROY_LOCAL_INSTANCE, *tPOCT6100_DESTROY_LOCAL_INSTANCE; + +typedef struct _OCT6100_GET_HW_REVISION_ +{ + UINT32 ulUserChipId; + PVOID pProcessContext; + UINT32 ulRevisionNum; + +} tOCT6100_GET_HW_REVISION, *tPOCT6100_GET_HW_REVISION; + +typedef struct _OCT6100_FREE_RESOURCES_ +{ + BOOL fFreeTsiConnections; + BOOL fFreeConferenceBridges; + BOOL fFreePlayoutBuffers; + BOOL fFreePhasingTssts; + BOOL fFreeAdpcmChannels; + +} tOCT6100_FREE_RESOURCES, *tPOCT6100_FREE_RESOURCES; + +typedef struct _OCT6100_PRODUCTION_BIST_ +{ + UINT32 ulCurrentAddress; + UINT32 ulCurrentLoop; + UINT32 ulCurrentTest; + UINT32 ulBistStatus; + UINT32 ulFailedAddress; + UINT32 ulReadValue; + UINT32 ulExpectedValue; + +} tOCT6100_PRODUCTION_BIST, *tPOCT6100_PRODUCTION_BIST; + +typedef struct _OCT6100_API_GET_VERSION_ +{ + UINT8 achApiVersion[ cOCT6100_API_VERSION_STRING_LENGTH ]; + +} tOCT6100_API_GET_VERSION, *tPOCT6100_API_GET_VERSION; + +typedef struct _OCT6100_API_GET_CAPACITY_PINS_ +{ + UINT32 ulUserChipId; + PVOID pProcessContext; + UINT32 ulMemoryType; /* SDRAM or DDR type external memory. */ + BOOL fEnableMemClkOut; + UINT32 ulMemClkFreq; + UINT32 ulCapacityValue; +} tOCT6100_API_GET_CAPACITY_PINS, *tPOCT6100_API_GET_CAPACITY_PINS; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ChipOpenDef( + OUT tPOCT6100_CHIP_OPEN f_pChipOpen ); +UINT32 Oct6100ChipOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHIP_OPEN f_pChipOpen ); + +UINT32 Oct6100ChipCloseDef( + OUT tPOCT6100_CHIP_CLOSE f_pChipClose ); +UINT32 Oct6100ChipClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHIP_CLOSE f_pChipClose ); + +UINT32 Oct6100GetInstanceSizeDef( + OUT tPOCT6100_GET_INSTANCE_SIZE f_pInstanceSize ); +UINT32 Oct6100GetInstanceSize( + IN OUT tPOCT6100_CHIP_OPEN f_pChipOpen, + IN OUT tPOCT6100_GET_INSTANCE_SIZE f_pInstanceSize ); + +UINT32 Oct6100CreateLocalInstanceDef( + OUT tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ); +UINT32 Oct6100CreateLocalInstance( + IN OUT tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ); + +UINT32 Oct6100DestroyLocalInstanceDef( + OUT tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ); +UINT32 Oct6100DestroyLocalInstance( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ); + +UINT32 Oct6100ApiGetVersionDef( + OUT tPOCT6100_API_GET_VERSION f_pApiGetVersion ); +UINT32 Oct6100ApiGetVersion( + IN OUT tPOCT6100_API_GET_VERSION f_pApiGetVersion ); + +UINT32 Oct6100GetHwRevisionDef( + OUT tPOCT6100_GET_HW_REVISION f_pRevision ); +UINT32 Oct6100GetHwRevision( + IN OUT tPOCT6100_GET_HW_REVISION f_pRevision ); + +UINT32 Oct6100FreeResourcesDef( + OUT tPOCT6100_FREE_RESOURCES f_pFreeResources ); +UINT32 Oct6100FreeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_FREE_RESOURCES f_pFreeResources ); + +UINT32 Oct6100ProductionBistDef( + OUT tPOCT6100_PRODUCTION_BIST f_pProductionBist ); +UINT32 Oct6100ProductionBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PRODUCTION_BIST f_pProductionBist ); + +UINT32 Oct6100ApiGetCapacityPinsDef( + tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins); + +UINT32 Oct6100ApiGetCapacityPins( + tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ); + + +#endif /* __OCT6100_CHIP_OPEN_PUB_H__ */ + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_stats_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_stats_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_stats_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_stats_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,84 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_stats_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_chip_stats.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_chip_stats_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 21 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_STATS_INST_H__ +#define __OCT6100_CHIP_STATS_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_CHIP_ERROR_STATS_ +{ + UINT8 fFatalChipError; + + UINT32 ulInternalReadTimeoutCnt; + UINT32 ulSdramRefreshTooLateCnt; + UINT32 ulPllJitterErrorCnt; + + /* Internal tone detector error counter. */ + UINT32 ulToneDetectorErrorCnt; + + UINT32 ulOverflowToneEventsCnt; + + UINT32 ulH100OutOfSyncCnt; + UINT32 ulH100ClkABadCnt; + UINT32 ulH100ClkBBadCnt; + UINT32 ulH100FrameABadCnt; + + + +} tOCT6100_API_CHIP_ERROR_STATS, *tPOCT6100_API_CHIP_ERROR_STATS; + +typedef struct _OCT6100_API_CHIP_STATS_ +{ + UINT16 usNumberChannels; + UINT16 usNumberBiDirChannels; + UINT16 usNumberTsiCncts; + UINT16 usNumberConfBridges; + UINT16 usNumberPlayoutBuffers; + UINT16 usNumEcChanUsingMixer; + + UINT32 ulPlayoutMemUsed; + UINT16 usNumberActiveBufPlayoutPorts; + + UINT16 usNumberPhasingTssts; + UINT16 usNumberAdpcmChans; + +} tOCT6100_API_CHIP_STATS, *tPOCT6100_API_CHIP_STATS; + +#endif /* __OCT6100_CHIP_STATS_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_stats_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_stats_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_stats_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_chip_stats_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,150 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_stats_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_chip_stats.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_chip_stats_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 59 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CHIP_STATS_PUB_H__ +#define __OCT6100_CHIP_STATS_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_CHIP_STATS_ +{ + BOOL fResetChipStats; + + UINT32 ulNumberChannels; + UINT32 ulNumberTsiCncts; + UINT32 ulNumberConfBridges; + UINT32 ulNumberPlayoutBuffers; + UINT32 ulPlayoutFreeMemSize; + UINT32 ulNumberPhasingTssts; + UINT32 ulNumberAdpcmChannels; + + UINT32 ulH100OutOfSynchCount; + UINT32 ulH100ClockABadCount; + UINT32 ulH100FrameABadCount; + UINT32 ulH100ClockBBadCount; + + UINT32 ulInternalReadTimeoutCount; + UINT32 ulSdramRefreshTooLateCount; + UINT32 ulPllJitterErrorCount; + + UINT32 ulOverflowToneEventsCount; + UINT32 ulSoftOverflowToneEventsCount; + + UINT32 ulSoftOverflowBufferPlayoutEventsCount; + +} tOCT6100_CHIP_STATS, *tPOCT6100_CHIP_STATS; + +typedef struct _OCT6100_CHIP_TONE_INFO_ +{ + UINT32 ulToneID; + UINT32 ulDetectionPort; + + UINT8 aszToneName[ cOCT6100_TLV_MAX_TONE_NAME_SIZE ]; + +} tOCT6100_CHIP_TONE_INFO, *tPOCT6100_CHIP_TONE_INFO; + +typedef struct _OCT6100_CHIP_IMAGE_INFO_ +{ + BOOL fBufferPlayout; + BOOL fAdaptiveNoiseReduction; + BOOL fSoutNoiseBleaching; + BOOL fAutoLevelControl; + BOOL fHighLevelCompensation; + BOOL fSilenceSuppression; + + BOOL fAdpcm; + BOOL fConferencing; + BOOL fConferencingNoiseReduction; + BOOL fDominantSpeaker; + + BOOL fAcousticEcho; + BOOL fAecTailLength; + BOOL fToneRemoval; + + BOOL fDefaultErl; + BOOL fNonLinearityBehaviorA; + BOOL fNonLinearityBehaviorB; + BOOL fPerChannelTailDisplacement; + BOOL fPerChannelTailLength; + BOOL fListenerEnhancement; + BOOL fRoutNoiseReduction; + BOOL fRoutNoiseReductionLevel; + BOOL fAnrSnrEnhancement; + BOOL fAnrVoiceNoiseSegregation; + BOOL fToneDisablerVqeActivationDelay; + BOOL fMusicProtection; + BOOL fDoubleTalkBehavior; + BOOL fIdleCodeDetection; + BOOL fSinLevel; + + UINT32 ulMaxChannels; + UINT32 ulNumTonesAvailable; + UINT32 ulToneProfileNumber; + UINT32 ulMaxTailDisplacement; + UINT32 ulMaxTailLength; + UINT32 ulDebugEventSize; + UINT32 ulMaxPlayoutEvents; + + UINT32 ulImageType; + + UINT8 szVersionNumber[ cOCT6100_VERSION_NUMBER_MAX_SIZE ]; + UINT32 ulBuildId; + + tOCT6100_CHIP_TONE_INFO aToneInfo[ cOCT6100_MAX_TONE_EVENT ]; + +} tOCT6100_CHIP_IMAGE_INFO, *tPOCT6100_CHIP_IMAGE_INFO; + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ChipGetStatsDef( + OUT tPOCT6100_CHIP_STATS f_pChipStats ); + +UINT32 Oct6100ChipGetStats( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_CHIP_STATS f_pChipStats ); + +UINT32 Oct6100ChipGetImageInfoDef( + OUT tPOCT6100_CHIP_IMAGE_INFO f_pChipImageInfo ); + +UINT32 Oct6100ChipGetImageInfo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + OUT tPOCT6100_CHIP_IMAGE_INFO f_pChipImageInfo ); + +#endif /* __OCT6100_CHIP_STATS_PUB_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_conf_bridge_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_conf_bridge_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_conf_bridge_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_conf_bridge_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,104 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_conf_bridge_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_conf_bridge.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_conf_bridge_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 19 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CONF_BRIDGE_INST_H__ +#define __OCT6100_CONF_BRIDGE_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_CONF_BRIDGE_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Entry counter for the resources. */ + UINT8 byEntryOpenCnt; + + /* Next bridge pointer. */ + UINT16 usNextBridgePtr; + + /* Previous bridge pointer. */ + UINT16 usPrevBridgePtr; + + /* Number of clients connected to the bridge. */ + UINT16 usNumClients; + + /* Store the index of the load event, to diffentiate him form the accumulate. */ + UINT16 usLoadIndex; + + /* Pointer to the first bridge events.*/ + UINT16 usFirstLoadEventPtr; + UINT16 usFirstSubStoreEventPtr; + UINT16 usLastSubStoreEventPtr; + + /* Pointer to the silence load event, if it exists. */ + UINT16 usSilenceLoadEventPtr; + + /* Flag specifying whether the dominant speaker is set or not. */ + UINT16 usDominantSpeakerChanIndex; + UINT8 fDominantSpeakerSet; + + /* Flag specifying if this is flexible conferencing bridge. */ + UINT8 fFlexibleConferencing; + + /* Number of clients being tapped. */ + UINT16 usNumTappedClients; + +} tOCT6100_API_CONF_BRIDGE, *tPOCT6100_API_CONF_BRIDGE; + +typedef struct _OCT6100_API_FLEX_CONF_PARTICIPANT_ +{ + /* Input port of the conferencing for this participant. */ + UINT32 ulInputPort; + + /* Whether the flexible mixer has been created. */ + UINT8 fFlexibleMixerCreated; + + /* Listener mask ( who can hear us ). */ + UINT32 ulListenerMask; + + /* Our index in the listener mask. */ + UINT32 ulListenerMaskIndex; + + /* Mixer event indexes for this participant's mixer. */ + UINT16 ausLoadOrAccumulateEventIndex[ cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ]; + +} tOCT6100_API_FLEX_CONF_PARTICIPANT, *tPOCT6100_API_FLEX_CONF_PARTICIPANT; + +#endif /* __OCT6100_CONF_BRIDGE_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_conf_bridge_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_conf_bridge_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_conf_bridge_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_conf_bridge_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,169 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_conf_bridge_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_conf_bridge.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_conf_bridge_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 22 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_CONF_BRIDGE_PUB_H__ +#define __OCT6100_CONF_BRIDGE_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_CONF_BRIDGE_OPEN_ +{ + PUINT32 pulConfBridgeHndl; /* Handle returned when the bridge is opened. */ + BOOL fFlexibleConferencing; + +} tOCT6100_CONF_BRIDGE_OPEN, *tPOCT6100_CONF_BRIDGE_OPEN; + +typedef struct _OCT6100_CONF_BRIDGE_CLOSE_ +{ + UINT32 ulConfBridgeHndl; + +} tOCT6100_CONF_BRIDGE_CLOSE, *tPOCT6100_CONF_BRIDGE_CLOSE; + +typedef struct _OCT6100_CONF_BRIDGE_CHAN_ADD_ +{ + UINT32 ulConfBridgeHndl; + UINT32 ulChannelHndl; + UINT32 ulInputPort; + UINT32 ulListenerMaskIndex; + UINT32 ulListenerMask; + BOOL fMute; + UINT32 ulTappedChannelHndl; + +} tOCT6100_CONF_BRIDGE_CHAN_ADD, *tPOCT6100_CONF_BRIDGE_CHAN_ADD; + +typedef struct _OCT6100_CONF_BRIDGE_CHAN_REMOVE_ +{ + UINT32 ulConfBridgeHndl; + UINT32 ulChannelHndl; + BOOL fRemoveAll; + +} tOCT6100_CONF_BRIDGE_CHAN_REMOVE, *tPOCT6100_CONF_BRIDGE_CHAN_REMOVE; + +typedef struct _OCT6100_CONF_BRIDGE_CHAN_MUTE_ +{ + UINT32 ulChannelHndl; + +} tOCT6100_CONF_BRIDGE_CHAN_MUTE, *tPOCT6100_CONF_BRIDGE_CHAN_MUTE; + +typedef struct _OCT6100_CONF_BRIDGE_CHAN_UNMUTE_ +{ + UINT32 ulChannelHndl; + +} tOCT6100_CONF_BRIDGE_CHAN_UNMUTE, *tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE; + +typedef struct _OCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET_ +{ + UINT32 ulConfBridgeHndl; + UINT32 ulChannelHndl; + +} tOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET, *tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET; + +typedef struct _OCT6100_CONF_BRIDGE_MASK_CHANGE_ +{ + UINT32 ulChannelHndl; + UINT32 ulNewListenerMask; + +} tOCT6100_CONF_BRIDGE_MASK_CHANGE, *tPOCT6100_CONF_BRIDGE_MASK_CHANGE; + +typedef struct _OCT6100_CONF_BRIDGE_STATS_ +{ + UINT32 ulConfBridgeHndl; + UINT32 ulNumChannels; + UINT32 ulNumTappedChannels; + BOOL fFlexibleConferencing; + +} tOCT6100_CONF_BRIDGE_STATS, *tPOCT6100_CONF_BRIDGE_STATS; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ConfBridgeOpenDef( + OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ); +UINT32 Oct6100ConfBridgeOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ); + +UINT32 Oct6100ConfBridgeCloseDef( + OUT tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ); +UINT32 Oct6100ConfBridgeClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ); + +UINT32 Oct6100ConfBridgeChanAddDef( + OUT tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ); +UINT32 Oct6100ConfBridgeChanAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ); + +UINT32 Oct6100ConfBridgeChanRemoveDef( + OUT tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ); +UINT32 Oct6100ConfBridgeChanRemove( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ); + +UINT32 Oct6100ConfBridgeChanMuteDef( + OUT tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ); +UINT32 Oct6100ConfBridgeChanMute( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ); + +UINT32 Oct6100ConfBridgeChanUnMuteDef( + OUT tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ); +UINT32 Oct6100ConfBridgeChanUnMute( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ); + +UINT32 Oct6100ConfBridgeDominantSpeakerSetDef( + OUT tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ); +UINT32 Oct6100ConfBridgeDominantSpeakerSet( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ); + +UINT32 Oct6100ConfBridgeMaskChangeDef( + OUT tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ); +UINT32 Oct6100ConfBridgeMaskChange( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ); + +UINT32 Oct6100ConfBridgeGetStatsDef( + OUT tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ); +UINT32 Oct6100ConfBridgeGetStats( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ); + +#endif /* __OCT6100_CONF_BRIDGE_PUB_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_debug_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_debug_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_debug_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_debug_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,124 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_debug_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_debug.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_debug_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_DEBUG_INST_H__ +#define __OCT6100_DEBUG_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_DEBUG_ +{ + /* Information from the TLVs. */ + UINT32 ulDebugEventSize; + UINT32 ulMatrixBaseAddress; + UINT32 ulDebugChanStatsByteSize; + UINT32 ulDebugChanLiteStatsByteSize; + UINT32 ulHotChannelSelectBaseAddress; + UINT32 ulMatrixTimestampBaseAddress; + UINT32 ulAfWritePtrByteOffset; + UINT32 ulRecordedPcmEventByteSize; + UINT32 ulMatrixWpBaseAddress; + + /* Pouch counter presence in the image. */ + UINT8 fPouchCounter; + + /* Record channel indexes. */ + UINT16 usRecordMemIndex; + UINT16 usRecordChanIndex; + + UINT16 usRecordRinRoutTsiMemIndex; + UINT16 usRecordSinSoutTsiMemIndex; + + /* Debug channel information.*/ + UINT16 usCurrentDebugChanIndex; + + /* Matrix event mask. */ + UINT16 usMatrixCBMask; + + /* If data is being dumped now. */ + UINT8 fDebugDataBeingDumped; + + /* Index of the last event retrieved. */ + UINT16 usLastDebugEventIndex; + + /* Number of events to retrieve. */ + UINT16 usNumEvents; + + /* Chip debug event write ptr. */ + UINT16 usChipDebugEventWritePtr; + + /* Hot channel read data. */ + UINT16 ausHotChannelData[ 2 ]; + + /* Last PCM sample index. */ + UINT32 ulLastPcmSampleIndex; + + /* Last AF log read pointer. */ + UINT16 usLastAfLogReadPtr; + + /* AF log hardware write pointer. */ + UINT16 usAfLogWritePtr; + + /* Last tone event index retrieved. */ + UINT16 usLastToneEventIndex; + + /* Whether the image version string has been copied in the user buffer. */ + BOOL fImageVersionCopied; + + /* Whether the api version string has been copied in the user buffer. */ + BOOL fApiVersionCopied; + + /* Total number of bytes that will be returned for the current dump. */ + UINT32 ulDebugDataTotalNumBytes; + + /* Field to detect if the ISR is called present? */ + BOOL fIsIsrCalledField; + + /* Remaining number of bytes that will be returned for the current dump. */ + UINT32 ulDebugDataRemainingNumBytes; + + /* AF events control block size. */ + UINT32 ulAfEventCbByteSize; + + /* Current user selected data mode. Must be kept constant throughout a debug session. */ + UINT32 ulCurrentGetDataMode; + +} tOCT6100_API_DEBUG, *tPOCT6100_API_DEBUG; + +#endif /* __OCT6100_DEBUG_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_debug_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_debug_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_debug_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_debug_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,76 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_debug_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_debug.c. All elements defined in this file are for public + usage of the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_DEBUG_PUB_H__ +#define __OCT6100_DEBUG_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_DEBUG_SELECT_CHANNEL_ +{ + UINT32 ulChannelHndl; + +} tOCT6100_DEBUG_SELECT_CHANNEL, *tPOCT6100_DEBUG_SELECT_CHANNEL; + +typedef struct _OCT6100_DEBUG_GET_DATA_ +{ + UINT32 ulGetDataMode; + UINT32 ulGetDataContent; + UINT32 ulRemainingNumBytes; + UINT32 ulTotalNumBytes; + UINT32 ulMaxBytes; + UINT32 ulValidNumBytes; + PUINT8 pbyData; + +} tOCT6100_DEBUG_GET_DATA, *tPOCT6100_DEBUG_GET_DATA; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100DebugSelectChannelDef( + OUT tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan ); +UINT32 Oct6100DebugSelectChannel( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan ); + +UINT32 Oct6100DebugGetDataDef( + OUT tPOCT6100_DEBUG_GET_DATA f_pGetData ); +UINT32 Oct6100DebugGetData( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_DEBUG_GET_DATA f_pGetData ); + +#endif /* __OCT6100_DEBUG_PUB_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_defines.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_defines.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_defines.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_defines.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,670 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_defines.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Header file containing all defines used throughout the API. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.7 + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 171 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_DEFINES_H__ +#define __OCT6100_DEFINES_H__ + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +/***************************** DEFINES *************************************/ + +/* 32-bits values. */ +#define cOCT6100_FFFFFFFF 0xFFFFFFFF +#define cOCT6100_FFFFFFFE 0xFFFFFFFE +#define cOCT6100_7FFFFFFF 0x7FFFFFFF + +/* 16-bits values. */ +#define cOCT6100_FFFD 0xFFFD +#define cOCT6100_FFFE 0xFFFE +#define cOCT6100_FFFF 0xFFFF +#define cOCT6100_7FFF 0x7FFF + +/* 8-bits values. */ +#define cOCT6100_FF 0xFF + +#define cOCT6100_CURRENT_VALUE cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_CHIP_ID cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_HANDLE cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_TIMESLOT cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_STREAM cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_VALUE cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_STAT cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_STAT_W cOCT6100_FFFF +#define cOCT6100_INVALID_PCM_LAW cOCT6100_FF +#define cOCT6100_INVALID_EVENT cOCT6100_FFFF +#define cOCT6100_INVALID_INDEX cOCT6100_FFFF +#define cOCT6100_INVALID_TONE cOCT6100_FFFFFFFF +#define cOCT6100_INVALID_PORT cOCT6100_FF + +#define cOCT6100_AUTO_SELECT cOCT6100_FFFFFFFE +#define cOCT6100_AUTO_SELECT_TAIL cOCT6100_FFFE + +#define cOCT6100_INVALID_BOOL 2 + +#define cOCT6100_KEEP_PREVIOUS_SETTING 0x70100000 + +#define cOCT6100_INVALID_SIGNED_STAT cOCT6100_7FFFFFFF +#define cOCT6100_INVALID_SIGNED_STAT_W cOCT6100_7FFF +#define cOCT6100_INVALID_ECHO_DELAY 0x400 + + + +#define cOCT6100_SIZE_128 128 +#define cOCT6100_SIZE_256 256 +#define cOCT6100_SIZE_512 512 +#define cOCT6100_SIZE_1K 1024 +#define cOCT6100_SIZE_2K 2048 +#define cOCT6100_SIZE_4K 4096 +#define cOCT6100_SIZE_8K 8192 +#define cOCT6100_SIZE_16K 16384 +#define cOCT6100_SIZE_32K 32768 +#define cOCT6100_SIZE_64K 65536 +#define cOCT6100_SIZE_128K 131072 +#define cOCT6100_SIZE_256K 262144 +#define cOCT6100_SIZE_512K 524288 +#define cOCT6100_SIZE_1M 1048576 +#define cOCT6100_SIZE_2M 2097152 +#define cOCT6100_SIZE_4M 4194304 +#define cOCT6100_SIZE_8M 8388608 +#define cOCT6100_SIZE_16M 16777216 +#define cOCT6100_SIZE_32M 33554432 +#define cOCT6100_SIZE_64M 67108864 +#define cOCT6100_SIZE_128M 134217728 +#define cOCT6100_SIZE_256M 268435456 +#define cOCT6100_SIZE_512M 536870912 +#define cOCT6100_SIZE_1G 1073741824 +#define cOCT6100_SIZE_2G 2147483648 + +#define cOCT6100_HNDL_TAG_MASK 0xFF000000 +#define cOCT6100_HNDL_INDEX_MASK 0x0000FFFF +#define cOCT6100_ENTRY_OPEN_CNT_MASK 0x000000FF +#define cOCT6100_ENTRY_OPEN_CNT_SHIFT 16 + +#define cOCT6100_HNDL_TAG_INVALID 0xFF000000 + +#define cOCT6100_HNDL_TAG_CHANNEL 0x01000000 +#define cOCT6100_HNDL_TAG_TSI_CNCT 0x02000000 +#define cOCT6100_HNDL_TAG_CONF_BRIDGE 0x03000000 +#define cOCT6100_HNDL_TAG_PHASING_TSST 0x04000000 +#define cOCT6100_HNDL_TAG_BIDIR_CHANNEL 0x05000000 +#define cOCT6100_HNDL_TAG_COPY_EVENT 0x06000000 +#define cOCT6100_HNDL_TAG_ADPCM_CHANNEL 0x07000000 + +#define cOCT6100_INVALID_HANDLE_TYPE cOCT6100_INVALID_VALUE + +#define cOCT6100_MEMORY_ROUND_SIZE 16 + +#define mOCT6100_ROUND_MEMORY_SIZE( ulMemorySize, ulTempVar ) \ + if ((ulTempVar = ulMemorySize % cOCT6100_MEMORY_ROUND_SIZE) != 0) \ + ulMemorySize += cOCT6100_MEMORY_ROUND_SIZE - ulTempVar; + +#define mOCT6100_ROUND_ADDRESS( ulAddress, ulBoundary, ulTempVar ) \ + if ((ulTempVar = ulAddress % ulBoundary) != 0) \ + ulAddress += ulBoundary - ulTempVar; + +#define cOCT6100_INTERNAL_CLOCK_SOURCE 0 +#define cOCT6100_EXTERNAL_CLOCK_SOURCE 1 + +#define cOCT6100_ACTIVE_HIGH_POLARITY 0 +#define cOCT6100_ACTIVE_LOW_POLARITY 1 + +#define cOCT6100_TDM_SAMPLE_AT_3_QUARTERS 0 +#define cOCT6100_TDM_SAMPLE_AT_RISING_EDGE 1 +#define cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE 2 + +#define cOCT6100_TDM_STREAM_FREQ_2MHZ 0 +#define cOCT6100_TDM_STREAM_FREQ_4MHZ 1 +#define cOCT6100_TDM_STREAM_FREQ_8MHZ 2 +#define cOCT6100_TDM_STREAM_FREQ_16MHZ 3 + +#define cOCT6100_TDM_STREAM_MAX_GROUPS 8 + +#define cOCT6100_PCM_U_LAW 0 +#define cOCT6100_PCM_A_LAW 1 +#define cOCT6100_PCM_UNCHANGED 2 +#define cOCT6100_ADPCM_ENCODED 3 + +#define cOCT6100_INTERRUPT_DISABLE 0 +#define cOCT6100_INTERRUPT_NO_TIMEOUT 1 +#define cOCT6100_INTERRUPT_TIMEOUT 2 + +#define cOCT6100_NUMBER_TSSTS_1 1 +#define cOCT6100_NUMBER_TSSTS_2 2 + +#define cOCT6100_G711_64KBPS 1 +#define cOCT6100_G726_40KBPS 2 +#define cOCT6100_G726_32KBPS 3 +#define cOCT6100_G726_24KBPS 4 +#define cOCT6100_G726_16KBPS 5 +#define cOCT6100_G727_40KBPS_4_1 6 +#define cOCT6100_G727_40KBPS_3_2 7 +#define cOCT6100_G727_40KBPS_2_3 8 +#define cOCT6100_G727_32KBPS_4_0 9 +#define cOCT6100_G727_32KBPS_3_1 10 +#define cOCT6100_G727_32KBPS_2_2 11 +#define cOCT6100_G727_24KBPS_3_0 12 +#define cOCT6100_G727_24KBPS_2_1 13 +#define cOCT6100_G727_16KBPS_2_0 14 +#define cOCT6100_G726_ENCODED 15 +#define cOCT6100_G711_G726_ENCODED 16 +#define cOCT6100_G711_G727_2C_ENCODED 17 +#define cOCT6100_G711_G727_3C_ENCODED 18 +#define cOCT6100_G711_G727_4C_ENCODED 19 +#define cOCT6100_G727_2C_ENCODED 20 +#define cOCT6100_G727_3C_ENCODED 21 +#define cOCT6100_G727_4C_ENCODED 22 + +#define cOCT6100_ADPCM_IN_HIGH_BITS 0 +#define cOCT6100_ADPCM_IN_LOW_BITS 1 + +/* The values of these defines must not change. */ +#define cOCT6100_H100_TRACKA 0 +#define cOCT6100_H100_TRACKB 1 +#define cOCT6100_H100_TRACKA_FALLBACKB 2 +#define cOCT6100_H100_TRACKB_FALLBACKA 3 +#define cOCT6100_H100_DISABLED 4 +#define cOCT6100_H100_MASTERA 5 +#define cOCT6100_H100_BACKUPA 6 +#define cOCT6100_H100_MASTERB 7 +#define cOCT6100_H100_BACKUPB 8 + +#define cOCT6100_FREE_TSST 0 +#define cOCT6100_RX_TSST 16 +#define cOCT6100_TX_TSST 32 + +#define cOCT6100_INTRPT_ACTIVE 0 +#define cOCT6100_INTRPT_WILL_TIMEOUT 1 +#define cOCT6100_INTRPT_IN_TIMEOUT 2 +#define cOCT6100_INTRPT_DISABLED 3 + +#define cOCT6100_EXTERNAL_MEM_BIST_TIMEOUT 1000000 + +/* Clocks defines */ +#define cOCT6100_UPCLK_FREQ_33_33_MHZ 33333333 + +#define cOCT6100_MCLK_FREQ_133_MHZ 133000000 +#define cOCT6100_MCLK_FREQ_125_MHZ 125000000 +#define cOCT6100_MCLK_FREQ_117_MHZ 117000000 +#define cOCT6100_MCLK_FREQ_108_MHZ 108000000 +#define cOCT6100_MCLK_FREQ_100_MHZ 100000000 +#define cOCT6100_MCLK_FREQ_92_MHZ 92000000 +#define cOCT6100_MCLK_FREQ_83_MHZ 83000000 +#define cOCT6100_MCLK_FREQ_75_MHZ 75000000 + +/* Tone buffer defines.*/ +#define cOCT6100_MAX_NUM_TONE_BUFFERS 1344 +#define cOCT6100_MAX_TONES_PER_CALL 32 + +/* Memory defines.*/ +#define cOCT6100_MEM_TYPE_SDR 0 +#define cOCT6100_MEM_TYPE_DDR 1 +#define cOCT6100_MEM_TYPE_SDR_PLL_BYPASS 2 + +#define cOCT6100_MEMORY_CHIP_SIZE_8MB cOCT6100_SIZE_8M +#define cOCT6100_MEMORY_CHIP_SIZE_16MB cOCT6100_SIZE_16M +#define cOCT6100_MEMORY_CHIP_SIZE_32MB cOCT6100_SIZE_32M +#define cOCT6100_MEMORY_CHIP_SIZE_64MB cOCT6100_SIZE_64M +#define cOCT6100_MEMORY_CHIP_SIZE_128MB cOCT6100_SIZE_128M + +#define cOCT6100_MAX_NUM_MEMORY_CHIP 2 + +#define cOCT6100_16MB_MEMORY_BANKS 0 +#define cOCT6100_32MB_MEMORY_BANKS 1 +#define cOCT6100_64MB_MEMORY_BANKS 2 +#define cOCT6100_128MB_MEMORY_BANKS 3 + +#define cOCT6100_1_MEMORY_BANKS 0 +#define cOCT6100_2_MEMORY_BANKS 1 +#define cOCT6100_3_MEMORY_BANKS 2 +#define cOCT6100_4_MEMORY_BANKS 3 + +/* Chip open defines.*/ +#define cOCT6100_INTERNAL_TONE_ARRAY_SIZE 256 /* in words.*/ +#define cOCT6100_INTERNAL_SUPER_ARRAY_SIZE 1024 /* in words.*/ + +/* Internal memory mapping.*/ + +/*=======================================================================*/ +#define cOCT6100_TSST_CONTROL_MEM_BASE 0x26000 + +#define cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE 2 /* Each entries are 2 bytes.*/ +#define cOCT6100_TSST_CONTROL_MEM_INPUT_TSST 0x0800 +#define cOCT6100_TSST_CONTROL_MEM_OUTPUT_TSST 0x2000 + +#define cOCT6100_TSST_CONTROL_MEM_PCM_LAW_OFFSET 12 +#define cOCT6100_TSST_CONTROL_MEM_NIBBLE_POS_OFFSET 11 +#define cOCT6100_TSST_CONTROL_MEM_TSST_NUM_OFFSET 12 + +#define cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK 0x7FF + +#define cOCT6100_TSST_CONTROL_PHASING_TSST_BASE_ENTRY 1344 +#define cOCT6100_TSST_CONTROL_TIMESTAMP_BASE_ENTRY 1516 + +/*=======================================================================*/ +#define cOCT6100_CONVERSION_CONTROL_MEM_BASE 0x28000 + +/* Each entries are 8 bytes but an 8 bytes mixer entry is located inbetween each entry.*/ +#define cOCT6100_CONVERSION_CONTROL_MEM_ENTRY_SIZE 16 +#define cOCT6100_CONVERSION_CONTROL_MEM_ENCODER 0x0000 +#define cOCT6100_CONVERSION_CONTROL_MEM_DECODER 0x8000 +#define cOCT6100_CONVERSION_CONTROL_MEM_ACTIVATE_ENTRY 0x8000 +#define cOCT6100_CONVERSION_CONTROL_MEM_RST_ON_NEXT_FR 0x8000 + +#define cOCT6100_CONVERSION_CONTROL_MEM_PHASE_OFFSET 12 +#define cOCT6100_CONVERSION_CONTROL_MEM_NIBBLE_POS_OFFSET 9 +#define cOCT6100_CONVERSION_CONTROL_MEM_COMP_OFFSET 11 +#define cOCT6100_CONVERSION_CONTROL_MEM_LAW_OFFSET 8 +#define cOCT6100_CONVERSION_CONTROL_MEM_SIL_SUP_OFFSET 8 + +#define cOCT6100_CONVERSION_CONTROL_PHASE_SIZE_BASE_ADD 0x5400 + +/*=======================================================================*/ +#define cOCT6100_MIXER_CONTROL_MEM_BASE 0x28008 + +/* Each entries are 8 bytes but an 8 bytes mixer entry is located inbetween each entry.*/ +#define cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE 16 +#define cOCT6100_MIXER_CONTROL_MEM_SUB_STORE 0xA000 +#define cOCT6100_MIXER_CONTROL_MEM_STORE 0x8000 +#define cOCT6100_MIXER_CONTROL_MEM_LOAD 0x4000 +#define cOCT6100_MIXER_CONTROL_MEM_ACCUMULATE 0x6000 +#define cOCT6100_MIXER_CONTROL_MEM_COPY 0x2000 +#define cOCT6100_MIXER_CONTROL_MEM_NO_OP 0x0000 + +#define cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET 11 + +#define cOCT6100_MIXER_HEAD_NODE 0 +#define cOCT6100_MIXER_TAIL_NODE 1 +#define cOCT6100_MIXER_RECORD_COPY_NODE 2 + +/*=======================================================================*/ +#define cOCT6100_ECHO_CONTROL_MEM_BASE 0x14000 + +#define cOCT6100_ECHO_CONTROL_MEM_ENTRY_SIZE 4 /* Each entries are 8 bytes.*/ +#define cOCT6100_ECHO_CONTROL_MEM_ACTIVATE_ENTRY 0x8000 +#define cOCT6100_ECHO_CONTROL_MEM_EXTERNAL_AF_CTRL 0x2000 + +#define cOCT6100_ECHO_CONTROL_MEM_DEBUG_OFFSET 14 +#define cOCT6100_ECHO_CONTROL_MEM_AF_CONTROL 14 +#define cOCT6100_ECHO_CONTROL_MEM_INPUT_LAW_OFFSET 12 +#define cOCT6100_ECHO_CONTROL_MEM_OUTPUT_LAW_OFFSET 11 + +#define cOCT6100_ECHO_CONTROL_MEM_TSI_MEM_MASK 0x7FF + +/*=======================================================================*/ +#define cOCT6100_ST_CONTROL_MEM_BASE 0x2000000 + +#define cOCT6100_ST_CONTROL_MEM_ENTRY_SIZE 16 /* Each entries are 8 bytes.*/ + +/*=======================================================================*/ +#define cOCT6100_PART1_BASE 0x00080000 +#define cOCT6100_PART1_CPU_LSU_CB_BASE cOCT6100_PART1_BASE+0x0000E3C0 /* 8 * 8 = 64 bytes */ +#define cOCT6100_PART1_HW_LSU_CB_BASE cOCT6100_PART1_BASE+0x0000E400 /* 8 * 128 = 1K byte */ +#define cOCT6100_PART1_END_STATICS_BASE cOCT6100_PART1_BASE+0x0000E9F0 /* 912 bytes available for your viewing pleasure. */ +#define cOCT6100_PART1_API_SCRATCH_PAD cOCT6100_PART1_END_STATICS_BASE+4+(12*8) +#define cOCT6100_PART1_EGO_REG cOCT6100_PART1_BASE+0x0007FF00 + +/* External Memory mapping. */ +#define cOCT6100_EXTERNAL_MEM_BLOCK_SIZE 1024 +#define cOCT6100_EXTERNAL_MEM_BASE_ADDRESS 0x08000000 + + +#define cOCT6100_TLV_BASE ( 0x00016000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) +#define cOCT6100_CHANNEL_ROOT_BASE ( 0x00020000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) +#define cOCT6100_PGSP_EVENT_OUT_BASE ( 0x002C0000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) +#define cOCT6100_POUCH_BASE ( 0x002E0000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) +#define cOCT6100_IMAGE_FILE_BASE ( 0x00300000 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) + +#define cOCT6100_CHANNEL_ROOT_SIZE 4096 +#define cOCT6100_CHANNEL_ROOT_TOTAL_SIZE ( 672 * cOCT6100_CHANNEL_ROOT_SIZE ) +#define cOCT6100_PGSP_EVENT_OUT_SIZE 131072 +#define cOCT6100_PGSP_TONE_EVENT_SIZE 0x40 +#define cOCT6100_IMAGE_FILE_SIZE 0x100000 + +#define cOCT6100_MATRIX_TIMESTAMP_DWORD_ADD cOCT6100_POUCH_BASE + 0x8 +#define cOCT6100_MATRIX_CHAN_SELECT_DWORD_ADD cOCT6100_POUCH_BASE + 0x14 +#define cOCT6100_MATRIX_WRITE_PTR_DWORD_ADD cOCT6100_POUCH_BASE + 0x4 +#define cOCT6100_MATRIX_PLL_JITTER_COUNT_ADD cOCT6100_POUCH_BASE + 0x1C +#define cOCT6100_MATRIX_DWORD_BASE cOCT6100_POUCH_BASE + 0xE0000 + +#define cOCT6100_CHANNEL_ROOT_GLOBAL_CONF_OFFSET 0x0000 + +#define cOCT6100_NUM_WORDS_PER_TONE_EVENT 32 +#define cOCT6100_NUM_PGSP_EVENT_OUT 2048 +#define cOCT6100_VALID_TONE_EVENT 0x8000 +#define cOCT6100_LOCAL_TIMESTAMP_INCREMENT 32 /* 4 ms increment. */ +#define cOCT6100_ABSOLUTE_MAX_NUM_PGSP_EVENT_OUT 65535 +#define cOCT6100_MIN_TIMESLOT_FOR_TIMESTAMP 5 + + +/*=======================================================================*/ +#define cOCT6100_GSC_PGSP_CONTEXT_BASE_ADD_OFFSET 0x0C +#define cOCT6100_GSC_PGSP_INIT_CONTEXT_BASE_ADD_OFFSET 0x10 +#define cOCT6100_GSC_RIN_CIRC_BUFFER_BASE_ADD_OFFSET 0x14 +#define cOCT6100_GSC_SIN_CIRC_BUFFER_BASE_ADD_OFFSET 0x18 +#define cOCT6100_GSC_SOUT_CIRC_BUFFER_BASE_ADD_OFFSET 0x1C + +#define cOCT6100_GSC_BUFFER_LAW_OFFSET 27 + +/*=======================================================================*/ +#define cOCT6100_CH_MAIN_PGSP_CONTEXT_OFFSET 0x00000 +#define cOCT6100_CH_MAIN_TONE_EVENT_OFFSET 0x00488 + +/*=======================================================================*/ +#define cOCT6100_PLAYOUT_EVENT_REPEAT_OFFSET 31 +#define cOCT6100_PLAYOUT_EVENT_LAW_OFFSET 30 +#define cOCT6100_PLAYOUT_EVENT_MIX_OFFSET 28 +#define cOCT6100_PLAYOUT_EVENT_LOOP_TIMES_OFFSET 27 +#define cOCT6100_PLAYOUT_EVENT_GAIN_OFFSET 24 + +#define cOCT6100_PLAYOUT_EVENT_MEM_SIZE 16 + +/* Image related defines.*/ +#define cOCT6100_MIN_IMAGE_SIZE 0x001000 +#define cOCT6100_MAX_IMAGE_SIZE 0x100000 +#define cOCT6100_MAX_IMAGE_REGION 60 +#define cOCT6100_IMAGE_AF_CST_OFFSET 0x1000; + +/* Max defines.*/ +#define cOCT6100_MAX_ECHO_CHANNELS 672 +#define cOCT6100_MAX_TSI_CNCTS 1530 +#define cOCT6100_MAX_CALLER_ID_PLAYOUT_BUFFERS ( 3328 + 6 ) +#define cOCT6100_MAX_PLAYOUT_BUFFERS ( 1344 + cOCT6100_MAX_CALLER_ID_PLAYOUT_BUFFERS ) +#define cOCT6100_MAX_CONF_BRIDGE 672 +#define cOCT6100_MAX_FLEX_CONF_PARTICIPANTS cOCT6100_MAX_ECHO_CHANNELS +#define cOCT6100_MAX_PHASING_TSST 16 +#define cOCT6100_MAX_ADPCM_CHANNELS 672 + +#define cOCT6100_NUM_TSI_B4_PHASING 1344 +#define cOCT6100_TOTAL_TSI_CONTROL_MEM_ENTRY 1534 +#define cOCT6100_MAX_TSI_CONTROL_MEM_ENTRY 1344 +#define cOCT6100_MAX_ECHO_CONTROL_MEM_ENTRY 672 +#define cOCT6100_MAX_TSI_B4_TIMESTAMP 172 +#define cOCT6100_TSI_MEM_FOR_TIMESTAMP 4 +#define cOCT6100_API_EXT_TONE_EXTRA_TSI 1533 + +/* Echo channel ports */ +#define cOCT6100_CHANNEL_PORT_RIN 0 +#define cOCT6100_CHANNEL_PORT_ROUT 1 +#define cOCT6100_CHANNEL_PORT_SIN 2 +#define cOCT6100_CHANNEL_PORT_SOUT 3 +#define cOCT6100_CHANNEL_PORT_ROUT_SOUT 4 + +#define cOCT6100_NO_ENCODING 10 +#define cOCT6100_NO_DECODING 11 + +/* Buffer playout defines */ +#define cOCT6100_NO_SKIP 0 +#define cOCT6100_BUFFER_PLAYOUT_MIN_SIZE 1024 +#define cOCT6100_DEFAULT_TIMESTAMP 0 +#define cOCT6100_MIXING_0_DB 0 +#define cOCT6100_MIXING_MINUS_6_DB 1 +#define cOCT6100_MIXING_MINUS_12_DB 2 +#define cOCT6100_MIXING_MUTE 3 +#define cOCT6100_PLAYOUT_GAIN 0x41000000 +#define cOCT6100_PLAYOUT_EVENT 1 +#define cOCT6100_MINIMUM_BUFFER_SIZE 64 +#define cOCT6100_BUFFER_SIZE_GRANULARITY 16 +#define cOCT6100_REPEAT_INFINITELY cOCT6100_INVALID_VALUE +#define cOCT6100_REPEAT_MAX 32767 +#define cOCT6100_SAMPLES_PER_MS 8 + +/* For the playout events. */ +#define cOCT6100_MAX_BUFFER_PLAYOUT_EVENT_PER_CALL 32 +#define cOCT6100_MIN_BUFFER_PLAYOUT_EVENT 128 +#define cOCT6100_MAX_BUFFER_PLAYOUT_EVENT 65535 +/* Event types */ +#define cOCT6100_BUFFER_PLAYOUT_EVENT_INVALID cOCT6100_INVALID_VALUE +#define cOCT6100_BUFFER_PLAYOUT_EVENT_STOP 1 + + +/* Phasing defines.*/ +#define cOCT6100_SINGLE_PHASING 0 +#define cOCT6100_DUAL_PHASING 1 +#define cOCT6100_NO_PHASING 2 + +/* Echo canceller mode.*/ +#define cOCT6100_ELECTRIC_EC 0 +#define cOCT6100_ELECTRIC_EC_DISPLACEMENT 1 +#define cOCT6100_ACCOUSTIC_ES 2 + +/* Echo control modes.*/ +#define cOCT6100_ECHO_OP_MODE_NORMAL 0 +#define cOCT6100_ECHO_OP_MODE_HT_FREEZE 1 +#define cOCT6100_ECHO_OP_MODE_HT_RESET 2 +#define cOCT6100_ECHO_OP_MODE_POWER_DOWN 3 +#define cOCT6100_ECHO_OP_MODE_EXTERNAL 4 +#define cOCT6100_ECHO_OP_MODE_NO_ECHO 5 +#define cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION 6 +#define cOCT6100_ECHO_OP_MODE_G169_ALC cOCT6100_ECHO_OP_MODE_NO_ECHO + +/* 2100 Hz disabling configuration. */ +#define cOCT6100_NEVER_DISABLED 0 +#define cOCT6100_G164_2100_HZ 1 +#define cOCT6100_G165_2100_HZ_WITH_PHASE_REV 2 + +/* TSST defines.*/ +#define cOCT6100_UNASSIGNED cOCT6100_FFFD + +#define cOCT6100_MAX_TSSTS 4096 +#define cOCT6100_TWO_TSSTS_INDEX_MASK 0x8000 +#define cOCT6100_TSST_INDEX_MASK 0x7FFF +#define cOCT6100_INPUT_TSST 0 +#define cOCT6100_OUTPUT_TSST 1 + +/* Conference bridges defines.*/ +#define cOCT6100_MAX_MIXER_EVENTS 1344 +#define cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE 32 +#define cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED 672 +#define cOCT6100_CONF_NO_DOMINANT_SPEAKER_HNDL cOCT6100_FFFFFFFE + +/* Conversion memory defines.*/ +#define cOCT6100_MAX_CONVERSION_MEMORY_BLOCKS 1344 + +/* Tone detection defines.*/ +#define cOCT6100_MAX_TONE_NUMBER 55 + +/* Register definition and address. */ +#define cOCT6100_TONE_EVENT_WRITE_PTR_REG 0x722 +#define cOCT6100_TONE_EVENT_READ_PTR_REG 0x720 + +/* Special Signaling tone IDs. */ +#define cOCT6100_TONE_SIN_SYSTEM7_2000 0x20000023 +#define cOCT6100_TONE_SIN_SYSTEM7_1780 0x20000024 +#define cOCT6100_TONE_ROUT_G168_2100GB_ON 0x10000000 +#define cOCT6100_TONE_ROUT_G168_2100GB_WSPR 0x10000002 +#define cOCT6100_TONE_ROUT_G168_1100GB_ON 0x10000004 +#define cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_A 0x10000005 +#define cOCT6100_TONE_ROUT_G168_2100GB_ON_WIDE_B 0x10000006 +#define cOCT6100_TONE_ROUT_G168_2100GB_WSPR_WIDE 0x10000008 +#define cOCT6100_TONE_SOUT_G168_2100GB_ON 0x40000000 +#define cOCT6100_TONE_SOUT_G168_2100GB_WSPR 0x40000002 +#define cOCT6100_TONE_SOUT_G168_1100GB_ON 0x40000004 +#define cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_A 0x40000005 +#define cOCT6100_TONE_SOUT_G168_2100GB_ON_WIDE_B 0x40000006 +#define cOCT6100_TONE_SOUT_G168_2100GB_WSPR_WIDE 0x40000008 +#define cOCT6100_TONE_SIN_SYSTEM5_2400 0x20000020 +#define cOCT6100_TONE_SIN_SYSTEM5_2600 0x20000021 +#define cOCT6100_TONE_SIN_SYSTEM5_2400_2600 0x20000022 + +#define cOCT6100_CHIP_ID_REVISION_REG 0x17E + +/* BOOT type. */ +#define cOCT6100_AF_BOOT_TYPE 0x5 +#define cOCT6100_PRODUCTION_BOOT_TYPE 0x7 +#define cOCT6100_PRODUCTION_SHORT_BOOT_TYPE 0x8 + +/*Production Bist Modes*/ +#define cOCT6100_PRODUCTION_BIST_STANDARD 0x0 +#define cOCT6100_PRODUCTION_BIST_SHORT 0x1 + +/* Interrupt register masks.*/ +#define cOCT6100_INTRPT_MASK_REG_102H 0x0001 +#define cOCT6100_INTRPT_MASK_REG_202H 0x1C01 +#define cOCT6100_INTRPT_MASK_REG_302H 0xF100 +#define cOCT6100_INTRPT_MASK_REG_502H 0x0002 +#define cOCT6100_INTRPT_MASK_REG_702H 0x0002 + +#define cOCT6100_DECODER_MEMORY_OFFSET 672 + +/* Debug defines.*/ +#define cOCT6100_DEBUG_MAX_READ_LENGTH 10240 +#define cOCT6100_DEBUG_SOUT_MAX_READ_LENGTH 2560 +#define cOCT6100_DEBUG_CHAN_RECORD_INDEX 64 +#define cOCT6100_DEBUG_RECORD_BUFFER_BYTE_SIZE 0x20000 +#define cOCT6100_DEBUG_RECORD_MATRIX_SIZE 0x8000 +#define cOCT6100_DEBUG_RECORD_READ_DATA_BYTE_SIZE 1024 +#define cOCT6100_DEBUG_RECORD_BLOCK_BYTE_SIZE 0x1000 + +/* Tone event defines.*/ +#define cOCT6100_MAX_TONE_EVENT 56 +#define cOCT6100_TONE_PRESENT 0 +#define cOCT6100_TONE_STOP 1 +#define cOCT6100_TONE_REFRESH 2 + +/* TLV defines.*/ +#define cOCT6100_TLV_MAX_ADDRESS 0x10000000 +#define cOCT6100_TLV_MAX_TONE_NAME_SIZE 64 + +#define cOCT6100_VERSION_NUMBER_MAX_SIZE 1016 + +/* Echo Tail defines.*/ +#define cOCT6100_TAIL_LENGTH_32MS 32 +#define cOCT6100_TAIL_LENGTH_64MS 64 +#define cOCT6100_TAIL_LENGTH_128MS 128 +#define cOCT6100_MAX_ECHO_TAIL_DISPLACEMENT 5600 /* In milliseconds */ + + + + + +/* Generic loop counter.*/ +#define cOCT6100_MAX_LOOP 0x2000 +/* CPU boot timeout counter. */ +#define cOCT6100_MAX_LOOP_CPU_TIMEOUT 0x20000 + +/* Automatic level control */ +#define cOCT6100_PASS_THROUGH_LEVEL_CONTROL 0x90 + +/* Channel stats debug info */ +#define cOCT6100_DEBUG_CHAN_STATS_EVENT_BYTE_SIZE 1024 +#define cOCT6100_DEBUG_CHAN_STATS_LITE_EVENT_BYTE_SIZE 720 + +/* Image start string define */ +#define cOCT6100_IMAGE_START_STRING "EDS3_IMAGE_NAME" + +/* Tone image info defines.*/ +#define cOCT6100_TONE_INFO_START_STRING "[ToneDetectorInfo]" +#define cOCT6100_TONE_INFO_STOP_STRING "[~ToneDetectorInfo]" +#define cOCT6100_TONE_INFO_EVENT_STRING "TONEEVENT=0x" + +#define cOCT6100_MAX_NLP_CONF_DWORD 20 + +/* Tail displacement info.*/ +#define cOCT6100_MAX_TAIL_DISPLACEMENT 896 + +/* Comfort noise define */ +#define cOCT6100_COMFORT_NOISE_NORMAL 0x0 +#define cOCT6100_COMFORT_NOISE_EXTENDED 0x3 +#define cOCT6100_COMFORT_NOISE_OFF 0x2 +#define cOCT6100_COMFORT_NOISE_FAST_LATCH 0x1 + +/* Mixer event type.*/ +#define cOCT6100_EVENT_TYPE_SOUT_COPY 0x0 +#define cOCT6100_EVENT_TYPE_SIN_COPY 0x1 + +/* Tone disabler status.*/ +#define cOCT6100_TONE_DISABLER_EC_ENABLED 0 +#define cOCT6100_TONE_DISABLER_EC_DISABLED 1 + +/* ADPCM Channel defines */ +#define cOCT6100_ADPCM_ENCODING 0 +#define cOCT6100_ADPCM_DECODING 1 + +/* Double talk behavior modes. */ +#define cOCT6100_DOUBLE_TALK_BEH_NORMAL 0x0 +#define cOCT6100_DOUBLE_TALK_BEH_LESS_AGGRESSIVE 0x1 + +/* Api Version string length.*/ +#define cOCT6100_API_VERSION_STRING_LENGTH 32 + +/* Extended tone detection information. */ +#define cOCT6100_API_EXT_TONE_DISABLED 0 +#define cOCT6100_API_EXT_TONE_SIN_PORT_MODE 1 +#define cOCT6100_API_EXT_TONE_RIN_PORT_MODE 2 + + + +/* Mute/UnMute defines. */ +#define cOCT6100_CHANNEL_MUTE_PORT_NONE 0x00 +#define cOCT6100_CHANNEL_MUTE_PORT_RIN 0x01 +#define cOCT6100_CHANNEL_MUTE_PORT_ROUT 0x02 +#define cOCT6100_CHANNEL_MUTE_PORT_SIN 0x04 +#define cOCT6100_CHANNEL_MUTE_PORT_SOUT 0x08 +#define cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES 0x10 + +/* Debug get data dump modes. */ +#define cOCT6100_DEBUG_GET_DATA_MODE_16S_LITE 0x0 +#define cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE 0x1 +#define cOCT6100_DEBUG_GET_DATA_MODE_16S 0x2 +#define cOCT6100_DEBUG_GET_DATA_MODE_120S 0x3 + +/* Debug get data dump content. */ +#define cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE 0x0 /* Full binary dump to be sent for support. */ +#define cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM 0x1 /* Only Rin PCM stream data. */ +#define cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM 0x2 /* Only Sin PCM stream data. */ +#define cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM 0x3 /* Only Sout PCM stream data. */ + + + +#define cOCT6100_BIST_IN_PROGRESS 0x0 +#define cOCT6100_BIST_CONFIGURATION_FAILED 0x1 +#define cOCT6100_BIST_STATUS_CRC_FAILED 0x2 +#define cOCT6100_BIST_MEMORY_FAILED 0x3 +#define cOCT6100_BIST_SUCCESS 0x4 + +/* Image types. */ +#define cOCT6100_IMAGE_TYPE_WIRELINE 0x0 +#define cOCT6100_IMAGE_TYPE_COMBINED 0x1 + +/* Fatal general error types. */ +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_1 0x0001 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_2 0x0002 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_3 0x0004 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_4 0x0008 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_5 0x0010 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_6 0x0020 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_7 0x0040 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_8 0x0080 +#define cOCT6100_FATAL_GENERAL_ERROR_TYPE_9 0x0100 + +#endif /* __OCT6100_DEFINES_H__ */ + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_errors.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_errors.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_errors.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_errors.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,838 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_errors.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Header file containing all defines used for error codes. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 205 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_ERRORS_H__ +#define __OCT6100_ERRORS_H__ + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +/***************************** DEFINES *************************************/ + +#define cOCT6100_ERR_OK 0x00000000 +#define cOCT6100_ERR_BASE 0x00100000 + +#define cOCT6100_NOT_SUPPORTED_BASE (0xFF000 + cOCT6100_ERR_BASE) + +/* Not supported defines. */ +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_DEBUG_RECORD (0x00000 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NLP_CONTROL (0x00001 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_BKG_NOISE_FREEZE (0x00002 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIN_DC_OFFSET_REM (0x00003 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_DC_OFFSET_REM (0x00004 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_AUTO_LC (0x00005 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SOUT_AUTO_LC (0x00006 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR (0x00007 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TAIL_DISPLACEMENT (0x00008 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ENCODING (0x00009 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DECODING (0x0000A + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_LAW_TRANSLATION (0x0000B + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ACOUSTIC_ECHO (0x0000C + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DEFAULT_ERL (0x0000D + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DOUBLE_TALK (0x0000E + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NON_LINEARITY_B (0x0000F + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_AEC_DEFAULT_ERL (0x00010 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_HIGH_LEVEL_COMP (0x00011 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_PER_CHAN_TAIL (0x00012 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIL_SUP (0x00013 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_ACOUSTIC_ECHO (0x00014 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_TAIL_DISPLACEMENT_VALUE (0x00015 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_MAX_ECHO_CHANNELS_VALUE (0x00016 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ALE (0x00017 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NLE (0x00018 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ROUT_NR (0x00019 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIN_MUTE_FEATURES (0x0001A + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR_SNR_ENHANCEMENT (0x0001B + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR_SEGREGATION (0x0001C + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_OPEN_USE_SYNCH_TIMESTAMP (0x0001D + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TAIL_LENGTH (0x0001E + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TONE_DISABLER_ACTIVATION_DELAY (0x0001F + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ACOUSTIC_ECHO_TAIL_LENGTH (0x00020 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_MUSIC_PROTECTION (0x00021 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_DEBUG_DATA_MODE_120S (0x00022 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_TONE_NOT_PRESENT_IN_FIRMWARE (0x00023 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_DOUBLE_TALK_BEHAVIOR_MODE (0x00024 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_IDLE_CODE_DETECTION (0x00025 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_IDLE_CODE_DETECTION_CONFIG (0x00026 + cOCT6100_NOT_SUPPORTED_BASE) + + +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ROUT_NOISE_REDUCTION_GAIN (0x0002B + cOCT6100_NOT_SUPPORTED_BASE) + +#define cOCT6100_ERR_NOT_SUPPORTED_BUFFER_PLAYOUT (0x00100 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_CNR (0x00101 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CONF_BRIDGE (0x00102 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CALLER_ID (0x00104 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NOISE_BLEACHING (0x00105 + cOCT6100_NOT_SUPPORTED_BASE) + +#define cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TONE_REMOVAL (0x00300 + cOCT6100_NOT_SUPPORTED_BASE) +#define cOCT6100_ERR_NOT_SUPPORTED_DOMINANT_SPEAKER (0x00301 + cOCT6100_NOT_SUPPORTED_BASE) + + + +#define cOCT6100_ERR_OPEN_INVALID_DEVICE (0x03000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INSUFFICIENT_EXTERNAL_MEMORY (0x03001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MEMORY_CHIP_SIZE (0x03002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_UP_CLK_FREQ (0x03003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_USER_CHIP_ID (0x03004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MULTI_PROCESS_SYSTEM (0x03005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_RW_ACCESSES (0x03006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_IMAGE_SIZE (0x03007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_IMAGE_FILE (0x03008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MEM_CLK_FREQ (0x03009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MEMORY_CHIPS_NUMBER (0x0300A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TOTAL_MEMORY_SIZE (0x0300B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_USE_SYNCH_TIMESTAMP (0x0300C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TIMESTAMP_STREAM (0x0300D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TIMESTAMP_TIMESLOT (0x0300E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TIMESTAMP_TSSTS (0x0300F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TDM_STREAM_FREQS (0x03010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TDM_SAMPLING (0x03011 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FAST_H100_MODE (0x03012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_ECHO_CHANNELS (0x03013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_PLAYOUT_BUFFERS (0x03014 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_TSI_CNCTS (0x03015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_PHASING_TSSTS (0x03016 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_EXTERNAL_MEM_BIST_FAILED (0x03017 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_EXTERNAL_MEM_BIST_TIMEOUT (0x03018 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_SDRAM_BIST_FAILED (0x03019 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_CORRUPTED_IMAGE (0x0301A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR (0x0301B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_SOFT_TONE_EVENT_SIZE (0x0301C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INTERRUPT_POLARITY (0x0301D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FATAL_GENERAL_CONFIG (0x0301E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_REMOTE_DEBUG_SESSIONS (0x0301F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ENABLE_MEM_CLK_OUT (0x03020 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_TDM_STREAM (0x03021 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_CONF_BRIDGES (0x03022 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_AF_CPU_TIMEOUT (0x03024 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MEMORY_TYPE (0x03025 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FATAL_MEMORY_CONFIG (0x03026 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_MEMORY_CONFIG (0x03027 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_CONFIG (0x03028 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_H100_CONFIG (0x03029 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FATAL_MEMORY_TIMEOUT (0x0302A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_MEMORY_TIMEOUT (0x0302B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_TIMEOUT (0x0302C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ERROR_H100_TIMEOUT (0x0302D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_IMAGE_WRITE_FAILED (0x0302E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_CRC_ERROR (0x0302F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_EGO_TIMEOUT (0x03030 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_SOFT_DEBUG_EVENT_BUF_SIZE (0x03031 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TONE_INFO_START_TAG_NOT_FOUND (0x03032 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TONE_INFO_STOP_TAG_NOT_FOUND (0x03033 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_TONE_EVENT (0x03034 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_TONE_NAME (0x03035 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_EVENT_NUMBER_SIZE (0x03036 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INTERNAL_MEMORY_BIST (0x03037 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_TAIL_DISPLACEMENT (0x03038 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_DEBUG_CHANNEL_RECORDING (0x03039 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_BIDIR_CHANNELS (0x0303A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_FUNCTIONAL_BIST_FAILED (0x0303C + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_MAX_ADPCM_CHANNELS (0x0303E + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_ENABLE_EXT_TONE_DETECTION (0x03040 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_SOFT_PLAYOUT_STOP_EVENT_SIZE (0x03041 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_FIRMWARE_OR_CAPACITY_PINS (0x03042 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ENABLE_ACOUSTIC_ECHO (0x03043 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_USER_WRITE_BURST_FAILED (0x03045 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_USER_WRITE_SMEAR_FAILED (0x03046 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_USER_READ_BURST_FAILED (0x03047 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_MAX_FLEXIBLE_CONF_PARTICIPANTS (0x03048 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_DEBUG_MEM_INDEX (0x03051 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_ENABLE_CALLER_ID (0x03052 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_CALLER_ID_PLAYOUT_BUFFERS (0x03053 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_ENABLE_PRODUCTION_BIST (0x03055 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BIST_ACTIVATED (0x03056 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_NUM_PRODUCTION_BIST_LOOPS (0x03057 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BOOT_FAILED (0x03058 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BIST_CONF_FAILED (0x03059 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BIST_POUCH_ERROR (0x0305A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_INVALID_TLV_LENGTH (0x0305B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_OPEN_PRODUCTION_BIST_MODE (0x0305C + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_OPEN_ENABLE_2100_STOP_EVENT (0x03060 + cOCT6100_ERR_BASE) + + +#define cOCT6100_ERR_CAP_PINS_INVALID_CHIP_STATE (0x03081 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CAP_PINS_INVALID_CAPACITY_VALUE (0x03082 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_TSI_CNCT_ALL_CHANNELS_ARE_OPENED (0x04000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_DISABLED (0x04001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_INVALID_HANDLE (0x04002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_INPUT_TIMESLOT (0x04003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_INPUT_STREAM (0x04004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_OUTPUT_TIMESLOT (0x04005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_OUTPUT_STREAM (0x04006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_INPUT_PCM_LAW (0x04007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_TIMESLOT (0x04008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_STREAM (0x04009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_TSST_RESERVED (0x0400A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_NOT_OPEN (0x0400B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_ASSOCIATED_TSST_RESERVED (0x0400C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSI_CNCT_NO_MORE_TSI_AVAILABLE (0x0400D + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_BUFFER_PLAYOUT_DISABLED (0x05000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_PATTERN (0x05001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_TOO_SMALL (0x05002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_PCM_LAW (0x05003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ALL_BUFFERS_OPEN (0x05004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_BUF_SIZE (0x05005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_BUF_INDEX (0x05006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN (0x05007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ACTIVE_DEPENDENCIES (0x05008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_HANDLE_INVALID (0x05009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_CHANNEL_NOT_OPEN (0x0500A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ROUT_PORT_PLAYING (0x0500B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_SOUT_PORT_PLAYING (0x0500C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_PORT_INVALID (0x0500D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_PLAYOUT_PORT (0x0500E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_EVENT_BUF_FULL (0x0500F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_REPEAT (0x05010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_MIXING (0x05011 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_STOP_CLEANLY (0x05012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NOT_STARTED (0x05013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_WRITE_BYTE_COUNT (0x05015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ECHO_OP_MODE (0x05016 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_BLOCK_LENGTH_INVALID (0x05017 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_BLOCK_OFFSET_INVALID (0x05018 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_RESET (0x05019 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_BUF_EMPTY (0x0501A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_MAX_EVENT (0x0501B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_DISABLED (0x0501C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NOTIFY_ON_STOP (0x0501D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ALLOW_ACTIVE (0x0501E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_STILL_ACTIVE (0x0501F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_REPEAT_USED (0x05020 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NLP_DISABLED (0x05021 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_MALLOC_ZERO (0x05022 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_NO_MEMORY (0x05023 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_MALLOC_POINT_NOT_FOUND (0x05024 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_REPEAT_COUNT (0x05025 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_ADD_GAIN_DB (0x05026 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_BUFFER_PLAYOUT_LIST_EMPTY (0x05027 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_MEMORY_ALL_TSI_MEM_ENTRY_RESERVED (0x06000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MEMORY_ALL_ECHO_MEM_ENTRY_RESERVED (0x06002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MEMORY_EXTERNAL_MEMORY_FULL (0x06003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MEMORY_ALL_CONVERSION_MEM_ENTRY_RESERVED (0x06004 + cOCT6100_ERR_BASE) + + +#define cOCT6100_ERR_CHANNEL_DISABLED (0x07000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_INVALID_HANDLE (0x07001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_NUM_TSSTS (0x07002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_NUM_TSSTS (0x07003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_NUM_TSSTS (0x07004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_NUM_TSSTS (0x07005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_TIMESLOT (0x07006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_STREAM (0x07007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_TIMESLOT (0x07008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_STREAM (0x07009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT (0x0700A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_STREAM (0x0700B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT (0x0700C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_STREAM (0x0700D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MISSING_TSST (0x07012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIL_SUP_ENABLE (0x07013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASING_TYPE (0x07014 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_INVALID_PHASING_HANDLE (0x07015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASING_TSST_NOT_OPEN (0x07016 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASING_INVALID_PHASE (0x07017 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DEBUG (0x07018 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE (0x0701F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_DC_OFFSET_REM (0x07020 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_DC_OFFSET_REM (0x07021 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_LEVEL_CONTROL (0x07022 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_LEVEL_CONTROL (0x07023 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_LEVEL_CONTROL_GAIN (0x07024 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_LEVEL_CONTROL_GAIN (0x07025 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_ADAPT_NOISE_REDUCTION (0x07026 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALL_CHANNELS_ARE_OPENED (0x07027 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NOT_OPEN (0x07029 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ADPCM_NIBBLE (0x0702A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_ADD_PORT (0x0702B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_ADD_TIMESLOT (0x0702C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_ADD_STREAM (0x0702D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_INVALID (0x0702E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_PCM_LAW (0x0702F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_PCM_LAW (0x07030 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_PCM_LAW (0x07031 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_PCM_LAW (0x07032 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DECODER_PORT (0x07033 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENCODER_PORT (0x07034 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DECODING_RATE (0x07035 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENCODING_RATE (0x07036 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENABLE_NLP (0x07037 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_COMFORT_NOISE_MODE (0x07038 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASING_TSST_REQUIRED (0x07039 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIL_SUP_INVALID_ENCODER_PORT (0x0703A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MODIFY_CODEC_CONFIG (0x0703B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MODIFY_VQE_CONFIG (0x0703C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MODIFY_TDM_CONFIG (0x0703D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_RIN_PORT_INVALID (0x0703E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_SIN_PORT_INVALID (0x0703F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_PORT (0x07041 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_TIMESLOT (0x07042 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_STREAM (0x07043 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_INVALID_TSST (0x07044 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_GET_STATS_MAX_BROADCAST_TSST (0x07045 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_BROADCAST_TIMESLOT (0x07046 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_BROADCAST_STREAM (0x07047 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_BROADCAST_TIMESLOT (0x07048 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_BROADCAST_STREAM (0x07049 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACTIVE_DEPENDENCIES (0x0704A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TONE_DISABLER_ENABLE (0x0704B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TAIL_LENGTH (0x07053 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TAIL_DISPLACEMENT (0x07054 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_INVALID_RIN_CB_SIZE (0x07058 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TSST_REMOVE_NO_BROADCAST_TSST (0x07059 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_INVALID_CODEC_POSITION (0x0705A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_STATS_RESET (0x0705B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENABLE_TAIL_DISPLACEMENT (0x0705C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE (0x0705E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_FIRST_CHANNEL_HANDLE (0x0705F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_SECOND_CHANNEL_HANDLE (0x07060 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED (0x07061 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALREADY_BIDIR (0x07062 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALL_BIDIR_CHANNELS_ARE_OPENED (0x07063 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_FIRST_CHAN_SOUT_PORT (0x07064 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_FIRST_CHAN_RIN_PORT (0x07065 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SECOND_CHAN_SOUT_PORT (0x07066 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SECOND_CHAN_RIN_PORT (0x07067 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_PCM_LAW (0x07068 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_BIDIR_CHAN_NOT_OPEN (0x07069 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_ROUT_LAW_CONVERSION (0x0706A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_SOUT_LAW_CONVERSION (0x0706B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PART_OF_BIDIR_CHANNEL (0x0706C + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_NO_VALID_TDM_CLOCKS (0x0706E + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_OUT_OF_TSI_MEMORY (0x07073 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TONE_REMOVAL (0x07075 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO (0x07077 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DEFAULT_ERL (0x07079 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DOUBLE_TALK (0x0707B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PHASE_TYPE_REQUIRED (0x0707C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIL_SUP_NLP_MUST_BE_ENABLED (0x0707D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENABLE_EXT_TONE_DETECTION (0x0707E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DECODER_PORT (0x0707F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DISABLED (0x07080 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NON_LINEARITY_B (0x07082 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_FIRST_CHAN_IN_CONFERENCE (0x07083 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SECOND_CHAN_IN_CONFERENCE (0x07084 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TAIL_DISPLACEMENT_CANNOT_MODIFY (0x07085 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NON_LINEARITY_B_CANNOT_MODIFY (0x07086 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_NOT_ENABLED (0x07087 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_BIDIR_DISABLED (0x0708B + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_TAIL_DISPLACEMENT_INVALID (0x0708D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_PER_CHAN_TAIL_DISPLACEMENT (0x0708E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_CONFERENCE_NOISE_REDUCTION (0x0708F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_AEC_DEFAULT_ERL (0x07092 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED (0x07093 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL (0x07094 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL (0x07095 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL_TARGET (0x07096 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL_TARGET (0x07097 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_MANUAL (0x07098 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_MANUAL (0x07099 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP (0x0709A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_HIGH_LEVEL_COMP (0x0709C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP_MANUAL (0x0709D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP_THRESHOLD (0x0709E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MUTE_MASK (0x0709F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MUTE_MASK_SIN (0x070A0 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALE_RATIO (0x070A1 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NLE_FLAG (0x070A2 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ALE_NLE_SIMULTANEOUSLY (0x070A3 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_NOISE_REDUCTION (0x070A4 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ANR_SNR_ENHANCEMENT (0x070A5 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ANR_SEGREGATION (0x070A6 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_NLE_RATIO (0x070A7 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_APPLY_TO_ALL_CHANNELS (0x070A8 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_STREAM_UNASSIGN (0x070A9 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT_UNASSIGN (0x070AA + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_STREAM_UNASSIGN (0x070AB + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_RIN_TIMESLOT_UNASSIGN (0x070AC + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_STREAM_UNASSIGN (0x070AD + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT_UNASSIGN (0x070AE + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_STREAM_UNASSIGN (0x070AF + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SIN_TIMESLOT_UNASSIGN (0x070B0 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DISABLE_TONE_DETECTION (0x070B1 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_STOP_BUFFER_PLAYOUT (0x070B2 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_REMOVE_CONF_BRIDGE_PARTICIPANT (0x070B3 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_REMOVE_BROADCAST_TSSTS (0x070B4 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TONE_DISABLER_ACTIVATION_DELAY (0x070B5 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_OUT_OF_MIXER_EVENTS (0x070B8 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_TAIL_LENGTH (0x070B9 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ENABLE_MUSIC_PROTECTION (0x070BA + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_TAIL_LENGTH_INVALID (0x070BB + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_TAIL_SUM (0x070BC + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_DOUBLE_TALK_MODE (0x070BD + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_NOISE_BLEACHING (0x070BE + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_NOISE_BLEACHING_NR (0x070BF + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ANR_CNR_SIMULTANEOUSLY (0x070C0 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_IDLE_CODE_DETECTION (0x070C1 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_MUST_ENABLE_TONE_DISABLER (0x070C2 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL_REQUIRED (0x070C5 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL_REQUIRED (0x070C6 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_AUTO_LEVEL_CONTROL_REQUIRED (0x070C8 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHANNEL_COMFORT_NOISE_REQUIRED (0x070CB + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CHANNEL_ROUT_NOISE_REDUCTION_GAIN (0x070CC + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_PHASING_TSST_ALL_ENTRIES_ARE_OPENED (0x08000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_DISABLED (0x08001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_INVALID_HANDLE (0x08002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_TIMESLOT (0x08003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_STREAM (0x08004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_PHASING_LENGTH (0x08005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_NOT_OPEN (0x08006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_PHASING_TSST_ACTIVE_DEPENDENCIES (0x08007 + cOCT6100_ERR_BASE) + + +#define cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE (0x09000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_DISABLED (0x09001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN (0x09002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_ACTIVE_DEPENDENCIES (0x09003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_HANDLE (0x09004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_MIXER_EVENT_NOT_FOUND (0x09005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_ALL_BUFFERS_OPEN (0x09006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_REMOVE_INVALID_HANDLE (0x09007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHAN_NOT_ON_BRIDGE (0x09008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_MUTE (0x09009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_INVALID_HANDLE (0x0900A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_ALREADY_MUTED (0x0900B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_MUTE_NOT_MUTED (0x0900C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_CODEC_ACTIVE (0x0900D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_MIXER_FULL (0x0900E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ALREADY_ON_BRIDGE (0x0900F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_REMOVE_ALL (0x09010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_EXT_TONE_ENABLED (0x09011 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_INVALID_INPUT_PORT (0x09012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_DOMINANT_SPEAKER (0x09013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_BIDIR (0x09015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CNR_MUST_BE_ENABLED (0x09016 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_NLP_MUST_BE_ENABLED (0x09017 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF (0x09018 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_PARTICIPANT_CNT (0x09019 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_LISTENER_MASK_INDEX (0x0901A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_ALL_BUFFERS_OPEN (0x0901B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_DISABLED (0x0901C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_LISTENER_INDEX_USED (0x0901D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_SIMPLE_BRIDGE (0x0901E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_COPY_EVENTS (0x0901F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_INVALID_TAP_HANDLE (0x09020 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF_TAP_NOT_SUPPORTED (0x09021 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_NOT_ON_BRIDGE (0x09022 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_DEPENDENCY (0x09023 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_NOT_ON_SAME_BRIDGE (0x09024 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_TAP_SOUT_ONLY (0x09025 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_ADD_ALREADY_TAPPED (0x09026 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_ALWAYS_MUTE (0x09027 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_CONF_BRIDGE_CHANNEL_LAW_CONVERSION (0x09028 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_MISC_CANNOT_ROUND_UP_NUMBER (0x0A000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MISC_ASCII_CONVERSION_FAILED (0x0A001 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_TONE_DETECTION_CHANNEL_HANDLE_INVALID (0x0B000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_CHANNEL_NOT_OPEN (0x0B001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_TONE_NUMBER_INVALID (0x0B002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_TONE_NOT_ACTIVATED (0x0B003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED (0x0B004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_TONE_NOT_AVAILABLE (0x0B005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TONE_DETECTION_DISABLE_ALL (0x0B006 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_EVENTS_GET_TONE_RESET_BUFS (0x0C000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY (0x0C001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_EVENTS_MAX_TONES (0x0C002 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_INTRPTS_RW_ERROR (0x0D000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_NOT_ACTIVE (0x0D001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_FATAL_GENERAL_CONFIG (0x0D002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_FATAL_MEMORY_CONFIG (0x0D003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_DATA_ERR_MEMORY_CONFIG (0x0D004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_OVERFLOW_TONE_EVENTS_CONFIG (0x0D005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_H100_ERROR_CONFIG (0x0D006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_FATAL_GENERAL_TIMEOUT (0x0D007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_FATAL_MEMORY_TIMEOUT (0x0D008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_DATA_ERR_MEMORY_TIMEOUT (0x0D009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_OVERFLOW_TONE_EVENTS_TIMEOUT (0x0D00A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_H100_ERROR_TIMEOUT (0x0D00B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_AF_TIMESTAMP_READ_TIMEOUT (0x0D00C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_INTRPTS_NLP_TIMESTAMP_READ_TIMEOUT (0x0D00D + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_TSST_TIMESLOT (0x0E000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSST_STREAM (0x0E001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSST_TSST_RESERVED (0x0E002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSST_ASSOCIATED_TSST_RESERVED (0x0E003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_TSST_ALL_TSSTS_ARE_OPENED (0x0E004 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_MULTIPROC_API_INST_SHARED (0x10000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MULTIPROC_API_INST_LOCAL (0x10001 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_DEBUG_CHANNEL_INVALID_HANDLE (0x11000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_PORT (0x11001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_READ_LENGTH (0x11002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_SOUT_READ_LENGTH (0x11003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_READ_DATA (0x11004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_EVENTS_RESET_BUFS (0x11005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_EVENTS_BUF_EMPTY (0x11006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_RIN_PTR_INVALID (0x11007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_SIN_PTR_INVALID (0x11008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_ROUT_PTR_INVALID (0x11009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_SOUT_PTR_INVALID (0x1100A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_RAW_DATA_PTR_INVALID (0x1100B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_LENGTH_INVALID (0x1100C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RECORD_NO_CHAN_SELECTED (0x1100D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_PCM_LAW (0x1100E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_CHANNEL_RECORDING_DISABLED (0x1100F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_MAX_BYTES (0x11010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_PTR_INVALID (0x11011 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_RC_CHANNEL_RECORDING_DISABLED (0x11012 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_MODE (0x11013 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_CHANNEL_IN_POWER_DOWN (0x11014 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_CONTENT (0x11015 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_DEBUG_GET_DATA_MODE_CANNOT_CHANGE (0x11016 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_MIXER_ALL_COPY_EVENT_ENTRY_OPENED (0x12000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_COPY_EVENT_HANDLE (0x12001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_SOURCE_CHAN_HANDLE (0x12002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_DESTINATION_CHAN_HANDLE (0x12003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_SOURCE_PORT (0x12004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_DESTINATION_PORT (0x12005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_EVENT_NOT_OPEN (0x12006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_SOURCE_ADPCM_RESOURCES_ACTIVATED (0x12007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_DEST_ADPCM_RESOURCES_ACTIVATED (0x12008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_MIXER_ALL_MIXER_EVENT_ENTRY_OPENED (0x12009 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_ADPCM_CHAN_DISABLED (0x13000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE (0x13001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INPUT_TIMESLOT (0x13002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INPUT_STREAM (0x13003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_OUTPUT_TIMESLOT (0x13004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_OUTPUT_STREAM (0x13005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INPUT_NUM_TSSTS (0x13006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_OUTPUT_NUM_TSSTS (0x13007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INPUT_PCM_LAW (0x13008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_MODE (0x13009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_ENCODING_RATE (0x1300A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_DECODING_RATE (0x1300B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_INCOMPATIBLE_NUM_TSSTS (0x1300C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_NO_MORE_TSI_AVAILABLE (0x1300D + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_OUTPUT_PCM_LAW (0x1300E + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_ADPCM_NIBBLE_POSITION (0x1300F + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_NOT_OPEN (0x13010 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_ADPCM_CHAN_ALL_ADPCM_CHAN_ARE_OPENED (0x13011 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_CHIP_STATS_RESET (0x14000 + cOCT6100_ERR_BASE) + + + +#define cOCT6100_ERR_PRODUCTION_BIST_DISABLED (0x16000 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_PAYLOAD (0x2C000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_RESPONSE_PKT_PAYLOAD (0x2C001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_RECEIVED_PKT_LENGTH (0x2C002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_RESPONSE_PKT_LENGTH (0x2C003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_ENDIAN_DETECTION_FIELD (0x2C004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_CHECKSUM (0x2C005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTE_DEBUG_PARSING_ERROR (0x2C006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_ALL_SESSIONS_OPEN (0x2C007 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_INVALID_PACKET (0x2C008 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_TRANSACTION_ANSWERED (0x2C009 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_INAVLID_SESSION_NUMBER (0x2C00A + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_INVALID_HOT_CHAN_INDEX (0x2C00B + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_DISABLED (0x2C00C + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_REMOTEDEBUG_INVALID_RPC_COMMAND_NUM (0x2C00D + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_TLV_TIMEOUT (0x31000 + cOCT6100_ERR_BASE) + +/* Fatal errors must always be greater or equal to 0xE000. */ +#define cOCT6100_ERR_FATAL (0xDE000 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_API (0xDE000 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_EXT_API (0xDE001 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_SMEAR_API (0xDE002 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_BURST_API (0xDE003 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_READ_API (0xDE004 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_READ_BURST_API (0xDE005 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_READ_DEBUG_API (0xDE006 + cOCT6100_ERR_BASE) +#define cOCT6100_ERR_FATAL_DRIVER_WRITE_ARRAY_API (0xDE007 + cOCT6100_ERR_BASE) + +#define cOCT6100_FATAL_BASE (0xDF000 + cOCT6100_ERR_BASE) + +#define cOCT6100_ERR_FATAL_0 (0x00000 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1 (0x00001 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2 (0x00002 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3 (0x00003 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4 (0x00004 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5 (0x00005 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6 (0x00006 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7 (0x00007 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8 (0x00008 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9 (0x00009 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A (0x0000A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B (0x0000B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C (0x0000C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D (0x0000D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E (0x0000E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_F (0x0000F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_10 (0x00010 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_11 (0x00011 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_12 (0x00012 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_13 (0x00013 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_14 (0x00014 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_15 (0x00015 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_16 (0x00016 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_17 (0x00017 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_18 (0x00018 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_19 (0x00019 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1A (0x0001A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1B (0x0001B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1C (0x0001C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1D (0x0001D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1E (0x0001E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_1F (0x0001F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_20 (0x00020 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_21 (0x00021 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_22 (0x00022 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_23 (0x00023 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_24 (0x00024 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_25 (0x00025 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_26 (0x00026 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_27 (0x00027 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_28 (0x00028 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_29 (0x00029 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2A (0x0002A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2B (0x0002B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2C (0x0002C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2D (0x0002D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2E (0x0002E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_2F (0x0002F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_30 (0x00030 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_31 (0x00031 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_32 (0x00032 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_33 (0x00033 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_34 (0x00034 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_35 (0x00035 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_36 (0x00036 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_37 (0x00037 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_38 (0x00038 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_39 (0x00039 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3A (0x0003A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3B (0x0003B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3C (0x0003C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3D (0x0003D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3E (0x0003E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_3F (0x0003F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_40 (0x00040 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_41 (0x00041 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_42 (0x00042 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_43 (0x00043 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_44 (0x00044 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_45 (0x00045 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_46 (0x00046 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_47 (0x00047 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_48 (0x00048 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_49 (0x00049 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4A (0x0004A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4B (0x0004B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4C (0x0004C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4D (0x0004D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4E (0x0004E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_4F (0x0004F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_50 (0x00050 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_51 (0x00051 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_52 (0x00052 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_53 (0x00053 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_54 (0x00054 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_55 (0x00055 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_56 (0x00056 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_57 (0x00057 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_58 (0x00058 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_59 (0x00059 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5A (0x0005A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5B (0x0005B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5C (0x0005C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5D (0x0005D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5E (0x0005E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_5F (0x0005F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_60 (0x00060 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_61 (0x00061 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_62 (0x00062 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_63 (0x00063 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_64 (0x00064 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_65 (0x00065 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_66 (0x00066 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_67 (0x00067 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_68 (0x00068 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_69 (0x00069 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6A (0x0006A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6B (0x0006B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6C (0x0006C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6D (0x0006D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6E (0x0006E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_6F (0x0006F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_70 (0x00070 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_71 (0x00071 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_72 (0x00072 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_73 (0x00073 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_74 (0x00074 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_75 (0x00075 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_76 (0x00076 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_77 (0x00077 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_78 (0x00078 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_79 (0x00079 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7A (0x0007A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7B (0x0007B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7C (0x0007C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7D (0x0007D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7E (0x0007E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_7F (0x0007F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_80 (0x00080 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_81 (0x00081 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_82 (0x00082 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_83 (0x00083 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_84 (0x00084 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_85 (0x00085 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_86 (0x00086 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_87 (0x00087 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_88 (0x00088 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_89 (0x00089 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8A (0x0008A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8B (0x0008B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8C (0x0008C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8D (0x0008D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8E (0x0008E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_8F (0x0008F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_90 (0x00090 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_91 (0x00091 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_92 (0x00092 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_93 (0x00093 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_94 (0x00094 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_95 (0x00095 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_96 (0x00096 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_97 (0x00097 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_98 (0x00098 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_99 (0x00099 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9A (0x0009A + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9B (0x0009B + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9C (0x0009C + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9D (0x0009D + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9E (0x0009E + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_9F (0x0009F + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A0 (0x000A0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A1 (0x000A1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A2 (0x000A2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A3 (0x000A3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A4 (0x000A4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A5 (0x000A5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A6 (0x000A6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A7 (0x000A7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A8 (0x000A8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_A9 (0x000A9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AA (0x000AA + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AB (0x000AB + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AC (0x000AC + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AD (0x000AD + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AE (0x000AE + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_AF (0x000AF + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B0 (0x000B0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B1 (0x000B1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B2 (0x000B2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B3 (0x000B3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B4 (0x000B4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B5 (0x000B5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B6 (0x000B6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B7 (0x000B7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B8 (0x000B8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_B9 (0x000B9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BA (0x000BA + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BB (0x000BB + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BC (0x000BC + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BD (0x000BD + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BE (0x000BE + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_BF (0x000BF + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C0 (0x000C0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C1 (0x000C1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C2 (0x000C2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C3 (0x000C3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C4 (0x000C4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C5 (0x000C5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C6 (0x000C6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C7 (0x000C7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C8 (0x000C8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_C9 (0x000C9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CA (0x000CA + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CB (0x000CB + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CC (0x000CC + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CD (0x000CD + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CE (0x000CE + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_CF (0x000CF + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D0 (0x000D0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D1 (0x000D1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D2 (0x000D2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D3 (0x000D3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D4 (0x000D4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D5 (0x000D5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D6 (0x000D6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D7 (0x000D7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D8 (0x000D8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_D9 (0x000D9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DA (0x000DA + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DB (0x000DB + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DC (0x000DC + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DD (0x000DD + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DE (0x000DE + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_DF (0x000DF + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E0 (0x000E0 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E1 (0x000E1 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E2 (0x000E2 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E3 (0x000E3 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E4 (0x000E4 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E5 (0x000E5 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E6 (0x000E6 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E7 (0x000E7 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E8 (0x000E8 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_E9 (0x000E9 + cOCT6100_FATAL_BASE) +#define cOCT6100_ERR_FATAL_EA (0x000EA + cOCT6100_FATAL_BASE) + +#endif /* __OCT6100_ERRORS_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_events_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_events_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_events_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_events_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,69 @@ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_events_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_events.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_events_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 12 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_EVENTS_INST_H__ +#define __OCT6100_EVENTS_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_TONE_EVENT_ +{ + UINT32 ulChannelHandle; + UINT32 ulUserChanId; + UINT32 ulToneDetected; /* Tone number of the tone detected. */ + UINT32 ulTimestamp; + UINT32 ulEventType; + UINT32 ulExtToneDetectionPort; + +} tOCT6100_API_TONE_EVENT, *tPOCT6100_API_TONE_EVENT; + +typedef struct _OCT6100_API_BUFFER_PLAYOUT_EVENT_ +{ + UINT32 ulChannelHandle; + UINT32 ulUserChanId; + UINT32 ulChannelPort; + UINT32 ulTimestamp; + UINT32 ulUserEventId; + UINT32 ulEventType; + +} tOCT6100_API_BUFFER_PLAYOUT_EVENT, *tPOCT6100_API_BUFFER_PLAYOUT_EVENT; + +#endif /* __OCT6100_EVENTS_INST_H__ */ + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_events_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_events_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_events_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_events_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,111 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_events_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_events.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_events_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_EVENTS_PUB_H__ +#define __OCT6100_EVENTS_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_TONE_EVENT_ +{ + UINT32 ulChannelHndl; + UINT32 ulUserChanId; + + UINT32 ulToneDetected; + + UINT32 ulTimestamp; + UINT32 ulEventType; + + UINT32 ulExtToneDetectionPort; + +} tOCT6100_TONE_EVENT, *tPOCT6100_TONE_EVENT; + +typedef struct _OCT6100_EVENT_GET_TONE_ +{ + BOOL fMoreEvents; + BOOL fResetBufs; + + UINT32 ulMaxToneEvent; + UINT32 ulNumValidToneEvent; + + tPOCT6100_TONE_EVENT pToneEvent; + +} tOCT6100_EVENT_GET_TONE, *tPOCT6100_EVENT_GET_TONE; + +typedef struct _OCT6100_BUFFER_PLAYOUT_EVENT_ +{ + UINT32 ulChannelHndl; + UINT32 ulUserChanId; + UINT32 ulChannelPort; + + UINT32 ulTimestamp; + + UINT32 ulUserEventId; + UINT32 ulEventType; + +} tOCT6100_BUFFER_PLAYOUT_EVENT, *tPOCT6100_BUFFER_PLAYOUT_EVENT; + +typedef struct _OCT6100_BUFFER_PLAYOUT_GET_EVENT_ +{ + BOOL fMoreEvents; + BOOL fResetBufs; + + UINT32 ulMaxEvent; + UINT32 ulNumValidEvent; + + tPOCT6100_BUFFER_PLAYOUT_EVENT pBufferPlayoutEvent; + +} tOCT6100_BUFFER_PLAYOUT_GET_EVENT, *tPOCT6100_BUFFER_PLAYOUT_GET_EVENT; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100EventGetToneDef( + OUT tPOCT6100_EVENT_GET_TONE f_pEventGetTone ); +UINT32 Oct6100EventGetTone( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_EVENT_GET_TONE f_pEventGetTone ); + +UINT32 Oct6100BufferPlayoutGetEventDef( + OUT tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ); +UINT32 Oct6100BufferPlayoutGetEvent( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent ); + +#endif /* __OCT6100_EVENTS_PUB_H__ */ + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_interrupts_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_interrupts_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_interrupts_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_interrupts_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,134 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_interrupts_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_interrupts.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_interrupts_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 16 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_INTERRUPTS_INST_H__ +#define __OCT6100_INTERRUPTS_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_INTRPT_CONFIG_ +{ + /* The configuration of each group of interrupts. Each can have one of the + following values: + cOCT6100_INTRPT_DISABLE, + cOCT6100_INTRPT_NO_TIMEOUT, + cOCT6100_INTRPT_TIMEOUT. */ + UINT8 byFatalGeneralConfig; + UINT8 byFatalMemoryConfig; + UINT8 byErrorMemoryConfig; + UINT8 byErrorOverflowToneEventsConfig; + UINT8 byErrorH100Config; + + /* The timeout value for each interrupt group, if the corresponding + configuration variable is set to cOCT6100_INTRPT_TIMEOUT. This + value is kept in mclk cycles. */ + UINT32 ulFatalMemoryTimeoutMclk; + UINT32 ulErrorMemoryTimeoutMclk; + UINT32 ulErrorOverflowToneEventsTimeoutMclk; + UINT32 ulErrorH100TimeoutMclk; + +} tOCT6100_API_INTRPT_CONFIG, *tPOCT6100_API_INTRPT_CONFIG; + +typedef struct _OCT6100_API_INTRPT_MANAGE_ +{ + /* Number of mclk cycles in 1ms. */ + UINT32 ulNumMclkCyclesIn1Ms; + + /* Whether the mclk interrupt is active. */ + UINT8 fMclkIntrptActive; + UINT32 ulNextMclkIntrptTimeHigh; + UINT32 ulNextMclkIntrptTimeLow; + + /* Mclk time read from registers. */ + UINT32 ulRegMclkTimeHigh; + UINT32 ulRegMclkTimeLow; + + /* Used by the interrupt service routine. */ + UINT16 usRegister102h; + UINT16 usRegister202h; + UINT16 usRegister302h; + UINT16 usRegister502h; + UINT16 usRegister702h; + + /* The state of each interrupt group. Can be one of the following: + cOCT6100_INTRPT_ACTIVE, + cOCT6100_INTRPT_WILL_TIMEOUT, + cOCT6100_INTRPT_IN_TIMEOUT, + cOCT6100_INTRPT_WILL_DISABLED. */ + UINT16 byFatalGeneralState; + UINT16 byFatalMemoryState; + UINT16 byErrorMemoryState; + UINT16 byErrorOverflowToneEventsState; + UINT16 byErrorH100State; + + /* The time at which each disabled interrupt was disabled, in mclk cycles. */ + UINT32 ulFatalMemoryDisableMclkHigh; + UINT32 ulFatalMemoryDisableMclkLow; + UINT32 ulErrorMemoryDisableMclkHigh; + UINT32 ulErrorMemoryDisableMclkLow; + UINT32 ulErrorOverflowToneEventsDisableMclkHigh; + UINT32 ulErrorOverflowToneEventsDisableMclkLow; + UINT32 ulErrorH100DisableMclkHigh; + UINT32 ulErrorH100DisableMclkLow; + + /* The time at which each disabled interrupt group is to be reenabled, + in number of mclk cycles. */ + UINT32 ulFatalGeneralEnableMclkHigh; + UINT32 ulFatalGeneralEnableMclkLow; + UINT32 ulFatalMemoryEnableMclkHigh; + UINT32 ulFatalMemoryEnableMclkLow; + UINT32 ulErrorMemoryEnableMclkHigh; + UINT32 ulErrorMemoryEnableMclkLow; + UINT32 ulErrorOverflowToneEventsEnableMclkHigh; + UINT32 ulErrorOverflowToneEventsEnableMclkLow; + UINT32 ulErrorH100EnableMclkHigh; + UINT32 ulErrorH100EnableMclkLow; + + /* If this is set, buffer playout events are pending. */ + UINT8 fBufferPlayoutEventsPending; + /* If this is set, tone events are pending. */ + UINT8 fToneEventsPending; + + + + UINT8 fIsrCalled; + +} tOCT6100_API_INTRPT_MANAGE, *tPOCT6100_API_INTRPT_MANAGE; + +#endif /* __OCT6100_INTERRUPTS_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_interrupts_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_interrupts_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_interrupts_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_interrupts_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,102 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_interrupts_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_interrupts.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_interrupts_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 23 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_INTERRUPTS_PUB_H__ +#define __OCT6100_INTERRUPTS_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_INTERRUPT_CONFIGURE_ +{ + UINT32 ulFatalGeneralConfig; + UINT32 ulFatalMemoryConfig; + + UINT32 ulErrorMemoryConfig; + UINT32 ulErrorOverflowToneEventsConfig; + UINT32 ulErrorH100Config; + + UINT32 ulFatalMemoryTimeout; + UINT32 ulErrorMemoryTimeout; + UINT32 ulErrorOverflowToneEventsTimeout; + UINT32 ulErrorH100Timeout; + +} tOCT6100_INTERRUPT_CONFIGURE, *tPOCT6100_INTERRUPT_CONFIGURE; + +typedef struct _OCT6100_INTERRUPT_FLAGS_ +{ + BOOL fFatalGeneral; + UINT32 ulFatalGeneralFlags; + + BOOL fFatalReadTimeout; + + BOOL fErrorRefreshTooLate; + BOOL fErrorPllJitter; + + BOOL fErrorOverflowToneEvents; + + BOOL fErrorH100OutOfSync; + BOOL fErrorH100ClkA; + BOOL fErrorH100ClkB; + BOOL fErrorH100FrameA; + + BOOL fToneEventsPending; + BOOL fBufferPlayoutEventsPending; + + BOOL fApiSynch; + + + +} tOCT6100_INTERRUPT_FLAGS, *tPOCT6100_INTERRUPT_FLAGS; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100InterruptConfigureDef( + OUT tPOCT6100_INTERRUPT_CONFIGURE f_pConfigInts ); +UINT32 Oct6100InterruptConfigure( + IN tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_INTERRUPT_CONFIGURE f_pConfigInts ); + +UINT32 Oct6100InterruptServiceRoutineDef( + OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ); +UINT32 Oct6100InterruptServiceRoutine( + IN tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_INTERRUPT_FLAGS f_pIntFlags ); + +#endif /* __OCT6100_INTERRUPTS_PUB_H__ */ + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_mixer_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_mixer_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_mixer_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_mixer_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,86 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mixer_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_mixer.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_mixer_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 13 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_MIXER_INST_H__ +#define __OCT6100_MIXER_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_MIXER_EVENT_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Type of the event.*/ + UINT16 usEventType; + + /* Source channel index */ + UINT16 usSourceChanIndex; + + /* Destination channel index */ + UINT16 usDestinationChanIndex; + + /* Pointer to the next entry.*/ + UINT16 usNextEventPtr; + +} tOCT6100_API_MIXER_EVENT, *tPOCT6100_API_MIXER_EVENT; + + +typedef struct _OCT6100_API_COPY_EVENT_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* Source + destination ports. */ + UINT8 bySourcePort; + UINT8 byDestinationPort; + + /* Index of the channels associated to this event.*/ + UINT16 usSourceChanIndex; + UINT16 usDestinationChanIndex; + + UINT16 usMixerEventIndex; + +} tOCT6100_API_COPY_EVENT, *tPOCT6100_API_COPY_EVENT; + + +#endif /* __OCT6100_MIXER_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_mixer_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_mixer_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_mixer_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_mixer_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,77 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_mixer_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_mixer.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_mixer_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 7 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_MIXER_PUB_H__ +#define __OCT6100_MIXER_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_COPY_EVENT_CREATE_ +{ + PUINT32 pulCopyEventHndl; + + UINT32 ulSourceChanHndl; + UINT32 ulSourcePort; + + UINT32 ulDestinationChanHndl; + UINT32 ulDestinationPort; + +} tOCT6100_COPY_EVENT_CREATE, *tPOCT6100_COPY_EVENT_CREATE; + +typedef struct _OCT6100_COPY_EVENT_DESTROY_ +{ + UINT32 ulCopyEventHndl; + +} tOCT6100_COPY_EVENT_DESTROY, *tPOCT6100_COPY_EVENT_DESTROY; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100MixerCopyEventCreateDef( + OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ); +UINT32 Oct6100MixerCopyEventCreate( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_COPY_EVENT_CREATE f_pCopyEventCreate ); + +UINT32 Oct6100MixerCopyEventDestroyDef( + OUT tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ); +UINT32 Oct6100MixerCopyEventDestroy( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_COPY_EVENT_DESTROY f_pCopyEventDestroy ); + +#endif /* __OCT6100_MIXER_PUB_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_phasing_tsst_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_phasing_tsst_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_phasing_tsst_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_phasing_tsst_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,68 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_phasing_tsst_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_phasing_tsst.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_phasing_tsst_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PHASING_TSST_INST_H__ +#define __OCT6100_PHASING_TSST_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_PHASING_TSST_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* Count of number of resources connected in some way to this buffer. */ + UINT16 usDependencyCnt; + + /* TDM timeslot and stream where the counter is read. */ + UINT16 usStream; + UINT16 usTimeslot; + + /* Length of the phasing TSST counter. */ + UINT16 usPhasingLength; + + /* TSST control index where the counter comes from. */ + UINT16 usPhasingTsstIndex; + +} tOCT6100_API_PHASING_TSST, *tPOCT6100_API_PHASING_TSST; + +#endif /* __OCT6100_PHASING_TSST_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_phasing_tsst_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_phasing_tsst_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_phasing_tsst_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_phasing_tsst_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,78 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_phasing_tsst_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_phasing_tsst.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_phasing_tsst_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PHASING_TSST_PUB_H__ +#define __OCT6100_PHASING_TSST_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_PHASING_TSST_OPEN_ +{ + PUINT32 pulPhasingTsstHndl; + + UINT32 ulPhasingLength; + UINT32 ulTimeslot; + UINT32 ulStream; + + + +} tOCT6100_PHASING_TSST_OPEN, *tPOCT6100_PHASING_TSST_OPEN; + +typedef struct _OCT6100_PHASING_TSST_CLOSE_ +{ + UINT32 ulPhasingTsstHndl; + +} tOCT6100_PHASING_TSST_CLOSE, *tPOCT6100_PHASING_TSST_CLOSE; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100PhasingTsstOpenDef( + OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ); +UINT32 Oct6100PhasingTsstOpen( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_OPEN f_pPhasingTsstOpen ); + +UINT32 Oct6100PhasingTsstCloseDef( + OUT tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ); +UINT32 Oct6100PhasingTsstClose( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PHASING_TSST_CLOSE f_pPhasingTsstClose ); + +#endif /* __OCT6100_PHASING_TSST_PUB_H__ */ + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_playout_buf_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_playout_buf_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_playout_buf_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_playout_buf_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,88 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_playout_buf_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_playout_buf.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_playout_buf_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PLAYOUT_BUF_INST_H__ +#define __OCT6100_PLAYOUT_BUF_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define mOCT6100_GET_BUFFER_MEMORY_NODE_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE )(( PUINT8 )pSharedInfo + pSharedInfo->ulPlayoutBufMemoryNodeListOfst ); + +#define mOCT6100_GET_BUFFER_MEMORY_NODE_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE )(( PUINT8 )pSharedInfo + pSharedInfo->ulPlayoutBufMemoryNodeListOfst)) + ulIndex; + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE_ +{ + /* Next node. */ + UINT32 ulNext; + + /* Previous node. */ + UINT32 ulPrevious; + + /* Start address of this node. */ + UINT32 ulStartAddress; + + /* Size of this node. */ + UINT32 ulSize; + + /* Allocated node? Free node? */ + UINT8 fAllocated; + +} tOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE, *tPOCT6100_API_BUFFER_PLAYOUT_MALLOC_NODE; + +typedef struct _OCT6100_API_BUFFER_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Pcm law of the buffer. */ + UINT8 byBufferPcmLaw; + + /* Number of channels currently playing this buffer.*/ + UINT16 usDependencyCnt; + + /* Length of the buffer ( in bytes ).*/ + UINT32 ulBufferSize; + + /* Address in external memory of the buffer. */ + UINT32 ulBufferBase; + +} tOCT6100_API_BUFFER, *tPOCT6100_API_BUFFER; + +#endif /* __OCT6100_PLAYOUT_BUF_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_playout_buf_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_playout_buf_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_playout_buf_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_playout_buf_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,183 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_playout_buf_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_playout_buf.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_playout_buf_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 21 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_PLAYOUT_BUF_PUB_H__ +#define __OCT6100_PLAYOUT_BUF_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_BUFFER_LOAD_ +{ + PUINT32 pulBufferIndex; /* Index identifying the buffer. */ + PUINT32 pulPlayoutFreeMemSize; /* Amount of free memory available for other buffers. */ + + PUINT8 pbyBufferPattern; /* A byte pointer pointing to a valid buffer to be loaded into the chip's external memory. */ + UINT32 ulBufferSize; /* Size of the buffer loaded into external memory. */ + + UINT32 ulBufferPcmLaw; /* Buffer PCM law. */ + +} tOCT6100_BUFFER_LOAD, *tPOCT6100_BUFFER_LOAD; + +typedef struct _OCT6100_BUFFER_LOAD_BLOCK_INIT_ +{ + PUINT32 pulBufferIndex; /* Index identifying the buffer. */ + PUINT32 pulPlayoutFreeMemSize; /* Amount of free memory available for other buffers. */ + + UINT32 ulBufferSize; /* Size of the buffer to be loaded in memory. This space will be reserved. */ + + UINT32 ulBufferPcmLaw; /* Buffer PCM law. */ + +} tOCT6100_BUFFER_LOAD_BLOCK_INIT, *tPOCT6100_BUFFER_LOAD_BLOCK_INIT; + +typedef struct _OCT6100_BUFFER_LOAD_BLOCK_ +{ + UINT32 ulBufferIndex; /* Index identifying the buffer. */ + + /* Offset, in bytes, of the first byte in the block to be loaded. */ + /* This offset is with respect to the beginning of the buffer. */ + /* This value must be modulo 2 */ + UINT32 ulBlockOffset; + + /* Size of the block to be loaded into external memory. */ + /* This value must be modulo 2. */ + UINT32 ulBlockLength; + + /* A pointer pointing to a valid buffer block to be loaded */ + /* into the chip's external memory. This is a pointer to the entire */ + /* buffer. The API uses the ulBlockOffset and ulBlockLength to index */ + /* within this buffer and obtain the block to be loaded. */ + PUINT8 pbyBufferPattern; + +} tOCT6100_BUFFER_LOAD_BLOCK, *tPOCT6100_BUFFER_LOAD_BLOCK; + +typedef struct _OCT6100_BUFFER_UNLOAD_ +{ + UINT32 ulBufferIndex; /* Index identifying the buffer. */ + +} tOCT6100_BUFFER_UNLOAD, *tPOCT6100_BUFFER_UNLOAD; + +typedef struct _OCT6100_BUFFER_PLAYOUT_ADD_ +{ + UINT32 ulChannelHndl; /* Echo cancelling channel on which to play the buffer. */ + + UINT32 ulBufferIndex; /* Index identifying the buffer. */ + + UINT32 ulPlayoutPort; /* Selected channel port where to play to tone. */ + UINT32 ulMixingMode; /* Weither or not the voice stream will be muted while playing the buffer. */ + + INT32 lGainDb; /* Gain applied to the buffer that will be played on the specified port. */ + + BOOL fRepeat; /* Use ulRepeatCount variable. */ + UINT32 ulRepeatCount; /* Number of times to repeat playing the selected buffer. */ + + UINT32 ulDuration; /* Duration in millisecond that this buffer should play. Setting this overrides fRepeat. */ + + UINT32 ulBufferLength; /* Length of the buffer to play (starting at the beginning), AUTO_SELECT for all. */ + +} tOCT6100_BUFFER_PLAYOUT_ADD, *tPOCT6100_BUFFER_PLAYOUT_ADD; + +typedef struct _OCT6100_BUFFER_PLAYOUT_START_ +{ + UINT32 ulChannelHndl; /* Echo cancelling channel on which to play the buffer. */ + UINT32 ulPlayoutPort; /* Selected channel port where to play to tone. */ + + BOOL fNotifyOnPlayoutStop; /* Check if the buffers have finished playing on this channel/port. */ + /* The events are queued in a soft buffer that the user must empty regularly. */ + UINT32 ulUserEventId; /* Returned to the user when the playout is finished and the user has set the fNotifyOnPlayoutStop flag. */ + + BOOL fAllowStartWhileActive; /* Use this to add buffers to something that is already playing on the channel/port. */ + +} tOCT6100_BUFFER_PLAYOUT_START, *tPOCT6100_BUFFER_PLAYOUT_START; + +typedef struct _OCT6100_BUFFER_PLAYOUT_STOP_ +{ + UINT32 ulChannelHndl; /* Echo cancelling channel on which to play the buffer. */ + UINT32 ulPlayoutPort; /* Selected channel port where to play to tone. */ + BOOL fStopCleanly; /* Whether or not the skip will be clean. */ + + PBOOL pfAlreadyStopped; /* Whether playout was already stopped or not. */ + PBOOL pfNotifyOnPlayoutStop; /* Whether the user chosed to receive an event on playout stop. */ + +} tOCT6100_BUFFER_PLAYOUT_STOP, *tPOCT6100_BUFFER_PLAYOUT_STOP; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100BufferPlayoutLoadDef( + OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad ); +UINT32 Oct6100BufferPlayoutLoad( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD f_pBufferLoad ); + +UINT32 Oct6100BufferPlayoutLoadBlockInitDef( + OUT tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ); +UINT32 Oct6100BufferPlayoutLoadBlockInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK_INIT f_pBufferLoadBlockInit ); + +UINT32 Oct6100BufferPlayoutLoadBlockDef( + OUT tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ); +UINT32 Oct6100BufferPlayoutLoadBlock( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_LOAD_BLOCK f_pBufferLoadBlock ); + +UINT32 Oct6100BufferPlayoutUnloadDef( + OUT tPOCT6100_BUFFER_UNLOAD f_pBufferUnload ); +UINT32 Oct6100BufferPlayoutUnload( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_UNLOAD f_pBufferUnload ); + +UINT32 Oct6100BufferPlayoutAddDef( + OUT tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ); +UINT32 Oct6100BufferPlayoutAdd( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_ADD f_pBufferPlayoutAdd ); + +UINT32 Oct6100BufferPlayoutStartDef( + OUT tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart ); +UINT32 Oct6100BufferPlayoutStart( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_START f_pBufferPlayoutStart ); + +UINT32 Oct6100BufferPlayoutStopDef( + OUT tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ); +UINT32 Oct6100BufferPlayoutStop( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_BUFFER_PLAYOUT_STOP f_pBufferPlayoutStop ); + +#endif /* __OCT6100_PLAYOUT_BUF_PUB_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_remote_debug_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_remote_debug_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_remote_debug_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_remote_debug_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,73 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_remote_debug_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_remote_debug.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_remote_debug_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_REMOTE_DEBUG_INST_H__ +#define __OCT6100_REMOTE_DEBUG_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_REMOTE_DEBUG_INFO_ +{ + UINT32 ulSessionTreeOfst; + UINT32 ulSessionListOfst; + UINT32 ulSessionListHead; + UINT32 ulSessionListTail; + + UINT32 ulPktCacheOfst; + UINT32 ulDataBufOfst; + + UINT32 ulNumSessionsOpen; + UINT32 ulMaxSessionsOpen; + +} tOCT6100_API_REMOTE_DEBUG_INFO, *tPOCT6100_API_REMOTE_DEBUG_INFO; + +typedef struct _OCT6100_API_REMOTE_DEBUG_SESSION_ +{ + UINT32 ulSessionNum; + UINT32 ulTransactionNum; + UINT32 ulPktRetryNum; + UINT32 ulPktByteSize; + + UINT32 aulLastPktTime[ 2 ]; + UINT32 ulForwardLink; + UINT32 ulBackwardLink; + +} tOCT6100_API_REMOTE_DEBUG_SESSION, *tPOCT6100_API_REMOTE_DEBUG_SESSION; + +#endif /* __OCT6100_REMOTE_DEBUG_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_remote_debug_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_remote_debug_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_remote_debug_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_remote_debug_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,64 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_remote_debug_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_remote_debug.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_remote_debug_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_REMOTE_DEBUG_PUB_H__ +#define __OCT6100_REMOTE_DEBUG_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_REMOTE_DEBUG_ +{ + PUINT32 pulReceivedPktPayload; + UINT32 ulReceivedPktLength; + + PUINT32 pulResponsePktPayload; + UINT32 ulMaxResponsePktLength; + UINT32 ulResponsePktLength; + +} tOCT6100_REMOTE_DEBUG, *tPOCT6100_REMOTE_DEBUG; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100RemoteDebugDef( + OUT tPOCT6100_REMOTE_DEBUG f_pRemoteDebug ); +UINT32 Oct6100RemoteDebug( + IN OUT tPOCT6100_INSTANCE_API f_pApiInst, + IN OUT tPOCT6100_REMOTE_DEBUG f_pRemoteDebug ); + +#endif /* __OCT6100_REMOTE_DEBUG_PUB_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tlv_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tlv_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tlv_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tlv_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,72 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tlv_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tlv.c. All elements defined in this file are for public + usage of the API. All instate elements are defined in the + oct6100_tlv_inst.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 7 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TLV_INST_H__ +#define __OCT6100_TLV_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_TLV_OFFSET_ +{ + /* The dword offset contain the number of dword from a base address to reach the desired dword. + + i.e. usDwordOffset = (total bit offset) / 32; */ + + UINT16 usDwordOffset; + + /* The bit offset will contain the bit offset required to right shift the DWORD read and obtain + the desired value. This field is depend on the field size. + + i.e. byBitOffset = 31 - ((total bit offset) % 32) - byFieldSize; */ + + UINT8 byBitOffset; + UINT8 byFieldSize; + +} tOCT6100_TLV_OFFSET, *tPOCT6100_TLV_OFFSET; + +typedef struct _OCT6100_TLV_TONE_INFO_ +{ + UINT32 ulToneID; + UINT32 ulDetectionPort; + + UINT8 aszToneName[ cOCT6100_TLV_MAX_TONE_NAME_SIZE ]; + + + +} tOCT6100_TLV_TONE_INFO, *tPOCT6100_TLV_TONE_INFO; + +#endif /* __OCT6100_TLV_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tone_detection_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tone_detection_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tone_detection_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tone_detection_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,46 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tone_detection_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tone_detection_buf.c. All elements defined in this file are for + public usage of the API. All private elements are defined in the + oct6100_tone_detection_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 8 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TONE_DETECTION_INST_H__ +#define __OCT6100_TONE_DETECTION_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + + +#endif /* __OCT6100_TONE_DETECTION_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tone_detection_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tone_detection_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tone_detection_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tone_detection_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,74 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tone_detection_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tone_detection.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_tone_detection_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 10 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TONE_DETECTION_PUB_H__ +#define __OCT6100_TONE_DETECTION_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_TONE_DETECTION_ENABLE_ +{ + UINT32 ulChannelHndl; + UINT32 ulToneNumber; + +} tOCT6100_TONE_DETECTION_ENABLE, *tPOCT6100_TONE_DETECTION_ENABLE; + +typedef struct _OCT6100_TONE_DETECTION_DISABLE_ +{ + UINT32 ulChannelHndl; + UINT32 ulToneNumber; + BOOL fDisableAll; + +} tOCT6100_TONE_DETECTION_DISABLE, *tPOCT6100_TONE_DETECTION_DISABLE; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ToneDetectionEnableDef( + OUT tPOCT6100_TONE_DETECTION_ENABLE f_pBufferLoad ); +UINT32 Oct6100ToneDetectionEnable( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TONE_DETECTION_ENABLE f_pBufferLoad ); + +UINT32 Oct6100ToneDetectionDisableDef( + OUT tPOCT6100_TONE_DETECTION_DISABLE f_pBufferUnload ); +UINT32 Oct6100ToneDetectionDisable( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TONE_DETECTION_DISABLE f_pBufferUnload ); + +#endif /* __OCT6100_TONE_DETECTION_PUB_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tsi_cnct_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tsi_cnct_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tsi_cnct_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tsi_cnct_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,70 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsi_cnct_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tsi_cnct.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_tsi_cnct_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 9 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSI_CNCT_INST_H__ +#define __OCT6100_TSI_CNCT_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_TSI_CNCT_ +{ + /* Flag specifying whether the entry is used or not. */ + UINT8 fReserved; + + /* Count used to manage entry handles allocated to user. */ + UINT8 byEntryOpenCnt; + + /* Input PCM law. */ + UINT8 byInputPcmLaw; + + /* TSI chariot memory entry. */ + UINT16 usTsiMemIndex; + + /* Input and output timeslot information. */ + UINT16 usInputTimeslot; + UINT16 usInputStream; + + UINT16 usOutputTimeslot; + UINT16 usOutputStream; + + /* Internal info for quick access to structures associated to this TSI cnct. */ + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + +} tOCT6100_API_TSI_CNCT, *tPOCT6100_API_TSI_CNCT; + +#endif /* __OCT6100_TSI_CNCT_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tsi_cnct_pub.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tsi_cnct_pub.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tsi_cnct_pub.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tsi_cnct_pub.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,76 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsi_cnct_pub.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tsi_cnct.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_tsi_cnct_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 11 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSI_CNCT_PUB_H__ +#define __OCT6100_TSI_CNCT_PUB_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_TSI_CNCT_OPEN_ +{ + PUINT32 pulTsiCnctHndl; + + UINT32 ulInputTimeslot; + UINT32 ulInputStream; + UINT32 ulOutputTimeslot; + UINT32 ulOutputStream; + +} tOCT6100_TSI_CNCT_OPEN, *tPOCT6100_TSI_CNCT_OPEN; + +typedef struct _OCT6100_TSI_CNCT_CLOSE_ +{ + UINT32 ulTsiCnctHndl; + +} tOCT6100_TSI_CNCT_CLOSE, *tPOCT6100_TSI_CNCT_CLOSE; + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100TsiCnctOpenDef( + OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ); +UINT32 Oct6100TsiCnctOpen( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_OPEN f_pTsiCnctOpen ); + +UINT32 Oct6100TsiCnctCloseDef( + OUT tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ); +UINT32 Oct6100TsiCnctClose( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_TSI_CNCT_CLOSE f_pTsiCnctClose ); + +#endif /* __OCT6100_TSI_CNCT_PUB_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tsst_inst.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tsst_inst.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tsst_inst.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/oct6100api/oct6100_tsst_inst.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,55 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_tsst_inst.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines, macros, and structures pertaining to the file + oct6100_tsst.c. All elements defined in this file are for public + usage of the API. All private elements are defined in the + oct6100_tsst_priv.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 5 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_TSST_INST_H__ +#define __OCT6100_TSST_INST_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + + +/***************************** TYPES ***************************************/ + +typedef struct _OCT6100_API_TSST_ENTRY_ +{ + UINT16 usTsstMemoryIndex; /* Index in the TSST memory of the TSST */ + UINT16 usTsstValue; /* Tsst value given by the user. */ + /* bit 5:0 = stream value, bit 13:6 = timeslot value. */ + + UINT16 usNextEntry; /* Pointer to the next entry in the list. */ + +} tOCT6100_API_TSST_ENTRY, *tPOCT6100_API_TSST_ENTRY; + +#endif /* __OCT6100_TSST_INST_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octdef.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octdef.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octdef.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octdef.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,116 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octdef.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Common system definitions. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 12 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCTDEF_H__ +#define __OCTDEF_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** INCLUDE FILES *******************************/ + +/*-------------------------------------------------------------------------- + Get Platform Dependency headers +----------------------------------------------------------------------------*/ +#include "octosdependant.h" + + +/*-------------------------------------------------------------------------- + Common Type definitions +----------------------------------------------------------------------------*/ +#include "octtype.h" + +/***************************** DEFINES *************************************/ + +/* List of functions to skip compiling since we don't use them */ +#include "digium_unused.h" + + + +/*-------------------------------------------------------------------------- + Miscellaneous constants +----------------------------------------------------------------------------*/ + +#ifndef PROTO +#define PROTO extern +#endif + +/* Generic return codes. */ +#define cOCTDEF_RC_OK 0 /* Generic Ok */ +#define cOCTDEF_RC_ERROR 1 /* Generic Error */ + +/* Default return values of all OCTAPI functions. */ +#ifndef GENERIC_OK +#define GENERIC_OK 0x00000000 +#endif + +#ifndef GENERIC_ERROR +#define GENERIC_ERROR 0x00000001 +#endif + +#ifndef GENERIC_BAD_PARAM +#define GENERIC_BAD_PARAM 0x00000002 +#endif + +/* Defines of boolean expressions (TRUE/FALSE) */ +#ifndef FALSE +#define FALSE (BOOL)0 +#endif + +#ifndef TRUE +#define TRUE (BOOL)1 +#endif + +/*-------------------------------------------------------------------------- + DLL Import-Export +----------------------------------------------------------------------------*/ + +#ifdef OCT_WINENV +#define DLLIMP __declspec( dllimport ) +#define DLLEXP __declspec( dllexport ) +#else +#define DLLIMP +#define DLLEXP +#endif + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __OCTDEF_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octmac.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octmac.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octmac.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octmac.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,98 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octmac.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + Common macro definitions. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 14 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTMAC_H__ +#define __OCTMAC_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** DEFINES *************************************/ + +/* Combine l & h to form a 32 bit quantity. */ +#define mMAKEULONG(l, h) ((ULONG)(((USHORT)(l)) | (((ULONG)((USHORT)(h))) << 16))) + +#define mLOUCHAR(w) ((UCHAR)(w)) +#define mHIUCHAR(w) ((UCHAR)(((USHORT)(w) >> 8) & 0xff)) +#define mLOUSHORT(l) ((USHORT)((ULONG)l)) +#define mHIUSHORT(l) ((USHORT)(((ULONG)(l) >> 16) & 0xffff)) +#define mLOSHORT(l) ((SHORT)((ULONG)l)) +#define mHISHORT(l) ((SHORT)(((ULONG)(l) >> 16) & 0xffff)) + +/* Combine l & h to form a 16 bit quantity. */ +#define mMAKEUSHORT(l, h) (((USHORT)(l)) | ((USHORT)(h)) << 8) +#define mMAKESHORT(l, h) ((SHORT)mMAKEUSHORT(l, h)) + +/* Extract high and low order parts of 16 and 32 bit quantity */ +#define mLOBYTE(w) mLOUCHAR(w) +#define mHIBYTE(w) mHIUCHAR(w) +#define mMAKELONG(l, h) ((LONG)mMAKEULONG(l, h)) + +/*-------------------------------------------------------------------------- + Bite conversion macro +----------------------------------------------------------------------------*/ +#define mSWAP_INT16(x) mMAKEUSHORT( mHIBYTE(x), mLOBYTE(x) ) +#define mSWAP_INT32(x) mMAKEULONG( mSWAP_INT16(mHIUSHORT(x)), mSWAP_INT16(mLOUSHORT(x)) ) + + +/* Cast any variable to an instance of the specified type. */ +#define mMAKETYPE(v, type) (*((type *)&v)) + +/* Calculate the byte offset of a field in a structure of type type. */ +#define mFIELDOFFSET(type, field) ((UINT32)&(((type *)0)->field)) +#define mCOUNTOF(array) (sizeof(array)/sizeof(array[0])) + +#define mMAX(a,b) (((a) > (b)) ? (a) : (b)) +#define mMIN(a,b) (((a) < (b)) ? (a) : (b)) + +#define mDIM(x) (sizeof(x) / sizeof(x[0])) + +#define mFROMDIGIT(ch) ((ch) - 0x30) /* digit to char */ +#define mTODIGIT(ch) ((ch) + 0x30) /* int to char */ + +#define mISLEAP(a) ( !( a % 400 ) || ( ( a % 100 ) && !( a % 4 ) ) ) + +#define mFOREVER for( ;; ) + +#define mROUND_TO_NEXT_4( a ) ( ((a) % 4) ? ( (a) + 4 - ((a)%4) ) : (a) ) + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __OCTMAC_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octosdependant.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octosdependant.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octosdependant.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octosdependant.h 2008-06-17 15:34:54.000000000 -0500 @@ -0,0 +1,170 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octosdependant.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file is included to set target-specific constants. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 18 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCTOSDEPENDANT_H__ +#define __OCTOSDEPENDANT_H__ + + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + + + +/***************************************************************************** + + Known define values + + MSDEV: + WIN32 == WINDOWS 32 bit app + __WIN32__ == WINDOWS 32 bit app + _Windows == WINDOWS 16 bit app + + _WINDOWS == Windows application .. not console + _DLL == Dll Application + _CONSOLE == Console Application .. no windows + + BORLANDC + __TURBOC__ == Turbo Compiler + __BORLANDC__ == Borland compiler + __OS2__ == Borland OS2 compiler + _Windows == Windows 16 bit app + + GCC Compiler + __GNUC__ == GCC Compiler + __unix__ == Unix system + __vax__ == Unix system + unix == Unix system + vax == vax system + + TORNADO + _VXWORKS_ == VXWORK + + ECOS/CYGWIN + _ECOS_ == eCos + + SOLARIS + _SOLARIS_ == Solaris + +*****************************************************************************/ + +/* Machine endian type */ + +#define OCT_MACH_LITTLE_ENDIAN 1 +#define OCT_MACH_BIG_ENDIAN 2 + +/* Try to find current OCT_MACH_ENDIAN from compiler define values */ +#if !defined( MACH_TYPE_BIG_ENDIAN ) && !defined( MACH_TYPE_LITTLE_ENDIAN ) + /* Does GNU defines the endian ? */ + #if defined(__GNU_C__) + #if defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN__) + #define OCT_MACH_ENDIAN OCT_MACH_BIG_ENDIAN + #elif defined(_LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #endif + #endif + + /* Try with cpu type */ + #if !defined(OCT_MACH_ENDIAN) + /* Look for intel */ + #if defined( _M_IX86 ) + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + /* Look for PowerPC */ + #elif defined( _M_MPPC ) || defined( _M_PPC ) || defined(PPC) || defined(__PPC) || defined(_ARCH_PPC) + #define OCT_MACH_ENDIAN OCT_MACH_BIG_ENDIAN + /* Look for Blackfin */ + #elif defined( __bfin__ ) + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #elif defined( CPU ) + #if CPU==PPC860 || CPU==SIMNT + #define OCT_MACH_ENDIAN OCT_MACH_BIG_ENDIAN + #else + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #endif + #else + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #endif + #endif +#else + #if defined( MACH_TYPE_BIG_ENDIAN ) + #define OCT_MACH_ENDIAN OCT_MACH_BIG_ENDIAN + #else + #define OCT_MACH_ENDIAN OCT_MACH_LITTLE_ENDIAN + #endif +#endif + +/* Find system type if not already defined */ +#if !defined( OCT_NTDRVENV ) && !defined( OCT_VXENV ) && !defined( OCT_WINENV ) + +#if defined( WIN32 ) || defined( __WIN32__ ) || defined( _WIN32_ ) || defined( WIN32S ) + /* Verif if building a win32 driver */ + #if ( defined( WIN32 ) && WIN32==100 ) + #define OCT_NTDRVENV + #else + #define OCT_WINENV + #endif +#elif defined( _VXWORKS_ ) + #define OCT_VXENV +#elif defined( _ECOS_ ) +#ifndef OCT_ECOSENV + #define OCT_ECOSENV +#endif /* OCT_ECOSENV */ +#elif defined( _SOLARIS_ ) + #define OCT_SOLARISENV +#elif defined( _LINUX_ ) + #define OCT_LINUXENV +#else + /* Unknown environment */ + #define OCT_UNKNOWNENV +#endif /* WIN env */ + +#endif /* Already defined */ + +#if defined( __KERNEL__ ) && defined( OCT_LINUXENV ) +#define OCT_LINUXDRVENV +#endif + +#ifdef _DEBUG +#define OCT_OPT_USER_DEBUG +#endif + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __OCTOSDEPENDANT_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octrpc/oct6100_rpc_protocol.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octrpc/oct6100_rpc_protocol.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octrpc/oct6100_rpc_protocol.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octrpc/oct6100_rpc_protocol.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,348 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_rpc_protocol.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all defines and prototypes related to the OCT6100 RPC + protocol for exchanging debug commands. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 6 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_RPC_PROTOCOL_H__ +#define __OCT6100_RPC_PROTOCOL_H__ + +/***************************** DEFINES *************************************/ + +#define cOCTRPC_INTERFACE_VERSION 0x00010002 + +/* Octasic commands. */ +#define cOCT6100_RPC_CHIP_LIST 0xFF000000 +#define cOCT6100_RPC_CHIP_CHOICE 0xFF000001 +#define cOCT6100_RPC_ENV_DISCONNECT 0xFF000002 + +/* Commands */ +/* Read commands */ +#define cOCT6100_RPC_READ_WORD 0x00000000 +#define cOCT6100_RPC_READ_BURST 0x00000001 +#define cOCT6100_RPC_READ_DEBUG 0x00000002 +#define cOCT6100_RPC_READ_ARRAY 0x00000003 +#define cOCT6100_RPC_API_DISCONNECT 0x00000004 + +/* Write commands */ +#define cOCT6100_RPC_WRITE_WORD 0x00000010 +#define cOCT6100_RPC_WRITE_BURST 0x00000011 +#define cOCT6100_RPC_WRITE_SMEAR 0x00000012 +#define cOCT6100_RPC_WRITE_INC 0x00000013 + +/* Debug commands.*/ +#define cOCT6100_RPC_SET_HOT_CHANNEL 0x00000014 +#define cOCT6100_RPC_GET_DEBUG_CHAN_INDEX 0x00000015 + +#define cOCTRPC_UNKNOWN_COMMAND_NUM 0xFFFFFFFF + +/* Errors */ +#define cOCT6100_RPCERR_OK 0x00000000 +#define cOCT6100_RPCERR_INVALID_COMMAND_NUMBER 0x00000001 +#define cOCT6100_RPCERR_INVALID_COMMAND_PAYLOAD 0x00000002 +#define cOCT6100_RPCERR_INVALID_COMMAND_LENGTH 0x00000003 + + +/***************************** TYPES ***************************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_READ_WORD + +Description: Command structure for the read of one word. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address at which to read. +OUT ulReadData The word read, returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_READ_WORD_ +{ + UINT32 IN ulAddress; + UINT32 OUT ulReadData; + +} tOCT6100_RPC_READ_WORD, *tPOCT6100_RPC_READ_WORD; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_READ_BURST + +Description: Command structure for a read burst. The burst starts at the + given address and reads the specified number of consecutive + words. + + Whereas every command structure uses a complete dword for every + member, irrespective of the size of data unit needed, this + structure does not do so for the read data. To save bandwidth + the read data words are returned two per dword. + +Example packet: 31 16 15 0 + ------------------------------------------- + | ulAddress = 0x100 | + ------------------------------------------- + | ulBurstLength = 0x3 | + ------------------------------------------- + aulReadData -> | D0 | D1 | + ------------------------------------------- + | D2 | xx | + ------------------------------------------- + + Dy is the read data at ulAddress + 2 * y. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address at which to read. +IN ulBurstLength The number of consecutive words to be read. +OUT aulReadData The read data returned. The dwords of the structure + starting at this address are arranged as indicated in + the example packet above. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_READ_BURST_ +{ + UINT32 IN ulAddress; + UINT32 IN ulBurstLength; + UINT32 OUT aulReadData[ 1 ]; + +} tOCT6100_RPC_READ_BURST, *tPOCT6100_RPC_READ_BURST; + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_READ_ARRAY + +Description: Command structure for a variable number of reads. The reads do + not have to be at contiguous addresses. + + Whereas every command structure uses a complete dword for every + member, irrespective of the size of data unit needed, this + structure does not do so for the read data. To save bandwidth + the read data words are returned two per dword, and the + parity bits are returned 16 per dword (two parity bits per read + access). + +Example packet: 31 16 15 0 + ------------------------------------------- + | ulArrayLength = 0x3 | + ------------------------------------------- + aulArrayData ->| A0 | + ------------------------------------------- + | A1 | + ------------------------------------------- + | A2 | + ------------------------------------------- + | D0 | D1 | + ------------------------------------------- + | D2 | xx | + ------------------------------------------- + + Ay is the address for access y. + Dy is the read data at Ay. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulArrayLength Number of reads to do. +IN OUT aulArrayData The addresses at which to read (IN) and the read data + returned (OUT). The dwords of the command structure + starting at this address are arranged as indicated in + the example packet above. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_READ_ARRAY +{ + UINT32 IN ulArrayLength; + UINT32 IN OUT aulArrayData[ 1 ]; + +} tOCT6100_RPC_READ_ARRAY, *tPOCT6100_RPC_READ_ARRAY; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_WRITE_WORD + +Description: Command structure for the write of one word. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address at which to write. +IN ulWriteData The word to write. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_WRITE_WORD_ +{ + UINT32 IN ulAddress; + UINT32 IN ulParity; + UINT32 IN ulWriteData; + +} tOCT6100_RPC_WRITE_WORD, *tPOCT6100_RPC_WRITE_WORD; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_WRITE_SMEAR + +Description: Command structure for the write of one word at one or many + consecutive addresses. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address of first write. +IN ulSmearLength Number of consecutive addresses to write. +IN ulWriteData The word to write at each address. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_WRITE_SMEAR_ +{ + UINT32 IN ulAddress; + UINT32 IN ulSmearLength; + UINT32 IN ulParity; + UINT32 IN ulWriteData; + +} tOCT6100_RPC_WRITE_SMEAR, *tPOCT6100_RPC_WRITE_SMEAR; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_WRITE_INC + +Description: Command structure for the write of an incremental pattern at + one or many consecutive addresses. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress Address of first write. +IN ulIncLength Number of consecutive addresses to write. +IN ulWriteData The first word of the incremental pattern. For each + consecutive write the word will be incremented by 1. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_WRITE_INC_ +{ + UINT32 IN ulAddress; + UINT32 IN ulIncLength; + UINT32 IN ulParity; + UINT32 IN ulWriteData; + +} tOCT6100_RPC_WRITE_INC, *tPOCT6100_RPC_WRITE_INC; + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_WRITE_BURST + +Description: Command structure for a write burst. The burst starts at the + given address and writes a given word for each address. + + Whereas every command structure uses a complete dword for every + member, irrespective of the size of data unit needed, this + structure does not do so for the write data. To save bandwidth + the write data words are sent two per dword. + +Example packet: 31 16 15 0 + ------------------------------------------- + | ulAddress = 0x100 | + ------------------------------------------- + | ulBurstLength = 0x3 | + ------------------------------------------- + aulWriteData ->| D0 | D1 | + ------------------------------------------- + | D2 | xx | + ------------------------------------------- + + Dy is the write data for ulAddress + 2 * y. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulAddress First address at which to write. +IN ulBurstLength The number of consecutive addresses to be write. +IN aulWriteData The write data words. The dwords of the structure + starting at this address are arranged as indicated in + the example packet above. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_WRITE_BURST_ +{ + UINT32 IN ulAddress; + UINT32 IN ulBurstLength; + UINT32 IN ulParity; + UINT32 IN aulWriteData[ 1 ]; + +} tOCT6100_RPC_WRITE_BURST, *tPOCT6100_RPC_WRITE_BURST; + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_SET_HOT_CHANNEL + +Description: Command structure to set the hot channel. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulDebugChannel Index of the channel to debug. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_SET_HOT_CHANNEL_ +{ + UINT32 IN ulHotChannel; + UINT32 IN ulPcmLaw; + +} tOCT6100_RPC_SET_HOT_CHANNEL, *tPOCT6100_RPC_SET_HOT_CHANNEL; + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Structure: OCT6100_RPC_GET_DEBUG_CHAN_INDEX + +Description: Command structure to get the debug channel index used by the API. + +------------------------------------------------------------------------------- +| Member | Description +------------------------------------------------------------------------------- +IN ulDebugChannel Index of the channel to debug. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +typedef struct _OCT6100_RPC_GET_DEBUG_CHAN_INDEX_ +{ + UINT32 OUT ulDebugChanIndex; + +} tOCT6100_RPC_GET_DEBUG_CHAN_INDEX, *tPOCT6100_RPC_GET_DEBUG_CHAN_INDEX; + +#endif /* __OCT6100_RPC_PROTOCOL_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octrpc/rpc_protocol.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octrpc/rpc_protocol.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octrpc/rpc_protocol.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octrpc/rpc_protocol.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,115 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: rpc_protocol.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + +This file contains RPC related definitions and prototypes. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 23 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __RPC_PROTOCOL_H__ +#define __RPC_PROTOCOL_H__ + +/***************************** INCLUDE FILES *******************************/ + + +/***************************** DEFINES *************************************/ + +#define cOCTRPC_ENDIAN_DETECT 0x27182819 +#define cOCTRPC_ENDIAN_DETECT_BYTE_W 0x19 +#define cOCTRPC_ENDIAN_DETECT_BYTE_X 0x28 +#define cOCTRPC_ENDIAN_DETECT_BYTE_Y 0x18 +#define cOCTRPC_ENDIAN_DETECT_BYTE_Z 0x27 +#define cOCTRPC_ECHO_PROTOCOL 0x00000000 + +#define cOCTRPC_MIN_PACKET_BYTE_LENGTH (sizeof( tOCTRPC_OGRDTP_HEADER )) +#define cOCTRPC_FIRST_COMMAND_BYTE_OFFSET (sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER )) +#define cOCTRPC_GENERIC_HEADERS_BYTE_SIZE (sizeof( tOCTRPC_OGRDTP_HEADER ) + sizeof( tOCTRPC_INTERFACE_HEADER ) + sizeof( tOCTRPC_COMMAND_HEADER )) +#define cOCTRPC_MAX_PACKET_BYTE_LENGTH 32768 + +/* Protocol versions */ +#define cOCTRPC_PROTOCOL_V1_0 0x00010000 +#define cOCTRPC_PROTOCOL_V1_1 0x00010001 +#define cOCTRPC_PROTOCOL_V1_2 0x00010002 +#define cOCTRPC_PROTOCOL_V1_3 0x00010003 +#define cOCTRPC_OCTASIC_PROTOCOL_V1_0 0xFF010000 +#define cOCTRPC_OCTASIC_PROTOCOL_V1_1 0xFF010001 +#define cOCTRPC_OCTASIC_PROTOCOL_V1_2 0xFF010002 +#define cOCTRPC_OCTASIC_PROTOCOL_V1_3 0xFF010003 + +/* Chips */ +#define cOCTRPC_OCT8304_INTERFACE 0x00000000 +#define cOCTRPC_OCT6100_INTERFACE 0x00000001 + +/* Timeout values. */ +#define cOCTRPC_SESSION_TIMEOUT 30 + +/* Generic errors */ +#define cOCTRPC_RDBGERR_OK 0x00000000 +#define cOCTRPC_RDBGERR_NO_ANSWER 0xFFFF0000 +#define cOCTRPC_RDBGERR_ALL_SESSIONS_OPEN 0xFFFF0001 +#define cOCTRPC_RDBGERR_PROTOCOL_NUMBER 0xFFFF0002 +#define cOCTRPC_RDBGERR_NO_COMMAND_HEADER 0xFFFF0003 +#define cOCTRPC_RDBGERR_INTERFACE_TYPE 0xFFFF0004 +#define cOCTRPC_RDBGERR_INTERFACE_VERSION 0xFFFF0005 +#define cOCTRPC_RDBGERR_INVALID_PACKET_LENGTH 0xFFFF0006 +#define cOCTRPC_RDBGERR_INVALID_COMMAND_LENGTH 0xFFFF0007 +#define cOCTRPC_RDBGERR_INVALID_COMMAND_NUMBER 0xFFFF0008 +#define cOCTRPC_RDBGERR_PACKET_TOO_LARGE 0xFFFF0009 +#define cOCTRPC_RDBGERR_LIST_EMPTY 0xFFFF000A + +#define cOCTRPC_RDBGERR_FATAL 0xFFFFFFFF + + +/***************************** TYPES ***************************************/ + +typedef struct _OCTRPC_OGRDTP_HEADER_ +{ + UINT32 IN ulEndianDetect; + UINT32 IN ulDebugSessionNum; + UINT32 IN ulTransactionNum; + UINT32 IN ulPktRetryNum; + UINT32 IN ulPktByteSize; + UINT32 IN ulChecksum; + UINT32 OUT ulParsingError; + UINT32 IN ulRpcProtocolNum; + +} tOCTRPC_OGRDTP_HEADER, *tPOCTRPC_OGRDTP_HEADER; + +typedef struct _OCTRPC_INTERFACE_HEADER_ +{ + UINT32 IN ulInterfaceType; + UINT32 IN ulInterfaceVersion; + +} tOCTRPC_INTERFACE_HEADER, *tPOCTRPC_INTERFACE_HEADER; + +typedef struct _OCTRPC_COMMAND_HEADER_ +{ + UINT32 IN ulCommandByteSize; + UINT32 IN OUT ulRpcCommandNum; + UINT32 OUT ulFunctionResult; + +} tOCTRPC_COMMAND_HEADER, *tPOCTRPC_COMMAND_HEADER; + +#endif /* __RPC_PROTOCOL_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octtype.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octtype.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octtype.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octtype.h 2008-10-28 16:50:30.000000000 -0500 @@ -0,0 +1,155 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octtype.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file defines the base storage types. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 18 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#ifndef __OCTTYPE_H__ +#define __OCTTYPE_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------------------------------------------------------------- + Include target-specific header if available +----------------------------------------------------------------------------*/ +#if defined( OCT_NTDRVENV ) + #include "octtypentdrv.h" /* All NT driver typedef */ +#elif defined( OCT_WINENV ) + #include "octtypewin.h" /* All Win32 typedef */ +#elif defined( OCT_VXENV ) + #include "octtypevx.h" /* All VxWorks typedef */ +#else +/*-------------------------------------------------------------------------- + No target-specific header available +----------------------------------------------------------------------------*/ + +#ifdef SZ +#undef SZ +#endif + +/***************************** DEFINES *************************************/ +/* 16-bit integer */ +typedef unsigned short UINT16; +typedef signed short INT16; +typedef unsigned short *PUINT16; +typedef signed short *PINT16; + +/* 8-bit integer */ +typedef unsigned char UINT8; +typedef signed char INT8; +typedef signed char OCT_INT8; +typedef unsigned char *PUINT8; +typedef signed char *PINT8; + + +/* 32 bit integer */ +typedef unsigned int UINT32; +typedef signed int INT32; +typedef INT32 * PINT32; +typedef UINT32 * PUINT32; + +/* Long integer */ +typedef signed long LONG; +typedef unsigned long ULONG; +typedef long * PLONG; +typedef unsigned long * PULONG; + +/* Short integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef short * PSHORT; +typedef unsigned short *PUSHORT; + +/* 8-bit integer*/ +typedef unsigned char BYTE; +typedef BYTE * PBYTE; +typedef unsigned char UCHAR; + +/* Character and strings */ +typedef char CHAR; +typedef CHAR SZ; +typedef CHAR * PSZ; +typedef CHAR * PCHAR; + +/* Double integers */ +typedef double DOUBLE; +typedef double * PDOUBLE; +typedef float FLOAT; +typedef float * PFLOAT; + +typedef void VOID; +typedef void * PVOID; + +/* Booleans */ +typedef int BOOL; +typedef BOOL * PBOOL; + +/* Integers */ +typedef int INT; +typedef int * PINT; +typedef unsigned int UINT; +typedef unsigned int * PUINT; + +/* Define pseudo-keywords IN and OUT if not defined yet */ +#ifndef IN +#define IN /* IN param */ +#endif + +#ifndef OUT +#define OUT /* OUT param */ +#endif + +/* LONG LONG */ +#define LLONG signed long long +#define PLLONG signed long long * +#define ULLONG unsigned long long +#define PULLONG unsigned long long * + +#ifndef OPT +#define OPT /* OPT param */ +#endif + +typedef PSZ * PPSZ; + +#include + +#endif + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __OCTTYPE_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octtypevx.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octtypevx.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octtypevx.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octtypevx.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,132 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octtypevx.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file defines the base storage types for the VxWorks environment. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 9 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCTTYPEVX_H__ +#define __OCTTYPEVX_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vxWorks.h" + +/* 16-bit pointer integer */ +typedef unsigned short *PUINT16; +typedef signed short *PINT16; + +/* 8-bit integer pointer */ +typedef unsigned char *PUINT8; +typedef signed char *PINT8; + +/* 32-bit integer pointer */ +typedef INT32 * PINT32; +typedef UINT32 * PUINT32; + +/* Long integer pointer */ +/*Intel library for file system definition*/ +#ifndef DATATYPE_H +typedef long LONG; +#endif +typedef long * PLONG; +typedef unsigned long * PULONG; + +/* Short integer pointer */ +typedef short SHORT; +typedef short * PSHORT; +typedef unsigned short *PUSHORT; + +/* 8-bit integer*/ +#if (CPU!=SIMNT) && !defined(DATATYPE_H) +typedef char BYTE; +#endif + + +typedef BYTE * PBYTE; + +/* Character and strings */ +/*Intel library for file system definition*/ +#ifndef DATATYPE_H +typedef char CHAR; +#endif +typedef char * PCHAR; +typedef CHAR SZ; +typedef CHAR * PSZ; +typedef signed char OCT_INT8; + +/* Double integers */ +typedef double DOUBLE; +typedef double * PDOUBLE; +typedef float FLOAT; +typedef float * PFLOAT; + +typedef void * PVOID; + +/* Booleans */ +typedef BOOL * PBOOL; + +/* Integers */ +typedef int INT; +typedef int * PINT; +typedef unsigned int PUINT; + +/* Define pseudo-keywords IN and OUT if not defined yet */ +#ifndef IN +#define IN /* IN param */ +#endif + +#ifndef OUT +#define OUT /* OUT param */ +#endif + +/* LONG LONG */ +#define LLONG signed long long +#define PLLONG signed long long * +#define ULLONG unsigned long long +#define PULLONG unsigned long long * + +#ifndef OPT +#define OPT /* OPT param */ +#endif + +typedef PSZ * PPSZ; + + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* __OCTTYPEVX_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octtypewin.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octtypewin.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octtypewin.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/include/octtypewin.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,100 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: octtypewin.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file defines the base storage types for the Windows environment. + Includes the Windows definition file and add the missing ones here. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 16 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCTTYPEWIN_H__ +#define __OCTTYPEWIN_H__ + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ +#define WIN32_LEAN_AND_MEAN /* just get the base type definition from Windows */ +#include + +/* Disable argument not used warning */ +#pragma warning( disable : 4100 ) +/* Disable Level 4 warning: nonstandard extension used : translation unit is empty */ +#pragma warning( disable : 4206 ) + +#ifdef __cplusplus +extern "C" { +#endif + +/* 16-bit integer */ +typedef unsigned short UINT16; +typedef signed short INT16; +typedef unsigned short *PUINT16; +typedef signed short *PINT16; + +/* 8-bit integer */ +typedef unsigned char UINT8; +typedef signed char INT8; +typedef signed char OCT_INT8; +typedef unsigned char *PUINT8; +typedef signed char *PINT8; + +typedef double DOUBLE; + + +/* 32 bit integer */ +#if ( defined( _MSC_VER ) && _MSC_VER == 1100 ) +/* MFC5 compiler does not define UINT32 */ +typedef unsigned int UINT32; +typedef signed int INT32; +typedef INT32 * PINT32; +typedef UINT32 * PUINT32; +#endif /* _MSC_VER */ + +/* LONG LONG */ +#define LLONG signed __int64 +#define PLLONG signed __int64 * +#define ULLONG unsigned __int64 +#define PULLONG unsigned __int64 * + +/* Double integers */ +typedef double DOUBLE; +typedef double * PDOUBLE; +typedef float FLOAT; +typedef float * PFLOAT; + +#ifndef OPT +#define OPT /* OPT param */ +#endif + +typedef PSZ * PPSZ; + +/*-------------------------------------------------------------------------- + C language +----------------------------------------------------------------------------*/ +#ifdef __cplusplus +} +#endif + +#endif /* __OCTTYPEWIN_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/Makefile dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/Makefile --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/Makefile 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/Makefile 2007-07-13 16:12:46.000000000 -0500 @@ -0,0 +1,38 @@ +CFLAGS=-V3.4 -ffunction-sections -I/lib/modules/$(shell uname -r)/build/include -Iinclude -Ioctdeviceapi -Ioctdeviceapi/oct6100api -DGFP_ATOMIC=0 -Dkmalloc=calloc -Dkfree=free +LDFLAGS=-V3.4 -Wl,-Map -Wl,test.map -Wl,--gc-sections + +APIDIR=octdeviceapi/oct6100api/oct6100_api + +OCTASIC_OBJS=$(APIDIR)/oct6100_adpcm_chan.o \ + $(APIDIR)/oct6100_channel.o \ + $(APIDIR)/oct6100_chip_open.o \ + $(APIDIR)/oct6100_chip_stats.o \ + $(APIDIR)/oct6100_conf_bridge.o \ + $(APIDIR)/oct6100_debug.o \ + $(APIDIR)/oct6100_events.o \ + $(APIDIR)/oct6100_interrupts.o \ + $(APIDIR)/oct6100_memory.o \ + $(APIDIR)/oct6100_miscellaneous.o \ + $(APIDIR)/oct6100_mixer.o \ + $(APIDIR)/oct6100_phasing_tsst.o \ + $(APIDIR)/oct6100_playout_buf.o \ + $(APIDIR)/oct6100_remote_debug.o \ + $(APIDIR)/oct6100_tlv.o \ + $(APIDIR)/oct6100_tone_detection.o \ + $(APIDIR)/oct6100_tsi_cnct.o \ + $(APIDIR)/oct6100_tsst.o \ + $(APIDIR)/oct6100_user.o \ + apilib/bt/octapi_bt0.o \ + apilib/largmath/octapi_largmath.o \ + apilib/llman/octapi_llman.o + + +all: test + +test.o: test.c + +test: test.o $(OCTASIC_OBJS) + +clean: + rm -rf test test.o + rm -rf $(OCTASIC_OBJS) diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octasic-helper dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octasic-helper --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octasic-helper 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octasic-helper 2006-08-09 09:29:53.000000000 -0500 @@ -0,0 +1,39 @@ +#!/bin/sh + +# +# Jeffrey C. Ollie +# +# $1 == information requested +# $2 == path to octasic directory +# + +APIDIR=$2/octdeviceapi/oct6100api/oct6100_api + +case $1 in + objects) + echo $APIDIR/oct6100_adpcm_chan.o \ + $APIDIR/oct6100_channel.o \ + $APIDIR/oct6100_chip_open.o \ + $APIDIR/oct6100_chip_stats.o \ + $APIDIR/oct6100_conf_bridge.o \ + $APIDIR/oct6100_debug.o \ + $APIDIR/oct6100_events.o \ + $APIDIR/oct6100_interrupts.o \ + $APIDIR/oct6100_memory.o \ + $APIDIR/oct6100_miscellaneous.o \ + $APIDIR/oct6100_mixer.o \ + $APIDIR/oct6100_phasing_tsst.o \ + $APIDIR/oct6100_playout_buf.o \ + $APIDIR/oct6100_remote_debug.o \ + $APIDIR/oct6100_tlv.o \ + $APIDIR/oct6100_tone_detection.o \ + $APIDIR/oct6100_tsi_cnct.o \ + $APIDIR/oct6100_tsst.o \ + $2/apilib/bt/octapi_bt0.o \ + $2/apilib/largmath/octapi_largmath.o \ + $2/apilib/llman/octapi_llman.o + ;; + cflags) + echo -I$2/include -I$2/octdeviceapi -I$2/octdeviceapi/oct6100api + ;; +esac diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_adpcm_chan_priv.h dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_adpcm_chan_priv.h --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_adpcm_chan_priv.h 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_adpcm_chan_priv.h 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,131 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_adpcm_chan_priv.h + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + File containing all private defines, macros, structures and prototypes + pertaining to the file oct6100_adpcm_chan.c. All elements defined in this + file are for private usage of the API. All public elements are defined + in the oct6100_adpcm_chan_pub.h file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 7 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + +#ifndef __OCT6100_ADPCM_CHAN_PRIV_H__ +#define __OCT6100_ADPCM_CHAN_PRIV_H__ + +/***************************** INCLUDE FILES *******************************/ + +/***************************** DEFINES *************************************/ + +/* ADPCM channel list pointer macros. */ +#define mOCT6100_GET_ADPCM_CHAN_LIST_PNT( pSharedInfo, pList ) \ + pList = ( tPOCT6100_API_ADPCM_CHAN )(( PUINT8 )pSharedInfo + pSharedInfo->ulAdpcmChanListOfst ); + +#define mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pEntry, ulIndex ) \ + pEntry = (( tPOCT6100_API_ADPCM_CHAN )(( PUINT8 )pSharedInfo + pSharedInfo->ulAdpcmChanListOfst)) + ulIndex; + +#define mOCT6100_GET_ADPCM_CHAN_ALLOC_PNT( pSharedInfo, pAlloc ) \ + pAlloc = ( PVOID )(( PUINT8 )pSharedInfo + pSharedInfo->ulAdpcmChanAllocOfst); + +/***************************** TYPES ***************************************/ + + +/************************** FUNCTION PROTOTYPES *****************************/ + +UINT32 Oct6100ApiGetAdpcmChanSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ); + +UINT32 Oct6100ApiAdpcmChanSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ); + + +UINT32 Oct6100AdpcmChanOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ); + +UINT32 Oct6100ApiCheckAdpcmChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ); + +UINT32 Oct6100ApiReserveAdpcmChanResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusAdpcmMemIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ); + +UINT32 Oct6100ApiWriteAdpcmChanStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100ApiUpdateAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100AdpcmChanCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ); + +UINT32 Oct6100ApiAssertAdpcmChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose, + OUT PUINT16 f_pusTsiChanIndex, + OUT PUINT16 f_pusAdpcmMemIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ); + +UINT32 Oct6100ApiInvalidateAdpcmChanStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmChanIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ); + +UINT32 Oct6100ApiReleaseAdpcmChanResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsiChanIndex, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex ); + +UINT32 Oct6100ApiReserveAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusAdpcmChanIndex ); + +UINT32 Oct6100ApiReleaseAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmChanIndex ); + +#endif /* __OCT6100_ADPCM_CHAN_PRIV_H__ */ diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.c 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,1237 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_adpcm_chan.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to open and close ADPCM channels. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 16 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_adpcm_chan_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_adpcm_chan_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_adpcm_chan_priv.h" + +/**************************** PUBLIC FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100AdpcmChanOpen + +Description: This function opens an ADPCM channel between two TDM timeslots. + This channel will perform ADPCM compression or decompression + depending on the channel mode. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100AdpcmChanOpenDef +UINT32 Oct6100AdpcmChanOpenDef( + tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ) +{ + f_pAdpcmChanOpen->pulChanHndl = NULL; + + f_pAdpcmChanOpen->ulInputTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pAdpcmChanOpen->ulInputStream = cOCT6100_INVALID_STREAM; + f_pAdpcmChanOpen->ulInputNumTssts = 1; + f_pAdpcmChanOpen->ulInputPcmLaw = cOCT6100_PCM_U_LAW; + + f_pAdpcmChanOpen->ulOutputTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pAdpcmChanOpen->ulOutputStream = cOCT6100_INVALID_STREAM; + f_pAdpcmChanOpen->ulOutputPcmLaw = cOCT6100_PCM_U_LAW; + f_pAdpcmChanOpen->ulOutputNumTssts = 1; + + f_pAdpcmChanOpen->ulChanMode = cOCT6100_ADPCM_ENCODING; + f_pAdpcmChanOpen->ulEncodingRate = cOCT6100_G726_32KBPS; + f_pAdpcmChanOpen->ulDecodingRate = cOCT6100_G726_32KBPS; + + f_pAdpcmChanOpen->ulAdpcmNibblePosition = cOCT6100_ADPCM_IN_LOW_BITS; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100AdpcmChanOpen +UINT32 Oct6100AdpcmChanOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100AdpcmChanOpenSer( f_pApiInstance, f_pAdpcmChanOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100AdpcmChanClose + +Description: This function closes an opened ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanClose Pointer to ADPCM channel close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100AdpcmChanCloseDef +UINT32 Oct6100AdpcmChanCloseDef( + tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ) +{ + f_pAdpcmChanClose->ulChanHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100AdpcmChanClose +UINT32 Oct6100AdpcmChanClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100AdpcmChanCloseSer( f_pApiInstance, f_pAdpcmChanClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetAdpcmChanSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of the ADPCM memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetAdpcmChanSwSizes +UINT32 Oct6100ApiGetAdpcmChanSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Determine the amount of memory required for the API ADPCM channel list.*/ + f_pInstSizes->ulAdpcmChannelList = f_pOpenChip->ulMaxAdpcmChannels * sizeof( tOCT6100_API_ADPCM_CHAN ); + + if ( f_pOpenChip->ulMaxAdpcmChannels > 0 ) + { + /* Calculate memory needed for ADPCM memory allocation */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxAdpcmChannels, &f_pInstSizes->ulAdpcmChannelAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_48; + } + else + { + f_pInstSizes->ulAdpcmChannelAlloc = 0; + } + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulAdpcmChannelList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulAdpcmChannelAlloc, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAdpcmChanSwInit + +Description: Initializes all elements of the instance structure associated + to the ADPCM memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAdpcmChanSwInit +UINT32 Oct6100ApiAdpcmChanSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_ADPCM_CHAN pChannelsTsiList; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulMaxAdpcmChannels; + PVOID pAdpcmChannelsAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize the ADPCM channel API list.*/ + ulMaxAdpcmChannels = pSharedInfo->ChipConfig.usMaxAdpcmChannels; + + /* Set all entries in the ADPCM channel list to unused. */ + mOCT6100_GET_ADPCM_CHAN_LIST_PNT( pSharedInfo, pChannelsTsiList ) + + /* Clear the memory */ + Oct6100UserMemSet( pChannelsTsiList, 0x00, sizeof(tOCT6100_API_ADPCM_CHAN) * ulMaxAdpcmChannels ); + + /* Initialize the ADPCM channel allocation structures to "all free". */ + if ( ulMaxAdpcmChannels > 0 ) + { + mOCT6100_GET_ADPCM_CHAN_ALLOC_PNT( pSharedInfo, pAdpcmChannelsAlloc ) + + ulResult = OctapiLlmAllocInit( &pAdpcmChannelsAlloc, ulMaxAdpcmChannels ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_BD; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100AdpcmChanOpenSer + +Description: Opens an ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to an ADPCM channel open structure + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100AdpcmChanOpenSer +UINT32 Oct6100AdpcmChanOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ) +{ + UINT16 usAdpcmChanIndex; + UINT16 usTsiMemIndex; + UINT16 usAdpcmMemIndex; + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + UINT32 ulResult; + + /* Check the user's configuration of the ADPCM channel open structure for errors. */ + ulResult = Oct6100ApiCheckAdpcmChanParams( f_pApiInstance, f_pAdpcmChanOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the ADPCM channel. */ + ulResult = Oct6100ApiReserveAdpcmChanResources( f_pApiInstance, f_pAdpcmChanOpen, &usAdpcmChanIndex, &usAdpcmMemIndex, &usTsiMemIndex, &usInputTsstIndex, &usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the ADPCM channel. */ + ulResult = Oct6100ApiWriteAdpcmChanStructs( f_pApiInstance, f_pAdpcmChanOpen, usAdpcmMemIndex, usTsiMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the ADPCM channel entry in the API list. */ + ulResult = Oct6100ApiUpdateAdpcmChanEntry( f_pApiInstance, f_pAdpcmChanOpen, usAdpcmChanIndex, usAdpcmMemIndex, usTsiMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckAdpcmChanParams + +Description: Checks the user's ADPCM channel open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel open configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckAdpcmChanParams +UINT32 Oct6100ApiCheckAdpcmChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen ) +{ + UINT32 ulResult; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxAdpcmChannels == 0 ) + return cOCT6100_ERR_ADPCM_CHAN_DISABLED; + + if ( f_pAdpcmChanOpen->pulChanHndl == NULL ) + return cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE; + + /* Check the input TDM streams, timeslots component for errors. */ + if ( f_pAdpcmChanOpen->ulInputNumTssts != 1 && + f_pAdpcmChanOpen->ulInputNumTssts != 2 ) + return cOCT6100_ERR_ADPCM_CHAN_INPUT_NUM_TSSTS; + + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulInputNumTssts, + f_pAdpcmChanOpen->ulInputTimeslot, + f_pAdpcmChanOpen->ulInputStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_ADPCM_CHAN_INPUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_ADPCM_CHAN_INPUT_STREAM; + } + else + { + return ulResult; + } + } + + if( f_pAdpcmChanOpen->ulInputPcmLaw != cOCT6100_PCM_U_LAW && + f_pAdpcmChanOpen->ulInputPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_ADPCM_CHAN_INPUT_PCM_LAW; + + /* Check the output TDM streams, timeslots component for errors. */ + if ( f_pAdpcmChanOpen->ulOutputNumTssts != 1 && + f_pAdpcmChanOpen->ulOutputNumTssts != 2 ) + return cOCT6100_ERR_ADPCM_CHAN_OUTPUT_NUM_TSSTS; + + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulOutputNumTssts, + f_pAdpcmChanOpen->ulOutputTimeslot, + f_pAdpcmChanOpen->ulOutputStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_ADPCM_CHAN_OUTPUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_ADPCM_CHAN_OUTPUT_STREAM; + } + else + { + return ulResult; + } + } + if( f_pAdpcmChanOpen->ulOutputPcmLaw != cOCT6100_PCM_U_LAW && + f_pAdpcmChanOpen->ulOutputPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_ADPCM_CHAN_OUTPUT_PCM_LAW; + + /* Now, check the channel mode. */ + if ( f_pAdpcmChanOpen->ulChanMode != cOCT6100_ADPCM_ENCODING && + f_pAdpcmChanOpen->ulChanMode != cOCT6100_ADPCM_DECODING ) + return cOCT6100_ERR_ADPCM_CHAN_MODE; + + if ( f_pAdpcmChanOpen->ulChanMode == cOCT6100_ADPCM_ENCODING ) + { + /* Check the encoding rate. */ + if ( ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G711_64KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G726_40KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G726_32KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G726_24KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G726_16KBPS ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_40KBPS_4_1 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_40KBPS_3_2 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_40KBPS_2_3 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_32KBPS_4_0 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_32KBPS_3_1 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_32KBPS_2_2 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_24KBPS_3_0 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_24KBPS_2_1 ) && + ( f_pAdpcmChanOpen->ulEncodingRate != cOCT6100_G727_16KBPS_2_0 ) ) + return cOCT6100_ERR_ADPCM_CHAN_ENCODING_RATE; + } + else /* if ( f_pAdpcmChanOpen->ulChanMode != cOCT6100_ADPCM_DECODING ) */ + { + /* Check the decoding rate. */ + if ( f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_64KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_40KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_32KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_24KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_16KBPS && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G726_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_G726_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G727_2C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G727_3C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G727_4C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_G727_2C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_G727_3C_ENCODED && + f_pAdpcmChanOpen->ulDecodingRate != cOCT6100_G711_G727_4C_ENCODED ) + return cOCT6100_ERR_ADPCM_CHAN_DECODING_RATE; + + /* Make sure that two timeslots are allocated if PCM-ECHO encoded is selected. */ + if ( (f_pAdpcmChanOpen->ulDecodingRate == cOCT6100_G711_G726_ENCODED || + f_pAdpcmChanOpen->ulDecodingRate == cOCT6100_G711_G727_2C_ENCODED || + f_pAdpcmChanOpen->ulDecodingRate == cOCT6100_G711_G727_3C_ENCODED || + f_pAdpcmChanOpen->ulDecodingRate == cOCT6100_G711_G727_4C_ENCODED ) && + f_pAdpcmChanOpen->ulInputNumTssts != 2 ) + return cOCT6100_ERR_ADPCM_CHAN_INCOMPATIBLE_NUM_TSSTS; + } + + /* Check the nibble position. */ + if ( f_pAdpcmChanOpen->ulAdpcmNibblePosition != cOCT6100_ADPCM_IN_LOW_BITS && + f_pAdpcmChanOpen->ulAdpcmNibblePosition != cOCT6100_ADPCM_IN_HIGH_BITS ) + return cOCT6100_ERR_ADPCM_CHAN_ADPCM_NIBBLE_POSITION; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveAdpcmChanResources + +Description: Reserves all resources needed for the new ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel configuration structure. +f_pusAdpcmChanIndex Allocated entry in ADPCM channel list. +f_pusAdpcmMemIndex Allocated entry in the ADPCM control memory. +f_pusTsiMemIndex Allocated entry in the TSI chariot memory. +f_pusInputTsstIndex TSST memory index of the input samples. +f_pusOutputTsstIndex TSST memory index of the output samples. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveAdpcmChanResources +UINT32 Oct6100ApiReserveAdpcmChanResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + OUT PUINT16 f_pusAdpcmChanIndex, + OUT PUINT16 f_pusAdpcmMemIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempVar; + BOOL fAdpcmChanEntry = FALSE; + BOOL fAdpcmMemEntry = FALSE; + BOOL fTsiMemEntry = FALSE; + BOOL fInputTsst = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Reserve an entry in the ADPCM channel list. */ + ulResult = Oct6100ApiReserveAdpcmChanEntry( f_pApiInstance, f_pusAdpcmChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fAdpcmChanEntry = TRUE; + + /* Find a TSI memory entry.*/ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, f_pusTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fTsiMemEntry = TRUE; + + /* Find a conversion memory entry. */ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, f_pusAdpcmMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fAdpcmMemEntry = TRUE; + + /* Reserve the input TSST entry. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulInputTimeslot, + f_pAdpcmChanOpen->ulInputStream, + f_pAdpcmChanOpen->ulInputNumTssts, + cOCT6100_INPUT_TSST, + f_pusInputTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fInputTsst = TRUE; + + /* Reserve the output TSST entry. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulOutputTimeslot, + f_pAdpcmChanOpen->ulOutputStream, + f_pAdpcmChanOpen->ulOutputNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusOutputTsstIndex, + NULL ); + } + } + } + else + { + /* Return an error other than a fatal error. */ + ulResult = cOCT6100_ERR_ADPCM_CHAN_NO_MORE_TSI_AVAILABLE; + } + } + + if ( ulResult != cOCT6100_ERR_OK ) + { + if( fAdpcmChanEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseAdpcmChanEntry( f_pApiInstance, *f_pusAdpcmChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fTsiMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, *f_pusTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fAdpcmMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, *f_pusAdpcmMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fInputTsst == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + f_pAdpcmChanOpen->ulInputTimeslot, + f_pAdpcmChanOpen->ulInputStream, + f_pAdpcmChanOpen->ulInputNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteAdpcmChanStructs + +Description: Performs all the required structure writes to configure the + new ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel configuration structure. +f_pusAdpcmChanIndex Allocated entry in ADPCM channel list. +f_pusAdpcmMemIndex Allocated entry in the ADPCM control memory. +f_pusTsiMemIndex Allocated entry in the TSI chariot memory. +f_pusInputTsstIndex TSST memory index of the input samples. +f_pusOutputTsstIndex TSST memory index of the output samples. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteAdpcmChanStructs +UINT32 Oct6100ApiWriteAdpcmChanStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT32 ulCompType = 0; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*------------------------------------------------------------------------------*/ + /* Configure the TSST control memory. */ + + /* Set the input TSST control entry. */ + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usInputTsstIndex, + f_usTsiMemIndex, + f_pAdpcmChanOpen->ulInputPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the output TSST control entry. */ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usOutputTsstIndex, + f_pAdpcmChanOpen->ulAdpcmNibblePosition, + f_pAdpcmChanOpen->ulOutputNumTssts, + f_usTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------------*/ + /* Configure the ADPCM memory. */ + + if ( f_pAdpcmChanOpen->ulChanMode == cOCT6100_ADPCM_ENCODING ) + { + switch( f_pAdpcmChanOpen->ulEncodingRate ) + { + case cOCT6100_G711_64KBPS: + + if ( f_pAdpcmChanOpen->ulOutputPcmLaw == cOCT6100_PCM_U_LAW ) + ulCompType = 0x4; + else /* if ( f_pAdpcmChanOpen->ulOutputPcmLaw != cOCT6100_PCM_U_LAW ) */ + ulCompType = 0x5; + break; + case cOCT6100_G726_40KBPS: ulCompType = 0x3; break; + case cOCT6100_G726_32KBPS: ulCompType = 0x2; break; + case cOCT6100_G726_24KBPS: ulCompType = 0x1; break; + case cOCT6100_G726_16KBPS: ulCompType = 0x0; break; + case cOCT6100_G727_40KBPS_4_1: ulCompType = 0xD; break; + case cOCT6100_G727_40KBPS_3_2: ulCompType = 0xA; break; + case cOCT6100_G727_40KBPS_2_3: ulCompType = 0x6; break; + case cOCT6100_G727_32KBPS_4_0: ulCompType = 0xE; break; + case cOCT6100_G727_32KBPS_3_1: ulCompType = 0xB; break; + case cOCT6100_G727_32KBPS_2_2: ulCompType = 0x7; break; + case cOCT6100_G727_24KBPS_3_0: ulCompType = 0xC; break; + case cOCT6100_G727_24KBPS_2_1: ulCompType = 0x8; break; + case cOCT6100_G727_16KBPS_2_0: ulCompType = 0x9; break; + } + + ulResult = Oct6100ApiWriteEncoderMemory( f_pApiInstance, + f_usAdpcmMemIndex, + ulCompType, + f_usTsiMemIndex, + FALSE, + f_pAdpcmChanOpen->ulAdpcmNibblePosition, + cOCT6100_INVALID_INDEX, + cOCT6100_INVALID_VALUE, + cOCT6100_INVALID_VALUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( f_pAdpcmChanOpen->ulChanMode != cOCT6100_ADPCM_DECODING ) */ + { + switch( f_pAdpcmChanOpen->ulDecodingRate ) + { + case cOCT6100_G711_64KBPS: ulCompType = 0x8; break; + case cOCT6100_G726_40KBPS: ulCompType = 0x3; break; + case cOCT6100_G726_32KBPS: ulCompType = 0x2; break; + case cOCT6100_G726_24KBPS: ulCompType = 0x1; break; + case cOCT6100_G726_16KBPS: ulCompType = 0x0; break; + case cOCT6100_G727_2C_ENCODED: ulCompType = 0x4; break; + case cOCT6100_G727_3C_ENCODED: ulCompType = 0x5; break; + case cOCT6100_G727_4C_ENCODED: ulCompType = 0x6; break; + case cOCT6100_G726_ENCODED: ulCompType = 0x9; break; + case cOCT6100_G711_G726_ENCODED: ulCompType = 0xA; break; + case cOCT6100_G711_G727_2C_ENCODED: ulCompType = 0xC; break; + case cOCT6100_G711_G727_3C_ENCODED: ulCompType = 0xD; break; + case cOCT6100_G711_G727_4C_ENCODED: ulCompType = 0xE; break; + } + + ulResult = Oct6100ApiWriteDecoderMemory( f_pApiInstance, + f_usAdpcmMemIndex, + ulCompType, + f_usTsiMemIndex, + f_pAdpcmChanOpen->ulOutputPcmLaw, + f_pAdpcmChanOpen->ulAdpcmNibblePosition ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateAdpcmChanEntry + +Description: Updates the new ADPCM channel in the ADPCM channel list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pAdpcmChanOpen Pointer to ADPCM channel open configuration structure. +f_usAdpcmChanIndex Allocated entry in the ADPCM channel list. +f_usAdpcmMemIndex Allocated entry in ADPCM memory. +f_usTsiMemIndex Allocated entry in TSI chariot memory. +f_usInputTsstIndex TSST control memory index of the input TSST. +f_usOutputTsstIndex TSST control memory index of the output TSST. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateAdpcmChanEntry +UINT32 Oct6100ApiUpdateAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_OPEN f_pAdpcmChanOpen, + IN UINT16 f_usAdpcmChanIndex, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_API_ADPCM_CHAN pAdpcmChanEntry; + + /*------------------------------------------------------------------------------*/ + /* Obtain a pointer to the new ADPCM channel's list entry. */ + + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( f_pApiInstance->pSharedInfo, pAdpcmChanEntry, f_usAdpcmChanIndex ) + + /* Copy the buffer's configuration and allocated resources. */ + pAdpcmChanEntry->usInputTimeslot = (UINT16)( f_pAdpcmChanOpen->ulInputTimeslot & 0xFFFF ); + pAdpcmChanEntry->usInputStream = (UINT16)( f_pAdpcmChanOpen->ulInputStream & 0xFFFF ); + pAdpcmChanEntry->byInputNumTssts = (UINT8)( f_pAdpcmChanOpen->ulInputNumTssts & 0xFF ); + pAdpcmChanEntry->byInputPcmLaw = (UINT8)( f_pAdpcmChanOpen->ulInputPcmLaw & 0xFF ); + + pAdpcmChanEntry->usOutputTimeslot = (UINT16)( f_pAdpcmChanOpen->ulOutputTimeslot & 0xFFFF ); + pAdpcmChanEntry->usOutputStream = (UINT16)( f_pAdpcmChanOpen->ulOutputStream & 0xFFFF ); + pAdpcmChanEntry->byOutputNumTssts = (UINT8)( f_pAdpcmChanOpen->ulOutputNumTssts & 0xFF ); + pAdpcmChanEntry->byOutputPcmLaw = (UINT8)( f_pAdpcmChanOpen->ulOutputPcmLaw & 0xFF ); + + /* Store hardware related information. */ + pAdpcmChanEntry->usTsiMemIndex = f_usTsiMemIndex; + pAdpcmChanEntry->usAdpcmMemIndex = f_usAdpcmMemIndex; + pAdpcmChanEntry->usInputTsstIndex = f_usInputTsstIndex; + pAdpcmChanEntry->usOutputTsstIndex = f_usOutputTsstIndex; + + /* Form handle returned to user. */ + *f_pAdpcmChanOpen->pulChanHndl = cOCT6100_HNDL_TAG_ADPCM_CHANNEL | (pAdpcmChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usAdpcmChanIndex; + + /* Finally, mark the ADPCM channel as opened. */ + pAdpcmChanEntry->fReserved = TRUE; + + /* Increment the number of ADPCM channel opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberAdpcmChans++; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100AdpcmChanCloseSer + +Description: Closes an ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pAdpcmChanClose Pointer to ADPCM channel close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100AdpcmChanCloseSer +UINT32 Oct6100AdpcmChanCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose ) +{ + UINT16 usAdpcmChanIndex; + UINT16 usTsiMemIndex; + UINT16 usAdpcmMemIndex; + UINT16 usInputTsstIndex; + UINT16 usOutputTsstIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertAdpcmChanParams( f_pApiInstance, f_pAdpcmChanClose, &usAdpcmChanIndex, &usAdpcmMemIndex, &usTsiMemIndex, &usInputTsstIndex, &usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the ADPCM channel. */ + ulResult = Oct6100ApiInvalidateAdpcmChanStructs( f_pApiInstance, usAdpcmMemIndex, usInputTsstIndex, usOutputTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the ADPCM channel. */ + ulResult = Oct6100ApiReleaseAdpcmChanResources( f_pApiInstance, usAdpcmChanIndex, usAdpcmMemIndex, usTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle. */ + f_pAdpcmChanClose->ulChanHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertAdpcmChanParams + +Description: Validate the handle given by the user and verify the state of + the ADPCM channel about to be closed. + Also return all required information to deactivate the channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_pAdpcmChanClose Pointer to ADPCM channel close structure. +f_pusAdpcmChanIndex Index of the ADPCM channel structure in the API list. +f_pusAdpcmMemIndex Index of the ADPCM memory structure in the API list. +f_pusTsiMemIndex Index of the TSI chariot memory used for this channel. +f_pusInputTsstIndex Index of the input entry in the TSST control memory. +f_pusOutputTsstIndex Index of the output entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertAdpcmChanParams +UINT32 Oct6100ApiAssertAdpcmChanParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_ADPCM_CHAN_CLOSE f_pAdpcmChanClose, + OUT PUINT16 f_pusAdpcmChanIndex, + OUT PUINT16 f_pusAdpcmMemIndex, + OUT PUINT16 f_pusTsiMemIndex, + OUT PUINT16 f_pusInputTsstIndex, + OUT PUINT16 f_pusOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_ADPCM_CHAN pAdpcmChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pAdpcmChanClose->ulChanHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_ADPCM_CHANNEL ) + return cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE; + + *f_pusAdpcmChanIndex = (UINT16)( f_pAdpcmChanClose->ulChanHndl & cOCT6100_HNDL_INDEX_MASK ); + + if ( *f_pusAdpcmChanIndex >= pSharedInfo->ChipConfig.usMaxAdpcmChannels ) + return cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE; + + /*------------------------------------------------------------------------------*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pAdpcmChanEntry, *f_pusAdpcmChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pAdpcmChanClose->ulChanHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pAdpcmChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_ADPCM_CHAN_NOT_OPEN; + if ( ulEntryOpenCnt != pAdpcmChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_ADPCM_CHAN_INVALID_HANDLE; + + /* Return info needed to close the channel and release all resources. */ + *f_pusInputTsstIndex = pAdpcmChanEntry->usInputTsstIndex; + *f_pusOutputTsstIndex = pAdpcmChanEntry->usOutputTsstIndex; + *f_pusTsiMemIndex = pAdpcmChanEntry->usTsiMemIndex; + *f_pusAdpcmMemIndex = pAdpcmChanEntry->usAdpcmMemIndex; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateAdpcmChanStructs + +Description: Closes an ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usAdpcmMemIndex Index of the ADPCM memory. +f_usInputTsstIndex Index of the input entry in the TSST control memory. +f_usOutputTsstIndex Index of the output entry in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateAdpcmChanStructs +UINT32 Oct6100ApiInvalidateAdpcmChanStructs( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usInputTsstIndex, + IN UINT16 f_usOutputTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*------------------------------------------------------------------------------*/ + /* Deactivate the TSST control memory. */ + + /* Set the input TSST control entry to unused. */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usInputTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the output TSST control entry to unused. */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( f_usOutputTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------------*/ + /* Clear the ADPCM memory. */ + + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, f_usAdpcmMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseAdpcmChanResources + +Description: Release and clear the API entry associated to the ADPCM channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_ulAdpcmChanIndex Index of the ADPCM channel in the API list. +f_usAdpcmMemIndex Index of the ADPCM memory used. +f_usTsiMemIndex Index of the TSI memory used. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseAdpcmChanResources +UINT32 Oct6100ApiReleaseAdpcmChanResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmChanIndex, + IN UINT16 f_usAdpcmMemIndex, + IN UINT16 f_usTsiMemIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_ADPCM_CHAN pAdpcmChanEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pAdpcmChanEntry, f_usAdpcmChanIndex ); + + /*------------------------------------------------------------------------------*/ + /* Release all resources associated with ADPCM channel. */ + + /* Release the entry in the ADPCM channel list. */ + ulResult = Oct6100ApiReleaseAdpcmChanEntry( f_pApiInstance, f_usAdpcmChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, f_usAdpcmMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, f_usTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Release the input TSST entry. */ + ulResult = Oct6100ApiReleaseTsst( + f_pApiInstance, + pAdpcmChanEntry->usInputTimeslot, + pAdpcmChanEntry->usInputStream, + pAdpcmChanEntry->byInputNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* Release the output TSST entry. */ + ulResult = Oct6100ApiReleaseTsst( + f_pApiInstance, + pAdpcmChanEntry->usOutputTimeslot, + pAdpcmChanEntry->usOutputStream, + pAdpcmChanEntry->byOutputNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + } + } + } + } + + /* Check if an error occured while releasing the reserved resources. */ + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult >= cOCT6100_ERR_FATAL ) + return ulResult; + else + return cOCT6100_ERR_FATAL_4A; + } + + /*------------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------------*/ + /* Update the ADPCM channel's list entry. */ + + /* Mark the channel as closed. */ + pAdpcmChanEntry->fReserved = FALSE; + pAdpcmChanEntry->byEntryOpenCnt++; + + /* Decrement the number of ADPCM channels opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberAdpcmChans--; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveAdpcmChanEntry + +Description: Reserves one of the ADPCM channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusAdpcmChanIndex Resulting index reserved in the ADPCM channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveAdpcmChanEntry +UINT32 Oct6100ApiReserveAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusAdpcmChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pAdpcmChanAlloc; + UINT32 ulResult; + UINT32 ulAdpcmChanIndex; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_ADPCM_CHAN_ALLOC_PNT( pSharedInfo, pAdpcmChanAlloc ) + + ulResult = OctapiLlmAllocAlloc( pAdpcmChanAlloc, &ulAdpcmChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_ADPCM_CHAN_ALL_ADPCM_CHAN_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_BE; + } + + *f_pusAdpcmChanIndex = (UINT16)( ulAdpcmChanIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseAdpcmChanEntry + +Description: Releases the specified ADPCM channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usAdpcmChanIndex Index reserved in the ADPCM channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseAdpcmChanEntry +UINT32 Oct6100ApiReleaseAdpcmChanEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usAdpcmChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pAdpcmChanAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_ADPCM_CHAN_ALLOC_PNT( pSharedInfo, pAdpcmChanAlloc ) + + ulResult = OctapiLlmAllocDealloc( pAdpcmChanAlloc, f_usAdpcmChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_BF; + } + + return cOCT6100_ERR_OK; +} +#endif diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.c 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,13931 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_channel.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to open, modify and close echo + cancellation channels. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 492 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_mixer_inst.h" +#include "oct6100api/oct6100_tsi_cnct_inst.h" +#include "oct6100api/oct6100_conf_bridge_inst.h" +#include "oct6100api/oct6100_tone_detection_inst.h" +#include "oct6100api/oct6100_phasing_tsst_inst.h" +#include "oct6100api/oct6100_tsst_inst.h" +#include "oct6100api/oct6100_channel_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_tsi_cnct_pub.h" +#include "oct6100api/oct6100_playout_buf_pub.h" +#include "oct6100api/oct6100_phasing_tsst_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" +#include "oct6100api/oct6100_conf_bridge_pub.h" +#include "oct6100api/oct6100_tone_detection_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_debug_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_mixer_priv.h" +#include "oct6100_phasing_tsst_priv.h" +#include "oct6100_tsi_cnct_priv.h" +#include "oct6100_playout_buf_priv.h" +#include "oct6100_conf_bridge_priv.h" +#include "oct6100_tone_detection_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_debug_priv.h" + + +/**************************** PUBLIC FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelOpen + +Description: This function opens a echo cancellation channel. An echo cancellation + channel is constituted of two voice stream (RIN/ROUT and SIN/SOUT), and + an echo cancelling core. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo channel open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelOpenDef +UINT32 Oct6100ChannelOpenDef( + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ) +{ + f_pChannelOpen->pulChannelHndl = NULL; + f_pChannelOpen->ulUserChanId = cOCT6100_INVALID_VALUE; + f_pChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_POWER_DOWN; + f_pChannelOpen->fEnableToneDisabler = FALSE; + f_pChannelOpen->fEnableExtToneDetection = FALSE; + + /* VQE configuration.*/ + f_pChannelOpen->VqeConfig.fSinDcOffsetRemoval = TRUE; + f_pChannelOpen->VqeConfig.fRinDcOffsetRemoval = TRUE; + f_pChannelOpen->VqeConfig.fRinLevelControl = FALSE; + f_pChannelOpen->VqeConfig.lRinLevelControlGainDb = 0; + f_pChannelOpen->VqeConfig.fSoutLevelControl = FALSE; + f_pChannelOpen->VqeConfig.lSoutLevelControlGainDb = 0; + f_pChannelOpen->VqeConfig.fRinAutomaticLevelControl = FALSE; + f_pChannelOpen->VqeConfig.lRinAutomaticLevelControlTargetDb = -20; + f_pChannelOpen->VqeConfig.fSoutAutomaticLevelControl = FALSE; + f_pChannelOpen->VqeConfig.lSoutAutomaticLevelControlTargetDb = -20; + f_pChannelOpen->VqeConfig.fRinHighLevelCompensation = FALSE; + f_pChannelOpen->VqeConfig.lRinHighLevelCompensationThresholdDb = -10; + f_pChannelOpen->VqeConfig.fSoutAdaptiveNoiseReduction = FALSE; + f_pChannelOpen->VqeConfig.fSoutNoiseBleaching = FALSE; + f_pChannelOpen->VqeConfig.fSoutConferencingNoiseReduction = FALSE; + f_pChannelOpen->VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; + f_pChannelOpen->VqeConfig.fEnableNlp = TRUE; + f_pChannelOpen->VqeConfig.fEnableTailDisplacement = FALSE; + f_pChannelOpen->VqeConfig.ulTailDisplacement = cOCT6100_AUTO_SELECT_TAIL; + f_pChannelOpen->VqeConfig.ulTailLength = cOCT6100_AUTO_SELECT_TAIL; + + f_pChannelOpen->VqeConfig.fDtmfToneRemoval = FALSE; + + f_pChannelOpen->VqeConfig.fAcousticEcho = FALSE; + f_pChannelOpen->VqeConfig.lDefaultErlDb = -6; + f_pChannelOpen->VqeConfig.ulAecTailLength = 128; + f_pChannelOpen->VqeConfig.lAecDefaultErlDb = 0; + f_pChannelOpen->VqeConfig.ulNonLinearityBehaviorA = 1; + f_pChannelOpen->VqeConfig.ulNonLinearityBehaviorB = 0; + f_pChannelOpen->VqeConfig.ulDoubleTalkBehavior = cOCT6100_DOUBLE_TALK_BEH_NORMAL; + f_pChannelOpen->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = 0; + f_pChannelOpen->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = 0; + f_pChannelOpen->VqeConfig.fSoutNaturalListenerEnhancement = FALSE; + f_pChannelOpen->VqeConfig.fRoutNoiseReduction = FALSE; + f_pChannelOpen->VqeConfig.lRoutNoiseReductionLevelGainDb = -18; + f_pChannelOpen->VqeConfig.lAnrSnrEnhancementDb = -18; + f_pChannelOpen->VqeConfig.ulAnrVoiceNoiseSegregation = 6; + f_pChannelOpen->VqeConfig.ulToneDisablerVqeActivationDelay = 300; + f_pChannelOpen->VqeConfig.fEnableMusicProtection = FALSE; + /* Older images have idle code detection hard-coded to enabled. */ + f_pChannelOpen->VqeConfig.fIdleCodeDetection = TRUE; + + /* TDM configuration.*/ + f_pChannelOpen->TdmConfig.ulRinNumTssts = 1; + f_pChannelOpen->TdmConfig.ulSinNumTssts = 1; + f_pChannelOpen->TdmConfig.ulRoutNumTssts = 1; + f_pChannelOpen->TdmConfig.ulSoutNumTssts = 1; + + f_pChannelOpen->TdmConfig.ulRinTimeslot = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulRinStream = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulRinPcmLaw = cOCT6100_PCM_U_LAW; + + f_pChannelOpen->TdmConfig.ulSinTimeslot = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulSinStream = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulSinPcmLaw = cOCT6100_PCM_U_LAW; + + f_pChannelOpen->TdmConfig.ulRoutTimeslot = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulRoutStream = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulRoutPcmLaw = cOCT6100_PCM_U_LAW; + + f_pChannelOpen->TdmConfig.ulSoutTimeslot = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulSoutStream = cOCT6100_UNASSIGNED; + f_pChannelOpen->TdmConfig.ulSoutPcmLaw = cOCT6100_PCM_U_LAW; + + /* CODEC configuration.*/ + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition = cOCT6100_ADPCM_IN_LOW_BITS; + + f_pChannelOpen->CodecConfig.ulEncoderPort = cOCT6100_CHANNEL_PORT_SOUT; + f_pChannelOpen->CodecConfig.ulEncodingRate = cOCT6100_G711_64KBPS; + f_pChannelOpen->CodecConfig.ulDecoderPort = cOCT6100_CHANNEL_PORT_RIN; + f_pChannelOpen->CodecConfig.ulDecodingRate = cOCT6100_G711_64KBPS; + + f_pChannelOpen->CodecConfig.fEnableSilenceSuppression = FALSE; + f_pChannelOpen->CodecConfig.ulPhasingTsstHndl = cOCT6100_INVALID_HANDLE; + f_pChannelOpen->CodecConfig.ulPhase = 1; + f_pChannelOpen->CodecConfig.ulPhasingType = cOCT6100_NO_PHASING; + + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelOpen +UINT32 Oct6100ChannelOpen( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelOpenSer( f_pApiInstance, f_pChannelOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelClose + +Description: This function closes an echo canceller channel + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelClose Pointer to channel close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelCloseDef +UINT32 Oct6100ChannelCloseDef( + IN OUT tPOCT6100_CHANNEL_CLOSE f_pChannelClose ) +{ + f_pChannelClose->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelClose +UINT32 Oct6100ChannelClose( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelCloseSer( f_pApiInstance, f_pChannelClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelModify + +Description: This function will modify the parameter of an echo channel. If + the call to this channel allows the channel to go from power down + to enable, the API will activate it. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to echo channel change structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelModifyDef +UINT32 Oct6100ChannelModifyDef( + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ) +{ + f_pChannelModify->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelModify->ulUserChanId = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->ulEchoOperationMode = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->fEnableToneDisabler = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->fApplyToAllChannels = FALSE; + + f_pChannelModify->fDisableToneDetection = FALSE; + f_pChannelModify->fStopBufferPlayout = FALSE; + f_pChannelModify->fRemoveConfBridgeParticipant = FALSE; + f_pChannelModify->fRemoveBroadcastTssts = FALSE; + + f_pChannelModify->fTdmConfigModified = FALSE; + f_pChannelModify->fVqeConfigModified = FALSE; + f_pChannelModify->fCodecConfigModified = FALSE; + + /* VQE config. */ + f_pChannelModify->VqeConfig.fSinDcOffsetRemoval = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRinDcOffsetRemoval = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRinLevelControl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lRinLevelControlGainDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutLevelControl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lSoutLevelControlGainDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRinAutomaticLevelControl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lRinAutomaticLevelControlTargetDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutAutomaticLevelControl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lSoutAutomaticLevelControlTargetDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRinHighLevelCompensation = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lRinHighLevelCompensationThresholdDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutAdaptiveNoiseReduction = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutNoiseBleaching = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutConferencingNoiseReduction = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulComfortNoiseMode = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fEnableNlp = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fEnableTailDisplacement = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulTailDisplacement = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->VqeConfig.fDtmfToneRemoval = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->VqeConfig.fAcousticEcho = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lDefaultErlDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulAecTailLength = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lAecDefaultErlDb = (INT32)cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulNonLinearityBehaviorA = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulNonLinearityBehaviorB = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulDoubleTalkBehavior = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fSoutNaturalListenerEnhancement = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fRoutNoiseReduction = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lRoutNoiseReductionLevelGainDb = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.lAnrSnrEnhancementDb = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulAnrVoiceNoiseSegregation = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.ulToneDisablerVqeActivationDelay = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fEnableMusicProtection = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->VqeConfig.fIdleCodeDetection = cOCT6100_KEEP_PREVIOUS_SETTING; + + /* TDM config. */ + f_pChannelModify->TdmConfig.ulRinNumTssts = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSinNumTssts = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRoutNumTssts = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSoutNumTssts = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->TdmConfig.ulRinTimeslot = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRinStream = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRinPcmLaw = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->TdmConfig.ulSinTimeslot = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSinStream = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSinPcmLaw = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->TdmConfig.ulRoutTimeslot = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRoutStream = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulRoutPcmLaw = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->TdmConfig.ulSoutTimeslot = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSoutStream = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->TdmConfig.ulSoutPcmLaw = cOCT6100_KEEP_PREVIOUS_SETTING; + + /* CODEC config. */ + f_pChannelModify->CodecConfig.ulEncoderPort = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulEncodingRate = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulDecoderPort = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulDecodingRate = cOCT6100_KEEP_PREVIOUS_SETTING; + + f_pChannelModify->CodecConfig.fEnableSilenceSuppression = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulPhasingTsstHndl = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulPhase = cOCT6100_KEEP_PREVIOUS_SETTING; + f_pChannelModify->CodecConfig.ulPhasingType = cOCT6100_KEEP_PREVIOUS_SETTING; + + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelModify +UINT32 Oct6100ChannelModify( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Check the apply to all channels flag first. */ + if ( f_pChannelModify->fApplyToAllChannels != TRUE && + f_pChannelModify->fApplyToAllChannels != FALSE ) + return cOCT6100_ERR_CHANNEL_APPLY_TO_ALL_CHANNELS; + + /* Check if must apply modification to all channels. */ + if ( f_pChannelModify->fApplyToAllChannels == TRUE ) + { + tPOCT6100_API_CHANNEL pChanEntry; + UINT16 usChanIndex; + + /* Loop through all channels and look for the opened ones. */ + for ( usChanIndex = 0; usChanIndex < f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels; usChanIndex++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, usChanIndex ); + + /* Check if this one is opened. */ + if ( pChanEntry->fReserved == TRUE ) + { + /* Channel is opened. Form handle and call actual modify function. */ + f_pChannelModify->ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | usChanIndex; + + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelModifySer( f_pApiInstance, f_pChannelModify ); + if ( ulFncRes != cOCT6100_ERR_OK ) + break; + } + } + } + else /* if ( f_pChannelModify->fApplyToAllChannels == FALSE ) */ + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelModifySer( f_pApiInstance, f_pChannelModify ); + } + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelCreateBiDir + +Description: This function creates a bidirectional channel using two standard + echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelCreateBiDir Pointer to channel create BiDir structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelCreateBiDirDef +UINT32 Oct6100ChannelCreateBiDirDef( + IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ) +{ + f_pChannelCreateBiDir->pulBiDirChannelHndl = NULL; + + f_pChannelCreateBiDir->ulFirstChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelCreateBiDir->ulSecondChannelHndl = cOCT6100_INVALID_HANDLE; + + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelCreateBiDir +UINT32 Oct6100ChannelCreateBiDir( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelCreateBiDirSer( f_pApiInstance, f_pChannelCreateBiDir ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelDestroyBiDir + +Description: This function destroys a bidirectional channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelDestroyBiDir Pointer to channel destroy BiDir structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelDestroyBiDirDef +UINT32 Oct6100ChannelDestroyBiDirDef( + IN OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ) +{ + f_pChannelDestroyBiDir->ulBiDirChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelDestroyBiDir +UINT32 Oct6100ChannelDestroyBiDir( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelDestroyBiDirSer( f_pApiInstance, f_pChannelDestroyBiDir ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelBroadcastTsstAdd + +Description: This function adds a TSST to one of the two output ports of a channel. + This TSST can never be modified by a call to Oct6100ChannelModify. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelBroadcastTsstAdd Pointer to the an Add Broadcast TSST structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelBroadcastTsstAddDef +UINT32 Oct6100ChannelBroadcastTsstAddDef( + tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelBroadcastTsstAdd ) +{ + f_pChannelBroadcastTsstAdd->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + f_pChannelBroadcastTsstAdd->ulPort = cOCT6100_INVALID_PORT; + f_pChannelBroadcastTsstAdd->ulTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pChannelBroadcastTsstAdd->ulStream = cOCT6100_INVALID_STREAM; + + return cOCT6100_ERR_OK; + +} +#endif + +#if !SKIP_Oct6100ChannelBroadcastTsstAdd +UINT32 Oct6100ChannelBroadcastTsstAdd( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelBroadcastTsstAdd ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelBroadcastTsstAddSer( f_pApiInstance, f_pChannelBroadcastTsstAdd ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelBroadcastTsstRemove + +Description: This function removes a TSST from one of the two output ports of a channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelBroadcastTsstRemove Pointer to the a Remove Broadcast TSST structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelBroadcastTsstRemoveDef +UINT32 Oct6100ChannelBroadcastTsstRemoveDef( + tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelBroadcastTsstRemove ) +{ + f_pChannelBroadcastTsstRemove->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + f_pChannelBroadcastTsstRemove->ulPort = cOCT6100_INVALID_PORT; + f_pChannelBroadcastTsstRemove->ulTimeslot = cOCT6100_INVALID_TIMESLOT; + f_pChannelBroadcastTsstRemove->ulStream = cOCT6100_INVALID_STREAM; + + f_pChannelBroadcastTsstRemove->fRemoveAll = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ChannelBroadcastTsstRemove +UINT32 Oct6100ChannelBroadcastTsstRemove( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelBroadcastTsstRemove ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelBroadcastTsstRemoveSer( f_pApiInstance, f_pChannelBroadcastTsstRemove ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelGetStats + +Description: This function retrieves all the config and stats related to the channel + designated by ulChannelHndl. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelStats Pointer to a tOCT6100_CHANNEL_STATS structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelGetStatsDef +UINT32 Oct6100ChannelGetStatsDef( + IN OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ) +{ + f_pChannelStats->fResetStats = FALSE; + + f_pChannelStats->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelStats->ulUserChanId = cOCT6100_INVALID_STAT; + f_pChannelStats->ulEchoOperationMode = cOCT6100_INVALID_STAT; + f_pChannelStats->fEnableToneDisabler = FALSE; + f_pChannelStats->ulMutePortsMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + f_pChannelStats->fEnableExtToneDetection = FALSE; + + /* VQE configuration.*/ + f_pChannelStats->VqeConfig.fEnableNlp = FALSE; + f_pChannelStats->VqeConfig.fEnableTailDisplacement = FALSE; + f_pChannelStats->VqeConfig.ulTailDisplacement = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulTailLength = cOCT6100_INVALID_STAT; + + f_pChannelStats->VqeConfig.fSinDcOffsetRemoval = FALSE; + f_pChannelStats->VqeConfig.fRinDcOffsetRemoval = FALSE; + f_pChannelStats->VqeConfig.fRinLevelControl = FALSE; + f_pChannelStats->VqeConfig.fSoutLevelControl = FALSE; + f_pChannelStats->VqeConfig.fRinAutomaticLevelControl = FALSE; + f_pChannelStats->VqeConfig.fSoutAutomaticLevelControl = FALSE; + f_pChannelStats->VqeConfig.fRinHighLevelCompensation = FALSE; + f_pChannelStats->VqeConfig.fAcousticEcho = FALSE; + f_pChannelStats->VqeConfig.fSoutAdaptiveNoiseReduction = FALSE; + f_pChannelStats->VqeConfig.fDtmfToneRemoval = FALSE; + + f_pChannelStats->VqeConfig.fSoutNoiseBleaching = FALSE; + f_pChannelStats->VqeConfig.fSoutConferencingNoiseReduction = FALSE; + + f_pChannelStats->VqeConfig.ulComfortNoiseMode = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulNonLinearityBehaviorA = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulNonLinearityBehaviorB = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulDoubleTalkBehavior = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.lRinLevelControlGainDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lSoutLevelControlGainDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lRinAutomaticLevelControlTargetDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lSoutAutomaticLevelControlTargetDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lRinHighLevelCompensationThresholdDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lDefaultErlDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lAecDefaultErlDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.ulAecTailLength = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.fSoutNaturalListenerEnhancement = FALSE; + f_pChannelStats->VqeConfig.fRoutNoiseReduction = FALSE; + f_pChannelStats->VqeConfig.lRoutNoiseReductionLevelGainDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.lAnrSnrEnhancementDb = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->VqeConfig.ulAnrVoiceNoiseSegregation = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.ulToneDisablerVqeActivationDelay = cOCT6100_INVALID_STAT; + f_pChannelStats->VqeConfig.fEnableMusicProtection = FALSE; + f_pChannelStats->VqeConfig.fIdleCodeDetection = FALSE; + + + + /* TDM configuration.*/ + f_pChannelStats->TdmConfig.ulMaxBroadcastTssts = 0; + f_pChannelStats->TdmConfig.fMoreRoutBroadcastTssts = FALSE; + f_pChannelStats->TdmConfig.fMoreSoutBroadcastTssts = FALSE; + + f_pChannelStats->TdmConfig.ulNumRoutBroadcastTssts = 0; + f_pChannelStats->TdmConfig.ulNumSoutBroadcastTssts = 0; + + f_pChannelStats->TdmConfig.ulRinNumTssts = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSinNumTssts = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRoutNumTssts = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSoutNumTssts = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.ulRinTimeslot = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRinStream = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRinPcmLaw = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.ulSinTimeslot = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSinStream = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSinPcmLaw = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.ulRoutTimeslot = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRoutStream = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulRoutPcmLaw = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.pulRoutBroadcastTimeslot = NULL; + f_pChannelStats->TdmConfig.pulRoutBroadcastStream = NULL; + + f_pChannelStats->TdmConfig.ulSoutTimeslot = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSoutStream = cOCT6100_INVALID_STAT; + f_pChannelStats->TdmConfig.ulSoutPcmLaw = cOCT6100_INVALID_STAT; + + f_pChannelStats->TdmConfig.pulSoutBroadcastTimeslot = NULL; + f_pChannelStats->TdmConfig.pulSoutBroadcastStream = NULL; + + + /* CODEC configuration.*/ + f_pChannelStats->CodecConfig.ulAdpcmNibblePosition = cOCT6100_INVALID_STAT; + + f_pChannelStats->CodecConfig.ulEncoderPort = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulEncodingRate = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulDecoderPort = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulDecodingRate = cOCT6100_INVALID_STAT; + + f_pChannelStats->CodecConfig.fEnableSilenceSuppression = FALSE; + f_pChannelStats->CodecConfig.ulPhasingTsstHndl = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulPhase = cOCT6100_INVALID_STAT; + f_pChannelStats->CodecConfig.ulPhasingType = cOCT6100_INVALID_STAT; + + f_pChannelStats->ulNumEchoPathChanges = cOCT6100_INVALID_STAT; + f_pChannelStats->ulToneDisablerStatus = cOCT6100_INVALID_STAT; + f_pChannelStats->fEchoCancellerConverged = FALSE; + f_pChannelStats->fSinVoiceDetected = FALSE; + f_pChannelStats->lCurrentERL = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lCurrentERLE = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->ulCurrentEchoDelay = cOCT6100_INVALID_STAT; + + f_pChannelStats->lMaxERL = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lMaxERLE = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->ulMaxEchoDelay = cOCT6100_INVALID_STAT; + + f_pChannelStats->lRinLevel = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lSinLevel = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lRinAppliedGain = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lSoutAppliedGain = cOCT6100_INVALID_SIGNED_STAT; + f_pChannelStats->lComfortNoiseLevel = cOCT6100_INVALID_SIGNED_STAT; + + + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelGetStats +UINT32 Oct6100ChannelGetStats( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_STATS f_pChannelStats ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ApiChannelGetStatsSer( f_pApiInstance, f_pChannelStats ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelMute + +Description: This function mutes some or all of the ports designated by + ulChannelHndl. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelMute Pointer to a tPOCT6100_CHANNEL_MUTE structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelMuteDef +UINT32 Oct6100ChannelMuteDef( + IN OUT tPOCT6100_CHANNEL_MUTE f_pChannelMute ) +{ + f_pChannelMute->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelMute->ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelMute +UINT32 Oct6100ChannelMute( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MUTE f_pChannelMute ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelMuteSer( f_pApiInstance, f_pChannelMute ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelUnMute + +Description: This function unmutes some or all of the ports designated by + ulChannelHndl. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelUnMute Pointer to a tPOCT6100_CHANNEL_UNMUTE structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelUnMuteDef +UINT32 Oct6100ChannelUnMuteDef( + IN OUT tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ) +{ + f_pChannelUnMute->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pChannelUnMute->ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChannelUnMute +UINT32 Oct6100ChannelUnMute( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChannelUnMuteSer( f_pApiInstance, f_pChannelUnMute ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetChannelsEchoSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of the ECHO memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetChannelsEchoSwSizes +UINT32 Oct6100ApiGetChannelsEchoSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + UINT32 ulMaxChannels; + + ulMaxChannels = f_pOpenChip->ulMaxChannels; + + if ( f_pOpenChip->fEnableChannelRecording == TRUE && ulMaxChannels != 672 ) + ulMaxChannels++; + + /* Determine the amount of memory required for the API echo channel list.*/ + f_pInstSizes->ulChannelList = ulMaxChannels * sizeof( tOCT6100_API_CHANNEL ); /* Add one for the record channel.*/ + f_pInstSizes->ulBiDirChannelList = f_pOpenChip->ulMaxBiDirChannels * sizeof( tOCT6100_API_BIDIR_CHANNEL ); + if ( ulMaxChannels > 0 ) + { + /* Calculate memory needed for ECHO memory allocation */ + ulResult = OctapiLlmAllocGetSize( ulMaxChannels, &f_pInstSizes->ulChannelAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_0; + } + else + { + f_pInstSizes->ulChannelAlloc = 0; + } + if ( f_pOpenChip->ulMaxBiDirChannels > 0 ) + { + /* Calculate memory needed for ECHO memory allocation */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxBiDirChannels, &f_pInstSizes->ulBiDirChannelAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_0; + } + else + { + f_pInstSizes->ulBiDirChannelAlloc = 0; + } + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulChannelList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulChannelAlloc, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulBiDirChannelList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulBiDirChannelAlloc, ulTempVar ) + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiChannelsEchoSwInit + +Description: Initializes all elements of the instance structure associated + to the ECHO memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiChannelsEchoSwInit +UINT32 Oct6100ApiChannelsEchoSwInit( + IN tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_API_CHANNEL pChannelsEchoList; + tPOCT6100_API_BIDIR_CHANNEL pBiDirChannelsList; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT16 usMaxChannels; + PVOID pEchoChanAlloc; + PVOID pBiDirChanAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of the API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize the ECHO channel API list.*/ + usMaxChannels = pSharedInfo->ChipConfig.usMaxChannels; + + /* add a channel to initialize if the recording is activated. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + usMaxChannels++; + + /* Set all entries in the ADCPM channel list to unused. */ + mOCT6100_GET_CHANNEL_LIST_PNT( pSharedInfo, pChannelsEchoList ); + + /* Initialize the API ECHO channels allocation software to "all free". */ + if ( usMaxChannels > 0 ) + { + /* Clear the memory */ + Oct6100UserMemSet( pChannelsEchoList, 0x00, sizeof(tOCT6100_API_CHANNEL) * usMaxChannels ); + + mOCT6100_GET_CHANNEL_ALLOC_PNT( pSharedInfo, pEchoChanAlloc ) + + ulResult = OctapiLlmAllocInit( &pEchoChanAlloc, usMaxChannels ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1; + } + + mOCT6100_GET_BIDIR_CHANNEL_LIST_PNT( pSharedInfo, pBiDirChannelsList ); + + if ( pSharedInfo->ChipConfig.usMaxBiDirChannels > 0 ) + { + /* Clear the memory */ + Oct6100UserMemSet( pBiDirChannelsList, 0x00, sizeof(tOCT6100_API_BIDIR_CHANNEL) * pSharedInfo->ChipConfig.usMaxBiDirChannels ); + + mOCT6100_GET_BIDIR_CHANNEL_ALLOC_PNT( pSharedInfo, pBiDirChanAlloc ) + + ulResult = OctapiLlmAllocInit( &pBiDirChanAlloc, pSharedInfo->ChipConfig.usMaxBiDirChannels ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A9; + + } + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelOpenSer + +Description: Opens a echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to channel configuration structure. Then handle + identifying the buffer in all future function calls is + returned in this structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelOpenSer +UINT32 Oct6100ChannelOpenSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChannelOpen ) +{ + tOCT6100_API_ECHO_CHAN_INDEX *ChannelIndexConf; + UINT32 ulResult; + + ChannelIndexConf = kmalloc(sizeof(*ChannelIndexConf), GFP_ATOMIC); + + if (!ChannelIndexConf) + return cOCT6100_ERR_FATAL_0; + + /* Check the user's configuration of the echo cancellation channel for errors. */ + ulResult = Oct6100ApiCheckChannelParams( f_pApiInstance, f_pChannelOpen, ChannelIndexConf ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Reserve all resources needed by the echo cancellation channel. */ + ulResult = Oct6100ApiReserveChannelResources( f_pApiInstance, f_pChannelOpen, ChannelIndexConf ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Write all necessary structures to activate the echo cancellation channel. */ + ulResult = Oct6100ApiWriteChannelStructs( f_pApiInstance, f_pChannelOpen, ChannelIndexConf ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Update the new echo cancellation channels's entry in the ECHO channel list. */ + ulResult = Oct6100ApiUpdateChannelEntry( f_pApiInstance, f_pChannelOpen, ChannelIndexConf ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + kfree(ChannelIndexConf); + return cOCT6100_ERR_OK; + +out: + kfree(ChannelIndexConf); + return ulResult; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChannelParams + +Description: Checks the user's echo cancellation channel open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo cancellation channel open configuration structure. +f_pChanIndexConf Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChannelParams +UINT32 Oct6100ApiCheckChannelParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ) +{ + tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig; + tPOCT6100_CHANNEL_OPEN_VQE pVqeConfig; + tPOCT6100_CHANNEL_OPEN_CODEC pCodecConfig; + UINT32 ulDecoderNumTssts; + UINT32 ulResult; + + /* Dereference the configuration structure for clearer code and faster access.*/ + pTdmConfig = &f_pChannelOpen->TdmConfig; + pVqeConfig = &f_pChannelOpen->VqeConfig; + pCodecConfig = &f_pChannelOpen->CodecConfig; + + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels == 0 ) + return cOCT6100_ERR_CHANNEL_DISABLED; + + if ( f_pChannelOpen->pulChannelHndl == NULL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + if ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NORMAL && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_FREEZE && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_RESET && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_POWER_DOWN && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_EXTERNAL && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION && + f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE; + + /* Check the 2100Hz echo disabling configuration.*/ + if ( f_pChannelOpen->fEnableToneDisabler != TRUE && + f_pChannelOpen->fEnableToneDisabler != FALSE ) + return cOCT6100_ERR_CHANNEL_TONE_DISABLER_ENABLE; + + /* Check the extended Tone Detection flag value.*/ + if ( f_pChannelOpen->fEnableExtToneDetection != TRUE && + f_pChannelOpen->fEnableExtToneDetection != FALSE ) + return cOCT6100_ERR_CHANNEL_ENABLE_EXT_TONE_DETECTION; + + /* Check that extented tone detection is actually enabled by the user. */ + if ( ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) && + ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableExtToneDetection == FALSE ) ) + return cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DISABLED; + + + + /*==============================================================================*/ + /* Check the TDM configuration parameters.*/ + + ulResult = Oct6100ApiCheckTdmConfig( f_pApiInstance, pTdmConfig ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Now validate the VQE parameters */ + + ulResult = Oct6100ApiCheckVqeConfig( f_pApiInstance, pVqeConfig, f_pChannelOpen->fEnableToneDisabler ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Verify if the echo operation mode selected can be applied. */ + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + && ( pVqeConfig->fEnableNlp == FALSE ) ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED; + + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + && ( pVqeConfig->fEnableNlp == FALSE ) ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED; + + /* Comfort noise must be activated for speech recognition mode to work. */ + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + && ( pVqeConfig->ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_OFF ) ) + return cOCT6100_ERR_CHANNEL_COMFORT_NOISE_REQUIRED; + + /*==============================================================================*/ + + /*==============================================================================*/ + /* Finally, validate the CODEC configuration.*/ + + if ( pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + ulDecoderNumTssts = pTdmConfig->ulRinNumTssts; + else /* pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + ulDecoderNumTssts = pTdmConfig->ulSinNumTssts; + + ulResult = Oct6100ApiCheckCodecConfig( f_pApiInstance, pCodecConfig, ulDecoderNumTssts, &f_pChanIndexConf->usPhasingTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + /* make sure that if silence suppression is activated, the NLP is enabled.*/ + if ( pCodecConfig->fEnableSilenceSuppression == TRUE && pVqeConfig->fEnableNlp == FALSE ) + return cOCT6100_ERR_CHANNEL_SIL_SUP_NLP_MUST_BE_ENABLED; + + /* Verify if law conversion is allowed. */ + if ( pCodecConfig->ulEncoderPort == cOCT6100_NO_ENCODING || + pCodecConfig->ulDecoderPort == cOCT6100_NO_DECODING ) + { + /* No law conversion can occurs if one ADPCM memory is not reserved.*/ + if ( pTdmConfig->ulRinPcmLaw != pTdmConfig->ulRoutPcmLaw ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_LAW_TRANSLATION; + + if ( pTdmConfig->ulSinPcmLaw != pTdmConfig->ulSoutPcmLaw ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_LAW_TRANSLATION; + } + + /* Verify if the config supports extended tone detection.*/ + if ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) + { + if ( pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + return cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DECODER_PORT; + } + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveChannelResources + +Description: Reserves all resources needed for the new channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo cancellation channel configuration structure. +f_pulChannelIndex Allocated entry in ECHO channel list. +f_pChanIndexConf Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveChannelResources +UINT32 Oct6100ApiReserveChannelResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig; + tPOCT6100_CHANNEL_OPEN_CODEC pCodecConfig; + + UINT32 ulResult; + UINT32 ulTempVar; + UINT32 ulFreeMixerEventCnt; + + BOOL fRinTsstEntry = FALSE; + BOOL fSinTsstEntry = FALSE; + BOOL fRoutTsstEntry = FALSE; + BOOL fSoutTsstEntry = FALSE; + + BOOL fRinRoutTsiMemEntry = FALSE; + BOOL fSinSoutTsiMemEntry = FALSE; + + BOOL fEchoChanEntry = FALSE; + + PUINT16 pusRinRoutConversionMemIndex = NULL; + PUINT16 pusSinSoutConversionMemIndex = NULL; + BOOL fRinRoutConversionMemEntry = FALSE; + BOOL fSinSoutConversionMemEntry = FALSE; + + BOOL fExtToneChanEntry = FALSE; + BOOL fExtToneTsiEntry = FALSE; + BOOL fExtToneMixerEntry = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a local pointer to the configuration structures.*/ + pTdmConfig = &f_pChannelOpen->TdmConfig; + pCodecConfig = &f_pChannelOpen->CodecConfig; + + /*===============================================================================*/ + /* Reserve Echo and TSI entries. */ + + ulResult = Oct6100ApiReserveEchoEntry( f_pApiInstance, + &f_pChanIndexConf->usEchoChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fEchoChanEntry = TRUE; + + /* Set the echo, encoder and decoder memory indexes.*/ + f_pChanIndexConf->usEchoMemIndex = f_pChanIndexConf->usEchoChanIndex; + + /* Reserve an entry for the RIN/ROUT tsi chariot memory. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &f_pChanIndexConf->usRinRoutTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinRoutTsiMemEntry = TRUE; + + /* Reserve an entry for the SIN/SOUT tsi chariot memory. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &f_pChanIndexConf->usSinSoutTsiMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinSoutTsiMemEntry = TRUE; + + /* Reserve an ADPCM memory block for compression if required.*/ + if ( pCodecConfig->ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + pusRinRoutConversionMemIndex = &f_pChanIndexConf->usRinRoutConversionMemIndex; + } + else if ( pCodecConfig->ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT ) + { + pusSinSoutConversionMemIndex = &f_pChanIndexConf->usSinSoutConversionMemIndex; + } + + /* Reserve an ADPCM memory block for decompression if required.*/ + if ( pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + pusRinRoutConversionMemIndex = &f_pChanIndexConf->usRinRoutConversionMemIndex; + } + else if ( pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN ) + { + pusSinSoutConversionMemIndex = &f_pChanIndexConf->usSinSoutConversionMemIndex; + } + + + /* Reserve the conversion memories. */ + if ( pusRinRoutConversionMemIndex != NULL ) + { + /* Reserve a conversion memory for the Rin/Rout stream. */ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, + pusRinRoutConversionMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinRoutConversionMemEntry = TRUE; + } + } + else + { + /* No conversion memory reserved.*/ + f_pChanIndexConf->usRinRoutConversionMemIndex = cOCT6100_INVALID_INDEX; + } + + if ( ( pusSinSoutConversionMemIndex != NULL ) && + ( ulResult == cOCT6100_ERR_OK ) ) + { + /* Reserve a conversion memory for the Sin/Sout stream. */ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, + pusSinSoutConversionMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinSoutConversionMemEntry = TRUE; + } + } + else + { + /* No conversion memory reserved.*/ + f_pChanIndexConf->usSinSoutConversionMemIndex = cOCT6100_INVALID_INDEX; + } + + /* Reserve any resources required if the extended Tone detection is enabled.*/ + if ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) + { + ulResult = Oct6100ApiReserveEchoEntry( f_pApiInstance, + &f_pChanIndexConf->usExtToneChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fExtToneChanEntry = TRUE; + + /* Reserve an entry for the TSI chariot memory for the additionnal channel. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + &f_pChanIndexConf->usExtToneTsiIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fExtToneTsiEntry = TRUE; + + /* Reserve an entry for the TSI chariot memory for the additionnal channel. */ + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, + &f_pChanIndexConf->usExtToneMixerIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fExtToneMixerEntry = TRUE; + } + } + } + else + { + f_pChanIndexConf->usExtToneChanIndex = cOCT6100_INVALID_INDEX; + f_pChanIndexConf->usExtToneMixerIndex = cOCT6100_INVALID_INDEX; + f_pChanIndexConf->usExtToneTsiIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + /* Return an error other then a Fatal.*/ + ulResult = cOCT6100_ERR_CHANNEL_OUT_OF_TSI_MEMORY; + } + } + else + { + /* Return an error other then a Fatal.*/ + ulResult = cOCT6100_ERR_CHANNEL_OUT_OF_TSI_MEMORY; + } + } + + /*===============================================================================*/ + + /*===============================================================================*/ + /* Now reserve the TSST entries if required.*/ + + /* Reserve the Rin TSST entry */ + if ( (ulResult == cOCT6100_ERR_OK ) && + (pTdmConfig->ulRinTimeslot != cOCT6100_UNASSIGNED && + pTdmConfig->ulRinStream != cOCT6100_UNASSIGNED) ) + { + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pTdmConfig->ulRinTimeslot, + pTdmConfig->ulRinStream, + pTdmConfig->ulRinNumTssts, + cOCT6100_INPUT_TSST, + &f_pChanIndexConf->usRinTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + fRinTsstEntry = TRUE; + } + else + { + f_pChanIndexConf->usRinTsstIndex = cOCT6100_INVALID_INDEX; + } + + + if ( (ulResult == cOCT6100_ERR_OK ) && + (pTdmConfig->ulSinTimeslot != cOCT6100_UNASSIGNED && + pTdmConfig->ulSinStream != cOCT6100_UNASSIGNED) ) + { + /* Reserve the Sin TSST entry.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pTdmConfig->ulSinTimeslot, + pTdmConfig->ulSinStream, + pTdmConfig->ulSinNumTssts, + cOCT6100_INPUT_TSST, + &f_pChanIndexConf->usSinTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + fSinTsstEntry = TRUE; + } + else + { + f_pChanIndexConf->usSinTsstIndex = cOCT6100_INVALID_INDEX; + } + + if ( (ulResult == cOCT6100_ERR_OK ) && + (pTdmConfig->ulRoutTimeslot != cOCT6100_UNASSIGNED && + pTdmConfig->ulRoutStream != cOCT6100_UNASSIGNED) ) + { + /* Reserve the Rout TSST entry.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pTdmConfig->ulRoutTimeslot, + pTdmConfig->ulRoutStream, + pTdmConfig->ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + &f_pChanIndexConf->usRoutTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + fRoutTsstEntry = TRUE; + } + else + { + f_pChanIndexConf->usRoutTsstIndex = cOCT6100_INVALID_INDEX; + } + + + if ( (ulResult == cOCT6100_ERR_OK ) && + (pTdmConfig->ulSoutTimeslot != cOCT6100_UNASSIGNED && + pTdmConfig->ulSoutStream != cOCT6100_UNASSIGNED) ) + { + /* Reserve the Sout TSST entry.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pTdmConfig->ulSoutTimeslot, + pTdmConfig->ulSoutStream, + pTdmConfig->ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + &f_pChanIndexConf->usSoutTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + fSoutTsstEntry = TRUE; + } + else + { + f_pChanIndexConf->usSoutTsstIndex = cOCT6100_INVALID_INDEX; + } + + /*===============================================================================*/ + + + /*===============================================================================*/ + /* Check if there are a couple of mixer events available for us. */ + + if ( ulResult == cOCT6100_ERR_OK ) + { + UINT32 ulMixerEventCntNeeded = 0; + + /* Calculate how many mixer events are needed. */ + if ( f_pChanIndexConf->usRinTsstIndex == cOCT6100_INVALID_INDEX ) + ulMixerEventCntNeeded++; + + if ( f_pChanIndexConf->usSinTsstIndex == cOCT6100_INVALID_INDEX ) + ulMixerEventCntNeeded++; + + /* If at least 1 mixer event is needed, check if those are available. */ + if ( ulMixerEventCntNeeded != 0 ) + { + ulResult = Oct6100ApiGetFreeMixerEventCnt( f_pApiInstance, &ulFreeMixerEventCnt ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* The API might need more mixer events if the ports have to be muted. */ + /* Check if these are available. */ + if ( ulFreeMixerEventCnt < ulMixerEventCntNeeded ) + { + ulResult = cOCT6100_ERR_CHANNEL_OUT_OF_MIXER_EVENTS; + } + } + } + } + + /*===============================================================================*/ + + + /*===============================================================================*/ + /* Release the resources if something went wrong */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /*===============================================================================*/ + /* Release the previously reserved resources .*/ + if( fRinTsstEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->ulRinTimeslot, + pTdmConfig->ulRinStream, + pTdmConfig->ulRinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fSinTsstEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->ulSinTimeslot, + pTdmConfig->ulSinStream, + pTdmConfig->ulSinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fRoutTsstEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->ulRoutTimeslot, + pTdmConfig->ulRoutStream, + pTdmConfig->ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fSoutTsstEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->ulSoutTimeslot, + pTdmConfig->ulSoutStream, + pTdmConfig->ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fRinRoutTsiMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + f_pChanIndexConf->usRinRoutTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fSinSoutTsiMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + f_pChanIndexConf->usSinSoutTsiMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /*===============================================================================*/ + + /*===============================================================================*/ + /* Release the previously reserved echo resources .*/ + if( fEchoChanEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseEchoEntry( f_pApiInstance, + f_pChanIndexConf->usEchoChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /*===============================================================================*/ + + /*===============================================================================*/ + /* Release the previously reserved resources for the extended tone detection.*/ + if( fExtToneChanEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseEchoEntry( f_pApiInstance, + f_pChanIndexConf->usExtToneChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fExtToneTsiEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + f_pChanIndexConf->usExtToneTsiIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fExtToneMixerEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + f_pChanIndexConf->usExtToneMixerIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + /*===============================================================================*/ + + /*===============================================================================*/ + /* Release the conversion resources. */ + if( fRinRoutConversionMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, + f_pChanIndexConf->usRinRoutConversionMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if( fSinSoutConversionMemEntry == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, + f_pChanIndexConf->usSinSoutConversionMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /*===============================================================================*/ + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteChannelStructs + +Description: Performs all the required structure writes to configure the + new echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo cancellation channel configuration structure. +f_pChanIndexConf Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteChannelStructs +UINT32 Oct6100ApiWriteChannelStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig; + tOCT6100_WRITE_PARAMS WriteParams; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + UINT32 ulDwordAddress; + UINT32 ulDwordData; + BOOL fConversionEnabled = FALSE; + BOOL fProgramAdpcmMem; + UINT32 ulCompType = 0; + UINT32 ulPcmLaw; + UINT16 usTempTsiMemIndex; + UINT16 usConversionMemIndex; + UINT32 ulToneEventNumber; + BOOL fSSTone; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a local pointer to the TDM configuration structure.*/ + pTdmConfig = &f_pChannelOpen->TdmConfig; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_pChanIndexConf->usEchoChanIndex ); + + /*==============================================================================*/ + /* Configure the Input Tsst control memory.*/ + + /* Set the RIN Tsst control entry.*/ + if ( f_pChanIndexConf->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_pChanIndexConf->usRinTsstIndex, + f_pChanIndexConf->usRinRoutTsiMemIndex, + pTdmConfig->ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the SIN Tsst control entry.*/ + if ( f_pChanIndexConf->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_pChanIndexConf->usSinTsstIndex, + f_pChanIndexConf->usSinSoutTsiMemIndex, + pTdmConfig->ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + + /*==============================================================================*/ + /* Configure the ADPCM control memory for the Decoder.*/ + + /* Set the codec state flags.*/ + f_pChanIndexConf->fRinRoutCodecActive = FALSE; + f_pChanIndexConf->fSinSoutCodecActive = FALSE; + + if ( f_pChannelOpen->CodecConfig.ulDecoderPort != cOCT6100_NO_DECODING ) + { + fProgramAdpcmMem = TRUE; + + switch( f_pChannelOpen->CodecConfig.ulDecodingRate ) + { + case cOCT6100_G711_64KBPS: + ulCompType = 0x8; + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + if ( pTdmConfig->ulRinPcmLaw == pTdmConfig->ulRoutPcmLaw ) + fProgramAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( pTdmConfig->ulRinStream == cOCT6100_UNASSIGNED ) + || ( pTdmConfig->ulRoutStream == cOCT6100_UNASSIGNED ) ) + fProgramAdpcmMem = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + if ( pTdmConfig->ulSinPcmLaw == pTdmConfig->ulSoutPcmLaw ) + fProgramAdpcmMem = FALSE; + + if ( ( pTdmConfig->ulSinStream == cOCT6100_UNASSIGNED ) + || ( pTdmConfig->ulSoutStream == cOCT6100_UNASSIGNED ) ) + fProgramAdpcmMem = FALSE; + } + break; + case cOCT6100_G726_40KBPS: + ulCompType = 0x3; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_32KBPS: + ulCompType = 0x2; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_24KBPS: + ulCompType = 0x1; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_16KBPS: + ulCompType = 0x0; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_2C_ENCODED: + ulCompType = 0x4; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_3C_ENCODED: + ulCompType = 0x5; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_4C_ENCODED: + ulCompType = 0x6; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_ENCODED: + ulCompType = 0x9; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G711_G726_ENCODED: + ulCompType = 0xA; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G711_G727_2C_ENCODED: + ulCompType = 0xC; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G711_G727_3C_ENCODED: + ulCompType = 0xD; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G711_G727_4C_ENCODED: + ulCompType = 0xE; + fConversionEnabled = TRUE; + break; + default: + return cOCT6100_ERR_FATAL_D4; + } + + if ( fProgramAdpcmMem == TRUE ) + { + /* Set the chariot memory based on the selected port.*/ + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + usTempTsiMemIndex = f_pChanIndexConf->usRinRoutTsiMemIndex; + ulPcmLaw = pTdmConfig->ulRoutPcmLaw; /* Set the law for later use */ + + /* Set the codec state flags.*/ + f_pChanIndexConf->fRinRoutCodecActive = TRUE; + + /* Set the conversion memory index to use for decompression */ + usConversionMemIndex = f_pChanIndexConf->usRinRoutConversionMemIndex; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + usTempTsiMemIndex = f_pChanIndexConf->usSinSoutTsiMemIndex; + ulPcmLaw = pTdmConfig->ulSoutPcmLaw; /* Set the law for later use */ + + /* Set the codec state flags.*/ + f_pChanIndexConf->fSinSoutCodecActive = TRUE; + + /* Set the conversion memory index to use for decompression */ + usConversionMemIndex = f_pChanIndexConf->usSinSoutConversionMemIndex; + } + + ulResult = Oct6100ApiWriteDecoderMemory( f_pApiInstance, + usConversionMemIndex, + ulCompType, + usTempTsiMemIndex, + ulPcmLaw, + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Configure the ADPCM control memory for the Encoder */ + + if ( f_pChannelOpen->CodecConfig.ulEncoderPort != cOCT6100_NO_ENCODING ) + { + fProgramAdpcmMem = TRUE; + + switch( f_pChannelOpen->CodecConfig.ulEncodingRate ) + { + case cOCT6100_G711_64KBPS: + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + if ( pTdmConfig->ulRoutPcmLaw == cOCT6100_PCM_U_LAW ) + ulCompType = 0x4; + else + ulCompType = 0x5; + + /* Check for law conversion.*/ + if ( pTdmConfig->ulRinPcmLaw == pTdmConfig->ulRoutPcmLaw ) + fProgramAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( pTdmConfig->ulRinStream == cOCT6100_UNASSIGNED ) + || ( pTdmConfig->ulRoutStream == cOCT6100_UNASSIGNED ) ) + fProgramAdpcmMem = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + if ( pTdmConfig->ulSoutPcmLaw == cOCT6100_PCM_U_LAW ) + ulCompType = 0x4; + else + ulCompType = 0x5; + + /* Check for law conversion.*/ + if ( pTdmConfig->ulSinPcmLaw == pTdmConfig->ulSoutPcmLaw ) + fProgramAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( pTdmConfig->ulSinStream == cOCT6100_UNASSIGNED ) + || ( pTdmConfig->ulSoutStream == cOCT6100_UNASSIGNED ) ) + fProgramAdpcmMem = FALSE; + } + + break; + case cOCT6100_G726_40KBPS: + ulCompType = 0x3; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_32KBPS: + ulCompType = 0x2; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_24KBPS: + ulCompType = 0x1; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_16KBPS: + ulCompType = 0x0; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_40KBPS_4_1: + ulCompType = 0xD; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_40KBPS_3_2: + ulCompType = 0xA; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_40KBPS_2_3: + ulCompType = 0x6; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_32KBPS_4_0: + ulCompType = 0xE; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_32KBPS_3_1: + ulCompType = 0xB; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_32KBPS_2_2: + ulCompType = 0x7; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_24KBPS_3_0: + ulCompType = 0xC; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_24KBPS_2_1: + ulCompType = 0x8; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_16KBPS_2_0: + ulCompType = 0x9; + fConversionEnabled = TRUE; + break; + + default: + return cOCT6100_ERR_FATAL_D5; + } + + /* Program the APDCM memory only if ADPCM is requried.*/ + if ( fProgramAdpcmMem == TRUE || f_pChanIndexConf->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Set the chariot memory based on the selected port.*/ + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + usTempTsiMemIndex = f_pChanIndexConf->usRinRoutTsiMemIndex; + + /* Set the codec state flags.*/ + f_pChanIndexConf->fRinRoutCodecActive = TRUE; + + /* Set the conversion memory index to use for compression */ + usConversionMemIndex = f_pChanIndexConf->usRinRoutConversionMemIndex; + } + + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + usTempTsiMemIndex = f_pChanIndexConf->usSinSoutTsiMemIndex; + + /* Set the codec state flags.*/ + f_pChanIndexConf->fSinSoutCodecActive = TRUE; + + /* Set the conversion memory index to use for compression */ + usConversionMemIndex = f_pChanIndexConf->usSinSoutConversionMemIndex; + } + + ulResult = Oct6100ApiWriteEncoderMemory( f_pApiInstance, + usConversionMemIndex, + ulCompType, + usTempTsiMemIndex, + f_pChannelOpen->CodecConfig.fEnableSilenceSuppression, + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition, + f_pChanIndexConf->usPhasingTsstIndex, + f_pChannelOpen->CodecConfig.ulPhasingType, + f_pChannelOpen->CodecConfig.ulPhase ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Clearing the tone events bit vector */ + + ulDwordAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_pChanIndexConf->usEchoChanIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ulDwordAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + ulDwordData = 0x00000000; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulDwordAddress, ulDwordData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulDwordAddress += 4; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulDwordAddress, ulDwordData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Write the VQE memory */ + + ulResult = Oct6100ApiWriteVqeMemory( f_pApiInstance, + &f_pChannelOpen->VqeConfig, + f_pChannelOpen, + f_pChanIndexConf->usEchoChanIndex, + f_pChanIndexConf->usEchoMemIndex, + TRUE, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + /*==============================================================================*/ + /* Write the echo memory */ + + ulResult = Oct6100ApiWriteEchoMemory( f_pApiInstance, + pTdmConfig, + f_pChannelOpen, + f_pChanIndexConf->usEchoMemIndex, + f_pChanIndexConf->usRinRoutTsiMemIndex, + f_pChanIndexConf->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + + /*==============================================================================*/ + /* Mute channel if required, this is done on a port basis */ + + /* Initialize the silence indexes to invalid for now. */ + pChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usSinSilenceEventIndex = cOCT6100_INVALID_INDEX; + + /* Set the TSI memory indexes. */ + pChanEntry->usRinRoutTsiMemIndex = f_pChanIndexConf->usRinRoutTsiMemIndex; + pChanEntry->usSinSoutTsiMemIndex = f_pChanIndexConf->usSinSoutTsiMemIndex; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, + f_pChanIndexConf->usEchoChanIndex, + f_pChanIndexConf->usRinTsstIndex, + f_pChanIndexConf->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the dominant speaker to unassigned, if required. */ + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fDominantSpeakerEnabled == TRUE ) + { + ulResult = Oct6100ApiBridgeSetDominantSpeaker( f_pApiInstance, f_pChanIndexConf->usEchoChanIndex, cOCT6100_CONF_DOMINANT_SPEAKER_UNASSIGNED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* If necessary, configure the extended tone detection channel.*/ + + if ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) + { + UINT32 ulTempSinLaw; + UINT32 ulTempSoutLaw; + UINT32 ulTempEchoOpMode; + + /* save the original law.*/ + ulTempSinLaw = pTdmConfig->ulSinPcmLaw; + ulTempSoutLaw = pTdmConfig->ulSoutPcmLaw; + ulTempEchoOpMode = f_pChannelOpen->ulEchoOperationMode; + + /* Now, make sure the Sin and Sout law are the same as the Rin law.*/ + + pTdmConfig->ulSinPcmLaw = pTdmConfig->ulRinPcmLaw; + pTdmConfig->ulSoutPcmLaw = pTdmConfig->ulRinPcmLaw; + + f_pChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_NORMAL; + + /* Write the Echo and VQE memory of the extended channel.*/ + + ulResult = Oct6100ApiWriteDebugChanMemory( f_pApiInstance, + pTdmConfig, + &f_pChannelOpen->VqeConfig, + f_pChannelOpen, + f_pChanIndexConf->usExtToneChanIndex, + f_pChanIndexConf->usExtToneChanIndex, + cOCT6100_API_EXT_TONE_EXTRA_TSI, + f_pChanIndexConf->usExtToneTsiIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now, write the mixer event used to copy the RIN signal of the original channel + into the SIN signal of the exteded channel. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_pChanIndexConf->usExtToneMixerIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= f_pChanIndexConf->usRinRoutTsiMemIndex; + WriteParams.usWriteData |= pTdmConfig->ulRinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = f_pChanIndexConf->usExtToneTsiIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now insert the Sin copy event into the list.*/ + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_pChanIndexConf->usExtToneMixerIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_pChanIndexConf->usEchoChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /*==============================================================================*/ + /* Clearing the tone events bit vector */ + + ulDwordAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_pChanIndexConf->usExtToneChanIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ); + ulDwordAddress += cOCT6100_CH_MAIN_TONE_EVENT_OFFSET; + ulDwordData = 0x00000000; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulDwordAddress, ulDwordData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulDwordAddress += 4; + + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulDwordAddress, ulDwordData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + /* Write back the original values in the channel open structure.*/ + + pTdmConfig->ulSinPcmLaw = ulTempSinLaw; + pTdmConfig->ulSoutPcmLaw = ulTempSoutLaw; + + f_pChannelOpen->ulEchoOperationMode = ulTempEchoOpMode; + } + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* If necessary, configure the SS tone detection. */ + + for ( ulToneEventNumber = 0; ulToneEventNumber < cOCT6100_MAX_TONE_EVENT; ulToneEventNumber++ ) + { + /* Check if the current tone is a SS tone. */ + ulResult = Oct6100ApiIsSSTone( + f_pApiInstance, + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulToneID, + &fSSTone ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( fSSTone == TRUE ) + { + /* Write to all resources needed to activate tone detection on this SS tone. */ + ulResult = Oct6100ApiWriteToneDetectEvent( + f_pApiInstance, + f_pChanIndexConf->usEchoChanIndex, + ulToneEventNumber, + + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Configure the Output Tsst control memory.*/ + + /* Set the ROUT Tsst control entry.*/ + if ( f_pChanIndexConf->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_pChanIndexConf->usRoutTsstIndex, + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition, + pTdmConfig->ulRoutNumTssts, + f_pChanIndexConf->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the SOUT Tsst control entry.*/ + if ( f_pChanIndexConf->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_pChanIndexConf->usSoutTsstIndex, + f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition, + pTdmConfig->ulSoutNumTssts, + f_pChanIndexConf->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateChannelEntry + +Description: Updates the new channel in the ECHO channel list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelOpen Pointer to echo cancellation channel configuration structure. +f_pChanIndexConf Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateChannelEntry +UINT32 Oct6100ApiUpdateChannelEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig; + tPOCT6100_CHANNEL_OPEN_VQE pVqeConfig; + tPOCT6100_CHANNEL_OPEN_CODEC pCodecConfig; + + /* Obtain a pointer to the config structures of the tPOCT6100_CHANNEL_OPEN structure. */ + pTdmConfig = &f_pChannelOpen->TdmConfig; + pVqeConfig = &f_pChannelOpen->VqeConfig; + pCodecConfig = &f_pChannelOpen->CodecConfig; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_pChanIndexConf->usEchoChanIndex ) + + /*=======================================================================*/ + /* Copy the channel's configuration and allocated resources. */ + pChanEntry->ulUserChanId = f_pChannelOpen->ulUserChanId; + pChanEntry->byEchoOperationMode = (UINT8)( f_pChannelOpen->ulEchoOperationMode & 0xFF ); + pChanEntry->fEnableToneDisabler = (UINT8)( f_pChannelOpen->fEnableToneDisabler & 0xFF ); + pChanEntry->fEnableExtToneDetection = (UINT8)( f_pChannelOpen->fEnableExtToneDetection & 0xFF ); + + /* Save the VQE configuration.*/ + pChanEntry->VqeConfig.byComfortNoiseMode = (UINT8)( pVqeConfig->ulComfortNoiseMode & 0xFF ); + pChanEntry->VqeConfig.fEnableNlp = (UINT8)( pVqeConfig->fEnableNlp & 0xFF ); + pChanEntry->VqeConfig.fEnableTailDisplacement = (UINT8)( pVqeConfig->fEnableTailDisplacement ); + pChanEntry->VqeConfig.usTailDisplacement = (UINT16)( pVqeConfig->ulTailDisplacement & 0xFFFF ); + pChanEntry->VqeConfig.usTailLength = (UINT16)( pVqeConfig->ulTailLength & 0xFFFF ); + + pChanEntry->VqeConfig.fSinDcOffsetRemoval = (UINT8)( pVqeConfig->fSinDcOffsetRemoval & 0xFF ); + pChanEntry->VqeConfig.fRinDcOffsetRemoval = (UINT8)( pVqeConfig->fRinDcOffsetRemoval & 0xFF ); + pChanEntry->VqeConfig.fRinLevelControl = (UINT8)( pVqeConfig->fRinLevelControl & 0xFF ); + pChanEntry->VqeConfig.chRinLevelControlGainDb = (OCT_INT8)( pVqeConfig->lRinLevelControlGainDb & 0xFF ); + pChanEntry->VqeConfig.fSoutLevelControl = (UINT8)( pVqeConfig->fSoutLevelControl & 0xFF ); + pChanEntry->VqeConfig.chSoutLevelControlGainDb = (OCT_INT8)( pVqeConfig->lSoutLevelControlGainDb & 0xFF ); + pChanEntry->VqeConfig.fRinAutomaticLevelControl = (UINT8)( pVqeConfig->fRinAutomaticLevelControl & 0xFF ); + pChanEntry->VqeConfig.chRinAutomaticLevelControlTargetDb = (OCT_INT8)( pVqeConfig->lRinAutomaticLevelControlTargetDb & 0xFF ); + pChanEntry->VqeConfig.fSoutAutomaticLevelControl = (UINT8)( pVqeConfig->fSoutAutomaticLevelControl & 0xFF ); + pChanEntry->VqeConfig.chSoutAutomaticLevelControlTargetDb = (OCT_INT8)( pVqeConfig->lSoutAutomaticLevelControlTargetDb & 0xFF ); + pChanEntry->VqeConfig.fRinHighLevelCompensation = (UINT8)( pVqeConfig->fRinHighLevelCompensation & 0xFF ); + pChanEntry->VqeConfig.chRinHighLevelCompensationThresholdDb = (OCT_INT8)( pVqeConfig->lRinHighLevelCompensationThresholdDb & 0xFF ); + pChanEntry->VqeConfig.fSoutAdaptiveNoiseReduction = (UINT8)( pVqeConfig->fSoutAdaptiveNoiseReduction & 0xFF ); + pChanEntry->VqeConfig.fSoutNoiseBleaching = (UINT8)( pVqeConfig->fSoutNoiseBleaching & 0xFF ); + pChanEntry->VqeConfig.fSoutConferencingNoiseReduction = (UINT8)( pVqeConfig->fSoutConferencingNoiseReduction & 0xFF ); + + pChanEntry->VqeConfig.fAcousticEcho = (UINT8)( pVqeConfig->fAcousticEcho & 0xFF ); + + pChanEntry->VqeConfig.fDtmfToneRemoval = (UINT8)( pVqeConfig->fDtmfToneRemoval & 0xFF ); + + pChanEntry->VqeConfig.chDefaultErlDb = (OCT_INT8)( pVqeConfig->lDefaultErlDb & 0xFF ); + pChanEntry->VqeConfig.chAecDefaultErlDb = (OCT_INT8)( pVqeConfig->lAecDefaultErlDb & 0xFF ); + pChanEntry->VqeConfig.usAecTailLength = (UINT16)( pVqeConfig->ulAecTailLength & 0xFFFF ); + pChanEntry->VqeConfig.byNonLinearityBehaviorA = (UINT8)( pVqeConfig->ulNonLinearityBehaviorA & 0xFF ); + pChanEntry->VqeConfig.byNonLinearityBehaviorB = (UINT8)( pVqeConfig->ulNonLinearityBehaviorB & 0xFF ); + pChanEntry->VqeConfig.byDoubleTalkBehavior = (UINT8)( pVqeConfig->ulDoubleTalkBehavior & 0xFF ); + pChanEntry->VqeConfig.chAnrSnrEnhancementDb = (OCT_INT8)( pVqeConfig->lAnrSnrEnhancementDb & 0xFF ); + pChanEntry->VqeConfig.byAnrVoiceNoiseSegregation = (UINT8)( pVqeConfig->ulAnrVoiceNoiseSegregation & 0xFF ); + pChanEntry->VqeConfig.usToneDisablerVqeActivationDelay = (UINT16)( pVqeConfig->ulToneDisablerVqeActivationDelay & 0xFFFF ); + + pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb = (UINT8)( pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb & 0xFF ); + pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb = (UINT8)( pVqeConfig->ulSoutNaturalListenerEnhancementGainDb & 0xFF ); + pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement = (UINT8)( pVqeConfig->fSoutNaturalListenerEnhancement & 0xFF ); + pChanEntry->VqeConfig.fRoutNoiseReduction = (UINT8)( pVqeConfig->fRoutNoiseReduction & 0xFF ); + pChanEntry->VqeConfig.chRoutNoiseReductionLevelGainDb = (OCT_INT8) (pVqeConfig->lRoutNoiseReductionLevelGainDb & 0xFF); + pChanEntry->VqeConfig.fEnableMusicProtection = (UINT8)( pVqeConfig->fEnableMusicProtection & 0xFF ); + pChanEntry->VqeConfig.fIdleCodeDetection = (UINT8)( pVqeConfig->fIdleCodeDetection & 0xFF ); + + /* Save the codec information.*/ + pChanEntry->CodecConfig.byAdpcmNibblePosition = (UINT8)( pCodecConfig->ulAdpcmNibblePosition & 0xFF ); + + pChanEntry->CodecConfig.byDecoderPort = (UINT8)( pCodecConfig->ulDecoderPort & 0xFF ); + pChanEntry->CodecConfig.byDecodingRate = (UINT8)( pCodecConfig->ulDecodingRate & 0xFF ); + pChanEntry->CodecConfig.byEncoderPort = (UINT8)( pCodecConfig->ulEncoderPort & 0xFF ); + pChanEntry->CodecConfig.byEncodingRate = (UINT8)( pCodecConfig->ulEncodingRate & 0xFF ); + + pChanEntry->CodecConfig.fEnableSilenceSuppression = (UINT8)( pCodecConfig->fEnableSilenceSuppression & 0xFF ); + pChanEntry->CodecConfig.byPhase = (UINT8)( pCodecConfig->ulPhase & 0xFF ); + pChanEntry->CodecConfig.byPhasingType = (UINT8)( pCodecConfig->ulPhasingType & 0xFF ); + + /* Save the RIN settings.*/ + pChanEntry->TdmConfig.byRinPcmLaw = (UINT8)( pTdmConfig->ulRinPcmLaw & 0xFF ); + pChanEntry->TdmConfig.usRinTimeslot = (UINT16)( pTdmConfig->ulRinTimeslot & 0xFFFF ); + pChanEntry->TdmConfig.usRinStream = (UINT16)( pTdmConfig->ulRinStream & 0xFFFF ); + + /* Save the SIN settings.*/ + pChanEntry->TdmConfig.bySinPcmLaw = (UINT8)( pTdmConfig->ulSinPcmLaw & 0xFF ); + pChanEntry->TdmConfig.usSinTimeslot = (UINT16)( pTdmConfig->ulSinTimeslot & 0xFFFF ); + pChanEntry->TdmConfig.usSinStream = (UINT16)( pTdmConfig->ulSinStream & 0xFFFF ); + + /* Save the ROUT settings.*/ + pChanEntry->TdmConfig.byRoutPcmLaw = (UINT8)( pTdmConfig->ulRoutPcmLaw & 0xFF ); + pChanEntry->TdmConfig.usRoutTimeslot = (UINT16)( pTdmConfig->ulRoutTimeslot & 0xFFFF ); + pChanEntry->TdmConfig.usRoutStream = (UINT16)( pTdmConfig->ulRoutStream & 0xFFFF ); + + pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry = cOCT6100_INVALID_INDEX; + pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry = 0; + + /* Save the SOUT settings.*/ + pChanEntry->TdmConfig.bySoutPcmLaw = (UINT8)( pTdmConfig->ulSoutPcmLaw & 0xFF ); + pChanEntry->TdmConfig.usSoutTimeslot = (UINT16)( pTdmConfig->ulSoutTimeslot & 0xFFFF ); + pChanEntry->TdmConfig.usSoutStream = (UINT16)( pTdmConfig->ulSoutStream & 0xFFFF ); + + pChanEntry->TdmConfig.byRinNumTssts = (UINT8)( pTdmConfig->ulRinNumTssts & 0xFF ); + pChanEntry->TdmConfig.bySinNumTssts = (UINT8)( pTdmConfig->ulSinNumTssts & 0xFF ); + pChanEntry->TdmConfig.byRoutNumTssts = (UINT8)( pTdmConfig->ulRoutNumTssts & 0xFF ); + pChanEntry->TdmConfig.bySoutNumTssts = (UINT8)( pTdmConfig->ulSoutNumTssts & 0xFF ); + pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry = cOCT6100_INVALID_INDEX; + pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry = 0; + + /* Save the extended Tone detection information.*/ + pChanEntry->usExtToneChanIndex = f_pChanIndexConf->usExtToneChanIndex; + pChanEntry->usExtToneMixerIndex = f_pChanIndexConf->usExtToneMixerIndex; + pChanEntry->usExtToneTsiIndex = f_pChanIndexConf->usExtToneTsiIndex; + + if ( f_pChannelOpen->fEnableExtToneDetection == TRUE ) + { + tPOCT6100_API_CHANNEL pExtToneChanEntry; + + /* Set the mode of the original channel. He is the channel performing detection on the + SIN port. The extended channel will perform detection on the RIN port.*/ + pChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_SIN_PORT_MODE; + + /* Now, program the associated channel.*/ + + /* Obtain a pointer to the extended tone detection channel entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pExtToneChanEntry, f_pChanIndexConf->usExtToneChanIndex ); + + pExtToneChanEntry->fReserved = TRUE; + pExtToneChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_RIN_PORT_MODE; /* Detect on RIN port.*/ + pExtToneChanEntry->usExtToneChanIndex = f_pChanIndexConf->usEchoChanIndex; + + pExtToneChanEntry->aulToneConf[ 0 ] = 0; + pExtToneChanEntry->aulToneConf[ 1 ] = 0; + + } + else + { + /* No extended tone detection supported.*/ + pChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_DISABLED; + } + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Store hardware related information.*/ + pChanEntry->usRinRoutTsiMemIndex = f_pChanIndexConf->usRinRoutTsiMemIndex; + pChanEntry->usSinSoutTsiMemIndex = f_pChanIndexConf->usSinSoutTsiMemIndex; + pChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usExtraRinTsiMemIndex = cOCT6100_INVALID_INDEX; + + /* We are not being tapped for now. */ + pChanEntry->fBeingTapped = FALSE; + + pChanEntry->usTapChanIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usTapBridgeIndex = cOCT6100_INVALID_INDEX; + + /* The copy event has not yet been created. */ + pChanEntry->fCopyEventCreated = FALSE; + + pChanEntry->usRinRoutConversionMemIndex = f_pChanIndexConf->usRinRoutConversionMemIndex; + pChanEntry->usSinSoutConversionMemIndex = f_pChanIndexConf->usSinSoutConversionMemIndex; + + pChanEntry->usPhasingTsstIndex = f_pChanIndexConf->usPhasingTsstIndex; + + pChanEntry->fSinSoutCodecActive = f_pChanIndexConf->fSinSoutCodecActive; + pChanEntry->fRinRoutCodecActive = f_pChanIndexConf->fRinRoutCodecActive; + + + + pChanEntry->usEchoMemIndex = f_pChanIndexConf->usEchoMemIndex; + + pChanEntry->usRinTsstIndex = f_pChanIndexConf->usRinTsstIndex; + pChanEntry->usSinTsstIndex = f_pChanIndexConf->usSinTsstIndex; + pChanEntry->usRoutTsstIndex = f_pChanIndexConf->usRoutTsstIndex; + pChanEntry->usSoutTsstIndex = f_pChanIndexConf->usSoutTsstIndex; + + pChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usSoutCopyEventIndex = cOCT6100_INVALID_INDEX; + + /* Nothing muted for now. */ + pChanEntry->usMutedPorts = cOCT6100_CHANNEL_MUTE_PORT_NONE; + + /* Set all the GW feature initial value.*/ + /* Bridge info */ + pChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + pChanEntry->fMute = FALSE; + + pChanEntry->usLoadEventIndex = cOCT6100_INVALID_INDEX; + pChanEntry->usSubStoreEventIndex = cOCT6100_INVALID_INDEX; + + /* Buffer playout info.*/ + pChanEntry->fRinBufPlaying = FALSE; + pChanEntry->fSoutBufPlaying = FALSE; + + /* Tone detection state. */ + /* This array is configured as follow.*/ + /* Index 0 contain event 0 to 31 (msb = event 31) and Index 1 contain index 32 - 55 */ + pChanEntry->aulToneConf[ 0 ] = 0; + pChanEntry->aulToneConf[ 1 ] = 0; + pChanEntry->ulLastSSToneDetected = cOCT6100_INVALID_VALUE; + pChanEntry->ulLastSSToneTimestamp = cOCT6100_INVALID_VALUE; + + /* Initialize the bidirectional flag.*/ + pChanEntry->fBiDirChannel = FALSE; + + /*=======================================================================*/ + /* Init some of the stats.*/ + + pChanEntry->sMaxERL = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->sMaxERLE = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->usMaxEchoDelay = cOCT6100_INVALID_STAT_W; + pChanEntry->usNumEchoPathChangesOfst = 0; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the dependency of the phasing TSST if one is associated to the chanel.*/ + + if ( f_pChanIndexConf->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingEntry; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingEntry, f_pChanIndexConf->usPhasingTsstIndex ); + + pPhasingEntry->usDependencyCnt++; + } + /*=======================================================================*/ + + /*=======================================================================*/ + + /* Form handle returned to user. */ + *f_pChannelOpen->pulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | (pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_pChanIndexConf->usEchoChanIndex; + + /* Finally, mark the channel as open. */ + pChanEntry->fReserved = TRUE; + pChanEntry->usExtraSinTsiDependencyCnt = 0; + + /* Increment the number of channel open.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberChannels++; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelCloseSer + +Description: Closes a echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelClose Pointer to echo cancellation channel close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelCloseSer +UINT32 Oct6100ChannelCloseSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose ) +{ + UINT16 usChannelIndex; + + + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertChannelParams( f_pApiInstance, + f_pChannelClose, + + &usChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiInvalidateChannelStructs( f_pApiInstance, + + usChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiReleaseChannelResources( f_pApiInstance, usChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle.*/ + f_pChannelClose->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertChannelParams + +Description: Validate the handle given by the user and verify the state of + the channel about to be closed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelClose Pointer to echo cancellation channel close structure. +f_pulFpgaChanIndex Pointer to the FPGA channel index associated to this channel. +f_pusChanIndex Pointer to the index of the channel within the API instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertChannelParams +UINT32 Oct6100ApiAssertChannelParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CLOSE f_pChannelClose, + + IN OUT PUINT16 f_pusChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pChannelClose->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelClose->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelClose->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + if ( pChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_PART_OF_BIDIR_CHANNEL; + + /*=======================================================================*/ + + /* Check if the channel is bound to a bridge. */ + if ( pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_ACTIVE_DEPENDENCIES; + + + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateChannelStructs + +Description: Closes a echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulFpgaChanIndex Index of the channel within the SCN_PLC FPGA. +f_usChanIndex Index of the channel within the API instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateChannelStructs +UINT32 Oct6100ApiInvalidateChannelStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usChanIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL_TDM pTdmConfig; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_WRITE_SMEAR_PARAMS SmearParams; + UINT32 ulResult; + UINT16 usCurrentEntry; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /* Obtain local pointer to the TDM configuration of the channel */ + pTdmConfig = &pChanEntry->TdmConfig; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + SmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + SmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* If this channel is currently debugged, automatically close the debug channel. */ + if ( ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + && ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex == f_usChanIndex ) ) + { + tOCT6100_DEBUG_SELECT_CHANNEL SelectDebugChan; + + /* Ensure forward compatibility. */ + Oct6100DebugSelectChannelDef( &SelectDebugChan ); + + /* Set the hot channel to an invalid handle to disable recording. */ + SelectDebugChan.ulChannelHndl = cOCT6100_INVALID_HANDLE; + + /* Call the serialized fonction. */ + ulResult = Oct6100DebugSelectChannelSer( f_pApiInstance, &SelectDebugChan, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Deactivate the TSST control memory if used. */ + + /* RIN port.*/ + if ( pTdmConfig->usRinTimeslot != cOCT6100_UNASSIGNED ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pChanEntry->usRinTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* SIN port.*/ + if ( pTdmConfig->usSinTimeslot != cOCT6100_UNASSIGNED ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pChanEntry->usSinTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*=======================================================================*/ + /* ROUT port.*/ + + if ( pTdmConfig->usRoutTimeslot != cOCT6100_UNASSIGNED ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pChanEntry->usRoutTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Now the broadcast TSST.*/ + usCurrentEntry = pTdmConfig->usRoutBrdcastTsstFirstEntry; + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pTsstEntry, usCurrentEntry ); + + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pTsstEntry->usTsstMemoryIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move to the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + } + /*=======================================================================*/ + + /*=======================================================================*/ + /* SOUT port.*/ + + if ( pTdmConfig->usSoutTimeslot != cOCT6100_UNASSIGNED ) + { + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( pChanEntry->usSoutTsstIndex * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Now the broadcast TSST.*/ + usCurrentEntry = pTdmConfig->usSoutBrdcastTsstFirstEntry; + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pTsstEntry, usCurrentEntry ); + + /* Deactivate the TSST entry.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pTsstEntry->usTsstMemoryIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move to the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + } + /*=======================================================================*/ + + + /*------------------------------------------------------------------------------*/ + /* Deactivate the ECHO control memory entry.*/ + + /* Set the input Echo control entry to unused.*/ + WriteParams.ulWriteAddress = cOCT6100_ECHO_CONTROL_MEM_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_ECHO_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x85FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0xC5FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Deactivate the conversion control memories if used. */ + + if ( pChanEntry->usRinRoutConversionMemIndex != cOCT6100_INVALID_INDEX ) + { + /* Rin/Rout stream conversion memory was used */ + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, pChanEntry->usRinRoutConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pChanEntry->usSinSoutConversionMemIndex != cOCT6100_INVALID_INDEX ) + { + /* Sin/Sout stream conversion memory was used */ + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, pChanEntry->usSinSoutConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*------------------------------------------------------------------------------*/ + + + /*------------------------------------------------------------------------------*/ + /* Clear the silence copy events if they were created. */ + + /* Unmute the Rin port if it was muted. */ + if ( pChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_DF; + + pChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + /* Unmute the Sin port if it was muted. */ + if ( pChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usSinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usSinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E0; + + pChanEntry->usSinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + /*------------------------------------------------------------------------------*/ + + /* Synch all the buffer playout field.*/ + if ( pSharedInfo->ImageInfo.fBufferPlayout == TRUE ) + { + Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); + + BufferPlayoutStop.ulChannelHndl = cOCT6100_INVALID_HANDLE; + BufferPlayoutStop.fStopCleanly = FALSE; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + pChanEntry->usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_SOUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + pChanEntry->usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + + + + + /* Free all resources reserved for extended tone detection.*/ + if ( pChanEntry->fEnableExtToneDetection == TRUE ) + { + /*------------------------------------------------------------------------------*/ + /* Deactivate the ECHO control memory entry of the extended channel.*/ + + /* Set the input Echo control entry to unused.*/ + WriteParams.ulWriteAddress = cOCT6100_ECHO_CONTROL_MEM_BASE + ( pChanEntry->usExtToneChanIndex * cOCT6100_ECHO_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x85FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0xC5FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Remove the mixer event used to copy the RIN signal to the SIN port of the extended + channel.*/ + + /* Clear the Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usExtToneMixerIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usExtToneMixerIndex, + cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + } + + /*------------------------------------------------------------------------------*/ + /* Reset PGSP */ + + WriteParams.ulWriteAddress = cOCT6100_CHANNEL_ROOT_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + WriteParams.usWriteData = 0x0800; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Clear the mute with feature bit. */ + + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + { + ulResult = Oct6100ApiMuteSinWithFeatures( f_pApiInstance, f_usChanIndex, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*------------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------------*/ + /* Clear the VQE memory. */ + + SmearParams.ulWriteAddress = cOCT6100_CHANNEL_ROOT_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst + 0x20; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteLength = 2; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + /*------------------------------------------------------------------------------*/ + /* Clear the NLP memory. */ + + SmearParams.ulWriteAddress = cOCT6100_CHANNEL_ROOT_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst + 0x28; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteLength = 2; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + /* Clear the AF information memory. */ + + SmearParams.ulWriteAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( pChanEntry->usEchoMemIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + SmearParams.usWriteData = 0x0000; + SmearParams.ulWriteLength = 12; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*Reset ALC status*/ + WriteParams.ulWriteAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( pChanEntry->usEchoMemIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst + 0x3A; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*------------------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseChannelResources + +Description: Release and clear the API entry associated to the echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usChannelIndex Index of the echo cancellation channel in the API list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseChannelResources +UINT32 Oct6100ApiReleaseChannelResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChannelIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL_TDM pTdmConfig; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + UINT32 ulResult; + UINT16 usCurrentEntry; + UINT32 ulTimeslot; + UINT32 ulStream; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChannelIndex ); + + /* Obtain local pointer to the TDM configurationof the channel */ + pTdmConfig = &pChanEntry->TdmConfig; + + /* Release the two TSI chariot memory entries.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_2; + + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_3; + + /* Now release the ECHO channel and control memory entries.*/ + ulResult = Oct6100ApiReleaseEchoEntry( f_pApiInstance, f_usChannelIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_4; + + /* Release the conversion resources.*/ + if ( pChanEntry->usRinRoutConversionMemIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, pChanEntry->usRinRoutConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_B9; + + pChanEntry->usRinRoutConversionMemIndex = cOCT6100_INVALID_INDEX; + } + + if ( pChanEntry->usSinSoutConversionMemIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, pChanEntry->usSinSoutConversionMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_BA; + + pChanEntry->usSinSoutConversionMemIndex = cOCT6100_INVALID_INDEX; + } + + /*=========================================================================*/ + /* Release the TSST control memory entries if any were reserved.*/ + if ( pTdmConfig->usRinTimeslot != cOCT6100_UNASSIGNED) + { + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->usRinTimeslot, + pTdmConfig->usRinStream, + pTdmConfig->byRinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_5; + } + + if ( pTdmConfig->usSinTimeslot != cOCT6100_UNASSIGNED) + { + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->usSinTimeslot, + pTdmConfig->usSinStream, + pTdmConfig->bySinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_6; + } + + /*=======================================================================*/ + /* Release all the TSSTs associated to the ROUT port of this channel. */ + if ( pTdmConfig->usRoutTimeslot != cOCT6100_UNASSIGNED) + { + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->usRoutTimeslot, + pTdmConfig->usRoutStream, + pTdmConfig->byRoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_7; + } + + /* Now release the Broadcast TSSTs. */ + usCurrentEntry = pTdmConfig->usRoutBrdcastTsstFirstEntry; + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pTsstEntry, usCurrentEntry ); + + ulTimeslot = pTsstEntry->usTsstValue >> 5; + ulStream = pTsstEntry->usTsstValue & 0x1F; + + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + ulTimeslot, + ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + usCurrentEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_8; + + /* Move to the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + + /* Invalidate the current entry.*/ + pTsstEntry->usTsstMemoryIndex = 0xFFFF; + pTsstEntry->usTsstValue = 0xFFFF; + pTsstEntry->usNextEntry = cOCT6100_INVALID_INDEX; + } + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Release all the TSSTs associated to the SOUT port of this channel. */ + if ( pTdmConfig->usSoutTimeslot != cOCT6100_UNASSIGNED) + { + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pTdmConfig->usSoutTimeslot, + pTdmConfig->usSoutStream, + pTdmConfig->bySoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_9; + } + + /* Now release the Broadcast TSSTs. */ + usCurrentEntry = pTdmConfig->usSoutBrdcastTsstFirstEntry; + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( pSharedInfo, pTsstEntry, usCurrentEntry ); + + ulTimeslot = pTsstEntry->usTsstValue >> 5; + ulStream = pTsstEntry->usTsstValue & 0x1F; + + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + ulTimeslot, + ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + usCurrentEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A; + + /* Move to the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + + /* Invalidate the current entry.*/ + pTsstEntry->usTsstMemoryIndex = 0xFFFF; + pTsstEntry->usTsstValue = 0xFFFF; + pTsstEntry->usNextEntry = cOCT6100_INVALID_INDEX; + } + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the dependency of the phasing TSST if one is associated to the chanel.*/ + + if ( pChanEntry->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingEntry; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingEntry, pChanEntry->usPhasingTsstIndex ); + + pPhasingEntry->usDependencyCnt--; + } + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Release any resources reserved for the extended tone detection.*/ + + if ( pChanEntry->fEnableExtToneDetection == TRUE ) + { + tPOCT6100_API_CHANNEL pExtToneChanEntry; + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pExtToneChanEntry, pChanEntry->usExtToneChanIndex ); + + /* Release the ECHO channel and control memory entries.*/ + ulResult = Oct6100ApiReleaseEchoEntry( f_pApiInstance, pChanEntry->usExtToneChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_C1; + + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pChanEntry->usExtToneTsiIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_C2; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usExtToneMixerIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_C3; + + /* Now release the channel entry */ + pExtToneChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_DISABLED; + pExtToneChanEntry->fReserved = FALSE; + + /* Set the current entry to disable, just in case.*/ + pChanEntry->ulExtToneChanMode = cOCT6100_API_EXT_TONE_DISABLED; + } + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Update the channel's list entry. */ + + /* Clear the NLP dword array. */ + Oct6100UserMemSet( pChanEntry->aulNlpConfDword, 0, sizeof( pChanEntry->aulNlpConfDword ) ); + + /* Clear the echo operation mode. */ + pChanEntry->byEchoOperationMode = cOCT6100_ECHO_OP_MODE_POWER_DOWN; + + /* Mark the channel as closed. */ + pChanEntry->fReserved = FALSE; + pChanEntry->byEntryOpenCnt++; + + /* Reset the port, the bridge and BidirInfo */ + pChanEntry->usMutedPorts = cOCT6100_CHANNEL_MUTE_PORT_NONE; + pChanEntry->fBiDirChannel = FALSE; + pChanEntry->usBridgeIndex = cOCT6100_INVALID_INDEX; + + /* Decrement the number of channel open.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberChannels--; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; + +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelModifySer + +Description: Modify an echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to channel configuration structure. The handle + identifying the buffer in all future function calls is + returned in this structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelModifySer +UINT32 Oct6100ChannelModifySer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify ) +{ + UINT16 usChanIndex; + UINT32 ulResult; + UINT16 usNewRinTsstIndex; + UINT16 usNewSinTsstIndex; + UINT16 usNewRoutTsstIndex; + UINT16 usNewSoutTsstIndex; + UINT8 fSinSoutCodecActive = FALSE; + UINT8 fRinRoutCodecActive = FALSE; + UINT16 usNewPhasingTsstIndex; + tOCT6100_CHANNEL_OPEN *pTempChanOpen; + + /* We don't want this 290 byte structure on the stack */ + pTempChanOpen = kmalloc(sizeof(*pTempChanOpen), GFP_ATOMIC); + if (!pTempChanOpen) + return cOCT6100_ERR_FATAL_0; + + /* Check the user's configuration of the echo cancellation channel for errors. */ + ulResult = Oct6100ApiCheckChannelModify( f_pApiInstance, + f_pChannelModify, + pTempChanOpen, + &usNewPhasingTsstIndex, + &usChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Reserve all resources needed by the echo cancellation channel. */ + ulResult = Oct6100ApiModifyChannelResources( f_pApiInstance, + f_pChannelModify, + usChanIndex, + &usNewRinTsstIndex, + &usNewSinTsstIndex, + &usNewRoutTsstIndex, + &usNewSoutTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Write all necessary structures to activate the echo cancellation channel. */ + ulResult = Oct6100ApiModifyChannelStructs( f_pApiInstance, + f_pChannelModify, + pTempChanOpen, + usChanIndex, + usNewPhasingTsstIndex, + &fSinSoutCodecActive, + &fRinRoutCodecActive, + usNewRinTsstIndex, + usNewSinTsstIndex, + usNewRoutTsstIndex, + usNewSoutTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + goto out; + + /* Update the new echo cancellation channels's entry in the ECHO channel list. */ + ulResult = Oct6100ApiModifyChannelEntry( f_pApiInstance, + f_pChannelModify, + pTempChanOpen, + usChanIndex, + usNewPhasingTsstIndex, + fSinSoutCodecActive, + fRinRoutCodecActive, + usNewRinTsstIndex, + usNewSinTsstIndex, + usNewRoutTsstIndex, + usNewSoutTsstIndex ); +out: + kfree(pTempChanOpen); + + return ulResult; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChannelModify + +Description: Checks the user's echo cancellation channel modify structure for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to echo cancellation channel modify structure. +f_pTempChanOpen Pointer to a channel open structure. +f_pusNewPhasingTsstIndex Pointer to a new phasing TSST index within the API instance. +f_pusChanIndex Pointer to the channel index within the API instance channel list + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChannelModify +UINT32 Oct6100ApiCheckChannelModify( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pTempChanOpen, + OUT PUINT16 f_pusNewPhasingTsstIndex, + OUT PUINT16 f_pusChanIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + UINT32 ulEntryOpenCnt; + UINT32 ulDecoderNumTssts; + + /* Check the provided handle. */ + if ( (f_pChannelModify->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelModify->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelModify->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Check the general modify parameters. */ + + if ( f_pChannelModify->ulEchoOperationMode != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NORMAL && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_FREEZE && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_RESET && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_POWER_DOWN && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_EXTERNAL && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION && + f_pChannelModify->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE; + + /* Check the 2100Hz echo disabling configuration.*/ + if ( f_pChannelModify->fEnableToneDisabler != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->fEnableToneDisabler != TRUE && + f_pChannelModify->fEnableToneDisabler != FALSE ) + return cOCT6100_ERR_CHANNEL_TONE_DISABLER_ENABLE; + + /* Check the disable tone detection flag. */ + if ( f_pChannelModify->fDisableToneDetection != TRUE && + f_pChannelModify->fDisableToneDetection != FALSE ) + return cOCT6100_ERR_CHANNEL_DISABLE_TONE_DETECTION; + + /* Check the stop buffer playout flag. */ + if ( f_pChannelModify->fStopBufferPlayout != TRUE && + f_pChannelModify->fStopBufferPlayout != FALSE ) + return cOCT6100_ERR_CHANNEL_STOP_BUFFER_PLAYOUT; + + /* Check the remove conference bridge participant flag. */ + if ( f_pChannelModify->fRemoveConfBridgeParticipant != TRUE && + f_pChannelModify->fRemoveConfBridgeParticipant != FALSE ) + return cOCT6100_ERR_CHANNEL_REMOVE_CONF_BRIDGE_PARTICIPANT; + + /* Check the remove broadcast timeslots flag. */ + if ( f_pChannelModify->fRemoveBroadcastTssts != TRUE && + f_pChannelModify->fRemoveBroadcastTssts != FALSE ) + return cOCT6100_ERR_CHANNEL_REMOVE_BROADCAST_TSSTS; + + if ( f_pChannelModify->fCodecConfigModified != TRUE && + f_pChannelModify->fCodecConfigModified != FALSE ) + return cOCT6100_ERR_CHANNEL_MODIFY_CODEC_CONFIG; + + if ( f_pChannelModify->fVqeConfigModified != TRUE && + f_pChannelModify->fVqeConfigModified != FALSE ) + return cOCT6100_ERR_CHANNEL_MODIFY_VQE_CONFIG; + + if ( f_pChannelModify->fTdmConfigModified != TRUE && + f_pChannelModify->fTdmConfigModified != FALSE ) + return cOCT6100_ERR_CHANNEL_MODIFY_TDM_CONFIG; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Verify if any law change was requested. If so reprogram all structures.*/ + + if (( f_pChannelModify->fTdmConfigModified == TRUE ) && + ( f_pChannelModify->TdmConfig.ulRinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulSinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulRoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulSoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING )) + { + f_pChannelModify->fVqeConfigModified = TRUE; + f_pChannelModify->fCodecConfigModified = TRUE; + } + /*=======================================================================*/ + + ulResult = Oct6100ApiUpdateOpenStruct( f_pApiInstance, f_pChannelModify, f_pTempChanOpen, pChanEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* All further check will now be performed using the TempOpenChan structure in order + to reuse the checks written for the open channel structure.*/ + + + + /* Check the TDM config.*/ + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + tPOCT6100_CHANNEL_MODIFY_TDM pModifyTdm; + tPOCT6100_CHANNEL_OPEN_TDM pOpenTdm; + + pModifyTdm = &f_pChannelModify->TdmConfig; + pOpenTdm = &f_pTempChanOpen->TdmConfig; + + ulResult = Oct6100ApiCheckTdmConfig( f_pApiInstance, + pOpenTdm ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if that Stream and Timeslot values are valid.*/ + + /* Check the RIN port.*/ + if ( f_pChannelModify->TdmConfig.ulRinStream == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT; + + if ( f_pChannelModify->TdmConfig.ulRinStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_RIN_STREAM; + + if ( pChanEntry->fBeingTapped == TRUE ) + { + /* Check that the Rin stream + timeslot are not being assigned. */ + if ( f_pChannelModify->TdmConfig.ulRinStream != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_pChannelModify->TdmConfig.ulRinStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_STREAM; + + if ( f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT; + } + } + + /* Check the SIN port.*/ + if ( f_pChannelModify->TdmConfig.ulSinStream == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_SIN_TIMESLOT; + + if ( f_pChannelModify->TdmConfig.ulSinStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_SIN_STREAM; + + /* Check the ROUT port.*/ + if ( f_pChannelModify->TdmConfig.ulRoutStream == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT; + + if ( f_pChannelModify->TdmConfig.ulRoutStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_ROUT_STREAM; + + /* Check the SOUT port.*/ + if ( f_pChannelModify->TdmConfig.ulSoutStream == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT; + + if ( f_pChannelModify->TdmConfig.ulSoutStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + return cOCT6100_ERR_CHANNEL_SOUT_STREAM; + + /* Verify if the channel is currently part of a bidirectional channel, and if */ + /* so perform the required checks. */ + if ( pChanEntry->fBiDirChannel == TRUE ) + { + /* Check the ports that must remain unassigned.*/ + if ( f_pTempChanOpen->TdmConfig.ulRinTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT; + if ( f_pTempChanOpen->TdmConfig.ulSoutTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT; + + /* Check that no PCM law change is requested.*/ + if ( f_pTempChanOpen->TdmConfig.ulRinPcmLaw != f_pTempChanOpen->TdmConfig.ulRoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_RIN_ROUT_LAW_CONVERSION; + if ( f_pTempChanOpen->TdmConfig.ulSinPcmLaw != f_pTempChanOpen->TdmConfig.ulSoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_SIN_SOUT_LAW_CONVERSION; + } + + /* If this channel is on a conference bridge, a few more things must be checked. */ + if ( pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + { + /* If conferencing, law conversion cannot be applied. */ + /* This check is done only if both input and output ports are assigned. */ + if ( ( f_pTempChanOpen->TdmConfig.ulRinTimeslot != cOCT6100_UNASSIGNED ) + && ( f_pTempChanOpen->TdmConfig.ulRoutTimeslot != cOCT6100_UNASSIGNED ) ) + { + /* Laws must be the same! */ + if ( f_pTempChanOpen->TdmConfig.ulRinPcmLaw != f_pTempChanOpen->TdmConfig.ulRoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_RIN_ROUT_LAW_CONVERSION; + } + + /* Check for Sin. */ + if ( ( f_pTempChanOpen->TdmConfig.ulSinTimeslot != cOCT6100_UNASSIGNED ) + && ( f_pTempChanOpen->TdmConfig.ulSoutTimeslot != cOCT6100_UNASSIGNED ) ) + { + /* Laws must be the same! */ + if ( f_pTempChanOpen->TdmConfig.ulSinPcmLaw != f_pTempChanOpen->TdmConfig.ulSoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_SIN_SOUT_LAW_CONVERSION; + } + + /* Check if ADPCM is requested. */ + if ( f_pTempChanOpen->CodecConfig.ulEncoderPort != cOCT6100_NO_ENCODING && + f_pTempChanOpen->CodecConfig.ulEncodingRate != cOCT6100_G711_64KBPS ) + { + /* No ADPCM in a conference bridge! */ + return cOCT6100_ERR_CHANNEL_ENCODING_RATE; + } + + if ( f_pTempChanOpen->CodecConfig.ulDecoderPort != cOCT6100_NO_DECODING && + f_pTempChanOpen->CodecConfig.ulDecodingRate != cOCT6100_G711_64KBPS ) + { + /* No ADPCM in a conference bridge! */ + return cOCT6100_ERR_CHANNEL_DECODING_RATE; + } + } + + if ( f_pTempChanOpen->CodecConfig.ulEncoderPort == cOCT6100_NO_ENCODING || + f_pTempChanOpen->CodecConfig.ulDecoderPort == cOCT6100_NO_DECODING ) + { + /* Make sure no law conversion is attempted since it is not supported by the device.*/ + if ( f_pTempChanOpen->TdmConfig.ulRinPcmLaw != f_pTempChanOpen->TdmConfig.ulRoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_RIN_ROUT_LAW_CONVERSION; + if ( f_pTempChanOpen->TdmConfig.ulSinPcmLaw != f_pTempChanOpen->TdmConfig.ulSoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_SIN_SOUT_LAW_CONVERSION; + } + + if ( pChanEntry->fEnableExtToneDetection == TRUE && + f_pTempChanOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + return cOCT6100_ERR_CHANNEL_EXT_TONE_DETECTION_DECODER_PORT; + + /* A few special checks must be done if the configuration is to be applied */ + /* to all opened channels. */ + if ( f_pChannelModify->fApplyToAllChannels == TRUE ) + { + /* When the configuration to be applied is for all channels, */ + /* check that the stream and timeslot parameters are not being assigned. */ + + /* Check the Rout port. */ + if ( f_pChannelModify->TdmConfig.ulRoutStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Check that the Rout ports is being unassigned. */ + if ( f_pTempChanOpen->TdmConfig.ulRoutStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_ROUT_STREAM_UNASSIGN; + if ( f_pTempChanOpen->TdmConfig.ulRoutTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT_UNASSIGN; + } + + /* Check the Rin port. */ + if ( f_pChannelModify->TdmConfig.ulRinStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Check that the Rin ports is being unassigned. */ + if ( f_pTempChanOpen->TdmConfig.ulRinStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_STREAM_UNASSIGN; + if ( f_pTempChanOpen->TdmConfig.ulRinTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT_UNASSIGN; + } + + /* Check the Sout port. */ + if ( f_pChannelModify->TdmConfig.ulSoutStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Check that the Sout ports is being unassigned. */ + if ( f_pTempChanOpen->TdmConfig.ulSoutStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SOUT_STREAM_UNASSIGN; + if ( f_pTempChanOpen->TdmConfig.ulSoutTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT_UNASSIGN; + } + + /* Check the Sin port. */ + if ( f_pChannelModify->TdmConfig.ulSinStream != cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Check that the Sin ports is being unassigned. */ + if ( f_pTempChanOpen->TdmConfig.ulSinStream != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SIN_STREAM_UNASSIGN; + if ( f_pTempChanOpen->TdmConfig.ulSinTimeslot != cOCT6100_UNASSIGNED ) + return cOCT6100_ERR_CHANNEL_SIN_TIMESLOT_UNASSIGN; + } + } + } + + /* Check the VQE config.*/ + if ( f_pChannelModify->fVqeConfigModified == TRUE ) + { + ulResult = Oct6100ApiCheckVqeConfig( f_pApiInstance, + &f_pTempChanOpen->VqeConfig, + f_pTempChanOpen->fEnableToneDisabler ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Verify if the echo operation mode selected can be applied. */ + if ( ( f_pTempChanOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + && ( f_pTempChanOpen->VqeConfig.fEnableNlp == FALSE ) ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED; + + if ( ( f_pTempChanOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + && ( f_pTempChanOpen->VqeConfig.fEnableNlp == FALSE ) ) + return cOCT6100_ERR_CHANNEL_ECHO_OP_MODE_NLP_REQUIRED; + + /* Comfort noise must be activated for speech recognition mode to work. */ + if ( ( f_pTempChanOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + && ( f_pTempChanOpen->VqeConfig.ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_OFF ) ) + return cOCT6100_ERR_CHANNEL_COMFORT_NOISE_REQUIRED; + + /* Check the Codec config.*/ + if ( f_pChannelModify->fCodecConfigModified == TRUE ) + { + if ( f_pTempChanOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + ulDecoderNumTssts = f_pTempChanOpen->TdmConfig.ulRinNumTssts; + else /* f_pTempChanOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + ulDecoderNumTssts = f_pTempChanOpen->TdmConfig.ulSinNumTssts; + + ulResult = Oct6100ApiCheckCodecConfig( f_pApiInstance, + &f_pTempChanOpen->CodecConfig, + ulDecoderNumTssts, + f_pusNewPhasingTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + /* make sure that if silence suppression is activated, the NLP is enabled.*/ + if ( f_pTempChanOpen->CodecConfig.fEnableSilenceSuppression == TRUE && f_pTempChanOpen->VqeConfig.fEnableNlp == FALSE ) + return cOCT6100_ERR_CHANNEL_SIL_SUP_NLP_MUST_BE_ENABLED; + + /* Verify if the channel is currently part of a bidirectional channel, and if so perform + the required checks.*/ + if ( pChanEntry->fBiDirChannel == TRUE ) + { + /* Check the ports that must remain unassigned.*/ + if ( f_pTempChanOpen->CodecConfig.ulEncoderPort != cOCT6100_NO_ENCODING && + f_pTempChanOpen->CodecConfig.ulEncodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_CHANNEL_ENCODING_RATE; + + if ( f_pTempChanOpen->CodecConfig.ulDecoderPort != cOCT6100_NO_DECODING && + f_pTempChanOpen->CodecConfig.ulDecodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_CHANNEL_DECODING_RATE; + } + + } + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiModifyChannelResources + +Description: Reserves any new resources needed for the channel +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to echo cancellation channel configuration structure. +f_usChanIndex Allocated entry in ECHO channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiModifyChannelResources +UINT32 Oct6100ApiModifyChannelResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN UINT16 f_usChanIndex, + OUT PUINT16 f_pusNewRinTsstIndex, + OUT PUINT16 f_pusNewSinTsstIndex, + OUT PUINT16 f_pusNewRoutTsstIndex, + OUT PUINT16 f_pusNewSoutTsstIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + + tPOCT6100_API_CHANNEL_TDM pApiTdmConf; + tPOCT6100_CHANNEL_MODIFY_TDM pModifyTdmConf; + + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar = cOCT6100_ERR_OK; + UINT32 ulFreeMixerEventCnt; + + BOOL fRinReleased = FALSE; + BOOL fSinReleased = FALSE; + BOOL fRoutReleased = FALSE; + BOOL fSoutReleased = FALSE; + + BOOL fRinReserved = FALSE; + BOOL fSinReserved = FALSE; + BOOL fRoutReserved = FALSE; + BOOL fSoutReserved = FALSE; + + BOOL fReserveRin = FALSE; + BOOL fReserveSin = FALSE; + BOOL fReserveRout = FALSE; + BOOL fReserveSout = FALSE; + + BOOL fRinRoutConversionMemReserved = FALSE; + BOOL fSinSoutConversionMemReserved = FALSE; + + + UINT32 ulRinNumTssts = 1; + UINT32 ulSinNumTssts = 1; + UINT32 ulRoutNumTssts = 1; + UINT32 ulSoutNumTssts = 1; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to the TDM configuration structure of the tPOCT6100_CHANNEL_MODIFY structure. */ + pModifyTdmConf = &f_pChannelModify->TdmConfig; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Obtain local pointer to the TDM configuration structure of the tPOCT6100_API_CHANNEL structure. */ + pApiTdmConf = &pChanEntry->TdmConfig; + + /*===============================================================================*/ + /* Modify TSST resources if required.*/ + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + /* First release any entry that need to be released.*/ + if ( ( pModifyTdmConf->ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( pModifyTdmConf->ulRinNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Release the previously reserved entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pChanEntry->TdmConfig.usRinTimeslot, + pChanEntry->TdmConfig.usRinStream, + pChanEntry->TdmConfig.byRinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinReleased = TRUE; + } + } + + fReserveRin = TRUE; + } + + /* Release SIN port.*/ + if ( ( ulResult == cOCT6100_ERR_OK ) + && ( ( pModifyTdmConf->ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( pModifyTdmConf->ulSinNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) ) + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Release the previously reserved entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pChanEntry->TdmConfig.usSinTimeslot, + pChanEntry->TdmConfig.usSinStream, + pChanEntry->TdmConfig.bySinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinReleased = TRUE; + } + } + + fReserveSin = TRUE; + } + + /* Release ROUT port.*/ + if ( ( ulResult == cOCT6100_ERR_OK ) + && ( ( pModifyTdmConf->ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( pModifyTdmConf->ulRoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) ) + { + if ( pChanEntry->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Release the previously reserved entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pChanEntry->TdmConfig.usRoutTimeslot, + pChanEntry->TdmConfig.usRoutStream, + pChanEntry->TdmConfig.byRoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRoutReleased = TRUE; + } + } + + fReserveRout = TRUE; + } + + /* Release the SOUT port.*/ + if ( ( ulResult == cOCT6100_ERR_OK ) + && ( ( pModifyTdmConf->ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( pModifyTdmConf->ulSoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) ) + { + if ( pChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Release the previously reserved entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + pChanEntry->TdmConfig.usSoutTimeslot, + pChanEntry->TdmConfig.usSoutStream, + pChanEntry->TdmConfig.bySoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSoutReleased = TRUE; + } + } + + fReserveSout = TRUE; + } + + /* Now reserve any new entry required.*/ + + /* Modify RIN port.*/ + if ( ( fReserveRin == TRUE ) && ( ulResult == cOCT6100_ERR_OK ) ) + { + if ( pModifyTdmConf->ulRinTimeslot != cOCT6100_UNASSIGNED ) + { + /* Check what number of TSSTs should be reserved this time. */ + if ( pModifyTdmConf->ulRinNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulRinNumTssts = pApiTdmConf->byRinNumTssts; + } + else /* if ( pModifyTdmConf->ulRinNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* New number of TSSTs. */ + ulRinNumTssts = pModifyTdmConf->ulRinNumTssts; + } + + if ( pModifyTdmConf->ulRinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Reserve the new number of TSSTs. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pApiTdmConf->usRinTimeslot, + pApiTdmConf->usRinStream, + ulRinNumTssts, + cOCT6100_INPUT_TSST, + f_pusNewRinTsstIndex, + NULL ); + } + else /* if ( pModifyTdmConf->ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* Reserve the new TSST.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pModifyTdmConf->ulRinTimeslot, + pModifyTdmConf->ulRinStream, + ulRinNumTssts, + cOCT6100_INPUT_TSST, + f_pusNewRinTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinReserved = TRUE; + } + } + } + else + { + *f_pusNewRinTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusNewRinTsstIndex = cOCT6100_INVALID_INDEX; + } + + /* Modify SIN port.*/ + if ( ( fReserveSin == TRUE ) && ( ulResult == cOCT6100_ERR_OK ) ) + { + if ( pModifyTdmConf->ulSinTimeslot != cOCT6100_UNASSIGNED ) + { + /* Check what number of TSSTs should be reserved this time. */ + if ( pModifyTdmConf->ulSinNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulSinNumTssts = pApiTdmConf->bySinNumTssts; + } + else /* if ( pModifyTdmConf->ulSinNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* New number of TSSTs. */ + ulSinNumTssts = pModifyTdmConf->ulSinNumTssts; + } + + if ( pModifyTdmConf->ulSinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Reserve the new number of TSSTs. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pApiTdmConf->usSinTimeslot, + pApiTdmConf->usSinStream, + ulSinNumTssts, + cOCT6100_INPUT_TSST, + f_pusNewSinTsstIndex, + NULL ); + } + else /* if ( pModifyTdmConf->ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* Reserve the new TSST.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pModifyTdmConf->ulSinTimeslot, + pModifyTdmConf->ulSinStream, + ulSinNumTssts, + cOCT6100_INPUT_TSST, + f_pusNewSinTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinReserved = TRUE; + } + } + } + else + { + *f_pusNewSinTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusNewSinTsstIndex = cOCT6100_INVALID_INDEX; + } + + /* Modify ROUT port.*/ + if ( ( fReserveRout == TRUE ) && ( ulResult == cOCT6100_ERR_OK ) ) + { + if ( pModifyTdmConf->ulRoutTimeslot != cOCT6100_UNASSIGNED ) + { + /* Check what number of TSSTs should be reserved this time. */ + if ( pModifyTdmConf->ulRoutNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulRoutNumTssts = pApiTdmConf->byRoutNumTssts; + } + else /* if ( pModifyTdmConf->ulRoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* New number of TSSTs. */ + ulRoutNumTssts = pModifyTdmConf->ulRoutNumTssts; + } + + if ( pModifyTdmConf->ulRoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Reserve the new number of TSSTs. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pApiTdmConf->usRoutTimeslot, + pApiTdmConf->usRoutStream, + ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewRoutTsstIndex, + NULL ); + } + else /* if ( pModifyTdmConf->ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* Reserve the new TSST.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pModifyTdmConf->ulRoutTimeslot, + pModifyTdmConf->ulRoutStream, + ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewRoutTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRoutReserved = TRUE; + } + } + } + else + { + *f_pusNewRoutTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusNewRoutTsstIndex = cOCT6100_INVALID_INDEX; + } + + /* Modify SOUT port.*/ + if ( ( fReserveSout == TRUE ) && ( ulResult == cOCT6100_ERR_OK ) ) + { + if ( pModifyTdmConf->ulSoutTimeslot != cOCT6100_UNASSIGNED ) + { + /* Check what number of TSSTs should be reserved this time. */ + if ( pModifyTdmConf->ulSoutNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulSoutNumTssts = pApiTdmConf->bySoutNumTssts; + } + else /* if ( pModifyTdmConf->ulSoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* New number of TSSTs. */ + ulSoutNumTssts = pModifyTdmConf->ulSoutNumTssts; + } + + if ( pModifyTdmConf->ulSoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* Reserve the new number of TSSTs. */ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pApiTdmConf->usSoutTimeslot, + pApiTdmConf->usSoutStream, + ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewSoutTsstIndex, + NULL ); + } + else /* if ( pModifyTdmConf->ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) */ + { + /* Reserve the new TSST.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + pModifyTdmConf->ulSoutTimeslot, + pModifyTdmConf->ulSoutStream, + ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewSoutTsstIndex, + NULL ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSoutReserved = TRUE; + } + } + } + else + { + *f_pusNewSoutTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusNewSoutTsstIndex = cOCT6100_INVALID_INDEX; + } + + + } + + if ( f_pChannelModify->fCodecConfigModified == TRUE ) + { + if ( ulResult == cOCT6100_ERR_OK && + pChanEntry->usRinRoutConversionMemIndex == cOCT6100_INVALID_INDEX && + ( f_pChannelModify->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT || + f_pChannelModify->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) ) + { + /* Reserve an ADPCM memory block.*/ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, &pChanEntry->usRinRoutConversionMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fRinRoutConversionMemReserved = TRUE; + } + } + + if ( ulResult == cOCT6100_ERR_OK && + pChanEntry->usSinSoutConversionMemIndex == cOCT6100_INVALID_INDEX && + ( f_pChannelModify->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT || + f_pChannelModify->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN ) ) + { + /* Reserve an ADPCM memory block.*/ + ulResult = Oct6100ApiReserveConversionMemEntry( f_pApiInstance, &pChanEntry->usSinSoutConversionMemIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fSinSoutConversionMemReserved = TRUE; + } + } + } + + + /*===============================================================================*/ + /* Check if there are a couple of mixer events available for us. */ + + if ( ulResult == cOCT6100_ERR_OK ) + { + UINT32 ulMixerEventCntNeeded = 0; + + /* Calculate how many mixer events are needed. */ + if ( pChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) + { + /* If the channel is in bidir mode, do not create the Rin silence event!!! */ + if ( pChanEntry->fBiDirChannel == FALSE ) + { + if ( ( *f_pusNewRinTsstIndex == cOCT6100_INVALID_INDEX ) + && ( pChanEntry->usRinSilenceEventIndex == cOCT6100_INVALID_INDEX ) ) + ulMixerEventCntNeeded++; + } + } + + if ( ( *f_pusNewSinTsstIndex == cOCT6100_INVALID_INDEX ) + && ( pChanEntry->usSinSilenceEventIndex == cOCT6100_INVALID_INDEX ) ) + { + ulMixerEventCntNeeded++; + } + + /* If at least 1 mixer event is needed, check if those are available. */ + if ( ulMixerEventCntNeeded != 0 ) + { + ulResult = Oct6100ApiGetFreeMixerEventCnt( f_pApiInstance, &ulFreeMixerEventCnt ); + if ( ulResult == cOCT6100_ERR_OK ) + { + /* The API might need more mixer events if the ports have to be muted. */ + /* Check if these are available. */ + if ( ulFreeMixerEventCnt < ulMixerEventCntNeeded ) + { + ulResult = cOCT6100_ERR_CHANNEL_OUT_OF_MIXER_EVENTS; + } + } + } + } + + /*===============================================================================*/ + + /* Verify if an error occured. */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /* Release any resources newly reserved.*/ + if ( fRinReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pModifyTdmConf->ulRinTimeslot, + pModifyTdmConf->ulRinStream, + ulRinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the SIN port.*/ + if ( fSinReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pModifyTdmConf->ulSinTimeslot, + pModifyTdmConf->ulSinStream, + ulSinNumTssts, + cOCT6100_INPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the ROUT port.*/ + if ( fRoutReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pModifyTdmConf->ulRoutTimeslot, + pModifyTdmConf->ulRoutStream, + ulRoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the SOUT port.*/ + if ( fSoutReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsst( f_pApiInstance, + pModifyTdmConf->ulSoutTimeslot, + pModifyTdmConf->ulSoutStream, + ulSoutNumTssts, + cOCT6100_OUTPUT_TSST, + cOCT6100_INVALID_INDEX ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* Now make sure any resources released gets reserved back again.*/ + + /* For the RIN port.*/ + if ( fRinReleased == TRUE ) + { + /* Reserve the new TSST.*/ + ulTempVar = Oct6100ApiReserveTsst( f_pApiInstance, + pChanEntry->TdmConfig.usRinTimeslot, + pChanEntry->TdmConfig.usRinStream, + pChanEntry->TdmConfig.byRinNumTssts, + cOCT6100_INPUT_TSST, + &pChanEntry->usRinTsstIndex, + NULL ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the SIN port.*/ + if ( fSinReleased == TRUE ) + { + /* Reserve the new TSST.*/ + ulTempVar = Oct6100ApiReserveTsst( f_pApiInstance, + pChanEntry->TdmConfig.usSinTimeslot, + pChanEntry->TdmConfig.usSinStream, + pChanEntry->TdmConfig.bySinNumTssts, + cOCT6100_INPUT_TSST, + &pChanEntry->usSinTsstIndex, + NULL ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the ROUT port.*/ + if ( fRoutReleased == TRUE ) + { + /* Reserve the new TSST.*/ + ulTempVar = Oct6100ApiReserveTsst( f_pApiInstance, + pChanEntry->TdmConfig.usRoutTimeslot, + pChanEntry->TdmConfig.usRoutStream, + pChanEntry->TdmConfig.byRoutNumTssts, + cOCT6100_OUTPUT_TSST, + &pChanEntry->usRoutTsstIndex, + NULL ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* For the SOUT port.*/ + if ( fSoutReleased == TRUE ) + { + /* Reserve the new TSST.*/ + ulTempVar = Oct6100ApiReserveTsst( f_pApiInstance, + pChanEntry->TdmConfig.usSoutTimeslot, + pChanEntry->TdmConfig.usSoutStream, + pChanEntry->TdmConfig.bySoutNumTssts, + cOCT6100_OUTPUT_TSST, + &pChanEntry->usSoutTsstIndex, + NULL ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* Release the conversion memories if they were reserved.*/ + if ( fRinRoutConversionMemReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, + pChanEntry->usRinRoutConversionMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fSinSoutConversionMemReserved == TRUE ) + { + ulTempVar = Oct6100ApiReleaseConversionMemEntry( f_pApiInstance, + pChanEntry->usSinSoutConversionMemIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /* Now return the error.*/ + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiModifyChannelStructs + +Description: Performs all the required structure writes to configure the + echo cancellation channel based on the new modifications. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelModify Pointer to echo cancellation channel configuration structure. +f_pChannelOpen Pointer to a structure used to store the multiple resources indexes. +f_usChanIndex Index of the channel within the API's channel list. +f_usNewPhasingTsstIndex Index of the new phasing TSST. +f_pfSinSoutCodecActive Pointer to the state of the SIN/SOUT codec. +f_pfRinRoutCodecActive Pointer to the state of the RIN/ROUT codec. +f_usNewRinTsstIndex New RIN TSST memory index. +f_usNewSinTsstIndex New SIN TSST memory index. +f_usNewRoutTsstIndex New ROUT TSST memory index. +f_usNewSoutTsstIndex New SOUT TSST memory index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiModifyChannelStructs +UINT32 Oct6100ApiModifyChannelStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewPhasingTsstIndex, + OUT PUINT8 f_pfSinSoutCodecActive, + OUT PUINT8 f_pfRinRoutCodecActive, + IN UINT16 f_usNewRinTsstIndex, + IN UINT16 f_usNewSinTsstIndex, + IN UINT16 f_usNewRoutTsstIndex, + IN UINT16 f_usNewSoutTsstIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_WRITE_PARAMS WriteParams; + tPOCT6100_API_CHANNEL_CODEC pApiCodecConf; + tPOCT6100_API_CHANNEL_TDM pApiTdmConf; + tPOCT6100_API_CHANNEL_VQE pApiVqeConf; + + UINT32 ulResult; + UINT16 usReadData; + + UINT16 usSinTsstIndex; + UINT16 usRinTsstIndex; + + UINT32 ulToneConfIndex; + BOOL fClearPlayoutPointers = FALSE; + + BOOL fConversionEnabled = FALSE; + + + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Obtain local pointer to the configuration structures of the tPOCT6100_API_CHANNEL structure. */ + pApiCodecConf = &pChanEntry->CodecConfig; + pApiTdmConf = &pChanEntry->TdmConfig; + pApiVqeConf = &pChanEntry->VqeConfig; + + /*=======================================================================*/ + /* Init the RIN and SIN TSST index */ + + usRinTsstIndex = pChanEntry->usRinTsstIndex; + usSinTsstIndex = pChanEntry->usSinTsstIndex; + + + /*==============================================================================*/ + /* Clear the TSST that will be release.*/ + + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + /* Modify RIN port.*/ + if ( f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Clear the previous entry */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pChanEntry->usRinTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Modify SIN port.*/ + if ( f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Clear the previous entry */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pChanEntry->usSinTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Modify ROUT port.*/ + if ( f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Clear the previous entry */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pChanEntry->usRoutTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Modify SOUT port.*/ + if ( f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING) + { + if ( pChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + /* Clear the previous entry */ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (pChanEntry->usSoutTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Now, Configure the Tsst control memory.*/ + + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + /* Modify RIN port.*/ + if ( f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + usRinTsstIndex = f_usNewRinTsstIndex; + + if ( f_usNewRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + if ( pChanEntry->usExtraRinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usNewRinTsstIndex, + pChanEntry->usExtraRinTsiMemIndex, + f_pChannelOpen->TdmConfig.ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usNewRinTsstIndex, + pChanEntry->usRinRoutTsiMemIndex, + f_pChannelOpen->TdmConfig.ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + if ( f_pChannelModify->TdmConfig.ulRinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulRinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usExtraRinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usRinTsstIndex, + pChanEntry->usExtraRinTsiMemIndex, + f_pChannelOpen->TdmConfig.ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + if ( pChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usRinTsstIndex, + pChanEntry->usRinRoutTsiMemIndex, + f_pChannelOpen->TdmConfig.ulRinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Modify SIN port.*/ + if ( f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + usSinTsstIndex = f_usNewSinTsstIndex; + + if ( f_usNewSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + if ( pChanEntry->usExtraSinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usNewSinTsstIndex, + pChanEntry->usExtraSinTsiMemIndex, + f_pChannelOpen->TdmConfig.ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + f_usNewSinTsstIndex, + pChanEntry->usSinSoutTsiMemIndex, + f_pChannelOpen->TdmConfig.ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + if ( f_pChannelModify->TdmConfig.ulSinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING && + f_pChannelModify->TdmConfig.ulSinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( pChanEntry->usExtraSinTsiMemIndex != cOCT6100_INVALID_INDEX ) + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usSinTsstIndex , + pChanEntry->usExtraSinTsiMemIndex, + f_pChannelOpen->TdmConfig.ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pChanEntry->usSinTsstIndex , + pChanEntry->usSinSoutTsiMemIndex, + f_pChannelOpen->TdmConfig.ulSinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Modify ROUT port.*/ + if ( ( f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( f_pChannelModify->TdmConfig.ulRoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) + { + if ( f_usNewRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + if ( f_pChannelModify->TdmConfig.ulRoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* If this output port is not muted. */ + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) == 0x0 ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usNewRoutTsstIndex, + pApiCodecConf->byAdpcmNibblePosition, + f_pChannelModify->TdmConfig.ulRoutNumTssts, + pChanEntry->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* If this output port is not muted. */ + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) == 0x0 ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usNewRoutTsstIndex, + pApiCodecConf->byAdpcmNibblePosition, + pApiTdmConf->byRoutNumTssts, + pChanEntry->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + + /* Modify SOUT port.*/ + if ( ( f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + || ( f_pChannelModify->TdmConfig.ulSoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + ) + { + if ( f_usNewSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + if ( f_pChannelModify->TdmConfig.ulSoutNumTssts != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + /* If this output port is not muted. */ + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) == 0x0 ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usNewSoutTsstIndex, + pApiCodecConf->byAdpcmNibblePosition, + f_pChannelModify->TdmConfig.ulSoutNumTssts, + pChanEntry->usSinSoutTsiMemIndex ); + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* If this output port is not muted. */ + if ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) == 0x0 ) + { + /* Write the new entry now.*/ + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + f_usNewSoutTsstIndex, + pApiCodecConf->byAdpcmNibblePosition, + pApiTdmConf->bySoutNumTssts, + pChanEntry->usSinSoutTsiMemIndex ); + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + } + + + + } + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Modify the Encoder/Decoder memory if required.*/ + + if ( f_pChannelModify->fCodecConfigModified == TRUE ) + { + UINT32 ulCompType = 0; + UINT16 usTempTsiMemIndex; + UINT16 usDecoderMemIndex; + UINT16 usEncoderMemIndex; + UINT32 ulPcmLaw; + UINT16 usPhasingIndex; + BOOL fModifyAdpcmMem = TRUE; + + /*==============================================================================*/ + /* Reprogram the Decoder memory.*/ + + if ( pChanEntry->CodecConfig.byDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + usDecoderMemIndex = pChanEntry->usRinRoutConversionMemIndex; + } + else + { + usDecoderMemIndex = pChanEntry->usSinSoutConversionMemIndex; + } + + if ( pChanEntry->CodecConfig.byEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + usEncoderMemIndex = pChanEntry->usRinRoutConversionMemIndex; + } + else + { + usEncoderMemIndex = pChanEntry->usSinSoutConversionMemIndex; + } + + if ( usDecoderMemIndex != cOCT6100_INVALID_INDEX ) + { + switch( f_pChannelOpen->CodecConfig.ulDecodingRate ) + { + case cOCT6100_G711_64KBPS: + ulCompType = 0x8; + + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + if ( f_pChannelOpen->TdmConfig.ulRinPcmLaw == f_pChannelOpen->TdmConfig.ulRoutPcmLaw ) + fModifyAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( f_pChannelOpen->TdmConfig.ulRinStream == cOCT6100_UNASSIGNED ) + || ( f_pChannelOpen->TdmConfig.ulRoutStream == cOCT6100_UNASSIGNED ) ) + fModifyAdpcmMem = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + if ( f_pChannelOpen->TdmConfig.ulSinPcmLaw == f_pChannelOpen->TdmConfig.ulSoutPcmLaw ) + fModifyAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( f_pChannelOpen->TdmConfig.ulSinStream == cOCT6100_UNASSIGNED ) + || ( f_pChannelOpen->TdmConfig.ulSoutStream == cOCT6100_UNASSIGNED ) ) + fModifyAdpcmMem = FALSE; + } + + break; + case cOCT6100_G726_40KBPS: + ulCompType = 0x3; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_32KBPS: + ulCompType = 0x2; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_24KBPS: + ulCompType = 0x1; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_16KBPS: + ulCompType = 0x0; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_2C_ENCODED: + ulCompType = 0x4; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_3C_ENCODED: + ulCompType = 0x5; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_4C_ENCODED: + ulCompType = 0x6; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_ENCODED: + ulCompType = 0x9; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G711_G726_ENCODED: + ulCompType = 0xA; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G711_G727_2C_ENCODED: + ulCompType = 0xC; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G711_G727_3C_ENCODED: + ulCompType = 0xD; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G711_G727_4C_ENCODED: + ulCompType = 0xE; + fConversionEnabled = TRUE; + break; + + default: + return cOCT6100_ERR_FATAL_D6; + } + + if ( fModifyAdpcmMem == TRUE ) + { + /* Set the chariot memory based on the selected port.*/ + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + usTempTsiMemIndex = pChanEntry->usRinRoutTsiMemIndex; + ulPcmLaw = f_pChannelOpen->TdmConfig.ulRoutPcmLaw; /* Set the law for later use */ + + /* Flag the entry as active.*/ + *f_pfRinRoutCodecActive = TRUE; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + usTempTsiMemIndex = pChanEntry->usSinSoutTsiMemIndex; + ulPcmLaw = f_pChannelOpen->TdmConfig.ulSoutPcmLaw; /* Set the law for later use */ + + /* Flag the entry as active.*/ + *f_pfSinSoutCodecActive = TRUE; + } + + ulResult = Oct6100ApiWriteDecoderMemory( f_pApiInstance, + usDecoderMemIndex, + ulCompType, + usTempTsiMemIndex, + ulPcmLaw, + pApiCodecConf->byAdpcmNibblePosition ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, + usDecoderMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Flag the entry as deactivated.*/ + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + *f_pfRinRoutCodecActive = FALSE; + } + else + { + *f_pfSinSoutCodecActive = FALSE; + } + } + } + + /*==============================================================================*/ + + + + + /*==============================================================================*/ + /* Reprogram the Encoder memory.*/ + + if ( usEncoderMemIndex != cOCT6100_INVALID_INDEX ) + { + + fModifyAdpcmMem = TRUE; + + /* Set the chariot memory based on the selected port.*/ + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + usTempTsiMemIndex = pChanEntry->usRinRoutTsiMemIndex; + ulPcmLaw = f_pChannelOpen->TdmConfig.ulRoutPcmLaw; /* Set the law for later use */ + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + usTempTsiMemIndex = pChanEntry->usSinSoutTsiMemIndex; + ulPcmLaw = f_pChannelOpen->TdmConfig.ulSoutPcmLaw; /* Set the law for later use */ + } + + /* Set the phasing index .*/ + if ( f_usNewPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + usPhasingIndex = f_usNewPhasingTsstIndex; + else + usPhasingIndex = pChanEntry->usPhasingTsstIndex; + + switch( f_pChannelOpen->CodecConfig.ulEncodingRate ) + { + case cOCT6100_G711_64KBPS: + if ( ulPcmLaw == cOCT6100_PCM_U_LAW ) + ulCompType = 0x4; + else /* ulPcmLaw == cOCT6100_PCM_A_LAW */ + ulCompType = 0x5; + + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + if ( f_pChannelOpen->TdmConfig.ulRinPcmLaw == f_pChannelOpen->TdmConfig.ulRoutPcmLaw ) + fModifyAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( f_pChannelOpen->TdmConfig.ulRinStream == cOCT6100_UNASSIGNED ) + || ( f_pChannelOpen->TdmConfig.ulRoutStream == cOCT6100_UNASSIGNED ) ) + fModifyAdpcmMem = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + if ( f_pChannelOpen->TdmConfig.ulSinPcmLaw == f_pChannelOpen->TdmConfig.ulSoutPcmLaw ) + fModifyAdpcmMem = FALSE; + + /* Check if both ports are assigned. If not, no law conversion needed here.. */ + if ( ( f_pChannelOpen->TdmConfig.ulSinStream == cOCT6100_UNASSIGNED ) + || ( f_pChannelOpen->TdmConfig.ulSoutStream == cOCT6100_UNASSIGNED ) ) + fModifyAdpcmMem = FALSE; + } + break; + case cOCT6100_G726_40KBPS: + ulCompType = 0x3; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_32KBPS: + ulCompType = 0x2; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_24KBPS: + ulCompType = 0x1; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G726_16KBPS: + ulCompType = 0x0; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_40KBPS_4_1: + ulCompType = 0xD; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_40KBPS_3_2: + ulCompType = 0xA; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_40KBPS_2_3: + ulCompType = 0x6; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_32KBPS_4_0: + ulCompType = 0xE; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_32KBPS_3_1: + ulCompType = 0xB; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_32KBPS_2_2: + ulCompType = 0x7; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_24KBPS_3_0: + ulCompType = 0xC; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_24KBPS_2_1: + ulCompType = 0x8; + fConversionEnabled = TRUE; + break; + + case cOCT6100_G727_16KBPS_2_0: + ulCompType = 0x9; + fConversionEnabled = TRUE; + break; + + default: + return cOCT6100_ERR_FATAL_D7; + } + + if ( fModifyAdpcmMem == TRUE ) + { + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + *f_pfRinRoutCodecActive = TRUE; + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + *f_pfSinSoutCodecActive = TRUE; + } + + ulResult = Oct6100ApiWriteEncoderMemory( f_pApiInstance, + usEncoderMemIndex, + ulCompType, + usTempTsiMemIndex, + f_pChannelOpen->CodecConfig.fEnableSilenceSuppression, + pApiCodecConf->byAdpcmNibblePosition, + usPhasingIndex, + f_pChannelOpen->CodecConfig.ulPhasingType, + f_pChannelOpen->CodecConfig.ulPhase ); + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + ulResult = Oct6100ApiClearConversionMemory( f_pApiInstance, + usEncoderMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + *f_pfRinRoutCodecActive = FALSE; + } + else /* f_pChannelOpen->CodecConfig.ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + *f_pfSinSoutCodecActive = FALSE; + } + } + } + + /*==============================================================================*/ + } + + + + + /*==============================================================================*/ + /* Modify the VQE parameter if required.*/ + + if ( ( f_pChannelModify->fVqeConfigModified == TRUE ) + || ( (UINT8)f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) + || ( f_pChannelOpen->fEnableToneDisabler != pChanEntry->fEnableToneDisabler ) ) + { + ulResult = Oct6100ApiWriteVqeMemory( f_pApiInstance, + &f_pChannelOpen->VqeConfig, + f_pChannelOpen, + f_usChanIndex, + pChanEntry->usEchoMemIndex, + FALSE, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + /* Modify the Echo memory if required.*/ + if ( f_pChannelModify->fEnableToneDisabler != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->ulEchoOperationMode != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulRinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulSinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulRoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING || + f_pChannelModify->TdmConfig.ulSoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ulResult = Oct6100ApiWriteEchoMemory( f_pApiInstance, + &f_pChannelOpen->TdmConfig, + f_pChannelOpen, + pChanEntry->usEchoMemIndex, + pChanEntry->usRinRoutTsiMemIndex, + pChanEntry->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Synch all the buffer playout field if needed by echo operation mode. */ + /* Note that Oct6100ApiWriteVqeMemory does not clear the playout pointers */ + /* since the flag is set to FALSE. */ + if ( ( pSharedInfo->ImageInfo.fBufferPlayout == TRUE ) + && ( ( f_pChannelModify->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_HT_FREEZE ) + || ( f_pChannelModify->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN ) ) ) + { + /* Buffer playout must be stopped. */ + fClearPlayoutPointers = TRUE; + } + } + + /*==============================================================================*/ + /* Modify the Mixer events if law changes are requested. */ + + if ( pChanEntry->usSinCopyEventIndex != cOCT6100_INVALID_INDEX && + f_pChannelModify->TdmConfig.ulSinPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Modify the value according to the new law.*/ + if ( f_pChannelModify->TdmConfig.ulSinPcmLaw == cOCT6100_PCM_A_LAW ) + WriteParams.usWriteData = (UINT16)( usReadData | ( f_pChannelModify->TdmConfig.ulSinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET )); + else + WriteParams.usWriteData = (UINT16)( usReadData & (~( f_pChannelModify->TdmConfig.ulSinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET ))); + + /* Write back the new value.*/ + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pChanEntry->usSoutCopyEventIndex != cOCT6100_INVALID_INDEX && + f_pChannelModify->TdmConfig.ulSoutPcmLaw != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + ReadParams.ulReadAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Modify the value according to the new law.*/ + if ( f_pChannelModify->TdmConfig.ulSoutPcmLaw == cOCT6100_PCM_A_LAW ) + WriteParams.usWriteData = (UINT16)( usReadData | ( f_pChannelModify->TdmConfig.ulSoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET )); + else + WriteParams.usWriteData = (UINT16)( usReadData & (~( f_pChannelModify->TdmConfig.ulSoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET ))); + + /* Write back the new value.*/ + WriteParams.ulWriteAddress = ReadParams.ulReadAddress; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + /* Mute channel if required, this is done on a port basis */ + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, + f_usChanIndex, + usRinTsstIndex, + usSinTsstIndex, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + /* Completely disable tone detection? */ + if ( f_pChannelModify->fDisableToneDetection == TRUE ) + { + /* Check if tone detection has been enabled on this channel. */ + for ( ulToneConfIndex = 0; ulToneConfIndex < ( sizeof( pChanEntry->aulToneConf ) / sizeof(UINT32) ); ulToneConfIndex ++ ) + { + /* Check if some tone has been activated on this channel. */ + if ( pChanEntry->aulToneConf[ ulToneConfIndex ] != 0 ) + { + tOCT6100_TONE_DETECTION_DISABLE ToneDetectDisable; + + /* Call the default function to make sure all parameters are assigned default values. */ + ulResult = Oct6100ToneDetectionDisableDef( &ToneDetectDisable ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Form channel handle. */ + ToneDetectDisable.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* Disable all tones activated on this channel. */ + ToneDetectDisable.fDisableAll = TRUE; + + /* Call tone detection serialized function. */ + ulResult = Oct6100ToneDetectionDisableSer( f_pApiInstance, &ToneDetectDisable ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get out of the loop, tone detection has been disabled! */ + break; + } + } + } + + /* Hard-stop buffer playout? */ + if ( f_pChannelModify->fStopBufferPlayout == TRUE ) + { + /* Check if playout has been started on the Rout port. */ + if ( ( pChanEntry->fRinBufPlaying == TRUE ) || ( pChanEntry->fRinBufAdded == TRUE ) ) + { + tOCT6100_BUFFER_PLAYOUT_STOP PlayoutStop; + + /* Call the default function to make sure all parameters are assigned default values. */ + ulResult = Oct6100BufferPlayoutStopDef( &PlayoutStop ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Hard stop request. */ + PlayoutStop.fStopCleanly = FALSE; + + /* Form channel handle. */ + PlayoutStop.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* For the Rout port. */ + PlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + + /* Call buffer playout stop serialized function. */ + ulResult = Oct6100BufferPlayoutStopSer( f_pApiInstance, &PlayoutStop ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* The chip might still be playing a last buffer. Make sure it hard-stops! */ + fClearPlayoutPointers = TRUE; + } + + /* Check if playout has been started on the Sout port. */ + if ( ( pChanEntry->fSoutBufPlaying == TRUE ) || ( pChanEntry->fSoutBufAdded == TRUE ) ) + { + tOCT6100_BUFFER_PLAYOUT_STOP PlayoutStop; + + /* Call the default function to make sure all parameters are assigned default values. */ + ulResult = Oct6100BufferPlayoutStopDef( &PlayoutStop ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Hard stop request. */ + PlayoutStop.fStopCleanly = FALSE; + + /* Form channel handle. */ + PlayoutStop.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* For the Rout port. */ + PlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_SOUT; + + /* Call buffer playout stop serialized function. */ + ulResult = Oct6100BufferPlayoutStopSer( f_pApiInstance, &PlayoutStop ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + /* The chip might still be playing a last buffer. Make sure it hard-stops! */ + fClearPlayoutPointers = TRUE; + } + } + + /* Remove participant from bridge? */ + if ( f_pChannelModify->fRemoveConfBridgeParticipant == TRUE ) + { + /* Check if this channel is on a bridge. */ + if ( pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + { + /* Channel is on a bridge, remove it. */ + tOCT6100_CONF_BRIDGE_CHAN_REMOVE BridgeChanRemove; + + /* Call the default function to make sure all parameters are assigned default values. */ + ulResult = Oct6100ConfBridgeChanRemoveDef( &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Form channel handle. */ + BridgeChanRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* Do not remove all channels, only the one specified. */ + BridgeChanRemove.fRemoveAll = FALSE; + + /* No need to assign conference bridge handle, the remove function will figure it out. */ + + /* Call conference bridge channel remove serialized function. */ + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_CONF_BRIDGE_CHANNEL_TAP_DEPENDENCY ) + { + tPOCT6100_API_CHANNEL pTapChanEntry; + + /* Get a pointer to the tap channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTapChanEntry, pChanEntry->usTapChanIndex ) + + /* Form tap channel handle. */ + BridgeChanRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pTapChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | pChanEntry->usTapChanIndex; + + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Re-form original channel handle. */ + BridgeChanRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else + { + return ulResult; + } + } + } + } + + /* Remove all broadcast TSSTs? */ + if ( f_pChannelModify->fRemoveBroadcastTssts == TRUE ) + { + /* Check if broadcast TSSTs were used on the Rout port. */ + if ( pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry != cOCT6100_INVALID_INDEX ) + { + tOCT6100_CHANNEL_BROADCAST_TSST_REMOVE BroadcastTsstRemove; + + ulResult = Oct6100ChannelBroadcastTsstRemoveDef( &BroadcastTsstRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Form channel handle. */ + BroadcastTsstRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* Remove all broadcast TSSTs associated to the current channel. */ + BroadcastTsstRemove.fRemoveAll = TRUE; + + /* On the Rout port. */ + BroadcastTsstRemove.ulPort = cOCT6100_CHANNEL_PORT_ROUT; + + ulResult = Oct6100ChannelBroadcastTsstRemoveSer( f_pApiInstance, &BroadcastTsstRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + + /* Check if broadcast TSSTs were used on the Sout port. */ + if ( pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry != cOCT6100_INVALID_INDEX ) + { + tOCT6100_CHANNEL_BROADCAST_TSST_REMOVE BroadcastTsstRemove; + + ulResult = Oct6100ChannelBroadcastTsstRemoveDef( &BroadcastTsstRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Form channel handle. */ + BroadcastTsstRemove.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | ( pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT ) | f_usChanIndex; + + /* Remove all broadcast TSSTs associated to the current channel. */ + BroadcastTsstRemove.fRemoveAll = TRUE; + + /* On the Sout port. */ + BroadcastTsstRemove.ulPort = cOCT6100_CHANNEL_PORT_SOUT; + + ulResult = Oct6100ChannelBroadcastTsstRemoveSer( f_pApiInstance, &BroadcastTsstRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Check if have to make sure buffer playout is stopped. */ + if ( fClearPlayoutPointers == TRUE ) + { + tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; + + Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); + + BufferPlayoutStop.fStopCleanly = FALSE; + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + pChanEntry->usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_SOUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + pChanEntry->usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiModifyChannelEntry + +Description: Updates the channel structure in the ECHO channel list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelModify Pointer to echo cancellation channel modify structure. +f_pChannelOpen Pointer to echo cancellation channel configuration structure. +f_usChanIndex Index of the channel within the API's channel list. +f_usNewPhasingTsstIndex Index of the new phasing TSST. +f_fSinSoutCodecActive State of the SIN/SOUT codec. +f_fRinRoutCodecActive State of the RIN/ROUT codec. +f_usNewRinTsstIndex New RIN TSST memory index. +f_usNewSinTsstIndex New SIN TSST memory index. +f_usNewRoutTsstIndex New ROUT TSST memory index. +f_usNewSoutTsstIndex New SOUT TSST memory index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiModifyChannelEntry +UINT32 Oct6100ApiModifyChannelEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewPhasingTsstIndex, + IN UINT8 f_fSinSoutCodecActive, + IN UINT8 f_fRinRoutCodecActive, + IN UINT16 f_usNewRinTsstIndex, + IN UINT16 f_usNewSinTsstIndex, + IN UINT16 f_usNewRoutTsstIndex, + IN UINT16 f_usNewSoutTsstIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_CHANNEL_CODEC pApiCodecConf; + tPOCT6100_API_CHANNEL_TDM pApiTdmConf; + tPOCT6100_API_CHANNEL_VQE pApiVqeConf; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Obtain local pointer to the configuration structures of the tPOCT6100_API_CHANNEL structure. */ + pApiCodecConf = &pChanEntry->CodecConfig; + pApiTdmConf = &pChanEntry->TdmConfig; + pApiVqeConf = &pChanEntry->VqeConfig; + + /*=======================================================================*/ + /* Copy the channel's general configuration. */ + + pChanEntry->ulUserChanId = f_pChannelOpen->ulUserChanId; + pChanEntry->byEchoOperationMode = (UINT8)( f_pChannelOpen->ulEchoOperationMode & 0xFF ); + pChanEntry->fEnableToneDisabler = (UINT8)( f_pChannelOpen->fEnableToneDisabler & 0xFF ); + + /* Save the codec state.*/ + pChanEntry->fSinSoutCodecActive = (UINT8)( f_fSinSoutCodecActive & 0xFF ); + pChanEntry->fRinRoutCodecActive = (UINT8)( f_fRinRoutCodecActive & 0xFF ); + + /*=======================================================================*/ + /* Copy the channel's TDM configuration of all the modified fields. */ + + if ( f_pChannelModify->fTdmConfigModified == TRUE ) + { + pApiTdmConf->byRinPcmLaw = (UINT8)( f_pChannelOpen->TdmConfig.ulRinPcmLaw & 0xFF ); + pApiTdmConf->bySinPcmLaw = (UINT8)( f_pChannelOpen->TdmConfig.ulSinPcmLaw & 0xFF ); + pApiTdmConf->byRoutPcmLaw = (UINT8)( f_pChannelOpen->TdmConfig.ulRoutPcmLaw & 0xFF ); + pApiTdmConf->bySoutPcmLaw = (UINT8)( f_pChannelOpen->TdmConfig.ulSoutPcmLaw & 0xFF ); + + pApiTdmConf->byRinNumTssts = (UINT8)( f_pChannelOpen->TdmConfig.ulRinNumTssts & 0xFF ); + pApiTdmConf->bySinNumTssts = (UINT8)( f_pChannelOpen->TdmConfig.ulSinNumTssts & 0xFF ); + pApiTdmConf->byRoutNumTssts = (UINT8)( f_pChannelOpen->TdmConfig.ulRoutNumTssts & 0xFF ); + pApiTdmConf->bySoutNumTssts = (UINT8)( f_pChannelOpen->TdmConfig.ulSoutNumTssts & 0xFF ); + + if ( f_pChannelModify->TdmConfig.ulRinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_usNewRinTsstIndex != cOCT6100_INVALID_INDEX ) + { + pApiTdmConf->usRinStream = (UINT16)( f_pChannelOpen->TdmConfig.ulRinStream & 0xFFFF ); + pApiTdmConf->usRinTimeslot = (UINT16)( f_pChannelOpen->TdmConfig.ulRinTimeslot & 0xFFFF ); + pChanEntry->usRinTsstIndex = f_usNewRinTsstIndex; + } + else /* f_ulNewRinTsstIndex != cOCT6100_INVALID_INDEX */ + { + pApiTdmConf->usRinStream = cOCT6100_UNASSIGNED; + pApiTdmConf->usRinTimeslot = cOCT6100_UNASSIGNED; + pChanEntry->usRinTsstIndex = cOCT6100_INVALID_INDEX; + } + } + + if ( f_pChannelModify->TdmConfig.ulSinTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_usNewSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + pApiTdmConf->usSinStream = (UINT16)( f_pChannelOpen->TdmConfig.ulSinStream & 0xFFFF ); + pApiTdmConf->usSinTimeslot = (UINT16)( f_pChannelOpen->TdmConfig.ulSinTimeslot & 0xFFFF ); + pChanEntry->usSinTsstIndex = f_usNewSinTsstIndex; + } + else /* f_ulNewSinTsstIndex != cOCT6100_INVALID_INDEX */ + { + pApiTdmConf->usSinStream = cOCT6100_UNASSIGNED; + pApiTdmConf->usSinTimeslot = cOCT6100_UNASSIGNED; + pChanEntry->usSinTsstIndex = cOCT6100_INVALID_INDEX; + } + } + + if ( f_pChannelModify->TdmConfig.ulRoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_usNewRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + pApiTdmConf->usRoutStream = (UINT16)( f_pChannelOpen->TdmConfig.ulRoutStream & 0xFFFF ); + pApiTdmConf->usRoutTimeslot = (UINT16)( f_pChannelOpen->TdmConfig.ulRoutTimeslot & 0xFFFF ); + pChanEntry->usRoutTsstIndex = f_usNewRoutTsstIndex; + } + else /* f_ulNewRoutTsstIndex != cOCT6100_INVALID_INDEX */ + { + pApiTdmConf->usRoutStream = cOCT6100_UNASSIGNED; + pApiTdmConf->usRoutTimeslot = cOCT6100_UNASSIGNED; + pChanEntry->usRoutTsstIndex = cOCT6100_INVALID_INDEX; + } + } + + if ( f_pChannelModify->TdmConfig.ulSoutTimeslot != cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_usNewSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + pApiTdmConf->usSoutStream = (UINT16)( f_pChannelOpen->TdmConfig.ulSoutStream & 0xFFFF ); + pApiTdmConf->usSoutTimeslot = (UINT16)( f_pChannelOpen->TdmConfig.ulSoutTimeslot & 0xFFFF ); + pChanEntry->usSoutTsstIndex = f_usNewSoutTsstIndex; + } + else /* f_ulNewSoutTsstIndex != cOCT6100_INVALID_INDEX */ + { + pApiTdmConf->usSoutStream = cOCT6100_UNASSIGNED; + pApiTdmConf->usSoutTimeslot = cOCT6100_UNASSIGNED; + pChanEntry->usSoutTsstIndex = cOCT6100_INVALID_INDEX; + } + } + } + + /*=======================================================================*/ + /* Copy the channel's VQE configuration of all the modified fields. */ + + if ( f_pChannelModify->fVqeConfigModified == TRUE ) + { + pApiVqeConf->fEnableNlp = (UINT8)( f_pChannelOpen->VqeConfig.fEnableNlp & 0xFF ); + pApiVqeConf->byComfortNoiseMode = (UINT8)( f_pChannelOpen->VqeConfig.ulComfortNoiseMode & 0xFF ); + pApiVqeConf->fSinDcOffsetRemoval = (UINT8)( f_pChannelOpen->VqeConfig.fSinDcOffsetRemoval & 0xFF ); + pApiVqeConf->fRinDcOffsetRemoval = (UINT8)( f_pChannelOpen->VqeConfig.fRinDcOffsetRemoval & 0xFF ); + pApiVqeConf->fRinLevelControl = (UINT8)( f_pChannelOpen->VqeConfig.fRinLevelControl & 0xFF ); + pApiVqeConf->fSoutLevelControl = (UINT8)( f_pChannelOpen->VqeConfig.fSoutLevelControl & 0xFF ); + pApiVqeConf->fRinAutomaticLevelControl = (UINT8)( f_pChannelOpen->VqeConfig.fRinAutomaticLevelControl & 0xFF ); + pApiVqeConf->fSoutAutomaticLevelControl = (UINT8)( f_pChannelOpen->VqeConfig.fSoutAutomaticLevelControl & 0xFF ); + pApiVqeConf->fRinHighLevelCompensation = (UINT8)( f_pChannelOpen->VqeConfig.fRinHighLevelCompensation & 0xFF ); + + pApiVqeConf->fSoutAdaptiveNoiseReduction = (UINT8)( f_pChannelOpen->VqeConfig.fSoutAdaptiveNoiseReduction & 0xFF ); + pApiVqeConf->fSoutNoiseBleaching = (UINT8)( f_pChannelOpen->VqeConfig.fSoutNoiseBleaching & 0xFF ); + pApiVqeConf->fSoutConferencingNoiseReduction = (UINT8)( f_pChannelOpen->VqeConfig.fSoutConferencingNoiseReduction & 0xFF ); + pApiVqeConf->chRinLevelControlGainDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lRinLevelControlGainDb & 0xFF ); + pApiVqeConf->chSoutLevelControlGainDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lSoutLevelControlGainDb & 0xFF ); + pApiVqeConf->chRinAutomaticLevelControlTargetDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lRinAutomaticLevelControlTargetDb & 0xFF ); + pApiVqeConf->chSoutAutomaticLevelControlTargetDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lSoutAutomaticLevelControlTargetDb & 0xFF ); + pApiVqeConf->chRinHighLevelCompensationThresholdDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lRinHighLevelCompensationThresholdDb & 0xFF ); + pApiVqeConf->fEnableTailDisplacement = (UINT8)( f_pChannelOpen->VqeConfig.fEnableTailDisplacement & 0xFF ); + pApiVqeConf->usTailDisplacement = (UINT16)( f_pChannelOpen->VqeConfig.ulTailDisplacement & 0xFFFF ); + pApiVqeConf->usTailLength = (UINT16)( f_pChannelOpen->VqeConfig.ulTailLength & 0xFFFF ); + pApiVqeConf->fAcousticEcho = (UINT8)( f_pChannelOpen->VqeConfig.fAcousticEcho & 0xFF ); + pApiVqeConf->fDtmfToneRemoval = (UINT8)( f_pChannelOpen->VqeConfig.fDtmfToneRemoval & 0xFF ); + + pApiVqeConf->chDefaultErlDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lDefaultErlDb & 0xFF ); + pApiVqeConf->chAecDefaultErlDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lAecDefaultErlDb & 0xFF ); + pApiVqeConf->usAecTailLength = (UINT16)( f_pChannelOpen->VqeConfig.ulAecTailLength & 0xFFFF ); + pApiVqeConf->chAnrSnrEnhancementDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lAnrSnrEnhancementDb & 0xFF ); + pApiVqeConf->byAnrVoiceNoiseSegregation = (UINT8)( f_pChannelOpen->VqeConfig.ulAnrVoiceNoiseSegregation & 0xFF ); + pApiVqeConf->usToneDisablerVqeActivationDelay = (UINT16)( f_pChannelOpen->VqeConfig.ulToneDisablerVqeActivationDelay & 0xFFFF ); + pApiVqeConf->byNonLinearityBehaviorA = (UINT8)( f_pChannelOpen->VqeConfig.ulNonLinearityBehaviorA & 0xFF ); + pApiVqeConf->byNonLinearityBehaviorB = (UINT8)( f_pChannelOpen->VqeConfig.ulNonLinearityBehaviorB & 0xFF ); + pApiVqeConf->byDoubleTalkBehavior = (UINT8)( f_pChannelOpen->VqeConfig.ulDoubleTalkBehavior & 0xFF ); + pApiVqeConf->bySoutAutomaticListenerEnhancementGainDb = (UINT8)( f_pChannelOpen->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb & 0xFF ); + pApiVqeConf->bySoutNaturalListenerEnhancementGainDb = (UINT8)( f_pChannelOpen->VqeConfig.ulSoutNaturalListenerEnhancementGainDb & 0xFF ); + pApiVqeConf->fSoutNaturalListenerEnhancement = (UINT8)( f_pChannelOpen->VqeConfig.fSoutNaturalListenerEnhancement & 0xFF ); + pApiVqeConf->fRoutNoiseReduction = (UINT8)( f_pChannelOpen->VqeConfig.fRoutNoiseReduction & 0xFF ); + pApiVqeConf->chRoutNoiseReductionLevelGainDb = (OCT_INT8)( f_pChannelOpen->VqeConfig.lRoutNoiseReductionLevelGainDb & 0xFF ); + pApiVqeConf->fEnableMusicProtection = (UINT8)( f_pChannelOpen->VqeConfig.fEnableMusicProtection & 0xFF ); + pApiVqeConf->fIdleCodeDetection = (UINT8)( f_pChannelOpen->VqeConfig.fIdleCodeDetection & 0xFF ); + } + + /*=======================================================================*/ + /* Copy the channel's CODEC configuration of all the modified fields. */ + if ( f_pChannelModify->fCodecConfigModified == TRUE ) + { + pApiCodecConf->byAdpcmNibblePosition = (UINT8)( f_pChannelOpen->CodecConfig.ulAdpcmNibblePosition & 0xFF ); + pApiCodecConf->byEncoderPort = (UINT8)( f_pChannelOpen->CodecConfig.ulEncoderPort & 0xFF ); + pApiCodecConf->byEncodingRate = (UINT8)( f_pChannelOpen->CodecConfig.ulEncodingRate & 0xFF ); + pApiCodecConf->byDecoderPort = (UINT8)( f_pChannelOpen->CodecConfig.ulDecoderPort & 0xFF ); + pApiCodecConf->byDecodingRate = (UINT8)( f_pChannelOpen->CodecConfig.ulDecodingRate & 0xFF ); + pApiCodecConf->fEnableSilenceSuppression = (UINT8)( f_pChannelOpen->CodecConfig.fEnableSilenceSuppression & 0xFF ); + pApiCodecConf->byPhase = (UINT8)( f_pChannelOpen->CodecConfig.ulPhase & 0xFF ); + pApiCodecConf->byPhasingType = (UINT8)( f_pChannelOpen->CodecConfig.ulPhasingType & 0xFF ); + + /* Update the API phasing TSST structure */ + if ( f_usNewPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingTsst; + + /* Release the previous phasing TSST if the channel was already bound to one.*/ + if ( pChanEntry->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingTsst, pChanEntry->usPhasingTsstIndex ); + + pPhasingTsst->usDependencyCnt--; + } + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingTsst, f_usNewPhasingTsstIndex ); + + pPhasingTsst->usDependencyCnt++; + pChanEntry->usPhasingTsstIndex = f_usNewPhasingTsstIndex; + + } + } + + + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelBroadcastTsstAddSer + +Description: Assign a TSST to one of the port of an echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to TSST assign structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelBroadcastTsstAddSer +UINT32 Oct6100ChannelBroadcastTsstAddSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd ) +{ + UINT16 usChanIndex; + UINT16 usNewTsstIndex; + UINT16 usNewTsstEntry; + UINT32 ulResult; + + ulResult = Oct6100ApiCheckChanTsstAddParams( f_pApiInstance, f_pChannelTsstAdd, &usChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReserveTsstAddResources( f_pApiInstance, f_pChannelTsstAdd, usChanIndex, &usNewTsstIndex, &usNewTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWriteTsstAddStructs( f_pApiInstance, f_pChannelTsstAdd, usChanIndex, usNewTsstIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiUpdateTsstAddChanEntry( f_pApiInstance, f_pChannelTsstAdd, usChanIndex, usNewTsstIndex, usNewTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChanTsstAddParams + +Description: Verify the validity of the tPOCT6100_CHANNEL_BROADCAST_TSST_ADD + structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to echo cancellation channel open configuration structure. +f_pusChanIndex Pointer to a structure used to store the multiple resources indexes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChanTsstAddParams +UINT32 Oct6100ApiCheckChanTsstAddParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd, + OUT PUINT16 f_pusChanIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + UINT32 ulNumTssts = 1; + UINT32 ulEntryOpenCnt; + + /* Check the provided handle. */ + if ( (f_pChannelTsstAdd->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelTsstAdd->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelTsstAdd->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + /* validate the port parameter.*/ + if ( f_pChannelTsstAdd->ulPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pChannelTsstAdd->ulPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_CHANNEL_TSST_ADD_PORT; + + /* Get the required number of TSST based on the port.*/ + switch( f_pChannelTsstAdd->ulPort ) + { + case cOCT6100_CHANNEL_PORT_ROUT: + ulNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + break; + case cOCT6100_CHANNEL_PORT_SOUT: + ulNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + break; + default: + return cOCT6100_ERR_FATAL_B; + } + + /* Check the validity of the timeslot and stream. */ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + ulNumTssts, + f_pChannelTsstAdd->ulTimeslot, + f_pChannelTsstAdd->ulStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_TSST_ADD_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_TSST_ADD_STREAM; + } + else + { + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveTsstAddResources + +Description: Reserve the entry for the new broadcast TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to echo cancellation channel open configuration structure. +f_usChanIndex Channel index within the API's channel list. +f_pusNewTsstIndex Pointer to the new TSST index within the API's TSST memory. +f_pusNewTsstEntry Pointer to the new TSST entry within the API's TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveTsstAddResources +UINT32 Oct6100ApiReserveTsstAddResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd, + IN UINT16 f_usChanIndex, + OUT PUINT16 f_pusNewTsstIndex, + OUT PUINT16 f_pusNewTsstEntry ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulResult; + UINT32 ulNumTssts = 1; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + + switch( f_pChannelTsstAdd->ulPort ) + { + case cOCT6100_CHANNEL_PORT_ROUT: + ulNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + break; + case cOCT6100_CHANNEL_PORT_SOUT: + ulNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + break; + default: + return cOCT6100_ERR_FATAL_C; + } + + /* Reserve the new entry.*/ + ulResult = Oct6100ApiReserveTsst( f_pApiInstance, + f_pChannelTsstAdd->ulTimeslot, + f_pChannelTsstAdd->ulStream, + ulNumTssts, + cOCT6100_OUTPUT_TSST, + f_pusNewTsstIndex, + f_pusNewTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteTsstAddStructs + +Description: Configure the TSST control memory for the new TSST entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to echo cancellation channel open configuration structure. +f_usChanIndex Channel index. +f_usNewTsstIndex Tsst index in the TSST control memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteTsstAddStructs +UINT32 Oct6100ApiWriteTsstAddStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewTsstIndex ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT16 usTsiMemIndex; + UINT32 ulNumTssts = 1; + + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + + switch( f_pChannelTsstAdd->ulPort ) + { + case cOCT6100_CHANNEL_PORT_ROUT: + usTsiMemIndex = pChanEntry->usRinRoutTsiMemIndex; + ulNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + break; + case cOCT6100_CHANNEL_PORT_SOUT: + usTsiMemIndex = pChanEntry->usSinSoutTsiMemIndex; + ulNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + break; + default: + return cOCT6100_ERR_FATAL_D; + } + + + /* Write the new entry now.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (f_usNewTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_TSST_CONTROL_MEM_OUTPUT_TSST; + WriteParams.usWriteData |= (UINT16)( pChanEntry->CodecConfig.byAdpcmNibblePosition << cOCT6100_TSST_CONTROL_MEM_NIBBLE_POS_OFFSET ); + WriteParams.usWriteData |= (UINT16)( (ulNumTssts - 1) << cOCT6100_TSST_CONTROL_MEM_TSST_NUM_OFFSET ); + WriteParams.usWriteData |= (UINT16)( usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateTsstAddChanEntry + +Description: Update the associated channel API entry to add the new broacast TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstAdd Pointer to echo cancellation channel open configuration structure. +f_usChanIndex Channel index. +f_usNewTsstIndex TSST index within the TSST control memory. +f_usNewTsstEntry TSST entry within the API TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateTsstAddChanEntry +UINT32 Oct6100ApiUpdateTsstAddChanEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_ADD f_pChannelTsstAdd, + IN UINT16 f_usChanIndex, + IN UINT16 f_usNewTsstIndex, + IN UINT16 f_usNewTsstEntry ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, f_usNewTsstEntry ); + + /* Update the channel entry.*/ + if ( f_pChannelTsstAdd->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Add the new TSST entry to the broadcast list.*/ + pTsstEntry->usNextEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + pTsstEntry->usTsstMemoryIndex = (UINT16)f_usNewTsstIndex; + pTsstEntry->usTsstValue = (UINT16)( (f_pChannelTsstAdd->ulTimeslot << 5) | f_pChannelTsstAdd->ulStream ); + + /* Modify the first entry pointer.*/ + pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry = f_usNewTsstEntry; + + /* Increment the number of broadcast TSST. */ + pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry++; + + } + else /* f_pChannelTsstAdd->ulPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + /* Add the new TSST entry to the broadcast list.*/ + pTsstEntry->usNextEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + pTsstEntry->usTsstMemoryIndex = (UINT16)f_usNewTsstIndex; + pTsstEntry->usTsstValue = (UINT16)( (f_pChannelTsstAdd->ulTimeslot << 5) | f_pChannelTsstAdd->ulStream ); + + /* Modify the first entry pointer.*/ + pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry = f_usNewTsstEntry; + + /* Increment the number of broadcast TSST. */ + pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry++; + } + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelBroadcastTsstRemoveSer + +Description: Removes a broadcast TSST from one of the output port of an + echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstRemove Pointer to TSST remove structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelBroadcastTsstRemoveSer +UINT32 Oct6100ChannelBroadcastTsstRemoveSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove) +{ + UINT16 usChanIndex; + UINT16 usTsstIndex; + UINT16 usTsstEntry; + UINT16 usPrevTsstEntry; + UINT32 ulResult; + + ulResult = Oct6100ApiAssertChanTsstRemoveParams( f_pApiInstance, f_pChannelTsstRemove, &usChanIndex, &usTsstIndex, &usTsstEntry, &usPrevTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiInvalidateTsstRemoveStructs( f_pApiInstance, usChanIndex, usTsstIndex, f_pChannelTsstRemove->ulPort, f_pChannelTsstRemove->fRemoveAll ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseTsstRemoveResources( f_pApiInstance, f_pChannelTsstRemove, usChanIndex, usTsstIndex, usTsstEntry, usPrevTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertChanTsstRemoveParams + +Description: Verify the validity of the tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE + structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstRemove Pointer to echo cancellation channel open configuration structure. +f_pulChanIndex Pointer to a channel index. +f_pulNewTsstIndex Pointer to a TSST index within the TSST control memory. +f_pulNewTsstEntry Pointer to a TSST entry within the API TSST list. +f_pulPrevTsstEntry Pointer to the previous TSST entry. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertChanTsstRemoveParams +UINT32 Oct6100ApiAssertChanTsstRemoveParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusTsstIndex, + OUT PUINT16 f_pusTsstEntry, + OUT PUINT16 f_pusPrevTsstEntry ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + UINT32 ulResult; + UINT32 ulNumTssts = 1; + UINT32 ulEntryOpenCnt; + UINT16 usCurrentEntry; + UINT16 usTsstValue; + UINT16 usNumEntry; + + /* Check the provided handle. */ + if ( (f_pChannelTsstRemove->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelTsstRemove->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelTsstRemove->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + /* validate the port parameter.*/ + if ( f_pChannelTsstRemove->ulPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pChannelTsstRemove->ulPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_PORT; + + /* Verify that the requested entry is present in the channel's port broadcast TSST.*/ + if ( f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + usCurrentEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + usNumEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry; + } + else /* f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + usCurrentEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + usNumEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry; + } + + /* Verify if at least one TSST is present on the channel port.*/ + if ( usNumEntry == 0 ) + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_NO_BROADCAST_TSST; + + /* Get the required number of TSST based on the port.*/ + switch( f_pChannelTsstRemove->ulPort ) + { + case cOCT6100_CHANNEL_PORT_ROUT: + ulNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + break; + case cOCT6100_CHANNEL_PORT_SOUT: + ulNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + break; + default: + return cOCT6100_ERR_FATAL_E; + } + + /* Initialize the TSST entry to invalid.*/ + *f_pusTsstEntry = cOCT6100_INVALID_INDEX; + *f_pusPrevTsstEntry = cOCT6100_INVALID_INDEX; + *f_pusTsstIndex = cOCT6100_INVALID_INDEX; + + if ( f_pChannelTsstRemove->fRemoveAll != TRUE ) + { + /* Check the validity of the timeslot and Stream.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + ulNumTssts, + f_pChannelTsstRemove->ulTimeslot, + f_pChannelTsstRemove->ulStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_STREAM; + } + else + { + return ulResult; + } + } + + /* Set the TSST value based on the timeslot and stream value.*/ + usTsstValue = (UINT16)( (f_pChannelTsstRemove->ulTimeslot << 5) | f_pChannelTsstRemove->ulStream ); + + while( usCurrentEntry != cOCT6100_INVALID_INDEX ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usCurrentEntry ); + + if ( usTsstValue == pTsstEntry->usTsstValue ) + { + /* A match was found.*/ + *f_pusTsstEntry = usCurrentEntry; + *f_pusTsstIndex = pTsstEntry->usTsstMemoryIndex; + break; + } + + /* Move on to the next entry.*/ + *f_pusPrevTsstEntry = usCurrentEntry; + usCurrentEntry = pTsstEntry->usNextEntry; + } + + if ( *f_pusTsstEntry == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_TSST_REMOVE_INVALID_TSST; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateTsstRemoveStructs + +Description: Invalidate the entry of the broadcast TSST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usChanIndex Channel index. +f_usTsstIndex TSST index within the TSST control memory. +f_ulPort Channel port where the TSST are removed from. (only used if remove all == TRUE) +f_fRemoveAll Remove all flag. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateTsstRemoveStructs +UINT32 Oct6100ApiInvalidateTsstRemoveStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usTsstIndex, + IN UINT32 f_ulPort, + IN BOOL f_fRemoveAll ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + if ( f_fRemoveAll == FALSE ) + { + /* Deactivate the entry now.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (f_usTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* f_fRemoveAll == TRUE */ + { + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + UINT16 usTsstEntry; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + + /* Clear all entry associated to the selected port.*/ + if ( f_ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + usTsstEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + else + usTsstEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + + do + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usTsstEntry ); + + /* Deactivate the entry now.*/ + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( ( pTsstEntry->usTsstMemoryIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usTsstEntry = pTsstEntry->usNextEntry; + + } while ( usTsstEntry != cOCT6100_INVALID_INDEX ); + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseTsstRemoveResources + +Description: Release all API resources associated to the Removed TSST and + update the channel entry accordingly. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelTsstRemove Pointer to echo cancellation channel open configuration structure. +f_usChanIndex Channel index. +f_usTsstIndex TSST index within the TSST control memory. +f_usTsstEntry TSST entry within the API's TSST list. +f_usPrevTsstEntry Previous TSST entry within the API's TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseTsstRemoveResources +UINT32 Oct6100ApiReleaseTsstRemoveResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_BROADCAST_TSST_REMOVE f_pChannelTsstRemove, + IN UINT16 f_usChanIndex, + IN UINT16 f_usTsstIndex, + IN UINT16 f_usTsstEntry, + IN UINT16 f_usPrevTsstEntry ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + tPOCT6100_API_TSST_ENTRY pPrevTsstEntry; + UINT16 usCurrentEntry; + UINT32 ulResult; + UINT32 ulTimeslot; + UINT32 ulStream; + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, f_usChanIndex ); + + if ( f_pChannelTsstRemove->fRemoveAll == FALSE ) + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, f_usTsstEntry ); + + /* Update the channel entry.*/ + if ( f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + /* Check if the entry was the first in the list.*/ + if ( f_usPrevTsstEntry == cOCT6100_INVALID_INDEX ) + { + pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry = pTsstEntry->usNextEntry; + } + else /* f_ulPrevTsstEntry != cOCT6100_INVALID_INDEX */ + { + /* Get a pointer to the previous entry.*/ + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPrevTsstEntry, f_usPrevTsstEntry ); + pPrevTsstEntry->usNextEntry = pTsstEntry->usNextEntry; + } + + /* Decrement the number of entry.*/ + pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry--; + } + else /* f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_SOUT */ + { + /* Check if the entry was the first in the list.*/ + if ( f_usPrevTsstEntry == cOCT6100_INVALID_INDEX ) + { + pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry = pTsstEntry->usNextEntry; + } + else /* f_ulPrevTsstEntry != cOCT6100_INVALID_INDEX */ + { + /* Get a pointer to the previous entry.*/ + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPrevTsstEntry, f_usPrevTsstEntry ); + pPrevTsstEntry->usNextEntry = pTsstEntry->usNextEntry; + } + + /* Decrement the number of entry.*/ + pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry--; + } + + ulTimeslot = pTsstEntry->usTsstValue >> 5; + ulStream = pTsstEntry->usTsstValue & 0x1F; + + /* Release the entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + ulTimeslot, + ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + f_usTsstEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* f_pChannelTsstRemove->fRemoveAll == TRUE */ + { + + /* Update the channel entry.*/ + if ( f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + usCurrentEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + else + usCurrentEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + + do + { + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usCurrentEntry ); + + ulTimeslot = pTsstEntry->usTsstValue >> 5; + ulStream = pTsstEntry->usTsstValue & 0x1F; + + /* Release the entry.*/ + ulResult = Oct6100ApiReleaseTsst( f_pApiInstance, + ulTimeslot, + ulStream, + cOCT6100_NUMBER_TSSTS_1, + cOCT6100_OUTPUT_TSST, + usCurrentEntry ); /* Release the entry.*/ + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usCurrentEntry = pTsstEntry->usNextEntry; + + /* Clear the previous node.*/ + pTsstEntry->usTsstMemoryIndex = 0xFFFF; + pTsstEntry->usTsstValue = 0xFFFF; + pTsstEntry->usNextEntry = cOCT6100_INVALID_INDEX; + + } while ( usCurrentEntry != cOCT6100_INVALID_INDEX ); + + /* Reset the channel status.*/ + if ( f_pChannelTsstRemove->ulPort == cOCT6100_CHANNEL_PORT_ROUT ) + { + pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry = cOCT6100_INVALID_INDEX; + pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry = 0; + } + else + { + pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry = cOCT6100_INVALID_INDEX; + pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry = 0; + } + } + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiChannelGetStatsSer + +Description: Serialized function that returns all the stats of the specified + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelStats Pointer to a channel stats structure. +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiChannelGetStatsSer +UINT32 Oct6100ApiChannelGetStatsSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_STATS f_pChannelStats ) +{ + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_READ_BURST_PARAMS BurstParams; + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_TSST_ENTRY pTsstEntry; + UINT32 ulEntryOpenCnt; + UINT16 usCurrentEntry; + UINT16 usTsstCount; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulTempData; + UINT32 ulMask; + UINT16 usChanIndex; + UINT16 ausReadData[ 32 ]; + + BYTE byRinEnergyRaw; + BYTE bySinEnergyRaw; + BYTE bySoutEnergyRaw; + INT32 lSoutEnergyIndB; + BYTE byCnEnergyRaw; + UINT16 usEchoDelayInFrames; + UINT16 usErlRaw; + + UINT32 ulResult; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + BurstParams.pusReadData = ausReadData; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Check the reset stats flag.*/ + if ( f_pChannelStats->fResetStats != TRUE && f_pChannelStats->fResetStats != FALSE ) + return cOCT6100_ERR_CHANNEL_STATS_RESET; + + /* Check the provided handle. */ + if ( cOCT6100_HNDL_TAG_CHANNEL != (f_pChannelStats->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + usChanIndex = (UINT16)( f_pChannelStats->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( usChanIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pChanEntry, usChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelStats->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + + /* Check the value of the max broadcast tsst.*/ + if ( f_pChannelStats->TdmConfig.ulMaxBroadcastTssts > cOCT6100_MAX_TSSTS ) + return cOCT6100_ERR_CHANNEL_GET_STATS_MAX_BROADCAST_TSST; + + if ( f_pChannelStats->TdmConfig.ulMaxBroadcastTssts != 0 ) + { + /* Check if memory was allocated by the user for the stream and timeslot values.*/ + if ( f_pChannelStats->TdmConfig.pulRoutBroadcastTimeslot == NULL ) + return cOCT6100_ERR_CHANNEL_ROUT_BROADCAST_TIMESLOT; + + if ( f_pChannelStats->TdmConfig.pulRoutBroadcastStream == NULL ) + return cOCT6100_ERR_CHANNEL_ROUT_BROADCAST_STREAM; + + if ( f_pChannelStats->TdmConfig.pulSoutBroadcastTimeslot == NULL ) + return cOCT6100_ERR_CHANNEL_SOUT_BROADCAST_TIMESLOT; + + if ( f_pChannelStats->TdmConfig.pulSoutBroadcastStream == NULL ) + return cOCT6100_ERR_CHANNEL_SOUT_BROADCAST_STREAM; + } + + /* Copy the general configuration.*/ + f_pChannelStats->ulUserChanId = pChanEntry->ulUserChanId; + f_pChannelStats->ulEchoOperationMode = pChanEntry->byEchoOperationMode; + f_pChannelStats->fEnableToneDisabler = pChanEntry->fEnableToneDisabler; + f_pChannelStats->ulMutePortsMask = pChanEntry->usMutedPorts; + f_pChannelStats->fEnableExtToneDetection = pChanEntry->fEnableExtToneDetection; + + + + /* Copy the TDM configuration.*/ + f_pChannelStats->TdmConfig.ulNumRoutBroadcastTssts = pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry; + f_pChannelStats->TdmConfig.ulNumSoutBroadcastTssts = pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry; + + f_pChannelStats->TdmConfig.ulSinNumTssts = pChanEntry->TdmConfig.bySinNumTssts; + f_pChannelStats->TdmConfig.ulSinTimeslot = pChanEntry->TdmConfig.usSinTimeslot; + f_pChannelStats->TdmConfig.ulSinStream = pChanEntry->TdmConfig.usSinStream; + f_pChannelStats->TdmConfig.ulSinPcmLaw = pChanEntry->TdmConfig.bySinPcmLaw; + + f_pChannelStats->TdmConfig.ulSoutNumTssts = pChanEntry->TdmConfig.bySoutNumTssts; + f_pChannelStats->TdmConfig.ulSoutTimeslot = pChanEntry->TdmConfig.usSoutTimeslot; + f_pChannelStats->TdmConfig.ulSoutStream = pChanEntry->TdmConfig.usSoutStream; + f_pChannelStats->TdmConfig.ulSoutPcmLaw = pChanEntry->TdmConfig.bySoutPcmLaw; + + /* Copy the SOUT Broadcast TSST into the Stream and timeslot array.*/ + usCurrentEntry = pChanEntry->TdmConfig.usSoutBrdcastTsstFirstEntry; + for( usTsstCount = 0; (usTsstCount < pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry) && (usTsstCount < f_pChannelStats->TdmConfig.ulMaxBroadcastTssts); usTsstCount++ ) + { + if ( usCurrentEntry == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_FATAL_F; + + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usCurrentEntry ); + + f_pChannelStats->TdmConfig.pulSoutBroadcastStream[ usTsstCount ] = pTsstEntry->usTsstValue & 0x1F; + f_pChannelStats->TdmConfig.pulSoutBroadcastStream[ usTsstCount ] = pTsstEntry->usTsstValue >> 5; + + /* Obtain the index of the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + } + + /* Check if all Sout Broadcast TSST were returned.*/ + if ( usTsstCount < pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry ) + { + f_pChannelStats->TdmConfig.fMoreSoutBroadcastTssts = TRUE; + } + else /* usTsstCount >= pChanEntry->TdmConfig.usSoutBrdcastTsstNumEntry */ + { + f_pChannelStats->TdmConfig.fMoreSoutBroadcastTssts = FALSE; + } + + f_pChannelStats->TdmConfig.ulRinNumTssts = pChanEntry->TdmConfig.byRinNumTssts; + f_pChannelStats->TdmConfig.ulRinTimeslot = pChanEntry->TdmConfig.usRinTimeslot; + f_pChannelStats->TdmConfig.ulRinStream = pChanEntry->TdmConfig.usRinStream; + f_pChannelStats->TdmConfig.ulRinPcmLaw = pChanEntry->TdmConfig.byRinPcmLaw; + + f_pChannelStats->TdmConfig.ulRoutNumTssts = pChanEntry->TdmConfig.byRoutNumTssts; + f_pChannelStats->TdmConfig.ulRoutTimeslot = pChanEntry->TdmConfig.usRoutTimeslot; + f_pChannelStats->TdmConfig.ulRoutStream = pChanEntry->TdmConfig.usRoutStream; + f_pChannelStats->TdmConfig.ulRoutPcmLaw = pChanEntry->TdmConfig.byRoutPcmLaw; + + + /* Copy the ROUT Broadcast TSST into the Stream and timeslot array.*/ + usCurrentEntry = pChanEntry->TdmConfig.usRoutBrdcastTsstFirstEntry; + for( usTsstCount = 0; (usTsstCount < pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry) && (usTsstCount < f_pChannelStats->TdmConfig.ulMaxBroadcastTssts); usTsstCount++ ) + { + if ( usCurrentEntry == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_FATAL_10; + + mOCT6100_GET_TSST_LIST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsstEntry, usCurrentEntry ); + + f_pChannelStats->TdmConfig.pulRoutBroadcastStream[ usTsstCount ] = pTsstEntry->usTsstValue & 0x1F; + f_pChannelStats->TdmConfig.pulRoutBroadcastStream[ usTsstCount ] = pTsstEntry->usTsstValue >> 5; + + /* Obtain the index of the next entry.*/ + usCurrentEntry = pTsstEntry->usNextEntry; + } + + /* Check if all Rout Broadcast TSST were returned.*/ + if ( usTsstCount < pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry ) + { + f_pChannelStats->TdmConfig.fMoreRoutBroadcastTssts = TRUE; + } + else /* usTsstCount >= pChanEntry->TdmConfig.usRoutBrdcastTsstNumEntry */ + { + f_pChannelStats->TdmConfig.fMoreRoutBroadcastTssts = FALSE; + } + + /* Copy the VQE configuration.*/ + f_pChannelStats->VqeConfig.fEnableNlp = pChanEntry->VqeConfig.fEnableNlp; + f_pChannelStats->VqeConfig.ulComfortNoiseMode = pChanEntry->VqeConfig.byComfortNoiseMode; + f_pChannelStats->VqeConfig.fEnableTailDisplacement = pChanEntry->VqeConfig.fEnableTailDisplacement; + if ( pChanEntry->VqeConfig.usTailDisplacement != cOCT6100_AUTO_SELECT_TAIL ) + f_pChannelStats->VqeConfig.ulTailDisplacement = pChanEntry->VqeConfig.usTailDisplacement; + else + f_pChannelStats->VqeConfig.ulTailDisplacement = f_pApiInstance->pSharedInfo->ChipConfig.usTailDisplacement; + + if ( pChanEntry->VqeConfig.usTailLength != cOCT6100_AUTO_SELECT_TAIL ) + f_pChannelStats->VqeConfig.ulTailLength = pChanEntry->VqeConfig.usTailLength; + else + f_pChannelStats->VqeConfig.ulTailLength = f_pApiInstance->pSharedInfo->ImageInfo.usMaxTailLength; + + + + f_pChannelStats->VqeConfig.fSinDcOffsetRemoval = pChanEntry->VqeConfig.fSinDcOffsetRemoval; + f_pChannelStats->VqeConfig.fRinDcOffsetRemoval = pChanEntry->VqeConfig.fRinDcOffsetRemoval; + f_pChannelStats->VqeConfig.fRinLevelControl = pChanEntry->VqeConfig.fRinLevelControl; + f_pChannelStats->VqeConfig.fSoutLevelControl = pChanEntry->VqeConfig.fSoutLevelControl; + f_pChannelStats->VqeConfig.fRinAutomaticLevelControl = pChanEntry->VqeConfig.fRinAutomaticLevelControl; + f_pChannelStats->VqeConfig.fSoutAutomaticLevelControl = pChanEntry->VqeConfig.fSoutAutomaticLevelControl; + f_pChannelStats->VqeConfig.fRinHighLevelCompensation = pChanEntry->VqeConfig.fRinHighLevelCompensation; + f_pChannelStats->VqeConfig.fSoutAdaptiveNoiseReduction = pChanEntry->VqeConfig.fSoutAdaptiveNoiseReduction; + f_pChannelStats->VqeConfig.fSoutNoiseBleaching = pChanEntry->VqeConfig.fSoutNoiseBleaching; + f_pChannelStats->VqeConfig.fSoutConferencingNoiseReduction = pChanEntry->VqeConfig.fSoutConferencingNoiseReduction; + f_pChannelStats->VqeConfig.lRinLevelControlGainDb = pChanEntry->VqeConfig.chRinLevelControlGainDb; + f_pChannelStats->VqeConfig.lSoutLevelControlGainDb = pChanEntry->VqeConfig.chSoutLevelControlGainDb; + f_pChannelStats->VqeConfig.lRinAutomaticLevelControlTargetDb = pChanEntry->VqeConfig.chRinAutomaticLevelControlTargetDb; + f_pChannelStats->VqeConfig.lSoutAutomaticLevelControlTargetDb = pChanEntry->VqeConfig.chSoutAutomaticLevelControlTargetDb; + f_pChannelStats->VqeConfig.lRinHighLevelCompensationThresholdDb = pChanEntry->VqeConfig.chRinHighLevelCompensationThresholdDb; + f_pChannelStats->VqeConfig.fAcousticEcho = pChanEntry->VqeConfig.fAcousticEcho; + f_pChannelStats->VqeConfig.fDtmfToneRemoval = pChanEntry->VqeConfig.fDtmfToneRemoval; + + f_pChannelStats->VqeConfig.lDefaultErlDb = pChanEntry->VqeConfig.chDefaultErlDb; + f_pChannelStats->VqeConfig.lAecDefaultErlDb = pChanEntry->VqeConfig.chAecDefaultErlDb; + f_pChannelStats->VqeConfig.ulAecTailLength = pChanEntry->VqeConfig.usAecTailLength; + f_pChannelStats->VqeConfig.lAnrSnrEnhancementDb = pChanEntry->VqeConfig.chAnrSnrEnhancementDb; + f_pChannelStats->VqeConfig.ulAnrVoiceNoiseSegregation = pChanEntry->VqeConfig.byAnrVoiceNoiseSegregation; + f_pChannelStats->VqeConfig.ulToneDisablerVqeActivationDelay = pChanEntry->VqeConfig.usToneDisablerVqeActivationDelay; + f_pChannelStats->VqeConfig.ulNonLinearityBehaviorA = pChanEntry->VqeConfig.byNonLinearityBehaviorA; + f_pChannelStats->VqeConfig.ulNonLinearityBehaviorB = pChanEntry->VqeConfig.byNonLinearityBehaviorB; + f_pChannelStats->VqeConfig.ulDoubleTalkBehavior = pChanEntry->VqeConfig.byDoubleTalkBehavior; + f_pChannelStats->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb; + f_pChannelStats->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb; + f_pChannelStats->VqeConfig.fSoutNaturalListenerEnhancement = pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement; + f_pChannelStats->VqeConfig.fRoutNoiseReduction = pChanEntry->VqeConfig.fRoutNoiseReduction; + f_pChannelStats->VqeConfig.lRoutNoiseReductionLevelGainDb = pChanEntry->VqeConfig.chRoutNoiseReductionLevelGainDb; + f_pChannelStats->VqeConfig.fEnableMusicProtection = pChanEntry->VqeConfig.fEnableMusicProtection; + f_pChannelStats->VqeConfig.fIdleCodeDetection = pChanEntry->VqeConfig.fIdleCodeDetection; + + /* Copy the CODEC configuration.*/ + f_pChannelStats->CodecConfig.ulAdpcmNibblePosition = pChanEntry->CodecConfig.byAdpcmNibblePosition; + + f_pChannelStats->CodecConfig.ulEncoderPort = pChanEntry->CodecConfig.byEncoderPort; + f_pChannelStats->CodecConfig.ulEncodingRate = pChanEntry->CodecConfig.byEncodingRate; + + f_pChannelStats->CodecConfig.ulDecoderPort = pChanEntry->CodecConfig.byDecoderPort; + f_pChannelStats->CodecConfig.ulDecodingRate = pChanEntry->CodecConfig.byDecodingRate; + + f_pChannelStats->CodecConfig.fEnableSilenceSuppression = pChanEntry->CodecConfig.fEnableSilenceSuppression; + f_pChannelStats->CodecConfig.ulPhase = pChanEntry->CodecConfig.byPhase; + f_pChannelStats->CodecConfig.ulPhasingType = pChanEntry->CodecConfig.byPhasingType; + + if ( pChanEntry->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingTsstEntry; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingTsstEntry, pChanEntry->usPhasingTsstIndex ); + + f_pChannelStats->CodecConfig.ulPhasingTsstHndl = cOCT6100_HNDL_TAG_PHASING_TSST | (pPhasingTsstEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pChanEntry->usPhasingTsstIndex; + } + else + { + f_pChannelStats->CodecConfig.ulPhasingTsstHndl = cOCT6100_INVALID_HANDLE; + } + + + /* Reset the stats and exit if the reset flag is set.*/ + if ( f_pChannelStats->fResetStats == TRUE ) + { + pChanEntry->sMaxERLE = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->sMaxERL = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->usMaxEchoDelay = cOCT6100_INVALID_STAT_W; + } + + /*---------------------------------------------------------------------*/ + /* Update the API internal stats.*/ + + BurstParams.ulReadAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + (usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ); + BurstParams.ulReadAddress += f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoStatsOfst; + BurstParams.ulReadLength = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoStatsSize / 2; /* Length in words.*/ + + mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the energy stat are found in the new memory location. */ + if ( ( pSharedInfo->ImageInfo.fRinEnergyStat == TRUE ) + && ( pSharedInfo->ImageInfo.fSoutEnergyStat == TRUE ) ) + { + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.RinEnergyStatFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.RinEnergyStatFieldOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.RinEnergyStatFieldOfst.byFieldSize; + + ReadParams.ulReadAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + (usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ); + ReadParams.ulReadAddress += f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst + ulFeatureBytesOffset; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulFeatureBitOffset < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulFeatureBitOffset < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= ulMask; + + /* Shift to get value. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + /* Overwrite value read the old way. */ + ausReadData[ 0 ] &= 0x00FF; + ausReadData[ 0 ] |= (UINT16)( ( ulTempData << 8 ) & 0xFF00 ); + + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.SoutEnergyStatFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.SoutEnergyStatFieldOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.SoutEnergyStatFieldOfst.byFieldSize; + + ReadParams.ulReadAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + (usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ); + ReadParams.ulReadAddress += f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst + ulFeatureBytesOffset; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulFeatureBitOffset < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulFeatureBitOffset < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= ulMask; + + /* Shift to get value. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + /* Overwrite value read the old way. */ + ausReadData[ 1 ] &= 0x00FF; + ausReadData[ 1 ] |= (UINT16)( ( ulTempData << 8 ) & 0xFF00 ); + } + + byRinEnergyRaw = (BYTE)(( ausReadData[ 0 ] >> 8 ) & 0xFF); + bySinEnergyRaw = (BYTE)(( ausReadData[ 0 ] >> 0 ) & 0xFF); + bySoutEnergyRaw = (BYTE)(( ausReadData[ 1 ] >> 8 ) & 0xFF); + byCnEnergyRaw = (BYTE)(( ausReadData[ 5 ] >> 8 ) & 0xFF); + + usEchoDelayInFrames = (UINT16)(ausReadData[ 4 ]); + usErlRaw = ausReadData[ 2 ]; + + pChanEntry->byToneDisablerStatus = (UINT8)(( ausReadData[ 5 ] >> 0 ) & 0xFF); + if ( f_pChannelStats->fResetStats == TRUE ) + { + pChanEntry->usNumEchoPathChangesOfst = (UINT16)(ausReadData[ 3 ]); + pChanEntry->usNumEchoPathChanges = 0; + } + else /* if ( f_pChannelStats->fResetStats == FALSE ) */ + { + pChanEntry->usNumEchoPathChanges = (UINT16)( ausReadData[ 3 ] - pChanEntry->usNumEchoPathChangesOfst ); + } + + pChanEntry->sComfortNoiseLevel = (INT16)( Oct6100ApiOctFloatToDbEnergyByte( byCnEnergyRaw ) & 0xFFFF ); + pChanEntry->sComfortNoiseLevel -= 12; + pChanEntry->sRinLevel = (INT16)( Oct6100ApiOctFloatToDbEnergyByte( byRinEnergyRaw ) & 0xFFFF ); + pChanEntry->sRinLevel -= 12; + pChanEntry->sSinLevel = (INT16)( Oct6100ApiOctFloatToDbEnergyByte( bySinEnergyRaw ) & 0xFFFF ); + pChanEntry->sSinLevel -= 12; + lSoutEnergyIndB = Oct6100ApiOctFloatToDbEnergyByte( bySoutEnergyRaw ); + lSoutEnergyIndB -= 12; + + /* Process some stats only if the channel is converged.*/ + if ( ( usEchoDelayInFrames != cOCT6100_INVALID_ECHO_DELAY ) + && ( pChanEntry->byEchoOperationMode != cOCT6100_ECHO_OP_MODE_POWER_DOWN ) + && ( pChanEntry->byEchoOperationMode != cOCT6100_ECHO_OP_MODE_HT_RESET ) ) + { + /* Update the current ERL. */ + pChanEntry->sCurrentERL = (INT16)( Oct6100ApiOctFloatToDbEnergyHalf( usErlRaw ) & 0xFFFF ); + pChanEntry->sCurrentERLE = (INT16)( ( lSoutEnergyIndB - pChanEntry->sSinLevel ) & 0xFFFF ); + pChanEntry->usCurrentEchoDelay = (UINT16)( usEchoDelayInFrames / 8 ); /* To convert in msec.*/ + + /* Update the max value if required.*/ + if ( pChanEntry->usCurrentEchoDelay > pChanEntry->usMaxEchoDelay || + pChanEntry->usMaxEchoDelay == cOCT6100_INVALID_STAT_W ) + { + pChanEntry->usMaxEchoDelay = pChanEntry->usCurrentEchoDelay; + } + + if ( pChanEntry->sCurrentERL > pChanEntry->sMaxERL || + pChanEntry->sMaxERL == cOCT6100_INVALID_SIGNED_STAT_W ) + { + pChanEntry->sMaxERL = pChanEntry->sCurrentERL; + } + + if ( pChanEntry->sCurrentERLE > pChanEntry->sMaxERLE || + pChanEntry->sMaxERLE == cOCT6100_INVALID_SIGNED_STAT_W ) + { + pChanEntry->sMaxERLE = pChanEntry->sCurrentERLE; + } + } + else + { + pChanEntry->sCurrentERLE = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->sCurrentERL = cOCT6100_INVALID_SIGNED_STAT_W; + pChanEntry->usCurrentEchoDelay = cOCT6100_INVALID_STAT_W; + } + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fRinAppliedGainStat == TRUE ) + { + /* Calculate base address for auto level control + high level compensation configuration. */ + ulBaseAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + ( usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.RinAppliedGainStatOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.RinAppliedGainStatOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.RinAppliedGainStatOfst.byFieldSize; + + ReadParams.ulReadAddress = ulBaseAddress + ulFeatureBytesOffset; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulFeatureBitOffset < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulFeatureBitOffset < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= ulMask; + + /* Shift to get value. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + pChanEntry->sRinAppliedGain = (INT16)( 2 * (INT16)( Oct6100ApiOctFloatToDbEnergyHalf( (UINT16)( ulTempData & 0xFFFF ) ) & 0xFFFF ) ); + } + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fSoutAppliedGainStat == TRUE ) + { + /* Calculate base address for auto level control + high level compensation configuration. */ + ulBaseAddress = f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemBase + ( usChanIndex * f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + ulFeatureBytesOffset = f_pApiInstance->pSharedInfo->MemoryMap.SoutAppliedGainStatOfst.usDwordOffset * 4; + ulFeatureBitOffset = f_pApiInstance->pSharedInfo->MemoryMap.SoutAppliedGainStatOfst.byBitOffset; + ulFeatureFieldLength = f_pApiInstance->pSharedInfo->MemoryMap.SoutAppliedGainStatOfst.byFieldSize; + + ReadParams.ulReadAddress = ulBaseAddress + ulFeatureBytesOffset; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulFeatureBitOffset < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulFeatureBitOffset < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= ulMask; + + /* Shift to get value. */ + ulTempData = ulTempData >> ulFeatureBitOffset; + + pChanEntry->sSoutAppliedGain = (INT16)( 2 * (INT16)( Oct6100ApiOctFloatToDbEnergyHalf( (UINT16)( ulTempData & 0xFFFF ) ) & 0xFFFF ) ); + } + + /*---------------------------------------------------------------------*/ + /* Return the real stats.*/ + + f_pChannelStats->ulNumEchoPathChanges = pChanEntry->usNumEchoPathChanges; + if ( usEchoDelayInFrames != cOCT6100_INVALID_ECHO_DELAY ) + { + f_pChannelStats->fEchoCancellerConverged = TRUE; + } + else + { + f_pChannelStats->fEchoCancellerConverged = FALSE; + } + if ( pChanEntry->sCurrentERL == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lCurrentERL = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lCurrentERL = pChanEntry->sCurrentERL; + + if ( pChanEntry->sMaxERL == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lMaxERL = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lMaxERL = pChanEntry->sMaxERL; + + if ( pChanEntry->usMaxEchoDelay == cOCT6100_INVALID_STAT_W ) + f_pChannelStats->ulMaxEchoDelay = cOCT6100_INVALID_STAT; + else + f_pChannelStats->ulMaxEchoDelay = pChanEntry->usMaxEchoDelay; + + if ( pChanEntry->sRinLevel == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lRinLevel = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lRinLevel = pChanEntry->sRinLevel; + + if ( pSharedInfo->ImageInfo.fSinLevel == TRUE ) + { + if ( pChanEntry->sSinLevel == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lSinLevel = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lSinLevel = pChanEntry->sSinLevel; + } + else /* if ( pSharedInfo->ImageInfo.fSinLevel != TRUE ) */ + { + /* SIN level is not supported in this image. */ + f_pChannelStats->lSinLevel = cOCT6100_INVALID_SIGNED_STAT; + } + + f_pChannelStats->lRinAppliedGain = pChanEntry->VqeConfig.chRinLevelControlGainDb; + if ( ( f_pApiInstance->pSharedInfo->ImageInfo.fRinAppliedGainStat == TRUE ) + && ( ( pChanEntry->VqeConfig.fRinAutomaticLevelControl == TRUE ) + || ( pChanEntry->VqeConfig.fRinHighLevelCompensation == TRUE ) ) ) + { + f_pChannelStats->lRinAppliedGain = pChanEntry->sRinAppliedGain; + } + + f_pChannelStats->lSoutAppliedGain = pChanEntry->VqeConfig.chSoutLevelControlGainDb; + if ( ( f_pApiInstance->pSharedInfo->ImageInfo.fSoutAppliedGainStat == TRUE ) + && ( pChanEntry->VqeConfig.fSoutAutomaticLevelControl == TRUE ) ) + { + f_pChannelStats->lSoutAppliedGain = pChanEntry->sSoutAppliedGain; + } + + if ( pChanEntry->usCurrentEchoDelay == cOCT6100_INVALID_STAT_W ) + f_pChannelStats->ulCurrentEchoDelay = cOCT6100_INVALID_STAT; + else + f_pChannelStats->ulCurrentEchoDelay = pChanEntry->usCurrentEchoDelay; + + if ( pSharedInfo->ImageInfo.fSinLevel == TRUE ) + { + if ( pChanEntry->sCurrentERLE == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lCurrentERLE = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lCurrentERLE = pChanEntry->sCurrentERLE; + } + else /* if ( pSharedInfo->ImageInfo.fSinLevel != TRUE ) */ + { + f_pChannelStats->lCurrentERLE = cOCT6100_INVALID_SIGNED_STAT; + } + + if ( pSharedInfo->ImageInfo.fSinLevel == TRUE ) + { + if ( pChanEntry->sMaxERLE == cOCT6100_INVALID_SIGNED_STAT_W ) + f_pChannelStats->lMaxERLE = cOCT6100_INVALID_SIGNED_STAT; + else + f_pChannelStats->lMaxERLE = pChanEntry->sMaxERLE; + } + else /* if ( pSharedInfo->ImageInfo.fSinLevel != TRUE ) */ + { + f_pChannelStats->lMaxERLE = cOCT6100_INVALID_SIGNED_STAT; + } + + f_pChannelStats->lComfortNoiseLevel = pChanEntry->sComfortNoiseLevel; + f_pChannelStats->ulToneDisablerStatus = pChanEntry->byToneDisablerStatus; + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fSinVoiceDetectedStat == TRUE ) + { + UINT32 ulVoiceDetectedBytesOfst = f_pApiInstance->pSharedInfo->MemoryMap.SinVoiceDetectedStatOfst.usDwordOffset * 4; + UINT32 ulVoiceDetectedBitOfst = f_pApiInstance->pSharedInfo->MemoryMap.SinVoiceDetectedStatOfst.byBitOffset; + UINT32 ulVoiceDetectedFieldSize = f_pApiInstance->pSharedInfo->MemoryMap.SinVoiceDetectedStatOfst.byFieldSize; + + /* Set the channel root base address.*/ + UINT32 ulChannelRootBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( usChanIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanRootConfOfst; + + ReadParams.ulReadAddress = ulChannelRootBaseAddress + ulVoiceDetectedBytesOfst; + + /* Optimize this access by only reading the word we are interested in. */ + if ( ulVoiceDetectedBitOfst < 16 ) + ReadParams.ulReadAddress += 2; + + /* Must read in memory directly since this value is changed by hardware */ + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Move data at correct position according to what was read. */ + if ( ulVoiceDetectedBitOfst < 16 ) + ulTempData = usReadData; + else + ulTempData = usReadData << 16; + + mOCT6100_CREATE_FEATURE_MASK( ulVoiceDetectedFieldSize, ulVoiceDetectedBitOfst, &ulMask ); + + if ( ( ulTempData & ulMask ) != 0x0 ) + f_pChannelStats->fSinVoiceDetected = TRUE; + else + f_pChannelStats->fSinVoiceDetected = FALSE; + } + + /*---------------------------------------------------------------------*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveEchoEntry + +Description: Reserves one of the echo channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusEchoIndex Resulting index reserved in the echo channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveEchoEntry +UINT32 Oct6100ApiReserveEchoEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusEchoIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pEchoAlloc; + UINT32 ulResult; + UINT32 ulEchoIndex; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ALLOC_PNT( pSharedInfo, pEchoAlloc ) + + ulResult = OctapiLlmAllocAlloc( pEchoAlloc, &ulEchoIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_CHANNEL_ALL_CHANNELS_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_11; + } + + *f_pusEchoIndex = (UINT16)( ulEchoIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseEchoEntry + +Description: Releases the specified ECHO channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usEchoIndex Index reserved in the echo channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseEchoEntry +UINT32 Oct6100ApiReleaseEchoEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEchoIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pEchoAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_CHANNEL_ALLOC_PNT( pSharedInfo, pEchoAlloc ) + + ulResult = OctapiLlmAllocDealloc( pEchoAlloc, f_usEchoIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_12; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBiDirChanEntry + +Description: Reserves one of the bidirectional channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pusBiDirChanIndex Resulting index reserved in the bidir channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBiDirChanEntry +UINT32 Oct6100ApiReserveBiDirChanEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusBiDirChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pChanAlloc; + UINT32 ulResult; + UINT32 ulBiDirChanIndex; + + /* Get local pointer to shared portion of the API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_BIDIR_CHANNEL_ALLOC_PNT( pSharedInfo, pChanAlloc ) + + ulResult = OctapiLlmAllocAlloc( pChanAlloc, &ulBiDirChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == OCTAPI_LLM_NO_STRUCTURES_LEFT ) + return cOCT6100_ERR_CHANNEL_ALL_BIDIR_CHANNELS_ARE_OPENED; + else + return cOCT6100_ERR_FATAL_9F; + } + + *f_pusBiDirChanIndex = (UINT16)( ulBiDirChanIndex & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBiDirChanEntry + +Description: Releases the specified bidirectional channel API entry. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulBiDirChanIndex Bidirectional channel index within the API's Bidir channel list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBiDirChanEntry +UINT32 Oct6100ApiReleaseBiDirChanEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBiDirChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + PVOID pChanAlloc; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_BIDIR_CHANNEL_ALLOC_PNT( pSharedInfo, pChanAlloc ) + + ulResult = OctapiLlmAllocDealloc( pChanAlloc, f_ulBiDirChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + { + return cOCT6100_ERR_FATAL_A0; + } + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckTdmConfig + +Description: This function will check the validity of the TDM config parameter + of an Open TDM config structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pTdmConfig TDM config of the channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckTdmConfig +UINT32 Oct6100ApiCheckTdmConfig( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig ) +{ + UINT32 ulResult; + + /*==============================================================================*/ + /* Check the TDM configuration parameters.*/ + + /* Check the validity of the timeslot and Stream only if it is defined.*/ + if ( f_pTdmConfig->ulRinTimeslot != cOCT6100_UNASSIGNED || + f_pTdmConfig->ulRinStream != cOCT6100_UNASSIGNED ) + { + if ( f_pTdmConfig->ulRinNumTssts != 1 && + f_pTdmConfig->ulRinNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_RIN_NUM_TSSTS; + + /* Check the RIN TDM streams, timeslots component for errors.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pTdmConfig->ulRinNumTssts, + f_pTdmConfig->ulRinTimeslot, + f_pTdmConfig->ulRinStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_RIN_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_RIN_STREAM; + } + else + { + return ulResult; + } + } + } + + /* Check the validity of the timeslot and Stream only if it is defined.*/ + if ( f_pTdmConfig->ulRoutTimeslot != cOCT6100_UNASSIGNED || + f_pTdmConfig->ulRoutStream != cOCT6100_UNASSIGNED ) + { + if ( f_pTdmConfig->ulRoutNumTssts != 1 && + f_pTdmConfig->ulRoutNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_ROUT_NUM_TSSTS; + + /* Check the ROUT TDM streams, timeslots component for errors.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pTdmConfig->ulRoutNumTssts, + f_pTdmConfig->ulRoutTimeslot, + f_pTdmConfig->ulRoutStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_ROUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_ROUT_STREAM; + } + else + { + return ulResult; + } + } + } + + /* Check the validity of the timeslot and Stream only if it is defined.*/ + if ( f_pTdmConfig->ulSinTimeslot != cOCT6100_UNASSIGNED || + f_pTdmConfig->ulSinStream != cOCT6100_UNASSIGNED ) + { + if ( f_pTdmConfig->ulSinNumTssts != 1 && + f_pTdmConfig->ulSinNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_SIN_NUM_TSSTS; + + /* Check the SIN TDM streams, timeslots component for errors.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pTdmConfig->ulSinNumTssts, + f_pTdmConfig->ulSinTimeslot, + f_pTdmConfig->ulSinStream, + cOCT6100_INPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_SIN_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_SIN_STREAM; + } + else + { + return ulResult; + } + } + } + + /* Check the validity of the timeslot and Stream only if it is defined.*/ + if ( f_pTdmConfig->ulSoutTimeslot != cOCT6100_UNASSIGNED || + f_pTdmConfig->ulSoutStream != cOCT6100_UNASSIGNED ) + { + if ( f_pTdmConfig->ulSoutNumTssts != 1 && + f_pTdmConfig->ulSoutNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_SOUT_NUM_TSSTS; + + /* Check the ROUT TDM streams, timeslots component for errors.*/ + ulResult = Oct6100ApiValidateTsst( f_pApiInstance, + f_pTdmConfig->ulSoutNumTssts, + f_pTdmConfig->ulSoutTimeslot, + f_pTdmConfig->ulSoutStream, + cOCT6100_OUTPUT_TSST ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_TSST_TIMESLOT ) + { + return cOCT6100_ERR_CHANNEL_SOUT_TIMESLOT; + } + else if ( ulResult == cOCT6100_ERR_TSST_STREAM ) + { + return cOCT6100_ERR_CHANNEL_SOUT_STREAM; + } + else + { + return ulResult; + } + } + } + + /* Check the PCM law parameters.*/ + if ( f_pTdmConfig->ulRinPcmLaw != cOCT6100_PCM_U_LAW && + f_pTdmConfig->ulRinPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_CHANNEL_RIN_PCM_LAW; + + if ( f_pTdmConfig->ulSinPcmLaw != cOCT6100_PCM_U_LAW && + f_pTdmConfig->ulSinPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_CHANNEL_SIN_PCM_LAW; + + if ( f_pTdmConfig->ulRoutPcmLaw != cOCT6100_PCM_U_LAW && + f_pTdmConfig->ulRoutPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_CHANNEL_ROUT_PCM_LAW; + + if ( f_pTdmConfig->ulSoutPcmLaw != cOCT6100_PCM_U_LAW && + f_pTdmConfig->ulSoutPcmLaw != cOCT6100_PCM_A_LAW ) + return cOCT6100_ERR_CHANNEL_SOUT_PCM_LAW; + + /*==============================================================================*/ + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckVqeConfig + +Description: This function will check the validity of the VQE config parameter + of an Open VQE config structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig VQE config of the channel. +f_fEnableToneDisabler Whether the tone disabler is active or not. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckVqeConfig +UINT32 Oct6100ApiCheckVqeConfig( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN BOOL f_fEnableToneDisabler ) +{ + tPOCT6100_API_IMAGE_INFO pImageInfo; + + pImageInfo = &f_pApiInstance->pSharedInfo->ImageInfo; + + if ( f_pVqeConfig->fEnableNlp != TRUE && f_pVqeConfig->fEnableNlp != FALSE ) + return cOCT6100_ERR_CHANNEL_ENABLE_NLP; + + if ( f_pVqeConfig->fEnableNlp == TRUE && pImageInfo->fNlpControl == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NLP_CONTROL; + + + + /* Check the comfort noise mode.*/ + if ( f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_OFF && pImageInfo->fComfortNoise == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_BKG_NOISE_FREEZE; + + if ( f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_NORMAL && + f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_EXTENDED && + f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_FAST_LATCH && + f_pVqeConfig->ulComfortNoiseMode != cOCT6100_COMFORT_NOISE_OFF ) + return cOCT6100_ERR_CHANNEL_COMFORT_NOISE_MODE; + + /* Check the DC offset removal.*/ + if ( f_pVqeConfig->fSinDcOffsetRemoval != TRUE && f_pVqeConfig->fSinDcOffsetRemoval != FALSE ) + return cOCT6100_ERR_CHANNEL_SIN_DC_OFFSET_REM; + + if ( f_pVqeConfig->fSinDcOffsetRemoval == TRUE && pImageInfo->fSinDcOffsetRemoval == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIN_DC_OFFSET_REM; + + if ( f_pVqeConfig->fRinDcOffsetRemoval != TRUE && f_pVqeConfig->fRinDcOffsetRemoval != FALSE ) + return cOCT6100_ERR_CHANNEL_RIN_DC_OFFSET_REM; + + if ( f_pVqeConfig->fRinDcOffsetRemoval == TRUE && pImageInfo->fRinDcOffsetRemoval == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_DC_OFFSET_REM; + + /* Check the Level control.*/ + if ( f_pVqeConfig->fRinLevelControl != TRUE && f_pVqeConfig->fRinLevelControl != FALSE ) + return cOCT6100_ERR_CHANNEL_RIN_LEVEL_CONTROL; + + if ( f_pVqeConfig->fSoutLevelControl != TRUE && f_pVqeConfig->fSoutLevelControl != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_LEVEL_CONTROL; + + if ( ( f_pVqeConfig->lRinLevelControlGainDb < -24 ) || ( f_pVqeConfig->lRinLevelControlGainDb > 24 ) ) + return cOCT6100_ERR_CHANNEL_RIN_LEVEL_CONTROL_GAIN; + + if ( ( f_pVqeConfig->lSoutLevelControlGainDb < -24 ) || ( f_pVqeConfig->lSoutLevelControlGainDb > 24 ) ) + return cOCT6100_ERR_CHANNEL_SOUT_LEVEL_CONTROL_GAIN; + + if ( ( f_pVqeConfig->fRinAutomaticLevelControl != TRUE ) && ( f_pVqeConfig->fRinAutomaticLevelControl != FALSE ) ) + return cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL; + + if ( ( f_pVqeConfig->fRinHighLevelCompensation != TRUE ) && ( f_pVqeConfig->fRinHighLevelCompensation != FALSE ) ) + return cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP; + + if ( ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) && ( pImageInfo->fRinAutoLevelControl == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_AUTO_LC; + + if ( ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) && ( pImageInfo->fRinHighLevelCompensation == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_RIN_HIGH_LEVEL_COMP; + + if ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + { + if ( f_pVqeConfig->fRinLevelControl == TRUE ) + return cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_MANUAL; + + if ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) + return cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_HIGH_LEVEL_COMP; + + if ( ( f_pVqeConfig->lRinAutomaticLevelControlTargetDb < -40 || f_pVqeConfig->lRinAutomaticLevelControlTargetDb > 0 ) ) + return cOCT6100_ERR_CHANNEL_RIN_AUTO_LEVEL_CONTROL_TARGET; + } + + if ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) + { + if ( f_pVqeConfig->fRinLevelControl == TRUE ) + return cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP_MANUAL; + + if ( ( f_pVqeConfig->lRinHighLevelCompensationThresholdDb < -40 || f_pVqeConfig->lRinHighLevelCompensationThresholdDb > 0 ) ) + return cOCT6100_ERR_CHANNEL_RIN_HIGH_LEVEL_COMP_THRESHOLD; + } + + if ( f_pVqeConfig->fSoutAutomaticLevelControl != TRUE && f_pVqeConfig->fSoutAutomaticLevelControl != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL; + + if ( ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) && ( pImageInfo->fSoutAutoLevelControl == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SOUT_AUTO_LC; + + if ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) + { + if ( f_pVqeConfig->fSoutLevelControl == TRUE ) + return cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_MANUAL; + + if ( ( f_pVqeConfig->lSoutAutomaticLevelControlTargetDb < -40 || f_pVqeConfig->lSoutAutomaticLevelControlTargetDb > 0 ) ) + return cOCT6100_ERR_CHANNEL_SOUT_AUTO_LEVEL_CONTROL_TARGET; + } + + if ( f_pVqeConfig->fSoutAdaptiveNoiseReduction != TRUE && + f_pVqeConfig->fSoutAdaptiveNoiseReduction != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_ADAPT_NOISE_REDUCTION; + + if ( f_pVqeConfig->fSoutAdaptiveNoiseReduction == TRUE && pImageInfo->fAdaptiveNoiseReduction == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR; + + if ( f_pVqeConfig->fSoutConferencingNoiseReduction != TRUE && + f_pVqeConfig->fSoutConferencingNoiseReduction != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_CONFERENCE_NOISE_REDUCTION; + + if ( f_pVqeConfig->fSoutConferencingNoiseReduction == TRUE && pImageInfo->fConferencingNoiseReduction == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_CNR; + + /* Validate Sout noise bleaching parameter. */ + if ( f_pVqeConfig->fSoutNoiseBleaching != TRUE && + f_pVqeConfig->fSoutNoiseBleaching != FALSE ) + return cOCT6100_ERR_CHANNEL_SOUT_NOISE_BLEACHING; + + /* Check if firmware supports Sout noise bleaching. */ + if ( f_pVqeConfig->fSoutNoiseBleaching == TRUE && pImageInfo->fSoutNoiseBleaching == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NOISE_BLEACHING; + + /* If Sout noise bleaching is requested, no ANR or CNR shall be activated. */ + if ( f_pVqeConfig->fSoutNoiseBleaching == TRUE ) + { + /* No xNR! */ + if ( ( f_pVqeConfig->fSoutConferencingNoiseReduction == TRUE ) + || ( f_pVqeConfig->fSoutAdaptiveNoiseReduction == TRUE ) ) + return cOCT6100_ERR_CHANNEL_SOUT_NOISE_BLEACHING_NR; + } + + /* Cannot activate both ANR and CNR when noise bleaching is present */ + if ( pImageInfo->fSoutNoiseBleaching == TRUE ) + { + if ( f_pVqeConfig->fSoutAdaptiveNoiseReduction == TRUE && + f_pVqeConfig->fSoutConferencingNoiseReduction == TRUE ) + return cOCT6100_ERR_CHANNEL_ANR_CNR_SIMULTANEOUSLY; + } + + /* Validate the DTMF tone removal parameter.*/ + if ( f_pVqeConfig->fDtmfToneRemoval != TRUE && f_pVqeConfig->fDtmfToneRemoval != FALSE ) + return cOCT6100_ERR_CHANNEL_TONE_REMOVAL; + + if ( f_pVqeConfig->fDtmfToneRemoval == TRUE && pImageInfo->fToneRemoval == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TONE_REMOVAL; + + + + /* Check the Tail displacement enable.*/ + if ( f_pVqeConfig->fEnableTailDisplacement != TRUE && f_pVqeConfig->fEnableTailDisplacement != FALSE ) + return cOCT6100_ERR_CHANNEL_ENABLE_TAIL_DISPLACEMENT; + + if ( f_pVqeConfig->fEnableTailDisplacement == TRUE && pImageInfo->fTailDisplacement == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TAIL_DISPLACEMENT; + + /* Check the Tail displacement value.*/ + if ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + { + if ( f_pVqeConfig->ulTailDisplacement != cOCT6100_AUTO_SELECT_TAIL ) + { + /* Check if this feature is supported by the image. */ + if ( pImageInfo->fPerChannelTailDisplacement == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_PER_CHAN_TAIL; + + /* Check that this value is not greater then what the image supports. */ + if ( f_pVqeConfig->ulTailDisplacement > pImageInfo->usMaxTailDisplacement ) + return cOCT6100_ERR_CHANNEL_TAIL_DISPLACEMENT_INVALID; + } + } + + /* Check the tail length value. */ + if ( f_pVqeConfig->ulTailLength != cOCT6100_AUTO_SELECT_TAIL ) + { + /* Check if this feature is supported by the image. */ + if ( ( pImageInfo->fPerChannelTailLength == FALSE ) + && ( (UINT16)( f_pVqeConfig->ulTailLength & 0xFFFF ) != pImageInfo->usMaxTailLength ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TAIL_LENGTH; + + if ( ( f_pVqeConfig->ulTailLength < 32 ) || ( f_pVqeConfig->ulTailLength > 128 ) + || ( ( f_pVqeConfig->ulTailLength % 4 ) != 0x0 ) ) + return cOCT6100_ERR_CHANNEL_TAIL_LENGTH; + + /* Check if the requested tail length is supported by the chip. */ + if ( f_pVqeConfig->ulTailLength > pImageInfo->usMaxTailLength ) + return cOCT6100_ERR_CHANNEL_TAIL_LENGTH_INVALID; + } + + /* Validate the acoustic echo cancellation parameter.*/ + if ( f_pVqeConfig->fAcousticEcho != TRUE && f_pVqeConfig->fAcousticEcho != FALSE ) + return cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO; + + if ( f_pVqeConfig->fAcousticEcho == TRUE && pImageInfo->fAcousticEcho == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ACOUSTIC_ECHO; + + if ( f_pVqeConfig->fAcousticEcho == TRUE ) + { + /* Check if acoustic echo tail length configuration is supported in the image. */ + if ( ( f_pVqeConfig->ulAecTailLength != 128 ) && ( pImageInfo->fAecTailLength == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ACOUSTIC_ECHO_TAIL_LENGTH; + + /* Check the requested acoustic echo tail length. */ + if ( ( f_pVqeConfig->ulAecTailLength != 128 ) + && ( f_pVqeConfig->ulAecTailLength != 256 ) + && ( f_pVqeConfig->ulAecTailLength != 512 ) + && ( f_pVqeConfig->ulAecTailLength != 1024 ) ) + return cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_TAIL_LENGTH; + + if ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + { + UINT32 ulTailSum; + + /* Start with requested tail displacement. */ + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum = f_pApiInstance->pSharedInfo->ChipConfig.usTailDisplacement; + } + else + { + ulTailSum = f_pVqeConfig->ulTailDisplacement; + } + + /* Add requested tail length. */ + if ( f_pVqeConfig->ulTailLength == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum += f_pApiInstance->pSharedInfo->ImageInfo.usMaxTailLength; + } + else + { + ulTailSum += f_pVqeConfig->ulTailLength; + } + + /* The tail sum must be smaller then the requested AEC tail length. */ + if ( ulTailSum > f_pVqeConfig->ulAecTailLength ) + return cOCT6100_ERR_CHANNEL_ACOUSTIC_ECHO_TAIL_SUM; + } + } + + /* Validate the Default ERL parameter.*/ + if ( f_pVqeConfig->lDefaultErlDb != -6 && pImageInfo->fDefaultErl == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DEFAULT_ERL; + + if ( ( f_pVqeConfig->lDefaultErlDb != 0 ) && + ( f_pVqeConfig->lDefaultErlDb != -3 ) && + ( f_pVqeConfig->lDefaultErlDb != -6 ) && + ( f_pVqeConfig->lDefaultErlDb != -9 ) && + ( f_pVqeConfig->lDefaultErlDb != -12 ) ) + return cOCT6100_ERR_CHANNEL_DEFAULT_ERL; + + /* Validate the Default AEC ERL parameter.*/ + if ( f_pVqeConfig->lAecDefaultErlDb != 0 && pImageInfo->fAecDefaultErl == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_AEC_DEFAULT_ERL; + + if ( f_pVqeConfig->lAecDefaultErlDb != 0 && f_pVqeConfig->lAecDefaultErlDb != -3 && f_pVqeConfig->lAecDefaultErlDb != -6 ) + return cOCT6100_ERR_CHANNEL_AEC_DEFAULT_ERL; + + /* Validate the non-linearity A parameter.*/ + if ( f_pVqeConfig->ulNonLinearityBehaviorA != 1 && pImageInfo->fNonLinearityBehaviorA == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DOUBLE_TALK; + + if ( f_pVqeConfig->ulNonLinearityBehaviorA >= 14 ) + return cOCT6100_ERR_CHANNEL_DOUBLE_TALK; + + /* Validate the non-linearity B parameter.*/ + if ( f_pVqeConfig->ulNonLinearityBehaviorB != 0 && pImageInfo->fNonLinearityBehaviorB == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NON_LINEARITY_B; + + if ( f_pVqeConfig->ulNonLinearityBehaviorB >= 9 ) + return cOCT6100_ERR_CHANNEL_NON_LINEARITY_B; + + /* Check if configuring the double talk behavior is supported in the firmware. */ + if ( f_pVqeConfig->ulDoubleTalkBehavior != cOCT6100_DOUBLE_TALK_BEH_NORMAL && pImageInfo->fDoubleTalkBehavior == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_DOUBLE_TALK_BEHAVIOR_MODE; + + /* Validate the double talk behavior mode parameter. */ + if ( f_pVqeConfig->ulDoubleTalkBehavior != cOCT6100_DOUBLE_TALK_BEH_NORMAL && f_pVqeConfig->ulDoubleTalkBehavior != cOCT6100_DOUBLE_TALK_BEH_LESS_AGGRESSIVE ) + return cOCT6100_ERR_CHANNEL_DOUBLE_TALK_MODE; + + /* Validate the Sout automatic listener enhancement ratio. */ + if ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0 && pImageInfo->fListenerEnhancement == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ALE; + + if ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb > 30 ) + return cOCT6100_ERR_CHANNEL_ALE_RATIO; + + /* Validate the Sout natural listener enhancement ratio. */ + if ( f_pVqeConfig->fSoutNaturalListenerEnhancement != TRUE && f_pVqeConfig->fSoutNaturalListenerEnhancement != FALSE ) + return cOCT6100_ERR_CHANNEL_NLE_FLAG; + + if ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE && pImageInfo->fListenerEnhancement == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_NLE; + + if ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE ) + { + if ( f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb > 30 ) + return cOCT6100_ERR_CHANNEL_NLE_RATIO; + } + + /* Both ALE and NLE cannot be activated simultaneously. */ + if ( ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0 ) + && ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE ) ) + return cOCT6100_ERR_CHANNEL_ALE_NLE_SIMULTANEOUSLY; + + /* Validate Rout noise reduction. */ + if ( f_pVqeConfig->fRoutNoiseReduction != TRUE && f_pVqeConfig->fRoutNoiseReduction != FALSE ) + return cOCT6100_ERR_CHANNEL_ROUT_NOISE_REDUCTION; + + /* Check if Rout noise reduction is supported. */ + if ( f_pVqeConfig->fRoutNoiseReduction == TRUE && pImageInfo->fRoutNoiseReduction == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ROUT_NR; + + /*Check if noise reduction level gain is supported*/ + if ( ( pImageInfo->fRoutNoiseReductionLevel == FALSE ) && ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != -18 ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ROUT_NOISE_REDUCTION_GAIN; + + if ( ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != 0 ) && + ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != -6 ) && + ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != -12 ) && + ( f_pVqeConfig->lRoutNoiseReductionLevelGainDb != -18 ) ) + + return cOCT6100_ERR_CHANNEL_ROUT_NOISE_REDUCTION_GAIN; + + /* Check if ANR SNRE is supported. */ + if ( ( f_pVqeConfig->lAnrSnrEnhancementDb != -18 ) && ( pImageInfo->fAnrSnrEnhancement == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR_SNR_ENHANCEMENT; + + /* Validate Sout ANR SNR enhancement. */ + if ( ( f_pVqeConfig->lAnrSnrEnhancementDb != -9 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -12 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -15 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -18 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -21 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -24 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -27 ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != -30 ) ) + return cOCT6100_ERR_CHANNEL_ANR_SNR_ENHANCEMENT; + + /* Validate ANR voice-noise segregation. */ + if ( f_pVqeConfig->ulAnrVoiceNoiseSegregation > 15 ) + return cOCT6100_ERR_CHANNEL_ANR_SEGREGATION; + + /* Check if ANR VN segregation is supported. */ + if ( ( f_pVqeConfig->ulAnrVoiceNoiseSegregation != 6 ) && ( pImageInfo->fAnrVoiceNoiseSegregation == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ANR_SEGREGATION; + + /* Check if the loaded image supports tone disabler VQE activation delay. */ + if ( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay != 300 ) + && ( pImageInfo->fToneDisablerVqeActivationDelay == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_TONE_DISABLER_ACTIVATION_DELAY; + + /* Check if the specified tone disabler VQE activation delay is correct. */ + if ( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay < 300 ) + || ( ( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay - 300 ) % 512 ) != 0 ) ) + return cOCT6100_ERR_CHANNEL_TONE_DISABLER_ACTIVATION_DELAY; + + /* Check the enable music protection flag. */ + if ( ( f_pVqeConfig->fEnableMusicProtection != TRUE ) && ( f_pVqeConfig->fEnableMusicProtection != FALSE ) ) + return cOCT6100_ERR_CHANNEL_ENABLE_MUSIC_PROTECTION; + + /* The music protection module can only be activated if the image supports it. */ + if ( ( f_pVqeConfig->fEnableMusicProtection == TRUE ) && + ( pImageInfo->fMusicProtection == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_MUSIC_PROTECTION; + + /* Check the enable idle code detection flag. */ + if ( ( f_pVqeConfig->fIdleCodeDetection != TRUE ) && ( f_pVqeConfig->fIdleCodeDetection != FALSE ) ) + return cOCT6100_ERR_CHANNEL_IDLE_CODE_DETECTION; + + /* The idle code detection module can only be activated if the image supports it. */ + if ( ( f_pVqeConfig->fIdleCodeDetection == TRUE ) && ( pImageInfo->fIdleCodeDetection == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_IDLE_CODE_DETECTION; + + /* The idle code detection module can be disabled only if idle code detection configuration */ + /* is supported in the image. */ + if ( pImageInfo->fIdleCodeDetection == TRUE ) + { + if ( ( f_pVqeConfig->fIdleCodeDetection == FALSE ) && ( pImageInfo->fIdleCodeDetectionConfiguration == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_IDLE_CODE_DETECTION_CONFIG; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckCodecConfig + +Description: This function will check the validity of the Codec config parameter + of an Open Codec config structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pCodecConfig Codec config of the channel. +f_ulDecoderNumTssts Number of TSST for the decoder. +f_pusPhasingTsstIndex Pointer to the Phasing TSST index within the API's phasing TSST list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckCodecConfig +UINT32 Oct6100ApiCheckCodecConfig( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_CODEC f_pCodecConfig, + IN UINT32 f_ulDecoderNumTssts, + OUT PUINT16 f_pusPhasingTsstIndex ) +{ + + /* Verify the ADPCM nibble value.*/ + if ( f_pCodecConfig->ulAdpcmNibblePosition != cOCT6100_ADPCM_IN_LOW_BITS && + f_pCodecConfig->ulAdpcmNibblePosition != cOCT6100_ADPCM_IN_HIGH_BITS ) + return cOCT6100_ERR_CHANNEL_ADPCM_NIBBLE; + + /* Verify the Encoder port.*/ + if ( f_pCodecConfig->ulEncoderPort != cOCT6100_CHANNEL_PORT_ROUT && + f_pCodecConfig->ulEncoderPort != cOCT6100_CHANNEL_PORT_SOUT && + f_pCodecConfig->ulEncoderPort != cOCT6100_NO_ENCODING ) + return cOCT6100_ERR_CHANNEL_ENCODER_PORT; + + /* Verify the Decoder port.*/ + if ( f_pCodecConfig->ulDecoderPort != cOCT6100_CHANNEL_PORT_RIN && + f_pCodecConfig->ulDecoderPort != cOCT6100_CHANNEL_PORT_SIN && + f_pCodecConfig->ulDecoderPort != cOCT6100_NO_DECODING ) + return cOCT6100_ERR_CHANNEL_DECODER_PORT; + + /* The codec cannot be on the same stream.*/ + if ( f_pCodecConfig->ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT && + f_pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + return cOCT6100_ERR_CHANNEL_INVALID_CODEC_POSITION; + + if ( f_pCodecConfig->ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT && + f_pCodecConfig->ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN ) + return cOCT6100_ERR_CHANNEL_INVALID_CODEC_POSITION; + + /* Verify if the requested functions are supported by the chip.*/ + if ( f_pApiInstance->pSharedInfo->ImageInfo.fAdpcm == FALSE && + f_pCodecConfig->ulEncoderPort != cOCT6100_NO_ENCODING ) + { + if ( f_pCodecConfig->ulEncodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_ENCODING; + } + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fAdpcm == FALSE && + f_pCodecConfig->ulDecoderPort != cOCT6100_NO_DECODING ) + { + if ( f_pCodecConfig->ulDecodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_DECODING; + } + + /* Check if encoder port has been specified when a rate has been set. */ + if ( f_pCodecConfig->ulEncoderPort == cOCT6100_NO_ENCODING && + f_pCodecConfig->ulEncodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_CHANNEL_ENCODER_PORT; + + /* Check if decoder port has been specified when a rate has been set. */ + if ( f_pCodecConfig->ulDecoderPort == cOCT6100_NO_DECODING && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_64KBPS ) + return cOCT6100_ERR_CHANNEL_DECODER_PORT; + + /* Check Encoder related parameter if one is used.*/ + if ( f_pCodecConfig->ulEncoderPort != cOCT6100_NO_ENCODING ) + { + /* Check the Encoder compression rate.*/ + if ( ( f_pCodecConfig->ulEncodingRate != cOCT6100_G711_64KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G726_40KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G726_32KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G726_24KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G726_16KBPS ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_40KBPS_4_1 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_40KBPS_3_2 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_40KBPS_2_3 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_32KBPS_4_0 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_32KBPS_3_1 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_32KBPS_2_2 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_24KBPS_3_0 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_24KBPS_2_1 ) && + ( f_pCodecConfig->ulEncodingRate != cOCT6100_G727_16KBPS_2_0 ) ) + return cOCT6100_ERR_CHANNEL_ENCODING_RATE; + + /* Verify phasing information.*/ + if ( f_pCodecConfig->ulPhasingType != cOCT6100_SINGLE_PHASING && + f_pCodecConfig->ulPhasingType != cOCT6100_DUAL_PHASING && + f_pCodecConfig->ulPhasingType != cOCT6100_NO_PHASING ) + return cOCT6100_ERR_CHANNEL_PHASING_TYPE; + + /* Verify the silence suppression parameters.*/ + if ( f_pCodecConfig->fEnableSilenceSuppression != TRUE && + f_pCodecConfig->fEnableSilenceSuppression != FALSE ) + return cOCT6100_ERR_CHANNEL_SIL_SUP_ENABLE; + + if ( f_pCodecConfig->fEnableSilenceSuppression == TRUE && + f_pApiInstance->pSharedInfo->ImageInfo.fSilenceSuppression == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIL_SUP; + + if ( f_pCodecConfig->fEnableSilenceSuppression == TRUE && + f_pCodecConfig->ulPhasingType == cOCT6100_NO_PHASING ) + return cOCT6100_ERR_CHANNEL_PHASE_TYPE_REQUIRED; + + if ( f_pCodecConfig->fEnableSilenceSuppression == TRUE && + f_pCodecConfig->ulPhasingTsstHndl == cOCT6100_INVALID_HANDLE ) + return cOCT6100_ERR_CHANNEL_PHASING_TSST_REQUIRED; + + if ( f_pCodecConfig->ulPhasingTsstHndl == cOCT6100_INVALID_HANDLE && + f_pCodecConfig->ulPhasingType != cOCT6100_NO_PHASING ) + return cOCT6100_ERR_CHANNEL_PHASING_TSST_REQUIRED; + + /* Silence suppression can only be performed if the encoder is using the SOUT port.*/ + if ( f_pCodecConfig->fEnableSilenceSuppression == TRUE && + f_pCodecConfig->ulEncoderPort != cOCT6100_CHANNEL_PORT_SOUT ) + return cOCT6100_ERR_CHANNEL_SIL_SUP_INVALID_ENCODER_PORT; + + /* Check phasing TSST info if phasing is required.*/ + if ( f_pCodecConfig->ulPhasingTsstHndl != cOCT6100_INVALID_HANDLE ) + { + tPOCT6100_API_PHASING_TSST pPhasingEntry; + UINT32 ulEntryOpenCnt; + + /* Check the provided handle. */ + if ( (f_pCodecConfig->ulPhasingTsstHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_PHASING_TSST ) + return cOCT6100_ERR_CHANNEL_INVALID_PHASING_HANDLE; + + *f_pusPhasingTsstIndex = (UINT16)( f_pCodecConfig->ulPhasingTsstHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusPhasingTsstIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxPhasingTssts ) + return cOCT6100_ERR_CHANNEL_INVALID_PHASING_HANDLE; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingEntry, *f_pusPhasingTsstIndex ); + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pCodecConfig->ulPhasingTsstHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Verify if the state of the phasing TSST.*/ + if ( pPhasingEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_PHASING_TSST_NOT_OPEN; + if ( ulEntryOpenCnt != pPhasingEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_PHASING_HANDLE; + + /* Check the specified phase value against the phasing length of the phasing TSST.*/ + if ( ( f_pCodecConfig->ulPhase == 0 ) + || ( f_pCodecConfig->ulPhase >= pPhasingEntry->usPhasingLength ) ) + return cOCT6100_ERR_CHANNEL_PHASING_INVALID_PHASE; + } + else + { + *f_pusPhasingTsstIndex = cOCT6100_INVALID_INDEX; + } + } + else + { + *f_pusPhasingTsstIndex = cOCT6100_INVALID_INDEX; + } + + + /* Check Decoder related parameter if one is used.*/ + if ( f_pCodecConfig->ulDecoderPort != cOCT6100_NO_DECODING ) + { + /* Check the Decoding rate.*/ + if ( f_pCodecConfig->ulDecodingRate != cOCT6100_G711_64KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_40KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_32KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_24KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_16KBPS && + f_pCodecConfig->ulDecodingRate != cOCT6100_G726_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_G726_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G727_2C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G727_3C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G727_4C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_G727_2C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_G727_3C_ENCODED && + f_pCodecConfig->ulDecodingRate != cOCT6100_G711_G727_4C_ENCODED ) + return cOCT6100_ERR_CHANNEL_DECODING_RATE; + + /* Make sure that two timeslot are allocated if PCM-ECHO encoded is selected.*/ + if ( (f_pCodecConfig->ulDecodingRate == cOCT6100_G711_G726_ENCODED || + f_pCodecConfig->ulDecodingRate == cOCT6100_G711_G727_2C_ENCODED || + f_pCodecConfig->ulDecodingRate == cOCT6100_G711_G727_3C_ENCODED || + f_pCodecConfig->ulDecodingRate == cOCT6100_G711_G727_4C_ENCODED ) && + f_ulDecoderNumTssts != 2 ) + return cOCT6100_ERR_CHANNEL_MISSING_TSST; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteInputTsstControlMemory + +Description: This function configure a TSST control memory entry in internal memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usTsstIndex TSST index within the TSST control memory. +f_usTsiMemIndex TSI index within the TSI chariot memory. +f_ulTsstInputLaw PCM law of the input TSST. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteInputTsstControlMemory +UINT32 Oct6100ApiWriteInputTsstControlMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulTsstInputLaw ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (f_usTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_TSST_CONTROL_MEM_INPUT_TSST; + WriteParams.usWriteData |= f_usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + + /* Set the PCM law.*/ + WriteParams.usWriteData |= f_ulTsstInputLaw << cOCT6100_TSST_CONTROL_MEM_PCM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteOutputTsstControlMemory + +Description: This function configure a TSST control memory entry in internal memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteOutputTsstControlMemory +UINT32 Oct6100ApiWriteOutputTsstControlMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usTsstIndex, + IN UINT32 f_ulAdpcmNibblePosition, + IN UINT32 f_ulNumTssts, + IN UINT16 f_usTsiMemIndex ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.ulWriteAddress = cOCT6100_TSST_CONTROL_MEM_BASE + ( (f_usTsstIndex & cOCT6100_TSST_INDEX_MASK) * cOCT6100_TSST_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_TSST_CONTROL_MEM_OUTPUT_TSST; + WriteParams.usWriteData |= f_ulAdpcmNibblePosition << cOCT6100_TSST_CONTROL_MEM_NIBBLE_POS_OFFSET; + WriteParams.usWriteData |= (f_ulNumTssts - 1) << cOCT6100_TSST_CONTROL_MEM_TSST_NUM_OFFSET; + WriteParams.usWriteData |= f_usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteEncoderMemory + +Description: This function configure a Encoded memory entry in internal memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_ulEncoderIndex Index of the encoder block within the ADPCM context memory. +f_ulCompType Compression rate of the encoder. +f_usTsiMemIndex TSI index within the TSI chariot memory used by the encoder. +f_ulEnableSilenceSuppression Silence suppression enable flag. +f_ulAdpcmNibblePosition ADPCM nibble position. +f_usPhasingTsstIndex Phasing TSST index within the API's Phassing TSST list. +f_ulPhasingType Type of the Phasing TSST. +f_ulPhase Phase used with this encoder. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteEncoderMemory +UINT32 Oct6100ApiWriteEncoderMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulEncoderIndex, + IN UINT32 f_ulCompType, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulEnableSilenceSuppression, + IN UINT32 f_ulAdpcmNibblePosition, + IN UINT16 f_usPhasingTsstIndex, + IN UINT32 f_ulPhasingType, + IN UINT32 f_ulPhase ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /*==============================================================================*/ + /* Conversion Control Base */ + WriteParams.ulWriteAddress = cOCT6100_CONVERSION_CONTROL_MEM_BASE + ( f_ulEncoderIndex * cOCT6100_CONVERSION_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_ENCODER; + WriteParams.usWriteData |= f_ulCompType << cOCT6100_CONVERSION_CONTROL_MEM_COMP_OFFSET; + WriteParams.usWriteData |= f_usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 2 */ + WriteParams.ulWriteAddress += 2; + + /* Set the phasing TSST number.*/ + if ( f_usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + WriteParams.usWriteData = (UINT16)( f_usPhasingTsstIndex << cOCT6100_CONVERSION_CONTROL_MEM_PHASE_OFFSET ); + else + WriteParams.usWriteData = 0; + + /* Set the phasing type and the phase value if required.*/ + switch( f_ulPhasingType ) + { + case cOCT6100_NO_PHASING: + WriteParams.usWriteData |= 0x1 << 10; + break; + case cOCT6100_SINGLE_PHASING: + WriteParams.usWriteData |= f_ulPhase; + break; + case cOCT6100_DUAL_PHASING: + WriteParams.usWriteData |= 0x1 << 11; + WriteParams.usWriteData |= f_ulPhase; + break; + default: + /* No problem. */ + break; + } + + /* Set the silence suppression flag.*/ + WriteParams.usWriteData |= f_ulEnableSilenceSuppression << cOCT6100_CONVERSION_CONTROL_MEM_SIL_SUP_OFFSET; + + /* Set the nibble position.*/ + WriteParams.usWriteData |= f_ulAdpcmNibblePosition << cOCT6100_CONVERSION_CONTROL_MEM_NIBBLE_POS_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 4 */ + WriteParams.ulWriteAddress += 2; + + /* Set the reset mode */ + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_RST_ON_NEXT_FR; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 6 */ + WriteParams.ulWriteAddress += 2; + + /* Set the reset mode */ + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_ACTIVATE_ENTRY; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteDecoderMemory + +Description: This function configure a Decoder memory entry in internal memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usDecoderIndex Index of the decoder block within the ADPCM context memory. +f_ulCompType Decompression rate of the decoder. +f_usTsiMemIndex TSI index within the TSI chariot memory. +f_ulPcmLaw PCM law of the decoded samples. +f_ulAdpcmNibblePosition ADPCM nibble position. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteDecoderMemory +UINT32 Oct6100ApiWriteDecoderMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usDecoderIndex, + IN UINT32 f_ulCompType, + IN UINT16 f_usTsiMemIndex, + IN UINT32 f_ulPcmLaw, + IN UINT32 f_ulAdpcmNibblePosition ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + + /*==============================================================================*/ + /* Conversion Control Base */ + WriteParams.ulWriteAddress = cOCT6100_CONVERSION_CONTROL_MEM_BASE + ( f_usDecoderIndex * cOCT6100_CONVERSION_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_DECODER; + WriteParams.usWriteData |= f_ulCompType << cOCT6100_CONVERSION_CONTROL_MEM_COMP_OFFSET; + WriteParams.usWriteData |= f_usTsiMemIndex & cOCT6100_TSST_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 2 */ + WriteParams.ulWriteAddress += 2; + + /* Set the nibble position.*/ + WriteParams.usWriteData = (UINT16)( f_ulAdpcmNibblePosition << cOCT6100_CONVERSION_CONTROL_MEM_NIBBLE_POS_OFFSET ); + + /* Set the law.*/ + WriteParams.usWriteData |= f_ulPcmLaw << cOCT6100_CONVERSION_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 4 */ + WriteParams.ulWriteAddress += 2; + + /* Set the reset mode */ + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_RST_ON_NEXT_FR; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + /* Conversion Control Base + 6 */ + WriteParams.ulWriteAddress += 2; + + /* Set the reset mode */ + WriteParams.usWriteData = cOCT6100_CONVERSION_CONTROL_MEM_ACTIVATE_ENTRY; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiClearConversionMemory + +Description: This function clears a conversion memory entry in internal + memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usConversionMemIndex Index of the block within the conversion memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiClearConversionMemory +UINT32 Oct6100ApiClearConversionMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usConversionMemIndex ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 ulBaseAddress; + UINT16 usReadData; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + WriteParams.usWriteData = 0; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*==============================================================================*/ + /* Clear the entry */ + ulBaseAddress = cOCT6100_CONVERSION_CONTROL_MEM_BASE + ( f_usConversionMemIndex * cOCT6100_CONVERSION_CONTROL_MEM_ENTRY_SIZE ); + /* The "activate" bit at offset +6 must be cleared first. */ + WriteParams.ulWriteAddress = ulBaseAddress + 6; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read at 0x200 to make sure there is no corruption on channel 0. */ + ReadParams.ulReadAddress = 0x200; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Then clear the rest of the structure. */ + WriteParams.ulWriteAddress = ulBaseAddress + 4; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ulBaseAddress + 2; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = ulBaseAddress; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteVqeMemory + +Description: This function configure an echo memory entry in internal memory and + external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig Pointer to a VQE config structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usChanIndex Index of the echo channel in the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fClearPlayoutPointers Flag indicating if the playout pointer should be cleared. +f_fModifyOnly Flag indicating if the configuration should be + modified only. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteVqeMemory +UINT32 Oct6100ApiWriteVqeMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ) +{ + UINT32 ulResult; + + /* Write the NLP software configuration structure. */ + ulResult = Oct6100ApiWriteVqeNlpMemory( + f_pApiInstance, + f_pVqeConfig, + f_pChannelOpen, + f_usChanIndex, + f_usEchoMemIndex, + f_fClearPlayoutPointers, + f_fModifyOnly ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the AF software configuration structure. */ + ulResult = Oct6100ApiWriteVqeAfMemory( + f_pApiInstance, + f_pVqeConfig, + f_pChannelOpen, + f_usChanIndex, + f_usEchoMemIndex, + f_fClearPlayoutPointers, + f_fModifyOnly ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteVqeNlpMemory + +Description: This function configures the NLP related VQE features of an + echo channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig Pointer to a VQE config structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usChanIndex Index of the echo channel in the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fClearPlayoutPointers Flag indicating if the playout pointer should be cleared. +f_fModifyOnly Flag indicating if the configuration should be + modified only. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteVqeNlpMemory +UINT32 Oct6100ApiWriteVqeNlpMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulNlpConfigBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT16 usTempData; + BOOL fEchoOperationModeChanged; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /*==============================================================================*/ + /* Configure the CPU NLP configuration of the channel feature by feature.*/ + + ulNlpConfigBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Set initial value to zero.*/ + ulTempData = 0; + + /* Configure Adaptive Noise Reduction.*/ + if ( pSharedInfo->ImageInfo.fAdaptiveNoiseReduction == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->fSoutAdaptiveNoiseReduction != pChanEntry->VqeConfig.fSoutAdaptiveNoiseReduction ) + || ( f_pVqeConfig->fSoutNoiseBleaching != pChanEntry->VqeConfig.fSoutNoiseBleaching ) + ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AdaptiveNoiseReductionOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AdaptiveNoiseReductionOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AdaptiveNoiseReductionOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set adaptive noise reduction on the SOUT port.*/ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fSoutAdaptiveNoiseReduction ) << ulFeatureBitOffset ); + + /* If SOUT noise bleaching is requested, ANR must be activated. */ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fSoutNoiseBleaching ) << ulFeatureBitOffset ); + + /* First read the DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure Rout Noise Reduction. */ + if ( pSharedInfo->ImageInfo.fRoutNoiseReduction == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fRoutNoiseReduction != pChanEntry->VqeConfig.fRoutNoiseReduction ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinAnrOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinAnrOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinAnrOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set noise reduction on the Rout port. */ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fRoutNoiseReduction ) << ulFeatureBitOffset ); + + /* Write the new DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + if (pSharedInfo->ImageInfo.fRoutNoiseReductionLevel == TRUE) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( (f_pVqeConfig->lRoutNoiseReductionLevelGainDb != pChanEntry->VqeConfig.chRoutNoiseReductionLevelGainDb ) + ||( f_pVqeConfig->fRoutNoiseReduction != pChanEntry->VqeConfig.fRoutNoiseReduction ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinAnrValOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinAnrValOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinAnrValOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if (f_pVqeConfig->fRoutNoiseReduction == TRUE) + { + switch( f_pVqeConfig->lRoutNoiseReductionLevelGainDb) + { + case 0: ulTempData |= ( 0 << ulFeatureBitOffset ); + break; + case -6: ulTempData |= ( 1 << ulFeatureBitOffset ); + break; + case -12: ulTempData |= ( 2 << ulFeatureBitOffset ); + break; + case -18: ulTempData |= ( 3 << ulFeatureBitOffset ); + break; + default: ulTempData |= ( 0 << ulFeatureBitOffset ); + break; + } + } + else + ulTempData |= ( 0 << ulFeatureBitOffset ); + + /* Write the new DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + } + + /* Configure Sout ANR SNR enhancement. */ + if ( pSharedInfo->ImageInfo.fAnrSnrEnhancement == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->lAnrSnrEnhancementDb != pChanEntry->VqeConfig.chAnrSnrEnhancementDb ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AnrSnrEnhancementOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AnrSnrEnhancementOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AnrSnrEnhancementOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set ANR SNR enhancement on the Sout port. */ + switch( f_pVqeConfig->lAnrSnrEnhancementDb ) + { + case -9: ulTempData |= ( 7 << ulFeatureBitOffset ); + break; + case -12: ulTempData |= ( 6 << ulFeatureBitOffset ); + break; + case -15: ulTempData |= ( 5 << ulFeatureBitOffset ); + break; + case -21: ulTempData |= ( 3 << ulFeatureBitOffset ); + break; + case -24: ulTempData |= ( 2 << ulFeatureBitOffset ); + break; + case -27: ulTempData |= ( 1 << ulFeatureBitOffset ); + break; + case -30: ulTempData |= ( 0 << ulFeatureBitOffset ); + break; + default: ulTempData |= ( 4 << ulFeatureBitOffset ); + /* -18 */ + break; + } + + /* Write the new DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure Sout ANR voice-noise segregation. */ + if ( pSharedInfo->ImageInfo.fAnrVoiceNoiseSegregation == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulAnrVoiceNoiseSegregation != pChanEntry->VqeConfig.byAnrVoiceNoiseSegregation ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AnrVoiceNoiseSegregationOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AnrVoiceNoiseSegregationOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AnrVoiceNoiseSegregationOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set ANR voice-noise segregation on the Sout port. */ + ulTempData |= ( ( (UINT32)f_pVqeConfig->ulAnrVoiceNoiseSegregation ) << ulFeatureBitOffset ); + + /* Write the new DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure the tone disabler VQE activation delay. */ + if ( pSharedInfo->ImageInfo.fToneDisablerVqeActivationDelay == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay != pChanEntry->VqeConfig.usToneDisablerVqeActivationDelay ) + || ( f_pChannelOpen->fEnableToneDisabler != pChanEntry->fEnableToneDisabler ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ToneDisablerVqeActivationDelayOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ToneDisablerVqeActivationDelayOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ToneDisablerVqeActivationDelayOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set the tone disabler VQE activation delay. The VQE activation delay */ + /* is only set if the tone disabler is activated. */ + if ( f_pChannelOpen->fEnableToneDisabler == TRUE ) + ulTempData |= ( ( (UINT32)( ( f_pVqeConfig->ulToneDisablerVqeActivationDelay - 300 ) / 512 ) ) << ulFeatureBitOffset ); + else + ulTempData |= ( 0 ) << ulFeatureBitOffset; + + /* Write the new DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure Conferencing Noise Reduction.*/ + if ( pSharedInfo->ImageInfo.fConferencingNoiseReduction == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->fSoutConferencingNoiseReduction != pChanEntry->VqeConfig.fSoutConferencingNoiseReduction ) + || ( f_pVqeConfig->fSoutNoiseBleaching != pChanEntry->VqeConfig.fSoutNoiseBleaching ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ConferencingNoiseReductionOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ConferencingNoiseReductionOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ConferencingNoiseReductionOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set conferencing noise reduction on the SOUT port. */ + ulTempData |= (f_pVqeConfig->fSoutConferencingNoiseReduction << ulFeatureBitOffset ); + + /* If SOUT noise bleaching is requested, CNR must be activated. */ + ulTempData |= (f_pVqeConfig->fSoutNoiseBleaching << ulFeatureBitOffset ); + + /* Save the DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the DC removal on RIN ports.*/ + if ( pSharedInfo->ImageInfo.fRinDcOffsetRemoval == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fRinDcOffsetRemoval != pChanEntry->VqeConfig.fRinDcOffsetRemoval ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinDcOffsetRemovalOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinDcOffsetRemovalOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinDcOffsetRemovalOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set adaptive noise reduction on the SOUT port.*/ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fRinDcOffsetRemoval ) << ulFeatureBitOffset ); + + /* The write the new DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the DC removal on SIN ports.*/ + if ( pSharedInfo->ImageInfo.fSinDcOffsetRemoval == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fSinDcOffsetRemoval != pChanEntry->VqeConfig.fSinDcOffsetRemoval ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SinDcOffsetRemovalOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SinDcOffsetRemovalOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SinDcOffsetRemovalOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set adaptive noise reduction on the SOUT port.*/ + ulTempData |= ( ( (UINT32)f_pVqeConfig->fSinDcOffsetRemoval ) << ulFeatureBitOffset ); + + /* Save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the level control. */ + if ( ( pChanEntry->byEchoOperationMode != f_pChannelOpen->ulEchoOperationMode ) + && ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NORMAL ) ) + fEchoOperationModeChanged = TRUE; + else + fEchoOperationModeChanged = FALSE; + + /* If opening the channel, all level control configuration must be written. */ + if ( f_fModifyOnly == FALSE ) + fEchoOperationModeChanged = TRUE; + ulResult = Oct6100ApiSetChannelLevelControl( f_pApiInstance, + f_pVqeConfig, + f_usChanIndex, + f_usEchoMemIndex, + fEchoOperationModeChanged ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the background noise freeze.*/ + if ( pSharedInfo->ImageInfo.fComfortNoise == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulComfortNoiseMode != pChanEntry->VqeConfig.byComfortNoiseMode ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ComfortNoiseModeOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ComfortNoiseModeOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ComfortNoiseModeOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( f_pVqeConfig->ulComfortNoiseMode << ulFeatureBitOffset ); + + /* Save the new DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the state of the NLP */ + if ( pSharedInfo->ImageInfo.fNlpControl == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fEnableNlp != pChanEntry->VqeConfig.fEnableNlp ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.NlpControlFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.NlpControlFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.NlpControlFieldOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->fEnableNlp == FALSE ) + ulTempData |= 0x1 << ulFeatureBitOffset; + + /* Save the new DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the tail configuration. */ + ulResult = Oct6100ApiSetChannelTailConfiguration( + f_pApiInstance, + f_pVqeConfig, + f_usChanIndex, + f_usEchoMemIndex, + f_fModifyOnly ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the Default ERL. */ + if ( ( pSharedInfo->ImageInfo.fDefaultErl == TRUE ) && ( f_pVqeConfig->fAcousticEcho == FALSE ) ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->lDefaultErlDb != pChanEntry->VqeConfig.chDefaultErlDb ) + || ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) + || ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.DefaultErlFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.DefaultErlFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.DefaultErlFieldOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Convert the DB value to octasic's float format. (In energy) */ + if ( ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + && ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + { + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lDefaultErlDb ); + } + else + { + /* Clear the defautl ERL when using the no echo cancellation operation mode. */ + usTempData = 0x0; + } + + if ( ulFeatureFieldLength < 16 ) + usTempData = (UINT16)( usTempData >> ( 16 - ulFeatureFieldLength ) ); + + ulTempData |= ( usTempData << ulFeatureBitOffset ); + + /* Save the new DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the Acoustic echo control.*/ + if ( pSharedInfo->ImageInfo.fAcousticEcho == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AecFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AecFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AecFieldOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( ( (UINT32)f_pVqeConfig->fAcousticEcho ) << ulFeatureBitOffset ); + + /* Then save the new DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the Acoustic Echo Default ERL. */ + if ( ( pSharedInfo->ImageInfo.fAecDefaultErl == TRUE ) && ( f_pVqeConfig->fAcousticEcho == TRUE ) ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->lAecDefaultErlDb != pChanEntry->VqeConfig.chAecDefaultErlDb ) + || ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AecDefaultErlFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AecDefaultErlFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AecDefaultErlFieldOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field. */ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + && ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + { + /* Convert the DB value to octasic's float format. (In energy) */ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lAecDefaultErlDb ); + } + else + { + /* Clear the AEC defautl ERL when using the no echo cancellation operation mode. */ + usTempData = 0x0; + } + + if ( ulFeatureFieldLength < 16 ) + usTempData = (UINT16)( usTempData >> ( 16 - ulFeatureFieldLength ) ); + + ulTempData |= ( usTempData << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the DTMF tone removal bit.*/ + if ( pSharedInfo->ImageInfo.fToneRemoval == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fDtmfToneRemoval != pChanEntry->VqeConfig.fDtmfToneRemoval ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ToneRemovalFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ToneRemovalFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ToneRemovalFieldOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( ( (UINT32)f_pVqeConfig->fDtmfToneRemoval ) << ulFeatureBitOffset ); + + /* First read the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + + + /* Set the non-linear behavior A.*/ + if ( pSharedInfo->ImageInfo.fNonLinearityBehaviorA == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->ulNonLinearityBehaviorA != pChanEntry->VqeConfig.byNonLinearityBehaviorA ) + || ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) ) ) ) + { + UINT16 ausLookupTable[ 14 ] = { 0x3663, 0x3906, 0x399C, 0x3A47, 0x3B06, 0x3B99, 0x3C47, 0x3D02, 0x3D99, 0x3E47, 0x3F00, 0x3F99, 0x4042, 0x4100 }; + + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PcmLeakFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PcmLeakFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PcmLeakFieldOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /*If we support ANR level the TLV is shared over 2 bits*/ + if (ulFeatureBitOffset == 18) + { + ulFeatureBitOffset -= 2; + ausLookupTable[ f_pVqeConfig->ulNonLinearityBehaviorA ] &= 0xFFFC; + } + + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + || ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + ulTempData |= ( 0x0 << ulFeatureBitOffset ); + else + ulTempData |= ( ausLookupTable[ f_pVqeConfig->ulNonLinearityBehaviorA ] << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Synch all the buffer playout field.*/ + if ( pSharedInfo->ImageInfo.fBufferPlayout == TRUE && f_fClearPlayoutPointers == TRUE ) + { + Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); + + BufferPlayoutStop.ulChannelHndl = cOCT6100_INVALID_HANDLE; + BufferPlayoutStop.fStopCleanly = TRUE; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + f_usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_SOUT; + ulResult = Oct6100ApiInvalidateChanPlayoutStructs( + f_pApiInstance, + &BufferPlayoutStop, + f_usChanIndex, + f_usEchoMemIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*==============================================================================*/ + /* Write the 2100 Hz Echo Disabling mode */ + + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pChannelOpen->fEnableToneDisabler != pChanEntry->fEnableToneDisabler ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ToneDisablerControlOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ToneDisablerControlOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ToneDisablerControlOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* This is a disable bit, so it must be set only if the enable flag is set to false. */ + if ( f_pChannelOpen->fEnableToneDisabler == FALSE ) + ulTempData |= 0x1 << ulFeatureBitOffset; + + /* Save the DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Write the Nlp Trivial enable flag. */ + + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( + + ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.NlpTrivialFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.NlpTrivialFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.NlpTrivialFieldOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + || ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + { + ulTempData |= TRUE << ulFeatureBitOffset; + } + + + /* Then write the DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the double talk behavior mode. */ + if ( pSharedInfo->ImageInfo.fDoubleTalkBehaviorFieldOfst == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulDoubleTalkBehavior != pChanEntry->VqeConfig.byDoubleTalkBehavior ) ) ) + { + /* The field is located in the CPURO structure. */ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.DoubleTalkBehaviorFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.DoubleTalkBehaviorFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.DoubleTalkBehaviorFieldOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= (f_pVqeConfig->ulDoubleTalkBehavior << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the music protection enable. */ + if ( ( pSharedInfo->ImageInfo.fMusicProtection == TRUE ) + && ( pSharedInfo->ImageInfo.fMusicProtectionConfiguration == TRUE ) ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fEnableMusicProtection != pChanEntry->VqeConfig.fEnableMusicProtection ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.MusicProtectionFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.MusicProtectionFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.MusicProtectionFieldOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + if ( f_pVqeConfig->fEnableMusicProtection == TRUE ) + ulTempData |= ( 1 << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteVqeAfMemory + +Description: This function configures the AF related VQE features of an + echo channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig Pointer to a VQE config structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usChanIndex Index of the echo channel in the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fClearPlayoutPointers Flag indicating if the playout pointer should be cleared. +f_fModifyOnly Flag indicating if the configuration should be + modified only. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteVqeAfMemory +UINT32 Oct6100ApiWriteVqeAfMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearPlayoutPointers, + IN BOOL f_fModifyOnly ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulAfConfigBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT16 usTempData; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /*==============================================================================*/ + /* Write the AF CPU configuration of the channel feature by feature.*/ + + /* Calculate AF CPU configuration base address. */ + ulAfConfigBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + /* Set initial value to zero.*/ + ulTempData = 0; + + /*==============================================================================*/ + /* Program the Maximum echo point within the Main channel memory.*/ + if ( pSharedInfo->ImageInfo.fMaxEchoPoint == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->lDefaultErlDb != pChanEntry->VqeConfig.chDefaultErlDb ) + || ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) ) ) ) + { + /* Write the echo tail length */ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.ChanMainIoMaxEchoPointOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.ChanMainIoMaxEchoPointOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.ChanMainIoMaxEchoPointOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Convert the DB value to octasic's float format.*/ + if ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_NO_ECHO ) + { + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lDefaultErlDb ); + } + else + { + /* Clear max echo point. No echo cancellation here. */ + usTempData = 0x0; + } + + if ( ulFeatureFieldLength < 16 ) + usTempData = (UINT16)( usTempData >> ( 16 - ulFeatureFieldLength ) ); + + ulTempData |= usTempData << ulFeatureBitOffset; + + /* First read the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the non-linear behavior B.*/ + if ( pSharedInfo->ImageInfo.fNonLinearityBehaviorB == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulNonLinearityBehaviorB != pChanEntry->VqeConfig.byNonLinearityBehaviorB ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.NlpConvCapFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.NlpConvCapFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.NlpConvCapFieldOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= (f_pVqeConfig->ulNonLinearityBehaviorB << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the listener enhancement feature. */ + if ( pSharedInfo->ImageInfo.fListenerEnhancement == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb ) + || ( f_pVqeConfig->fSoutNaturalListenerEnhancement != pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement ) + || ( f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb != pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AdaptiveAleOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AdaptiveAleOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AdaptiveAleOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0 ) + { + UINT32 ulGainDb; + + ulGainDb = f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb / 3; + + /* Round up. */ + if ( ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb % 3 ) != 0x0 ) + ulGainDb ++; + + ulTempData |= ( ulGainDb << ulFeatureBitOffset ); + } + else if ( f_pVqeConfig->fSoutNaturalListenerEnhancement != 0 ) + { + UINT32 ulGainDb; + + ulGainDb = f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb / 3; + + /* Round up. */ + if ( ( f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb % 3 ) != 0x0 ) + ulGainDb ++; + + ulTempData |= ( ( 0x80 | ulGainDb ) << ulFeatureBitOffset ); + } + + /* Now write the DWORD where the field is located containing the new configuration. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the idle code detection enable. */ + if ( ( pSharedInfo->ImageInfo.fIdleCodeDetection == TRUE ) + && ( pSharedInfo->ImageInfo.fIdleCodeDetectionConfiguration == TRUE ) ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->fIdleCodeDetection != pChanEntry->VqeConfig.fIdleCodeDetection ) ) ) + { + /* Calculate base address in the AF software configuration. */ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.IdleCodeDetectionFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.IdleCodeDetectionFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.IdleCodeDetectionFieldOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + if ( f_pVqeConfig->fIdleCodeDetection == FALSE ) + ulTempData |= ( 1 << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Set the AFT control field. */ + if ( pSharedInfo->ImageInfo.fAftControl == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pChannelOpen->ulEchoOperationMode != pChanEntry->byEchoOperationMode ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AftControlOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AftControlOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AftControlOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* If the operation mode is no echo, set the field such that echo cancellation is disabled. */ + if ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + { + ulTempData |= ( 0x1234 << ulFeatureBitOffset ); + } + else if ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) + { + /* For clarity. */ + ulTempData |= ( 0x0 << ulFeatureBitOffset ); + } + + /* Then save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfigBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteEchoMemory + +Description: This function configure an echo memory entry in internal memory.and + external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pTdmConfig Pointer to a TDM config structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usEchoIndex Echo channel index within the SSPX memory. +f_usRinRoutTsiIndex RIN/ROUT TSI index within the TSI chariot memory +f_usSinSoutTsiIndex SIN/SOUT TSI index within the TSI chariot memory + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteEchoMemory +UINT32 Oct6100ApiWriteEchoMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usEchoIndex, + IN UINT16 f_usRinRoutTsiIndex, + IN UINT16 f_usSinSoutTsiIndex ) + +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulRinPcmLaw; + UINT32 ulRoutPcmLaw; + UINT32 ulSinPcmLaw; + UINT32 ulSoutPcmLaw; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Set immediately the PCM law to be programmed in the SSPX and NLP memory.*/ + if ( f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN ) + { + ulRinPcmLaw = f_pChannelOpen->TdmConfig.ulRoutPcmLaw; + ulRoutPcmLaw = f_pChannelOpen->TdmConfig.ulRoutPcmLaw; + ulSinPcmLaw = f_pChannelOpen->TdmConfig.ulSinPcmLaw; + ulSoutPcmLaw = f_pChannelOpen->TdmConfig.ulSinPcmLaw; + } + else /* f_pChannelOpen->CodecConfig.ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN */ + { + ulRinPcmLaw = f_pChannelOpen->TdmConfig.ulRinPcmLaw; + ulRoutPcmLaw = f_pChannelOpen->TdmConfig.ulRinPcmLaw; + ulSinPcmLaw = f_pChannelOpen->TdmConfig.ulSoutPcmLaw; + ulSoutPcmLaw = f_pChannelOpen->TdmConfig.ulSoutPcmLaw; + } + + /*==============================================================================*/ + /* Configure the Global Static Configuration of the channel.*/ + + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + cOCT6100_CHANNEL_ROOT_GLOBAL_CONF_OFFSET; + + /* Set the PGSP context base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + cOCT6100_CH_MAIN_PGSP_CONTEXT_OFFSET; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the PGSP init context base address. */ + ulTempData = ( cOCT6100_IMAGE_FILE_BASE + 0x200 ) & 0x07FFFFFF; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_INIT_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the RIN circular buffer base address. */ + ulTempData = ( pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainRinCBMemOfst) & 0x07FFFF00; + ulTempData |= ( ulRoutPcmLaw << cOCT6100_GSC_BUFFER_LAW_OFFSET ); + + /* Set the circular buffer size.*/ + if (( pSharedInfo->MemoryMap.ulChanMainRinCBMemSize & 0xFFFF00FF ) != 0 ) + return cOCT6100_ERR_CHANNEL_INVALID_RIN_CB_SIZE; + ulTempData |= pSharedInfo->MemoryMap.ulChanMainRinCBMemSize >> 8; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_RIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SIN circular buffer base address. */ + ulTempData = ( pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSinCBMemOfst) & 0x07FFFF00; + ulTempData |= ( ulSinPcmLaw << cOCT6100_GSC_BUFFER_LAW_OFFSET ); + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SOUT circular buffer base address. */ + ulTempData = ( pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSoutCBMemOfst ) & 0x07FFFF00; + ulTempData |= ( ulSoutPcmLaw << cOCT6100_GSC_BUFFER_LAW_OFFSET ); + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SOUT_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* ECHO SSPX Memory configuration.*/ + + WriteParams.ulWriteAddress = cOCT6100_ECHO_CONTROL_MEM_BASE + ( f_usEchoIndex * cOCT6100_ECHO_CONTROL_MEM_ENTRY_SIZE ); + + /* ECHO memory BASE + 2 */ + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0x0000; + + /* Set the echo control field.*/ + if ( ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_NO_ECHO ) + || ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION ) ) + { + WriteParams.usWriteData |= cOCT6100_ECHO_OP_MODE_NORMAL << cOCT6100_ECHO_CONTROL_MEM_AF_CONTROL; + } + else if ( f_pChannelOpen->ulEchoOperationMode != cOCT6100_ECHO_OP_MODE_EXTERNAL ) + { + WriteParams.usWriteData |= f_pChannelOpen->ulEchoOperationMode << cOCT6100_ECHO_CONTROL_MEM_AF_CONTROL; + } + + /* Set the SIN/SOUT law.*/ + WriteParams.usWriteData |= ulSinPcmLaw << cOCT6100_ECHO_CONTROL_MEM_INPUT_LAW_OFFSET; + WriteParams.usWriteData |= ulSoutPcmLaw << cOCT6100_ECHO_CONTROL_MEM_OUTPUT_LAW_OFFSET; + + /* Set the TSI chariot memory field.*/ + WriteParams.usWriteData |= f_usSinSoutTsiIndex & cOCT6100_ECHO_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* ECHO memory BASE */ + WriteParams.ulWriteAddress -= 2; + WriteParams.usWriteData = cOCT6100_ECHO_CONTROL_MEM_ACTIVATE_ENTRY; + + /* Set the RIN/ROUT law.*/ + WriteParams.usWriteData |= ulRinPcmLaw << cOCT6100_ECHO_CONTROL_MEM_INPUT_LAW_OFFSET; + WriteParams.usWriteData |= ulRoutPcmLaw << cOCT6100_ECHO_CONTROL_MEM_OUTPUT_LAW_OFFSET; + + /* Set the RIN external echo control bit.*/ + if ( f_pChannelOpen->ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_EXTERNAL ) + WriteParams.usWriteData |= cOCT6100_ECHO_CONTROL_MEM_EXTERNAL_AF_CTRL; + + /* Set the TSI chariot memory field.*/ + WriteParams.usWriteData |= f_usRinRoutTsiIndex & cOCT6100_ECHO_CONTROL_MEM_TSI_MEM_MASK; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateOpenStruct + +Description: This function will copy the new parameter from the modify structure + into a channel open structure to be processed later by the same path + as the channel open function. + If a parameter is set to keep previous, it's current value will be + extracted from the channel entry in the API. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +IN f_pApiInstance Pointer to an API instance structure. +IN f_pChanModify Pointer to a channel modify structure. +IN OUT f_pChanOpen Pointer to a channel open structure. +IN f_pChanEntry Pointer to an API channel structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateOpenStruct +UINT32 Oct6100ApiUpdateOpenStruct( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MODIFY f_pChanModify, + IN OUT tPOCT6100_CHANNEL_OPEN f_pChanOpen, + IN tPOCT6100_API_CHANNEL f_pChanEntry ) +{ + + /* Check the generic Echo parameters.*/ + if ( f_pChanModify->ulEchoOperationMode == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->ulEchoOperationMode = f_pChanEntry->byEchoOperationMode; + else + f_pChanOpen->ulEchoOperationMode = f_pChanModify->ulEchoOperationMode; + + + if ( f_pChanModify->fEnableToneDisabler == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->fEnableToneDisabler = f_pChanEntry->fEnableToneDisabler; + else + f_pChanOpen->fEnableToneDisabler = f_pChanModify->fEnableToneDisabler; + + + if ( f_pChanModify->ulUserChanId == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->ulUserChanId = f_pChanEntry->ulUserChanId; + else + f_pChanOpen->ulUserChanId = f_pChanModify->ulUserChanId; + + + + /*======================================================================*/ + /* Now update the TDM config.*/ + /* Rin PCM LAW */ + if ( f_pChanModify->TdmConfig.ulRinPcmLaw == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRinPcmLaw = f_pChanEntry->TdmConfig.byRinPcmLaw; + else + f_pChanOpen->TdmConfig.ulRinPcmLaw = f_pChanModify->TdmConfig.ulRinPcmLaw; + + /* Sin PCM LAW */ + if ( f_pChanModify->TdmConfig.ulSinPcmLaw == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSinPcmLaw = f_pChanEntry->TdmConfig.bySinPcmLaw; + else + f_pChanOpen->TdmConfig.ulSinPcmLaw = f_pChanModify->TdmConfig.ulSinPcmLaw; + + /* Rout PCM LAW */ + if ( f_pChanModify->TdmConfig.ulRoutPcmLaw == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRoutPcmLaw = f_pChanEntry->TdmConfig.byRoutPcmLaw; + else + f_pChanOpen->TdmConfig.ulRoutPcmLaw = f_pChanModify->TdmConfig.ulRoutPcmLaw; + + /* Sout PCM LAW */ + if ( f_pChanModify->TdmConfig.ulSoutPcmLaw == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSoutPcmLaw = f_pChanEntry->TdmConfig.bySoutPcmLaw; + else + f_pChanOpen->TdmConfig.ulSoutPcmLaw = f_pChanModify->TdmConfig.ulSoutPcmLaw; + + + /* Rin Timeslot */ + if ( f_pChanModify->TdmConfig.ulRinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRinTimeslot = f_pChanEntry->TdmConfig.usRinTimeslot; + else + f_pChanOpen->TdmConfig.ulRinTimeslot = f_pChanModify->TdmConfig.ulRinTimeslot; + + /* Rin Stream */ + if ( f_pChanModify->TdmConfig.ulRinStream == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRinStream = f_pChanEntry->TdmConfig.usRinStream; + else + f_pChanOpen->TdmConfig.ulRinStream = f_pChanModify->TdmConfig.ulRinStream; + + /* Rin Num TSSTs */ + if ( f_pChanModify->TdmConfig.ulRinNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRinNumTssts = f_pChanEntry->TdmConfig.byRinNumTssts; + else + f_pChanOpen->TdmConfig.ulRinNumTssts = f_pChanModify->TdmConfig.ulRinNumTssts; + + + /* Sin Timeslot */ + if ( f_pChanModify->TdmConfig.ulSinTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSinTimeslot = f_pChanEntry->TdmConfig.usSinTimeslot; + else + f_pChanOpen->TdmConfig.ulSinTimeslot = f_pChanModify->TdmConfig.ulSinTimeslot; + + /* Sin Stream */ + if ( f_pChanModify->TdmConfig.ulSinStream == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSinStream = f_pChanEntry->TdmConfig.usSinStream; + else + f_pChanOpen->TdmConfig.ulSinStream = f_pChanModify->TdmConfig.ulSinStream; + + /* Sin Num TSSTs */ + if ( f_pChanModify->TdmConfig.ulSinNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSinNumTssts = f_pChanEntry->TdmConfig.bySinNumTssts; + else + f_pChanOpen->TdmConfig.ulSinNumTssts = f_pChanModify->TdmConfig.ulSinNumTssts; + + + /* Rout Timeslot */ + if ( f_pChanModify->TdmConfig.ulRoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRoutTimeslot = f_pChanEntry->TdmConfig.usRoutTimeslot; + else + f_pChanOpen->TdmConfig.ulRoutTimeslot = f_pChanModify->TdmConfig.ulRoutTimeslot; + + /* Rout Stream */ + if ( f_pChanModify->TdmConfig.ulRoutStream == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRoutStream = f_pChanEntry->TdmConfig.usRoutStream; + else + f_pChanOpen->TdmConfig.ulRoutStream = f_pChanModify->TdmConfig.ulRoutStream; + + /* Rout Num TSSTs */ + if ( f_pChanModify->TdmConfig.ulRoutNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulRoutNumTssts = f_pChanEntry->TdmConfig.byRoutNumTssts; + else + f_pChanOpen->TdmConfig.ulRoutNumTssts = f_pChanModify->TdmConfig.ulRoutNumTssts; + + + /* Sout Timeslot */ + if ( f_pChanModify->TdmConfig.ulSoutTimeslot == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSoutTimeslot = f_pChanEntry->TdmConfig.usSoutTimeslot; + else + f_pChanOpen->TdmConfig.ulSoutTimeslot = f_pChanModify->TdmConfig.ulSoutTimeslot; + + /* Sout Stream */ + if ( f_pChanModify->TdmConfig.ulSoutStream == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSoutStream = f_pChanEntry->TdmConfig.usSoutStream; + else + f_pChanOpen->TdmConfig.ulSoutStream = f_pChanModify->TdmConfig.ulSoutStream; + + /* Sout Num TSSTs */ + if ( f_pChanModify->TdmConfig.ulSoutNumTssts == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->TdmConfig.ulSoutNumTssts = f_pChanEntry->TdmConfig.bySoutNumTssts; + else + f_pChanOpen->TdmConfig.ulSoutNumTssts = f_pChanModify->TdmConfig.ulSoutNumTssts; + + /*======================================================================*/ + + /*======================================================================*/ + /* Now update the VQE config.*/ + + if ( f_pChanModify->VqeConfig.ulComfortNoiseMode == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulComfortNoiseMode = f_pChanEntry->VqeConfig.byComfortNoiseMode; + else + f_pChanOpen->VqeConfig.ulComfortNoiseMode = f_pChanModify->VqeConfig.ulComfortNoiseMode; + + if ( f_pChanModify->VqeConfig.fEnableNlp == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fEnableNlp = f_pChanEntry->VqeConfig.fEnableNlp; + else + f_pChanOpen->VqeConfig.fEnableNlp = f_pChanModify->VqeConfig.fEnableNlp; + + if ( f_pChanModify->VqeConfig.fEnableTailDisplacement == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fEnableTailDisplacement = f_pChanEntry->VqeConfig.fEnableTailDisplacement; + else + f_pChanOpen->VqeConfig.fEnableTailDisplacement = f_pChanModify->VqeConfig.fEnableTailDisplacement; + + if ( f_pChanModify->VqeConfig.ulTailDisplacement == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulTailDisplacement = f_pChanEntry->VqeConfig.usTailDisplacement; + else + f_pChanOpen->VqeConfig.ulTailDisplacement = f_pChanModify->VqeConfig.ulTailDisplacement; + + /* Tail length cannot be modifed. */ + f_pChanOpen->VqeConfig.ulTailLength = f_pChanEntry->VqeConfig.usTailLength; + + + + if ( f_pChanModify->VqeConfig.fRinDcOffsetRemoval == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRinDcOffsetRemoval = f_pChanEntry->VqeConfig.fRinDcOffsetRemoval; + else + f_pChanOpen->VqeConfig.fRinDcOffsetRemoval = f_pChanModify->VqeConfig.fRinDcOffsetRemoval; + + + if ( f_pChanModify->VqeConfig.fRinLevelControl == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRinLevelControl = f_pChanEntry->VqeConfig.fRinLevelControl; + else + f_pChanOpen->VqeConfig.fRinLevelControl = f_pChanModify->VqeConfig.fRinLevelControl; + + + if ( f_pChanModify->VqeConfig.fRinAutomaticLevelControl == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRinAutomaticLevelControl = f_pChanEntry->VqeConfig.fRinAutomaticLevelControl; + else + f_pChanOpen->VqeConfig.fRinAutomaticLevelControl = f_pChanModify->VqeConfig.fRinAutomaticLevelControl; + + + if ( f_pChanModify->VqeConfig.fRinHighLevelCompensation == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRinHighLevelCompensation = f_pChanEntry->VqeConfig.fRinHighLevelCompensation; + else + f_pChanOpen->VqeConfig.fRinHighLevelCompensation = f_pChanModify->VqeConfig.fRinHighLevelCompensation; + + + if ( f_pChanModify->VqeConfig.lRinHighLevelCompensationThresholdDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.lRinHighLevelCompensationThresholdDb = f_pChanEntry->VqeConfig.chRinHighLevelCompensationThresholdDb; + else + f_pChanOpen->VqeConfig.lRinHighLevelCompensationThresholdDb = f_pChanModify->VqeConfig.lRinHighLevelCompensationThresholdDb; + + + if ( f_pChanModify->VqeConfig.fSinDcOffsetRemoval == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSinDcOffsetRemoval = f_pChanEntry->VqeConfig.fSinDcOffsetRemoval; + else + f_pChanOpen->VqeConfig.fSinDcOffsetRemoval = f_pChanModify->VqeConfig.fSinDcOffsetRemoval; + + + if ( f_pChanModify->VqeConfig.fSoutAdaptiveNoiseReduction == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutAdaptiveNoiseReduction = f_pChanEntry->VqeConfig.fSoutAdaptiveNoiseReduction; + else + f_pChanOpen->VqeConfig.fSoutAdaptiveNoiseReduction = f_pChanModify->VqeConfig.fSoutAdaptiveNoiseReduction; + + + if ( f_pChanModify->VqeConfig.fSoutConferencingNoiseReduction == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutConferencingNoiseReduction = f_pChanEntry->VqeConfig.fSoutConferencingNoiseReduction; + else + f_pChanOpen->VqeConfig.fSoutConferencingNoiseReduction = f_pChanModify->VqeConfig.fSoutConferencingNoiseReduction; + + + if ( f_pChanModify->VqeConfig.fSoutNoiseBleaching == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutNoiseBleaching = f_pChanEntry->VqeConfig.fSoutNoiseBleaching; + else + f_pChanOpen->VqeConfig.fSoutNoiseBleaching = f_pChanModify->VqeConfig.fSoutNoiseBleaching; + + + if ( f_pChanModify->VqeConfig.fSoutLevelControl == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutLevelControl = f_pChanEntry->VqeConfig.fSoutLevelControl; + else + f_pChanOpen->VqeConfig.fSoutLevelControl = f_pChanModify->VqeConfig.fSoutLevelControl; + + + if ( f_pChanModify->VqeConfig.fSoutAutomaticLevelControl == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutAutomaticLevelControl = f_pChanEntry->VqeConfig.fSoutAutomaticLevelControl; + else + f_pChanOpen->VqeConfig.fSoutAutomaticLevelControl = f_pChanModify->VqeConfig.fSoutAutomaticLevelControl; + + + if ( f_pChanModify->VqeConfig.lRinLevelControlGainDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lRinLevelControlGainDb = f_pChanEntry->VqeConfig.chRinLevelControlGainDb; + else + f_pChanOpen->VqeConfig.lRinLevelControlGainDb = f_pChanModify->VqeConfig.lRinLevelControlGainDb; + + + if ( f_pChanModify->VqeConfig.lSoutLevelControlGainDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lSoutLevelControlGainDb = f_pChanEntry->VqeConfig.chSoutLevelControlGainDb; + else + f_pChanOpen->VqeConfig.lSoutLevelControlGainDb = f_pChanModify->VqeConfig.lSoutLevelControlGainDb; + + + if ( f_pChanModify->VqeConfig.lRinAutomaticLevelControlTargetDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lRinAutomaticLevelControlTargetDb = f_pChanEntry->VqeConfig.chRinAutomaticLevelControlTargetDb; + else + f_pChanOpen->VqeConfig.lRinAutomaticLevelControlTargetDb = f_pChanModify->VqeConfig.lRinAutomaticLevelControlTargetDb; + + + if ( f_pChanModify->VqeConfig.lSoutAutomaticLevelControlTargetDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lSoutAutomaticLevelControlTargetDb = f_pChanEntry->VqeConfig.chSoutAutomaticLevelControlTargetDb; + else + f_pChanOpen->VqeConfig.lSoutAutomaticLevelControlTargetDb = f_pChanModify->VqeConfig.lSoutAutomaticLevelControlTargetDb; + + + if ( f_pChanModify->VqeConfig.lDefaultErlDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lDefaultErlDb = f_pChanEntry->VqeConfig.chDefaultErlDb; + else + f_pChanOpen->VqeConfig.lDefaultErlDb = f_pChanModify->VqeConfig.lDefaultErlDb; + + + if ( f_pChanModify->VqeConfig.lAecDefaultErlDb == ( (INT32)cOCT6100_KEEP_PREVIOUS_SETTING ) ) + f_pChanOpen->VqeConfig.lAecDefaultErlDb = f_pChanEntry->VqeConfig.chAecDefaultErlDb; + else + f_pChanOpen->VqeConfig.lAecDefaultErlDb = f_pChanModify->VqeConfig.lAecDefaultErlDb; + + + if ( f_pChanModify->VqeConfig.ulAecTailLength == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulAecTailLength = f_pChanEntry->VqeConfig.usAecTailLength; + else + f_pChanOpen->VqeConfig.ulAecTailLength = f_pChanModify->VqeConfig.ulAecTailLength; + + + if ( f_pChanModify->VqeConfig.fAcousticEcho == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fAcousticEcho = f_pChanEntry->VqeConfig.fAcousticEcho; + else + f_pChanOpen->VqeConfig.fAcousticEcho = f_pChanModify->VqeConfig.fAcousticEcho; + + + if ( f_pChanModify->VqeConfig.fDtmfToneRemoval == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fDtmfToneRemoval = f_pChanEntry->VqeConfig.fDtmfToneRemoval; + else + f_pChanOpen->VqeConfig.fDtmfToneRemoval = f_pChanModify->VqeConfig.fDtmfToneRemoval; + + + + + + if ( f_pChanModify->VqeConfig.ulNonLinearityBehaviorA == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulNonLinearityBehaviorA = f_pChanEntry->VqeConfig.byNonLinearityBehaviorA; + else + f_pChanOpen->VqeConfig.ulNonLinearityBehaviorA = f_pChanModify->VqeConfig.ulNonLinearityBehaviorA; + + + if ( f_pChanModify->VqeConfig.ulNonLinearityBehaviorB == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulNonLinearityBehaviorB = f_pChanEntry->VqeConfig.byNonLinearityBehaviorB; + else + f_pChanOpen->VqeConfig.ulNonLinearityBehaviorB = f_pChanModify->VqeConfig.ulNonLinearityBehaviorB; + + + if ( f_pChanModify->VqeConfig.ulDoubleTalkBehavior == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulDoubleTalkBehavior = f_pChanEntry->VqeConfig.byDoubleTalkBehavior; + else + f_pChanOpen->VqeConfig.ulDoubleTalkBehavior = f_pChanModify->VqeConfig.ulDoubleTalkBehavior; + + + if ( f_pChanModify->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = f_pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb; + else + f_pChanOpen->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb = f_pChanModify->VqeConfig.ulSoutAutomaticListenerEnhancementGainDb; + + + if ( f_pChanModify->VqeConfig.ulSoutNaturalListenerEnhancementGainDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = f_pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb; + else + f_pChanOpen->VqeConfig.ulSoutNaturalListenerEnhancementGainDb = f_pChanModify->VqeConfig.ulSoutNaturalListenerEnhancementGainDb; + + + if ( f_pChanModify->VqeConfig.fSoutNaturalListenerEnhancement == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fSoutNaturalListenerEnhancement = f_pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement; + else + f_pChanOpen->VqeConfig.fSoutNaturalListenerEnhancement = f_pChanModify->VqeConfig.fSoutNaturalListenerEnhancement; + + + if ( f_pChanModify->VqeConfig.fRoutNoiseReduction == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fRoutNoiseReduction = f_pChanEntry->VqeConfig.fRoutNoiseReduction; + else + f_pChanOpen->VqeConfig.fRoutNoiseReduction = f_pChanModify->VqeConfig.fRoutNoiseReduction; + + if ( f_pChanModify->VqeConfig.lRoutNoiseReductionLevelGainDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.lRoutNoiseReductionLevelGainDb = f_pChanEntry->VqeConfig.chRoutNoiseReductionLevelGainDb; + else + f_pChanOpen->VqeConfig.lRoutNoiseReductionLevelGainDb = f_pChanModify->VqeConfig.lRoutNoiseReductionLevelGainDb; + + + if ( f_pChanModify->VqeConfig.lAnrSnrEnhancementDb == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.lAnrSnrEnhancementDb = f_pChanEntry->VqeConfig.chAnrSnrEnhancementDb; + else + f_pChanOpen->VqeConfig.lAnrSnrEnhancementDb = f_pChanModify->VqeConfig.lAnrSnrEnhancementDb; + + + if ( f_pChanModify->VqeConfig.ulAnrVoiceNoiseSegregation == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulAnrVoiceNoiseSegregation = f_pChanEntry->VqeConfig.byAnrVoiceNoiseSegregation; + else + f_pChanOpen->VqeConfig.ulAnrVoiceNoiseSegregation = f_pChanModify->VqeConfig.ulAnrVoiceNoiseSegregation; + + + if ( f_pChanModify->VqeConfig.ulToneDisablerVqeActivationDelay == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.ulToneDisablerVqeActivationDelay = f_pChanEntry->VqeConfig.usToneDisablerVqeActivationDelay; + else + f_pChanOpen->VqeConfig.ulToneDisablerVqeActivationDelay = f_pChanModify->VqeConfig.ulToneDisablerVqeActivationDelay; + + + if ( f_pChanModify->VqeConfig.fEnableMusicProtection == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fEnableMusicProtection = f_pChanEntry->VqeConfig.fEnableMusicProtection; + else + f_pChanOpen->VqeConfig.fEnableMusicProtection = f_pChanModify->VqeConfig.fEnableMusicProtection; + + + if ( f_pChanModify->VqeConfig.fIdleCodeDetection == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->VqeConfig.fIdleCodeDetection = f_pChanEntry->VqeConfig.fIdleCodeDetection; + else + f_pChanOpen->VqeConfig.fIdleCodeDetection = f_pChanModify->VqeConfig.fIdleCodeDetection; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Finaly the codec config.*/ + + if ( f_pChanModify->CodecConfig.ulDecoderPort == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulDecoderPort = f_pChanEntry->CodecConfig.byDecoderPort; + else + f_pChanOpen->CodecConfig.ulDecoderPort = f_pChanModify->CodecConfig.ulDecoderPort; + + + if ( f_pChanModify->CodecConfig.ulDecodingRate == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulDecodingRate = f_pChanEntry->CodecConfig.byDecodingRate; + else + f_pChanOpen->CodecConfig.ulDecodingRate = f_pChanModify->CodecConfig.ulDecodingRate; + + + if ( f_pChanModify->CodecConfig.ulEncoderPort == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulEncoderPort = f_pChanEntry->CodecConfig.byEncoderPort; + else + f_pChanOpen->CodecConfig.ulEncoderPort = f_pChanModify->CodecConfig.ulEncoderPort; + + + if ( f_pChanModify->CodecConfig.ulEncodingRate == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulEncodingRate = f_pChanEntry->CodecConfig.byEncodingRate; + else + f_pChanOpen->CodecConfig.ulEncodingRate = f_pChanModify->CodecConfig.ulEncodingRate; + + if ( f_pChanModify->CodecConfig.fEnableSilenceSuppression == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.fEnableSilenceSuppression = f_pChanEntry->CodecConfig.fEnableSilenceSuppression; + else + f_pChanOpen->CodecConfig.fEnableSilenceSuppression = f_pChanModify->CodecConfig.fEnableSilenceSuppression; + + if ( f_pChanModify->CodecConfig.ulPhasingType == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulPhasingType = f_pChanEntry->CodecConfig.byPhasingType; + else + f_pChanOpen->CodecConfig.ulPhasingType = f_pChanModify->CodecConfig.ulPhasingType; + + if ( f_pChanModify->CodecConfig.ulPhase == cOCT6100_KEEP_PREVIOUS_SETTING ) + f_pChanOpen->CodecConfig.ulPhase = f_pChanEntry->CodecConfig.byPhase; + else + f_pChanOpen->CodecConfig.ulPhase = f_pChanModify->CodecConfig.ulPhase; + + if ( f_pChanModify->CodecConfig.ulPhasingTsstHndl == cOCT6100_KEEP_PREVIOUS_SETTING ) + { + if ( f_pChanEntry->usPhasingTsstIndex != cOCT6100_INVALID_INDEX ) + { + tPOCT6100_API_PHASING_TSST pPhasingEntry; + + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( f_pApiInstance->pSharedInfo, pPhasingEntry, f_pChanEntry->usPhasingTsstIndex ); + + /* Now recreate the Phasing TSST handle.*/ + f_pChanOpen->CodecConfig.ulPhasingTsstHndl = cOCT6100_HNDL_TAG_PHASING_TSST | (pPhasingEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_pChanEntry->usPhasingTsstIndex; + } + else + { + f_pChanOpen->CodecConfig.ulPhasingTsstHndl = cOCT6100_INVALID_HANDLE; + } + } + else + { + f_pChanOpen->CodecConfig.ulPhasingTsstHndl = f_pChanModify->CodecConfig.ulPhasingTsstHndl; + } + + f_pChanOpen->CodecConfig.ulAdpcmNibblePosition = f_pChanEntry->CodecConfig.byAdpcmNibblePosition; + /*======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRetrieveNlpConfDword + +Description: This function is used by the API to store on a per channel basis + the various confguration DWORD from the device. The API performs + less read to the chip that way since it is always in synch with the + chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChanEntry Pointer to an API channel structure.. +f_ulAddress Address that needs to be modified.. +f_pulConfigDword Pointer to the content stored in the API located at the + desired address. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRetrieveNlpConfDword +UINT32 Oct6100ApiRetrieveNlpConfDword( + + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_CHANNEL f_pChanEntry, + IN UINT32 f_ulAddress, + OUT PUINT32 f_pulConfigDword ) +{ + UINT32 ulResult; + UINT32 ulFirstEmptyIndex = 0xFFFFFFFF; + UINT32 i; + + /* Search for the Dword.*/ + for ( i = 0; i < cOCT6100_MAX_NLP_CONF_DWORD; i++ ) + { + if ( ( ulFirstEmptyIndex == 0xFFFFFFFF ) && ( f_pChanEntry->aulNlpConfDword[ i ][ 0 ] == 0x0 ) ) + ulFirstEmptyIndex = i; + + if ( f_pChanEntry->aulNlpConfDword[ i ][ 0 ] == f_ulAddress ) + { + /* We found the matching Dword.*/ + *f_pulConfigDword = f_pChanEntry->aulNlpConfDword[ i ][ 1 ]; + return cOCT6100_ERR_OK; + } + } + + if ( i == cOCT6100_MAX_NLP_CONF_DWORD && ulFirstEmptyIndex == 0xFFFFFFFF ) + return cOCT6100_ERR_FATAL_8E; + + /* We did not found any entry, let's create a new entry.*/ + f_pChanEntry->aulNlpConfDword[ ulFirstEmptyIndex ][ 0 ] = f_ulAddress; + + + /* Read the DWORD where the field is located.*/ + ulResult = Oct6100ApiReadDword( f_pApiInstance, + f_ulAddress, + f_pulConfigDword ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSaveNlpConfDword + +Description: This function stores a configuration Dword within an API channel + structure and then writes it into the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChanEntry Pointer to an API channel structure.. +f_ulAddress Address that needs to be modified.. +f_pulConfigDword content to be stored in the API located at the + desired address. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiSaveNlpConfDword +UINT32 Oct6100ApiSaveNlpConfDword( + + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_CHANNEL f_pChanEntry, + IN UINT32 f_ulAddress, + IN UINT32 f_ulConfigDword ) +{ + UINT32 ulResult; + UINT32 i; + + /* Search for the Dword.*/ + for ( i = 0; i < cOCT6100_MAX_NLP_CONF_DWORD; i++ ) + { + + if ( f_pChanEntry->aulNlpConfDword[ i ][ 0 ] == f_ulAddress ) + { + /* We found the matching Dword.*/ + f_pChanEntry->aulNlpConfDword[ i ][ 1 ] = f_ulConfigDword; + break; + } + } + + if ( i == cOCT6100_MAX_NLP_CONF_DWORD ) + return cOCT6100_ERR_FATAL_8F; + + + /* Write the config DWORD.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + f_ulAddress, + f_ulConfigDword ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelCreateBiDirSer + +Description: Creates a bidirectional echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelCreateBiDir Pointer to a create bidirectionnal channel structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelCreateBiDirSer +UINT32 Oct6100ChannelCreateBiDirSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir ) +{ + UINT16 usFirstChanIndex; + UINT16 usFirstChanExtraTsiIndex; + UINT16 usFirstChanSinCopyEventIndex; + UINT16 usFirstChanSoutCopyEventIndex; + UINT16 usSecondChanIndex; + UINT16 usSecondChanExtraTsiIndex; + UINT16 usSecondChanSinCopyEventIndex; + UINT16 usSecondChanSoutCopyEventIndex; + UINT16 usBiDirChanIndex; + UINT32 ulResult; + + + /* Check the user's configuration of the bidir channel for errors. */ + ulResult = Oct6100ApiCheckChannelCreateBiDirParams( f_pApiInstance, + f_pChannelCreateBiDir, + &usFirstChanIndex, + &usFirstChanExtraTsiIndex, + &usFirstChanSinCopyEventIndex, + &usSecondChanIndex, + &usSecondChanExtraTsiIndex, + &usSecondChanSinCopyEventIndex + + ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the bidir channel. */ + ulResult = Oct6100ApiReserveChannelCreateBiDirResources(f_pApiInstance, + + &usBiDirChanIndex, + &usFirstChanExtraTsiIndex, + &usFirstChanSinCopyEventIndex, + &usFirstChanSoutCopyEventIndex, + &usSecondChanExtraTsiIndex, + &usSecondChanSinCopyEventIndex, + &usSecondChanSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write all necessary structures to activate the echo cancellation channel. */ + ulResult = Oct6100ApiWriteChannelCreateBiDirStructs( f_pApiInstance, + + usFirstChanIndex, + usFirstChanExtraTsiIndex, + usFirstChanSinCopyEventIndex, + usFirstChanSoutCopyEventIndex, + usSecondChanIndex, + usSecondChanExtraTsiIndex, + usSecondChanSinCopyEventIndex, + usSecondChanSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new echo cancellation channels's entry in the ECHO channel list. */ + ulResult = Oct6100ApiUpdateBiDirChannelEntry( f_pApiInstance, + f_pChannelCreateBiDir, + usBiDirChanIndex, + usFirstChanIndex, + usFirstChanExtraTsiIndex, + usFirstChanSinCopyEventIndex, + usFirstChanSoutCopyEventIndex, + usSecondChanIndex, + usSecondChanExtraTsiIndex, + usSecondChanSinCopyEventIndex, + usSecondChanSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChannelCreateBiDirParams + +Description: Checks the user's parameter passed to the create bidirectional channel + function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelCreateBiDir Pointer to a create bidirectionnal channel structure. +f_pusFirstChanIndex Pointer to the first channel index. +f_pusFirstChanExtraTsiIndex Pointer to the first channel extra TSI index. +f_pusFirstChanSinCopyEventIndex Pointer to the first channel Sin copy event index. +f_pusSecondChanIndex Pointer to the second channel index. +f_pusSecondChanExtraTsiIndex Pointer to the second channel extra TSI index. +f_pusSecondChanSinCopyEventIndex Pointer to the second channel Sin copy event index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChannelCreateBiDirParams +UINT32 Oct6100ApiCheckChannelCreateBiDirParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir, + OUT PUINT16 f_pusFirstChanIndex, + OUT PUINT16 f_pusFirstChanExtraTsiIndex, + OUT PUINT16 f_pusFirstChanSinCopyEventIndex, + OUT PUINT16 f_pusSecondChanIndex, + OUT PUINT16 f_pusSecondChanExtraTsiIndex, + OUT PUINT16 f_pusSecondChanSinCopyEventIndex + + ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + UINT32 ulEntryOpenCnt; + BOOL fCheckTssts = TRUE; + + /* Obtain shared resources pointer.*/ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* validate the bidirectional channel handle memory.*/ + if ( f_pChannelCreateBiDir->pulBiDirChannelHndl == NULL ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE; + + + + /* Check if bi-dir channels are activated. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxBiDirChannels == 0 ) + return cOCT6100_ERR_CHANNEL_BIDIR_DISABLED; + + /*=======================================================================*/ + /* Verify the first channel handle. */ + + if ( (f_pChannelCreateBiDir->ulFirstChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_BIDIR_FIRST_CHANNEL_HANDLE; + + *f_pusFirstChanIndex = (UINT16)( f_pChannelCreateBiDir->ulFirstChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusFirstChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_BIDIR_FIRST_CHANNEL_HANDLE; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, *f_pusFirstChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelCreateBiDir->ulFirstChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pFirstChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pFirstChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_BIDIR_FIRST_CHANNEL_HANDLE; + + /* Check the specific state of the channel.*/ + if ( pFirstChanEntry->fRinRoutCodecActive == TRUE && pFirstChanEntry->CodecConfig.byEncoderPort != cOCT6100_CHANNEL_PORT_ROUT) + return cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED; + if ( pFirstChanEntry->fSinSoutCodecActive == TRUE && pFirstChanEntry->CodecConfig.byEncoderPort != cOCT6100_CHANNEL_PORT_SOUT) + return cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED; + if ( pFirstChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_ALREADY_BIDIR; + + if ( pFirstChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_FIRST_CHAN_IN_CONFERENCE; + + if ( fCheckTssts == TRUE ) + { + if ( pFirstChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_FIRST_CHAN_SOUT_PORT; + if ( pFirstChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_FIRST_CHAN_RIN_PORT; + } + + /* Return the desired info.*/ + *f_pusFirstChanExtraTsiIndex = pFirstChanEntry->usExtraSinTsiMemIndex; + *f_pusFirstChanSinCopyEventIndex = pFirstChanEntry->usSinCopyEventIndex; + /*=======================================================================*/ + + /*=======================================================================*/ + /* Verify the second channel handle. */ + + if ( (f_pChannelCreateBiDir->ulSecondChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_BIDIR_SECOND_CHANNEL_HANDLE; + + *f_pusSecondChanIndex = (UINT16)( f_pChannelCreateBiDir->ulSecondChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusSecondChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_BIDIR_SECOND_CHANNEL_HANDLE; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, *f_pusSecondChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelCreateBiDir->ulSecondChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pSecondChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pSecondChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_BIDIR_SECOND_CHANNEL_HANDLE; + + /* Check the specific state of the channel.*/ + if ( pSecondChanEntry->fRinRoutCodecActive == TRUE && pSecondChanEntry->CodecConfig.byEncoderPort != cOCT6100_CHANNEL_PORT_ROUT) + return cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED; + if ( pSecondChanEntry->fSinSoutCodecActive == TRUE && pSecondChanEntry->CodecConfig.byEncoderPort != cOCT6100_CHANNEL_PORT_SOUT) + { + + return cOCT6100_ERR_CHANNEL_CODEC_ACTIVATED; + } + + if ( pSecondChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_ALREADY_BIDIR; + + if ( fCheckTssts == TRUE ) + { + if ( pSecondChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_SECOND_CHAN_SOUT_PORT; + if ( pSecondChanEntry->usRinTsstIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_SECOND_CHAN_RIN_PORT; + } + + if ( pSecondChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_CHANNEL_SECOND_CHAN_IN_CONFERENCE; + + /* Return the desired info.*/ + *f_pusSecondChanExtraTsiIndex = pSecondChanEntry->usExtraSinTsiMemIndex; + *f_pusSecondChanSinCopyEventIndex = pSecondChanEntry->usSinCopyEventIndex; + /*=======================================================================*/ + + /* Check the law compatibility.*/ + if ( pFirstChanEntry->TdmConfig.bySoutPcmLaw != pSecondChanEntry->TdmConfig.byRinPcmLaw || + pFirstChanEntry->TdmConfig.byRinPcmLaw != pSecondChanEntry->TdmConfig.bySoutPcmLaw ) + return cOCT6100_ERR_CHANNEL_BIDIR_PCM_LAW; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveChannelCreateBiDirResources + +Description: Reserves all resources needed for the new bidirectional channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusBiDirChanIndex Pointer to the index of the bidirectionnal channel within the API instance. +f_pusFirstChanExtraTsiIndex Pointer to the first channel extra TSI index. +f_pusFirstChanSinCopyEventIndex Pointer to the first channel Sin copy event index. +f_pusFirstChanSoutCopyEventIndex Pointer to the first channel Sout copy event index. +f_pusSecondChanExtraTsiIndex Pointer to the second channel extra TSI index. +f_pusSecondChanSinCopyEventIndex Pointer to the second channel Sin copy event index. +f_pusSecondChanSoutCopyEventIndex Pointer to the second channel Sout copy event index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveChannelCreateBiDirResources +UINT32 Oct6100ApiReserveChannelCreateBiDirResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + + OUT PUINT16 f_pusBiDirChanIndex, + IN OUT PUINT16 f_pusFirstChanExtraTsiIndex, + IN OUT PUINT16 f_pusFirstChanSinCopyEventIndex, + OUT PUINT16 f_pusFirstChanSoutCopyEventIndex, + IN OUT PUINT16 f_pusSecondChanExtraTsiIndex, + IN OUT PUINT16 f_pusSecondChanSinCopyEventIndex, + OUT PUINT16 f_pusSecondChanSoutCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult = cOCT6100_ERR_OK; + UINT32 ulTempVar; + + BOOL fBiDirChanIndex = FALSE; + BOOL fFirstExtraTsi = FALSE; + BOOL fSecondExtraTsi = FALSE; + BOOL fFirstSinCopyEvent = FALSE; + BOOL fSecondSinCopyEvent = FALSE; + BOOL fFirstSoutCopyEvent = FALSE; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*===============================================================================*/ + /* Verify and reserve the resources that might already by allocated. */ + + + { + if ( *f_pusFirstChanExtraTsiIndex == cOCT6100_INVALID_INDEX ) + { + /* Reserve the first Extra TSI memory entry */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + f_pusFirstChanExtraTsiIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fFirstExtraTsi = TRUE; + } + + if ( *f_pusFirstChanSinCopyEventIndex == cOCT6100_INVALID_INDEX && ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the Sin copy event for the first channel.*/ + ulResult = Oct6100ApiReserveMixerEventEntry ( f_pApiInstance, + f_pusFirstChanSinCopyEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fFirstSinCopyEvent = TRUE; + } + } + + if ( *f_pusSecondChanExtraTsiIndex == cOCT6100_INVALID_INDEX && ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the second Extra TSI memory entry */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, + f_pusSecondChanExtraTsiIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fSecondExtraTsi = TRUE; + } + + if ( *f_pusSecondChanSinCopyEventIndex == cOCT6100_INVALID_INDEX && ulResult == cOCT6100_ERR_OK ) + { + /* Reserve the Sin copy event for the second channel.*/ + ulResult = Oct6100ApiReserveMixerEventEntry ( f_pApiInstance, + f_pusSecondChanSinCopyEventIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + fSecondSinCopyEvent = TRUE; + } + /*===============================================================================*/ + + + /*===============================================================================*/ + /* Now reserve all the resources specific to bidirectional channels */ + + if ( ulResult == cOCT6100_ERR_OK ) + { + ulResult = Oct6100ApiReserveBiDirChanEntry( f_pApiInstance, + f_pusBiDirChanIndex ); + if ( ulResult == cOCT6100_ERR_OK ) + { + fBiDirChanIndex = TRUE; + + + { + + /* Reserve the first channel Sout copy mixer event.*/ + ulResult = Oct6100ApiReserveMixerEventEntry ( f_pApiInstance, + f_pusFirstChanSoutCopyEventIndex ); + } + + if ( ulResult == cOCT6100_ERR_OK ) + { + fFirstSoutCopyEvent = TRUE; + + /* Reserve the second channel Sout copy mixer event.*/ + ulResult = Oct6100ApiReserveMixerEventEntry ( f_pApiInstance, + f_pusSecondChanSoutCopyEventIndex ); + } + } + } + + /*===============================================================================*/ + + + /*===============================================================================*/ + /* Release the resources if something went wrong */ + if ( ulResult != cOCT6100_ERR_OK ) + { + /*===============================================================================*/ + /* Release the previously reserved echo resources .*/ + if ( fBiDirChanIndex == TRUE ) + { + ulTempVar = Oct6100ApiReleaseBiDirChanEntry( f_pApiInstance, + *f_pusBiDirChanIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fFirstExtraTsi == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + *f_pusFirstChanExtraTsiIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fSecondExtraTsi == TRUE ) + { + ulTempVar = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, + *f_pusSecondChanExtraTsiIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fFirstSinCopyEvent == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + *f_pusFirstChanSinCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( fSecondSinCopyEvent == TRUE ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + *f_pusSecondChanSinCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + if ( ( fFirstSoutCopyEvent == TRUE ) + + ) + { + ulTempVar = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, + *f_pusFirstChanSoutCopyEventIndex ); + if ( ulTempVar != cOCT6100_ERR_OK ) + return ulTempVar; + } + + /*===============================================================================*/ + + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteChannelCreateBiDirStructs + +Description: Performs all the required structure writes to configure the + new echo cancellation channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usFirstChanIndex Pointer to the first channel index. +f_usFirstChanExtraTsiIndex Pointer to the first channel extra TSI index. +f_usFirstChanSinCopyEventIndex Pointer to the first channel Sin copy event index. +f_usFirstChanSoutCopyEventIndex Pointer to the first channel Sout copy event index. +f_usFirstChanIndex Pointer to the second channel index. +f_usSecondChanExtraTsiIndex Pointer to the second channel extra TSI index. +f_usSecondChanSinCopyEventIndex Pointer to the second channel Sin copy event index. +f_usSecondChanSoutCopyEventIndex Pointer to the second channel Sout copy event index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteChannelCreateBiDirStructs +UINT32 Oct6100ApiWriteChannelCreateBiDirStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usFirstChanExtraTsiIndex, + IN UINT16 f_usFirstChanSinCopyEventIndex, + IN UINT16 f_usFirstChanSoutCopyEventIndex, + IN UINT16 f_usSecondChanIndex, + IN UINT16 f_usSecondChanExtraTsiIndex, + IN UINT16 f_usSecondChanSinCopyEventIndex, + IN UINT16 f_usSecondChanSoutCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /*==============================================================================*/ + /* Get a pointer to the two channel entry.*/ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, f_usFirstChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, f_usSecondChanIndex ); + + + + + { + /*==============================================================================*/ + /* Configure the Tsst control memory and add the Sin copy event if necessary. */ + + /*=======================================================================*/ + /* Program the Sin Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usFirstChanSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= f_usFirstChanExtraTsiIndex; + WriteParams.usWriteData |= pFirstChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pFirstChanEntry->usSinSoutTsiMemIndex ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Configure the TSST memory.*/ + if ( pFirstChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pFirstChanEntry->usSinTsstIndex, + f_usFirstChanExtraTsiIndex, + pFirstChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Now insert the event into the event list.*/ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usFirstChanSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usFirstChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + } + + + + /*==============================================================================*/ + /* Configure the Tsst control memory and add the Sin copy event if necessary.*/ + + /*=======================================================================*/ + /* Program the Sin Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSecondChanSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= f_usSecondChanExtraTsiIndex; + WriteParams.usWriteData |= pSecondChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSecondChanEntry->usSinSoutTsiMemIndex ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Configure the TSST memory.*/ + if ( pSecondChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pSecondChanEntry->usSinTsstIndex, + f_usSecondChanExtraTsiIndex, + pSecondChanEntry->TdmConfig.bySinPcmLaw ); + } + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Now insert the event into the event list.*/ + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usSecondChanSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY, + f_usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + + /*==============================================================================*/ + /* Now, let's configure the two Sout copy events.*/ + + + /* First event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usFirstChanSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= pFirstChanEntry->usSinSoutTsiMemIndex; + WriteParams.usWriteData |= pFirstChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pSecondChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usFirstChanSoutCopyEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY, + f_usFirstChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + /* Second event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( f_usSecondChanSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= pSecondChanEntry->usSinSoutTsiMemIndex; + WriteParams.usWriteData |= pSecondChanEntry->TdmConfig.bySoutPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pFirstChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + f_usSecondChanSoutCopyEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY, + f_usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + /* Clear + release the silence events if they were created. */ + + if ( pFirstChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pFirstChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pFirstChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E0; + + pFirstChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + if ( ( pSecondChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) + + ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pSecondChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pSecondChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E0; + + pSecondChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBiDirChannelEntry + +Description: Updates the new bidir channel and the channel used to create that channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBiDirChannelEntry +UINT32 Oct6100ApiUpdateBiDirChannelEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_CHANNEL_CREATE_BIDIR f_pChannelCreateBiDir, + IN UINT16 f_usBiDirChanIndex, + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usFirstChanExtraTsiIndex, + IN UINT16 f_usFirstChanSinCopyEventIndex, + IN UINT16 f_usFirstChanSoutCopyEventIndex, + IN UINT16 f_usSecondChanIndex, + IN UINT16 f_usSecondChanExtraTsiIndex, + IN UINT16 f_usSecondChanSinCopyEventIndex, + IN UINT16 f_usSecondChanSoutCopyEventIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, f_usBiDirChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, f_usFirstChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, f_usSecondChanIndex ); + + /*=======================================================================*/ + /* Copy the channel's configuration and allocated resources. */ + + pFirstChanEntry->usExtraSinTsiMemIndex = f_usFirstChanExtraTsiIndex; + pFirstChanEntry->usSinCopyEventIndex = f_usFirstChanSinCopyEventIndex; + pFirstChanEntry->usSoutCopyEventIndex = f_usFirstChanSoutCopyEventIndex; + + pSecondChanEntry->usExtraSinTsiMemIndex = f_usSecondChanExtraTsiIndex; + pSecondChanEntry->usSinCopyEventIndex = f_usSecondChanSinCopyEventIndex; + pSecondChanEntry->usSoutCopyEventIndex = f_usSecondChanSoutCopyEventIndex; + + /* Save the channel info in the bidir channel.*/ + pBiDirChanEntry->usFirstChanIndex = f_usFirstChanIndex; + pBiDirChanEntry->usSecondChanIndex = f_usSecondChanIndex; + + + + /* Increment the extra TSI memory dependency count.*/ + + pFirstChanEntry->usExtraSinTsiDependencyCnt++; + pSecondChanEntry->usExtraSinTsiDependencyCnt++; + + /* Set the bidir flag in the channel structure.*/ + pFirstChanEntry->fBiDirChannel = TRUE; + pSecondChanEntry->fBiDirChannel = TRUE; + + /*=======================================================================*/ + + /* Form handle returned to user. */ + *f_pChannelCreateBiDir->pulBiDirChannelHndl = cOCT6100_HNDL_TAG_BIDIR_CHANNEL | (pBiDirChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usBiDirChanIndex; + + /* Finally, mark the channel as open. */ + pBiDirChanEntry->fReserved = TRUE; + + /* Increment the number of channel open.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberBiDirChannels++; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelDestroyBiDirSer + +Description: Closes a bidirectional channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelDestroyBiDir Pointer to a destroy bidirectionnal channel structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelDestroyBiDirSer +UINT32 Oct6100ChannelDestroyBiDirSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir ) +{ + UINT16 usBiDirChanIndex; + UINT16 usFirstChanIndex; + UINT16 usSecondChanIndex; + + + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertDestroyBiDirChanParams( f_pApiInstance, + f_pChannelDestroyBiDir, + &usBiDirChanIndex, + + &usFirstChanIndex, + &usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiInvalidateBiDirChannelStructs( f_pApiInstance, + + usFirstChanIndex, + usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the echo cancellation channel. */ + ulResult = Oct6100ApiReleaseBiDirChannelResources( f_pApiInstance, + usBiDirChanIndex, + + usFirstChanIndex, + usSecondChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle.*/ + f_pChannelDestroyBiDir->ulBiDirChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertDestroyBiDirChanParams + +Description: Validate the handle given by the user and verify the state of + the channel about to be closed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChannelDestroyBiDir Pointer to a destroy bidirectional channel structure. +f_pusBiDirChanIndex Pointer to the bidir channel entry within the API's list. +f_pusFirstChanIndex Pointer to the first channel index part of the bidir channel. +f_pusFirstChanIndex Pointer to the second channel index part of the bidir channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertDestroyBiDirChanParams +UINT32 Oct6100ApiAssertDestroyBiDirChanParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_DESTROY_BIDIR f_pChannelDestroyBiDir, + IN OUT PUINT16 f_pusBiDirChanIndex, + + IN OUT PUINT16 f_pusFirstChanIndex, + IN OUT PUINT16 f_pusSecondChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pChannelDestroyBiDir->ulBiDirChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_BIDIR_CHANNEL ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE; + + *f_pusBiDirChanIndex = (UINT16)( f_pChannelDestroyBiDir->ulBiDirChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusBiDirChanIndex >= pSharedInfo->ChipConfig.usMaxBiDirChannels ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the bidir channel's list entry. */ + + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, *f_pusBiDirChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelDestroyBiDir->ulBiDirChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pBiDirChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHAN_NOT_OPEN; + if ( ulEntryOpenCnt != pBiDirChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_BIDIR_CHANNEL_HANDLE; + + /*=======================================================================*/ + + /* Return the index of the channel used to create this bidirectional channel.*/ + *f_pusFirstChanIndex = pBiDirChanEntry->usFirstChanIndex; + *f_pusSecondChanIndex = pBiDirChanEntry->usSecondChanIndex; + + + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInvalidateBiDirChannelStructs + +Description: Destroy the link between the two channels. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInvalidateBiDirChannelStructs +UINT32 Oct6100ApiInvalidateBiDirChannelStructs( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usSecondChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get pointers to the API entry of the two channel used to create the bidir channel.*/ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, f_usFirstChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, f_usSecondChanIndex ); + + /* Clear the SIN copy event of the first channel and release the Extra TSI memory if + this feature was the only one using it. */ + + { + if ( pFirstChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /*=======================================================================*/ + /* Clear the Sin Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pFirstChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Configure the TSST memory.*/ + if ( pFirstChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pFirstChanEntry->usSinTsstIndex, + pFirstChanEntry->usSinSoutTsiMemIndex, + pFirstChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pFirstChanEntry->usSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + } + + /* Clear the SIN copy event of the first channel and release the Extra TSI memory if + this feature was the only one using it. */ + if ( pSecondChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /*=======================================================================*/ + /* Clear the Sin Copy event.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSecondChanEntry->usSinCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + /* Configure the TSST memory.*/ + if ( pSecondChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance, + pSecondChanEntry->usSinTsstIndex, + pSecondChanEntry->usSinSoutTsiMemIndex, + pSecondChanEntry->TdmConfig.bySinPcmLaw ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pSecondChanEntry->usSinCopyEventIndex, + cOCT6100_EVENT_TYPE_SIN_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + } + + /* Now remove the sout copy of the first channel.*/ + + + { + /*=======================================================================*/ + /* Clear the Sout Copy event of the first channel.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pFirstChanEntry->usSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pFirstChanEntry->usSoutCopyEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + + + /* Now remove the sout copy of the second channel.*/ + + /*=======================================================================*/ + /* Clear the Sout Copy event of the second channel.*/ + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSecondChanEntry->usSoutCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_NO_OP; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*=======================================================================*/ + + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pSecondChanEntry->usSoutCopyEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBiDirChannelResources + +Description: Release and clear the API entry associated to the bidirectional channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usBiDirChanIndex Index of the bidirectionnal channel in the API's bidir channel list. +f_usFirstChanIndex Index of the first channel used to create the bidir channel. +f_usSecondChanIndex Index of the second channel used to create the bidir channel. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBiDirChannelResources +UINT32 Oct6100ApiReleaseBiDirChannelResources( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBiDirChanIndex, + + IN UINT16 f_usFirstChanIndex, + IN UINT16 f_usSecondChanIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + tPOCT6100_API_CHANNEL pFirstChanEntry; + tPOCT6100_API_CHANNEL pSecondChanEntry; + tPOCT6100_API_MIXER_EVENT pTempEventEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, f_usBiDirChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pFirstChanEntry, f_usFirstChanIndex ); + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pSecondChanEntry, f_usSecondChanIndex ); + + /* Release the bidir entry.*/ + ulResult = Oct6100ApiReleaseBiDirChanEntry( f_pApiInstance, f_usBiDirChanIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_AC; + + /* Release the Extra TSI memory and the SIN copy event if required.*/ + + { + if ( pFirstChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the two TSI chariot memory entries.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pFirstChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A3; + + /* Relese the SIN copy event.*/ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pFirstChanEntry->usSinCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A4; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, pFirstChanEntry->usSinCopyEventIndex ); + + /* Invalidate the entry.*/ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + pFirstChanEntry->usExtraSinTsiDependencyCnt--; + pFirstChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + pFirstChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + } + else + { + pFirstChanEntry->usExtraSinTsiDependencyCnt--; + } + } + + if ( pSecondChanEntry->usExtraSinTsiDependencyCnt == 1 ) + { + /* Release the two TSI chariot memory entries.*/ + ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pSecondChanEntry->usExtraSinTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A5; + + /* Relese the SIN copy event.*/ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pSecondChanEntry->usSinCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A6; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, pSecondChanEntry->usSinCopyEventIndex ); + /* Invalidate the entry.*/ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + pSecondChanEntry->usExtraSinTsiDependencyCnt--; + pSecondChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX; + pSecondChanEntry->usSinCopyEventIndex = cOCT6100_INVALID_INDEX; + } + else + { + pSecondChanEntry->usExtraSinTsiDependencyCnt--; + } + + + { + /* Release the SOUT copy event of the first channel.*/ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pFirstChanEntry->usSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A7; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, pFirstChanEntry->usSoutCopyEventIndex ); + /* Invalidate the entry.*/ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + } + + /* Release the SOUT copy event of the second channel.*/ + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pSecondChanEntry->usSoutCopyEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_A8; + + mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEventEntry, pSecondChanEntry->usSoutCopyEventIndex ); + /* Invalidate the entry.*/ + pTempEventEntry->fReserved = FALSE; + pTempEventEntry->usEventType = cOCT6100_INVALID_EVENT; + pTempEventEntry->usNextEventPtr = cOCT6100_INVALID_INDEX; + + + /*=======================================================================*/ + /* Update the first channel's list entry. */ + + /* Mark the channel as closed. */ + pFirstChanEntry->usSoutCopyEventIndex = cOCT6100_INVALID_INDEX; + pFirstChanEntry->fBiDirChannel = FALSE; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the second channel's list entry. */ + + /* Mark the channel as closed. */ + + pSecondChanEntry->usSoutCopyEventIndex = cOCT6100_INVALID_INDEX; + pSecondChanEntry->fBiDirChannel = FALSE; + + /*=======================================================================*/ + + /*=======================================================================*/ + /* Update the bidirectional channel's list entry. */ + + /* Mark the channel as closed. */ + pBiDirChanEntry->fReserved = FALSE; + pBiDirChanEntry->byEntryOpenCnt++; + + pBiDirChanEntry->usFirstChanIndex = cOCT6100_INVALID_INDEX; + pBiDirChanEntry->usSecondChanIndex = cOCT6100_INVALID_INDEX; + + /* Decrement the number of channel open.*/ + f_pApiInstance->pSharedInfo->ChipStats.usNumberBiDirChannels--; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Check if some of the ports must be muted back. */ + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, + f_usFirstChanIndex, + pFirstChanEntry->usRinTsstIndex, + pFirstChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, + f_usSecondChanIndex, + pSecondChanEntry->usRinTsstIndex, + pSecondChanEntry->usSinTsstIndex, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ApiOctFloatToDbEnergyByte +INT32 Oct6100ApiOctFloatToDbEnergyByte(UINT8 x) +{ + INT32 lResult; + + lResult = Oct6100ApiOctFloatToDbEnergyHalf( (UINT16)(x << 8) ); + return lResult; +} +#endif + +#if !SKIP_Oct6100ApiOctFloatToDbEnergyHalf +INT32 Oct6100ApiOctFloatToDbEnergyHalf(UINT16 x) +{ + INT32 y; + UINT16 m; + + y = (((x >> 8) & 0x7F) - 0x41) * 3; + + m = (UINT16)((x & 0x00E0) >> 5); + if (m < 2) y += 0; + else if (m < 5) y += 1; + else y += 2; + + return y; +} +#endif + +#if !SKIP_Oct6100ApiDbAmpHalfToOctFloat +UINT16 Oct6100ApiDbAmpHalfToOctFloat(INT32 x) +{ + INT32 db_div6; + INT32 db_mod6; + UINT16 rval; + INT32 x_unsigned; + + if(x < 0) + { + x_unsigned = -x; + } + else + { + x_unsigned = x; + } + + db_div6 = x_unsigned / 6; + db_mod6 = x_unsigned % 6; + + if(x < 0) + { + if(db_mod6 == 0) + { + /* Change nothing! */ + db_div6 = -db_div6; + } + else + { + /* When we are negative, round down, and then adjust modulo. For example, if + x is -1, then db_div6 is 0 and db_mod6 is 1. We adjust so db_div6 = -1 and + db_mod6 = 5, which gives the correct adjustment. */ + db_div6 = -db_div6-1; + db_mod6 = 6 - db_mod6; + } + } + + rval = (UINT16)(0x4100 + db_div6 * 0x100); + + if(db_mod6 == 0) + { + rval += 0x0000; + } + else if(db_mod6 == 1) + { + rval += 0x0020; + } + else if(db_mod6 == 2) + { + rval += 0x0040; + } + else if(db_mod6 == 3) + { + rval += 0x0070; + } + else if(db_mod6 == 4) + { + rval += 0x0090; + } + else /* if(db_mod6 == 5) */ + { + rval += 0x00D0; + } + + return rval; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteDebugChanMemory + +Description: This function configure a debug channel echo memory entry + in internal memory.and external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pTdmConfig Pointer to a TDM configuration structure. +f_pVqeConfig Pointer to a VQE configuration structure. +f_pChannelOpen Pointer to a channel configuration structure. +f_usChanIndex Index of the echo channel in the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_usRinRoutTsiIndex RIN/ROUT TSI index within the TSI chariot memory. +f_usSinSoutTsiIndex SIN/SOUT TSI index within the TSI chariot memory. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteDebugChanMemory +UINT32 Oct6100ApiWriteDebugChanMemory( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_TDM f_pTdmConfig, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN UINT16 f_usRinRoutTsiIndex, + IN UINT16 f_usSinSoutTsiIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + + /* Obtain pointer to local portion of the instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /*==============================================================================*/ + /* Write the VQE configuration of the debug channel. */ + + ulResult = Oct6100ApiWriteVqeMemory( + f_pApiInstance, + f_pVqeConfig, + f_pChannelOpen, + f_usChanIndex, + f_usEchoMemIndex, + TRUE, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + + /*==============================================================================*/ + + /* Write the echo memory configuration of the debug channel. */ + ulResult = Oct6100ApiWriteEchoMemory( + f_pApiInstance, + f_pTdmConfig, + f_pChannelOpen, + f_usEchoMemIndex, + f_usRinRoutTsiIndex, + f_usSinSoutTsiIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiDebugChannelOpen + +Description: Internal function used to open a debug channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiDebugChannelOpen +UINT32 Oct6100ApiDebugChannelOpen( + IN tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_CHANNEL_OPEN TempChanOpen; + + UINT32 ulResult; + UINT16 usChanIndex; + UINT16 usDummyEchoIndex; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Let's program the channel memory.*/ + Oct6100ChannelOpenDef( &TempChanOpen ); + + TempChanOpen.ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_HT_RESET; /* Activate the channel in reset.*/ + TempChanOpen.VqeConfig.fEnableNlp = FALSE; + TempChanOpen.VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL; + TempChanOpen.VqeConfig.fSinDcOffsetRemoval = FALSE; + TempChanOpen.VqeConfig.fRinDcOffsetRemoval = FALSE; + TempChanOpen.VqeConfig.lDefaultErlDb = 0; + + /* Loop to reserve the proper entry for the debug channel */ + for( usChanIndex = 0; usChanIndex < ( pSharedInfo->DebugInfo.usRecordChanIndex + 1 ); usChanIndex ++ ) + { + ulResult = Oct6100ApiReserveEchoEntry( f_pApiInstance, &usDummyEchoIndex ); + if( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Loop to free all entries except the one for the debug channel */ + for( usChanIndex = pSharedInfo->DebugInfo.usRecordChanIndex; usChanIndex > 0; ) + { + usChanIndex--; + ulResult = Oct6100ApiReleaseEchoEntry( f_pApiInstance, usChanIndex ); + if( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + ulResult = Oct6100ApiWriteDebugChanMemory( f_pApiInstance, + &TempChanOpen.TdmConfig, + &TempChanOpen.VqeConfig, + &TempChanOpen, + pSharedInfo->DebugInfo.usRecordChanIndex, + pSharedInfo->DebugInfo.usRecordMemIndex, + pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex, + pSharedInfo->DebugInfo.usRecordSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMuteChannelPort + +Description: This function will verify if a input TSST is bound to the RIN and + SIN port. If not, the port will be muted. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMutePorts +UINT32 Oct6100ApiMutePorts( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usEchoIndex, + IN UINT16 f_usRinTsstIndex, + IN UINT16 f_usSinTsstIndex, + IN BOOL f_fCheckBridgeIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Obtain a pointer to the new buffer's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usEchoIndex ); + + /* Mute the Rin port. */ + if ( ( f_fCheckBridgeIndex == FALSE ) + || ( ( f_fCheckBridgeIndex == TRUE ) && ( pChanEntry->usBridgeIndex == cOCT6100_INVALID_INDEX ) ) ) + { + /* If the channel is in bidir mode, do not create the Rin silence event!!! */ + if ( pChanEntry->fBiDirChannel == FALSE ) + { + if ( ( ( f_usRinTsstIndex == cOCT6100_INVALID_INDEX ) || ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_RIN ) != 0x0 ) ) + && ( pChanEntry->usRinSilenceEventIndex == cOCT6100_INVALID_INDEX ) ) + { + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, + &pChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now, write the mixer event used to copy the RIN signal of the silence channel + into the RIN signal of the current channel. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usRinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= 1534; + WriteParams.usWriteData |= cOCT6100_PCM_U_LAW << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pChanEntry->usRinRoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now insert the Sin copy event into the list.*/ + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + pChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY, + f_usEchoIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Mute the Sin port. */ + if ( ( ( f_usSinTsstIndex == cOCT6100_INVALID_INDEX ) || ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) ) + && ( pChanEntry->usSinSilenceEventIndex == cOCT6100_INVALID_INDEX ) ) + { + ulResult = Oct6100ApiReserveMixerEventEntry( f_pApiInstance, + &pChanEntry->usSinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now, write the mixer event used to copy the SIN signal of the silence channel + into the SIN signal of the current channel. */ + + WriteParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pChanEntry->usSinSilenceEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + + WriteParams.usWriteData = cOCT6100_MIXER_CONTROL_MEM_COPY; + WriteParams.usWriteData |= 1534; + WriteParams.usWriteData |= cOCT6100_PCM_U_LAW << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = pChanEntry->usSinSoutTsiMemIndex; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*=======================================================================*/ + + + /*=======================================================================*/ + /* Now insert the Sin copy event into the list.*/ + + ulResult = Oct6100ApiMixerEventAdd( f_pApiInstance, + pChanEntry->usSinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY, + f_usEchoIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Unmute the Rin port if it was muted. */ + if ( ( ( f_usRinTsstIndex != cOCT6100_INVALID_INDEX ) && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_RIN ) == 0x0 ) ) + && ( pChanEntry->usRinSilenceEventIndex != cOCT6100_INVALID_INDEX ) ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usRinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usRinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E1; + + pChanEntry->usRinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + /* Unmute the Sin port if it was muted. */ + if ( ( ( f_usSinTsstIndex != cOCT6100_INVALID_INDEX ) && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) == 0x0 ) ) + && ( pChanEntry->usSinSilenceEventIndex != cOCT6100_INVALID_INDEX ) ) + { + /* Remove the event from the list.*/ + ulResult = Oct6100ApiMixerEventRemove( f_pApiInstance, + pChanEntry->usSinSilenceEventIndex, + cOCT6100_EVENT_TYPE_SOUT_COPY ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReleaseMixerEventEntry( f_pApiInstance, pChanEntry->usSinSilenceEventIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_E2; + + pChanEntry->usSinSilenceEventIndex = cOCT6100_INVALID_INDEX; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSetChannelLevelControl + +Description: This function will configure the level control on a given + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig VQE config of the channel. +f_usChanIndex Index of the channel within the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fClearAlcHlcStatusBit If this is set, the ALC-HLC status bit must be + incremented. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiSetChannelLevelControl +UINT32 Oct6100ApiSetChannelLevelControl( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fClearAlcHlcStatusBit ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT32 i; + UINT16 usTempData; + UINT8 byLastStatus; + BOOL fDisableAlcFirst; + + /* Get local pointer to shared portion of the API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the channel list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /* Before doing anything, check if the configuration has changed. */ + if ( ( f_fClearAlcHlcStatusBit == TRUE ) + || ( f_pVqeConfig->fRinLevelControl != pChanEntry->VqeConfig.fRinLevelControl ) + || ( f_pVqeConfig->lRinLevelControlGainDb != pChanEntry->VqeConfig.chRinLevelControlGainDb ) + || ( f_pVqeConfig->fRinAutomaticLevelControl != pChanEntry->VqeConfig.fRinAutomaticLevelControl ) + || ( f_pVqeConfig->lRinAutomaticLevelControlTargetDb != pChanEntry->VqeConfig.chRinAutomaticLevelControlTargetDb ) + || ( f_pVqeConfig->fRinHighLevelCompensation != pChanEntry->VqeConfig.fRinHighLevelCompensation ) + || ( f_pVqeConfig->lRinHighLevelCompensationThresholdDb != pChanEntry->VqeConfig.chRinHighLevelCompensationThresholdDb ) + || ( f_pVqeConfig->fSoutLevelControl != pChanEntry->VqeConfig.fSoutLevelControl ) + || ( f_pVqeConfig->lSoutLevelControlGainDb != pChanEntry->VqeConfig.chSoutLevelControlGainDb ) + || ( f_pVqeConfig->fSoutAutomaticLevelControl != pChanEntry->VqeConfig.fSoutAutomaticLevelControl ) + || ( f_pVqeConfig->lSoutAutomaticLevelControlTargetDb != pChanEntry->VqeConfig.chSoutAutomaticLevelControlTargetDb ) + || ( f_pVqeConfig->fSoutNaturalListenerEnhancement != pChanEntry->VqeConfig.fSoutNaturalListenerEnhancement ) + || ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != pChanEntry->VqeConfig.bySoutAutomaticListenerEnhancementGainDb ) + || ( f_pVqeConfig->ulSoutNaturalListenerEnhancementGainDb != pChanEntry->VqeConfig.bySoutNaturalListenerEnhancementGainDb ) ) + { + /* Calculate base address for manual level control configuration. */ + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + /* Set the Level control on RIN port.*/ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinLevelControlOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinLevelControlOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinLevelControlOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( ( f_pVqeConfig->fRinLevelControl == TRUE ) + || ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + || ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) ) + { + /* Set the level control value.*/ + if ( ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + || ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) ) + ulTempData |= ( 0xFF << ulFeatureBitOffset ); + else + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( f_pVqeConfig->lRinLevelControlGainDb ); + usTempData -= 0x3800; + usTempData &= 0x0FF0; + usTempData >>= 4; + + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + } + else /* ( ( f_pVqeConfig->fRinLevelControl == FALSE ) && ( f_pVqeConfig->fRinAutomaticLevelControl == FALSE ) && ( f_pVqeConfig->fRinHighLevelCompensation == FALSE ) ) */ + { + ulTempData |= ( cOCT6100_PASS_THROUGH_LEVEL_CONTROL << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the Level control on SOUT port.*/ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SoutLevelControlOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SoutLevelControlOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SoutLevelControlOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( ( f_pVqeConfig->fSoutLevelControl == TRUE ) + || ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) + || ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE ) + || ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0x0 ) ) + { + /* Set the level control value.*/ + if ( ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) + || ( f_pVqeConfig->fSoutNaturalListenerEnhancement == TRUE ) + || ( f_pVqeConfig->ulSoutAutomaticListenerEnhancementGainDb != 0x0 ) ) + ulTempData |= ( 0xFF << ulFeatureBitOffset ); + else + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( f_pVqeConfig->lSoutLevelControlGainDb ); + usTempData -= 0x3800; + usTempData &= 0x0FF0; + usTempData >>= 4; + + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + } + else + { + ulTempData |= ( cOCT6100_PASS_THROUGH_LEVEL_CONTROL << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Calculate base address for auto level control + high level compensation configuration. */ + ulBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + f_pApiInstance->pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + /* Check which one is to be disabled first. */ + if ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + fDisableAlcFirst = FALSE; + else + fDisableAlcFirst = TRUE; + + for ( i = 0; i < 2; i ++ ) + { + /* Set the auto level control target Db for the Rin port. */ + if ( ( ( i == 0 ) && ( fDisableAlcFirst == TRUE ) ) || ( ( i == 1 ) && ( fDisableAlcFirst == FALSE ) ) ) + { + if ( pSharedInfo->ImageInfo.fRinAutoLevelControl == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinAutoLevelControlTargetOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinAutoLevelControlTargetOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinAutoLevelControlTargetOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->fRinAutomaticLevelControl == TRUE ) + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lRinAutomaticLevelControlTargetDb ); + + /* Set auto level control target on the Rin port. */ + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + else /* if ( f_pVqeConfig->fRinAutomaticLevelControl == FALSE ) */ + { + /* Disable auto level control. */ + ulTempData |= ( 0xFFFF << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* Set the high level compensation threshold Db for the Rin port. */ + if ( pSharedInfo->ImageInfo.fRinHighLevelCompensation == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.RinHighLevelCompensationThresholdOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.RinHighLevelCompensationThresholdOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.RinHighLevelCompensationThresholdOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->fRinHighLevelCompensation == TRUE ) + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lRinHighLevelCompensationThresholdDb ); + + /* Set high level compensation threshold on the Rin port. */ + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + else /* if ( f_pVqeConfig->fRinHighLevelCompensation == FALSE ) */ + { + /* Disable high level compensation. */ + ulTempData |= ( 0xFFFF << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Set the auto level control target Db for the Sout port. */ + if ( pSharedInfo->ImageInfo.fRinAutoLevelControl == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SoutAutoLevelControlTargetOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SoutAutoLevelControlTargetOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SoutAutoLevelControlTargetOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->fSoutAutomaticLevelControl == TRUE ) + { + /* Convert the dB value into OctFloat format.*/ + usTempData = Oct6100ApiDbAmpHalfToOctFloat( 2 * f_pVqeConfig->lSoutAutomaticLevelControlTargetDb ); + + /* Set auto level control target on the Sout port. */ + ulTempData |= ( usTempData << ulFeatureBitOffset ); + } + else /* if ( f_pVqeConfig->fSoutAutomaticLevelControl == FALSE ) */ + { + /* Disable auto level control. */ + ulTempData |= ( 0xFFFF << ulFeatureBitOffset ); + } + + /* Save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the high level compensation threshold Db for the Sout port. */ + if ( pSharedInfo->ImageInfo.fSoutHighLevelCompensation == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SoutHighLevelCompensationThresholdOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SoutHighLevelCompensationThresholdOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SoutHighLevelCompensationThresholdOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Disable high level compensation on Sout for now. */ + ulTempData |= ( 0xFFFF << ulFeatureBitOffset ); + + /* Save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if have to clear the ALC-HLC status. */ + if ( ( pSharedInfo->ImageInfo.fAlcHlcStatus == TRUE ) + && ( ( f_fClearAlcHlcStatusBit == TRUE ) + + ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AlcHlcStatusOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AlcHlcStatusOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AlcHlcStatusOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Retrieve last status. */ + byLastStatus = (UINT8)( ( ( ulTempData & ulMask ) >> ulFeatureBitOffset ) & 0xFF ); + + /* Increment to reset context. */ + byLastStatus ++; + + /* Just in case, not to overwrite some context in external memory. */ + byLastStatus &= ( 0x1 << ulFeatureFieldLength ) - 1; + + /* Clear last status. */ + ulTempData &= (~ulMask); + + /* Set new status. */ + ulTempData |= ( byLastStatus << ulFeatureBitOffset ); + + /* Save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSetChannelTailConfiguration + +Description: This function will configure the tail displacement and length + on a given channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pVqeConfig VQE config of the channel. +f_usChanIndex Index of the channel within the API instance. +f_usEchoMemIndex Index of the echo channel within the SSPX memory. +f_fModifyOnly Function called from a modify or open? + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiSetChannelTailConfiguration +UINT32 Oct6100ApiSetChannelTailConfiguration( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_OPEN_VQE f_pVqeConfig, + IN UINT16 f_usChanIndex, + IN UINT16 f_usEchoMemIndex, + IN BOOL f_fModifyOnly ) +{ + tPOCT6100_API_CHANNEL pChanEntry; + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + UINT32 ulTempData; + UINT32 ulNlpConfBaseAddress; + UINT32 ulAfConfBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT32 ulTailSum; + BOOL fTailDisplacementModified = FALSE; + + /* Get local pointer to shared portion of the API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a pointer to the channel list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ); + + /* Calculate base addresses of NLP + AF configuration structure for the specified channel. */ + ulNlpConfBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + ulAfConfBaseAddress = pSharedInfo->MemoryMap.ulChanMainMemBase + ( f_usEchoMemIndex * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainIoMemOfst; + + /* Set the tail displacement.*/ + if ( pSharedInfo->ImageInfo.fTailDisplacement == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->fEnableTailDisplacement != pChanEntry->VqeConfig.fEnableTailDisplacement ) + || ( f_pVqeConfig->ulTailDisplacement != pChanEntry->VqeConfig.usTailDisplacement ) + || ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) ) + { + /* Remember that the tail displacement parameters were changed. */ + fTailDisplacementModified = TRUE; + + /* Check if we must set the tail displacement value. */ + if ( ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + && ( pSharedInfo->ImageInfo.fPerChannelTailDisplacement == TRUE ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PerChanTailDisplacementFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PerChanTailDisplacementFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PerChanTailDisplacementFieldOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + if ( ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + && ( f_pVqeConfig->ulTailDisplacement != 0x0 ) ) + { + if ( pSharedInfo->ImageInfo.fAfTailDisplacement == FALSE ) + { + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTempData |= ( ( ( pSharedInfo->ChipConfig.usTailDisplacement / 16 ) ) << ulFeatureBitOffset ); + } + else + { + ulTempData |= ( ( ( f_pVqeConfig->ulTailDisplacement / 16 ) ) << ulFeatureBitOffset ); + } + } + else /* if ( pSharedInfo->ImageInfo.fAfTailDisplacement == TRUE ) */ + { + /* If AEC is not activated, this must be set to the requested tail displacement. */ + if ( f_pVqeConfig->fAcousticEcho == FALSE ) + { + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum = pSharedInfo->ChipConfig.usTailDisplacement; + } + else + { + ulTailSum = f_pVqeConfig->ulTailDisplacement; + } + + if ( ulTailSum == 0 ) + { + ulTempData |= ( ( 0 ) << ulFeatureBitOffset ); + } + else if ( ulTailSum <= 128 ) + { + ulTempData |= ( ( 1 ) << ulFeatureBitOffset ); + } + else if ( ulTailSum <= 384 ) + { + ulTempData |= ( ( 3 ) << ulFeatureBitOffset ); + } + else /* if ( ulTailSum <= 896 ) */ + { + ulTempData |= ( ( 7 ) << ulFeatureBitOffset ); + } + } + else /* if ( f_pVqeConfig->fAcousticEcho == FALSE ) */ + { + /* Otherwise, the tail displacement is configured differently. This field stays to 0. */ + ulTempData |= ( 0x0 << ulFeatureBitOffset ); + } + } + } + + /* Then save the new DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pSharedInfo->ImageInfo.fAfTailDisplacement == TRUE ) + { + /* Set the tail displacement offset in the AF. */ + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AfTailDisplacementFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AfTailDisplacementFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AfTailDisplacementFieldOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTempData |= ( ( ( pSharedInfo->ChipConfig.usTailDisplacement / 16 ) ) << ulFeatureBitOffset ); + } + else + { + ulTempData |= ( ( ( f_pVqeConfig->ulTailDisplacement / 16 ) ) << ulFeatureBitOffset ); + } + + /* Then save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + ulFeatureBytesOffset = pSharedInfo->MemoryMap.TailDisplEnableOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.TailDisplEnableOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.TailDisplEnableOfst.byFieldSize; + + /* First read the DWORD where the field is located.*/ + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + ulTempData |= ( ( (UINT32)f_pVqeConfig->fEnableTailDisplacement ) << ulFeatureBitOffset ); + + /* Then save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the tail length. */ + if ( pSharedInfo->ImageInfo.fPerChannelTailLength == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( ( f_fModifyOnly == TRUE ) + && ( f_pVqeConfig->ulTailLength != pChanEntry->VqeConfig.usTailLength ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PerChanTailLengthFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PerChanTailLengthFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PerChanTailLengthFieldOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + /* Check if must automatically select maximum or if must use user specific value. */ + if ( f_pVqeConfig->ulTailLength == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTempData |= ( ( ( pSharedInfo->ImageInfo.usMaxTailLength - 32 ) / 4 ) << ulFeatureBitOffset ); + } + else + { + ulTempData |= ( ( ( f_pVqeConfig->ulTailLength - 32 ) / 4 ) << ulFeatureBitOffset ); + } + + /* Then save the DWORD where the field is located.*/ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulAfConfBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Configure AEC tail length. */ + if ( pSharedInfo->ImageInfo.fAecTailLength == TRUE ) + { + /* Check if the configuration has been changed. */ + if ( ( f_fModifyOnly == FALSE ) + || ( fTailDisplacementModified == TRUE ) + || ( ( f_fModifyOnly == TRUE ) + && ( ( f_pVqeConfig->ulAecTailLength != pChanEntry->VqeConfig.usAecTailLength ) + || ( f_pVqeConfig->fAcousticEcho != pChanEntry->VqeConfig.fAcousticEcho ) ) ) ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.AecTailLengthFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.AecTailLengthFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.AecTailLengthFieldOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set acoustic echo tail length. */ + if ( f_pVqeConfig->fAcousticEcho == TRUE ) + { + switch( f_pVqeConfig->ulAecTailLength ) + { + case 1024: + ulTempData |= ( ( 3 ) << ulFeatureBitOffset ); + break; + case 512: + ulTempData |= ( ( 2 ) << ulFeatureBitOffset ); + break; + case 256: + ulTempData |= ( ( 1 ) << ulFeatureBitOffset ); + break; + case 128: + default: + ulTempData |= ( ( 0 ) << ulFeatureBitOffset ); + break; + } + } + else if ( f_pVqeConfig->fEnableTailDisplacement == TRUE ) + { + /* No acoustic echo case. */ + + /* Start with requested tail displacement. */ + if ( f_pVqeConfig->ulTailDisplacement == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum = pSharedInfo->ChipConfig.usTailDisplacement; + } + else + { + ulTailSum = f_pVqeConfig->ulTailDisplacement; + } + + /* Add requested tail length. */ + if ( f_pVqeConfig->ulTailLength == cOCT6100_AUTO_SELECT_TAIL ) + { + ulTailSum += pSharedInfo->ImageInfo.usMaxTailLength; + } + else + { + ulTailSum += f_pVqeConfig->ulTailLength; + } + + /* Round this value up. */ + if ( ulTailSum <= 128 ) + { + ulTempData |= ( ( 0 ) << ulFeatureBitOffset ); + } + else if ( ulTailSum <= 256 ) + { + ulTempData |= ( ( 1 ) << ulFeatureBitOffset ); + } + else if ( ulTailSum <= 512 ) + { + ulTempData |= ( ( 2 ) << ulFeatureBitOffset ); + } + else /* if ( ulTailSum <= 1024 ) */ + { + ulTempData |= ( ( 3 ) << ulFeatureBitOffset ); + } + } + else + { + /* Keep this to zero. */ + ulTempData |= ( ( 0 ) << ulFeatureBitOffset ); + } + + /* Write the new DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulNlpConfBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelMuteSer + +Description: This function will mute some of the ports on a given + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelMute What channel/ports to mute. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelMuteSer +UINT32 Oct6100ChannelMuteSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MUTE f_pChannelMute ) +{ + UINT32 ulResult; + UINT16 usChanIndex; + UINT16 usPortMask; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertChannelMuteParams( f_pApiInstance, + f_pChannelMute, + &usChanIndex, + &usPortMask ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Call the actual channel mute ports function. */ + ulResult = Oct6100ApiMuteChannelPorts( f_pApiInstance, + usChanIndex, + usPortMask, + TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertChannelMuteParams + +Description: Check the user parameters passed to the channel mute function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelMute What channel/ports to mute. +f_pusChanIndex Resulting channel index where the muting should + be applied. +f_pusPorts Port mask on which to apply the muting. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertChannelMuteParams +UINT32 Oct6100ApiAssertChannelMuteParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_MUTE f_pChannelMute, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusPorts ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pChannelMute->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelMute->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelMute->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + if ( pChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_PART_OF_BIDIR_CHANNEL; + + /*=======================================================================*/ + + /* Check the provided port mask. */ + + if ( ( f_pChannelMute->ulPortMask & + ~( cOCT6100_CHANNEL_MUTE_PORT_NONE | + cOCT6100_CHANNEL_MUTE_PORT_RIN | + cOCT6100_CHANNEL_MUTE_PORT_ROUT | + cOCT6100_CHANNEL_MUTE_PORT_SIN | + cOCT6100_CHANNEL_MUTE_PORT_SOUT | + cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) ) != 0 ) + return cOCT6100_ERR_CHANNEL_MUTE_MASK; + + /* Sin + Sin with features cannot be muted simultaneously. */ + if ( ( ( f_pChannelMute->ulPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) + && ( ( f_pChannelMute->ulPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) ) + return cOCT6100_ERR_CHANNEL_MUTE_MASK_SIN; + + /* Check if Sin mute with features is supported by the firmware. */ + if ( ( ( f_pChannelMute->ulPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + && ( pSharedInfo->ImageInfo.fSinMute == FALSE ) ) + return cOCT6100_ERR_NOT_SUPPORTED_CHANNEL_SIN_MUTE_FEATURES; + + /* Return the ports to the calling function. */ + *f_pusPorts = (UINT16)( f_pChannelMute->ulPortMask & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChannelUnMuteSer + +Description: This function will unmute some of the ports on a given + channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelUnMute What channel/ports to unmute. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChannelUnMuteSer +UINT32 Oct6100ChannelUnMuteSer( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute ) +{ + UINT32 ulResult; + UINT16 usChanIndex; + UINT16 usPortMask; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertChannelUnMuteParams( f_pApiInstance, + f_pChannelUnMute, + &usChanIndex, + &usPortMask ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Call the actual channel mute ports function. */ + ulResult = Oct6100ApiMuteChannelPorts( f_pApiInstance, + usChanIndex, + usPortMask, + FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertChannelUnMuteParams + +Description: Check the user parameters passed to the channel unmute function. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pChannelUnMute What channel/ports to Unmute. +f_pusChanIndex Resulting channel index where the muting should + be applied. +f_pusPorts Port mask on which to apply the muting. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertChannelUnMuteParams +UINT32 Oct6100ApiAssertChannelUnMuteParams( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHANNEL_UNMUTE f_pChannelUnMute, + OUT PUINT16 f_pusChanIndex, + OUT PUINT16 f_pusPorts ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + UINT32 ulEntryOpenCnt; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check the provided handle. */ + if ( (f_pChannelUnMute->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + *f_pusChanIndex = (UINT16)( f_pChannelUnMute->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusChanIndex >= pSharedInfo->ChipConfig.usMaxChannels ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + + /*=======================================================================*/ + /* Get a pointer to the channel's list entry. */ + + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, *f_pusChanIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = ( f_pChannelUnMute->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pChanEntry->fReserved != TRUE ) + return cOCT6100_ERR_CHANNEL_NOT_OPEN; + if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CHANNEL_INVALID_HANDLE; + if ( pChanEntry->fBiDirChannel == TRUE ) + return cOCT6100_ERR_CHANNEL_PART_OF_BIDIR_CHANNEL; + + /*=======================================================================*/ + + /* Check the provided port mask. */ + + if ( ( f_pChannelUnMute->ulPortMask & + ~( cOCT6100_CHANNEL_MUTE_PORT_NONE | + cOCT6100_CHANNEL_MUTE_PORT_RIN | + cOCT6100_CHANNEL_MUTE_PORT_ROUT | + cOCT6100_CHANNEL_MUTE_PORT_SIN | + cOCT6100_CHANNEL_MUTE_PORT_SOUT | + cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) ) != 0 ) + return cOCT6100_ERR_CHANNEL_MUTE_MASK; + + /* Return the ports to the calling function. */ + *f_pusPorts = (UINT16)( f_pChannelUnMute->ulPortMask & 0xFFFF ); + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMuteSinWithFeatures + +Description: Mute or Unmute the sin with features port. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usChanIndex Resulting channel index where the muting should + be applied. +f_fEnableSinWithFeatures Whether to enable the feature or not. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMuteSinWithFeatures +UINT32 Oct6100ApiMuteSinWithFeatures( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN BOOL f_fEnableSinWithFeatures ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( pChanEntry->usEchoMemIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst; + + if ( pSharedInfo->ImageInfo.fSinMute == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.SinMuteOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.SinMuteOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.SinMuteOfst.byFieldSize; + + mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + &ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Clear the mute flag. */ + ulTempData &= (~ulMask); + + /* Set the mute flag on the Sin port.*/ + if ( f_fEnableSinWithFeatures == TRUE ) + ulTempData |= ( 0x1 << ulFeatureBitOffset ); + + /* Write the new DWORD where the field is located. */ + mOCT6100_SAVE_NLP_CONF_DWORD( f_pApiInstance, + pChanEntry, + ulBaseAddress + ulFeatureBytesOffset, + ulTempData, + ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiMuteChannelPorts + +Description: Mute or Unmute the specified ports, according to the mask. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_usChanIndex Resulting channel index where the muting should + be applied. +f_usPortMask Port mask on which to apply the muting/unmuting. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiMuteChannelPorts +UINT32 Oct6100ApiMuteChannelPorts( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usChanIndex, + IN UINT16 f_usPortMask, + IN BOOL f_fMute ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + BOOL fDisableSinWithFeatures = FALSE; + BOOL fEnableSinWithFeatures = FALSE; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Get a pointer to the channel's list entry. */ + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex ) + + /* Rin port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_RIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_RIN ) == 0x0 ) ) + { + /* Mute this port. */ + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_RIN; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, f_usChanIndex, pChanEntry->usRinTsstIndex, pChanEntry->usSinTsstIndex, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + { + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_RIN; + return ulResult; + } + } + else if ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_RIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_RIN ) != 0x0 ) ) + { + /* Unmute this port. */ + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_RIN; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, f_usChanIndex, pChanEntry->usRinTsstIndex, pChanEntry->usSinTsstIndex, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Rout port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) == 0x0 ) ) + { + /* Mute this port. */ + + if ( pChanEntry->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + pChanEntry->usRoutTsstIndex, + pChanEntry->CodecConfig.byAdpcmNibblePosition, + pChanEntry->TdmConfig.byRoutNumTssts, + 1534 ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_ROUT; + } + else if ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_ROUT ) != 0x0 ) ) + { + /* Unmute this port. */ + + if ( pChanEntry->usRoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + pChanEntry->usRoutTsstIndex, + pChanEntry->CodecConfig.byAdpcmNibblePosition, + pChanEntry->TdmConfig.byRoutNumTssts, + pChanEntry->usRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_ROUT; + } + + /* Sin port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) == 0x0 ) ) + { + /* Mute this port. */ + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_SIN; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, f_usChanIndex, pChanEntry->usRinTsstIndex, pChanEntry->usSinTsstIndex, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + { + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_SIN; + return ulResult; + } + } + else if ( + ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) ) + || + ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) ) ) + { + /* Unmute this port. */ + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_SIN; + + ulResult = Oct6100ApiMutePorts( f_pApiInstance, f_usChanIndex, pChanEntry->usRinTsstIndex, pChanEntry->usSinTsstIndex, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Sout port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) == 0x0 ) ) + { + /* Mute this port. */ + + if ( pChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + pChanEntry->usSoutTsstIndex, + pChanEntry->CodecConfig.byAdpcmNibblePosition, + pChanEntry->TdmConfig.bySoutNumTssts, + 1534 ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_SOUT; + } + else if ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SOUT ) != 0x0 ) ) + { + /* Unmute this port. */ + + if ( pChanEntry->usSoutTsstIndex != cOCT6100_INVALID_INDEX ) + { + ulResult = Oct6100ApiWriteOutputTsstControlMemory( f_pApiInstance, + pChanEntry->usSoutTsstIndex, + pChanEntry->CodecConfig.byAdpcmNibblePosition, + pChanEntry->TdmConfig.bySoutNumTssts, + pChanEntry->usSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_SOUT; + } + + /* Sin with features port. */ + if ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) == 0x0 ) ) + { + /* Mute this port. */ + pChanEntry->usMutedPorts |= cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES; + fEnableSinWithFeatures = TRUE; + } + else if ( + ( ( f_fMute == FALSE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) ) + || + ( ( f_fMute == TRUE ) + && ( ( f_usPortMask & cOCT6100_CHANNEL_MUTE_PORT_SIN ) != 0x0 ) + && ( ( pChanEntry->usMutedPorts & cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES ) != 0x0 ) ) ) + { + /* Unmute this port. */ + pChanEntry->usMutedPorts &= ~cOCT6100_CHANNEL_MUTE_PORT_SIN_WITH_FEATURES; + + fDisableSinWithFeatures = TRUE; + } + + /* Check if must enable or disable SIN mute with features. */ + if ( fDisableSinWithFeatures == TRUE || fEnableSinWithFeatures == TRUE ) + { + ulResult = Oct6100ApiMuteSinWithFeatures( f_pApiInstance, f_usChanIndex, fEnableSinWithFeatures ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,6905 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_open.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains the functions used to power-up the chip according to the + user's configuration. Also, the API instance is initialized to reflect the + desired configuration. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 347 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_bt0.h" +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_tsi_cnct_inst.h" +#include "oct6100api/oct6100_events_inst.h" +#include "oct6100api/oct6100_conf_bridge_inst.h" +#include "oct6100api/oct6100_playout_buf_inst.h" + +#include "oct6100api/oct6100_mixer_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_adpcm_chan_inst.h" +#include "oct6100api/oct6100_phasing_tsst_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_chip_stats_pub.h" +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_tsi_cnct_pub.h" +#include "oct6100api/oct6100_events_pub.h" +#include "oct6100api/oct6100_conf_bridge_pub.h" +#include "oct6100api/oct6100_playout_buf_pub.h" + +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_adpcm_chan_pub.h" +#include "oct6100api/oct6100_phasing_tsst_pub.h" +#include "oct6100api/oct6100_remote_debug_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_debug_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_interrupts_priv.h" +#include "oct6100_chip_stats_priv.h" +#include "octrpc/rpc_protocol.h" +#include "oct6100_remote_debug_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_tsi_cnct_priv.h" +#include "oct6100_mixer_priv.h" +#include "oct6100_events_priv.h" +#include "oct6100_conf_bridge_priv.h" +#include "oct6100_playout_buf_priv.h" + +#include "oct6100_channel_priv.h" +#include "oct6100_adpcm_chan_priv.h" +#include "oct6100_phasing_tsst_priv.h" +#include "oct6100_tlv_priv.h" +#include "oct6100_debug_priv.h" +#include "oct6100_version.h" + + +/**************************** PUBLIC FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100GetInstanceSizeDef + +Description: Retrieves the size of the required API instance structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pGetSize Structure containing API instance size. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100GetInstanceSizeDef +UINT32 Oct6100GetInstanceSizeDef( + tPOCT6100_GET_INSTANCE_SIZE f_pGetSize ) +{ + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100GetInstanceSize +UINT32 Oct6100GetInstanceSize( + tPOCT6100_CHIP_OPEN f_pChipOpen, + tPOCT6100_GET_INSTANCE_SIZE f_pGetSize ) +{ + tOCT6100_API_INSTANCE_SIZES InstanceSizes; + UINT32 ulResult; + + /* Check user configuration for errors and conflicts. */ + ulResult = Oct6100ApiCheckChipConfiguration( f_pChipOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Calculate the instance size required for user's configuration. */ + ulResult = Oct6100ApiCalculateInstanceSizes( f_pChipOpen, &InstanceSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Return required size to user. */ + f_pGetSize->ulApiInstanceSize = InstanceSizes.ulApiInstTotal; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipOpenDef + +Description: Inserts default chip configuration parameters into the + structure pointed to by f_pChipOpen. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pChipOpen Structure containing user chip configuration. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipOpenDef +UINT32 Oct6100ChipOpenDef( + tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + UINT32 i; + + f_pChipOpen->ulUserChipId = 0; + f_pChipOpen->fMultiProcessSystem = FALSE; + f_pChipOpen->pProcessContext = NULL; + + f_pChipOpen->ulMaxRwAccesses = 8; + + f_pChipOpen->pbyImageFile = NULL; + f_pChipOpen->ulImageSize = 0; + + f_pChipOpen->ulMemClkFreq = 133000000; /* 133 Mhz */ + f_pChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ; /* 33.33 Mhz */ + f_pChipOpen->fEnableMemClkOut = TRUE; + + f_pChipOpen->ulMemoryType = cOCT6100_MEM_TYPE_DDR; + f_pChipOpen->ulNumMemoryChips = 1; + f_pChipOpen->ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_64MB; + + /* Set the tail displacement to zero. */ + f_pChipOpen->ulTailDisplacement = 0; + + /* Disable acoustic echo by default. */ + f_pChipOpen->fEnableAcousticEcho = FALSE; + + /* Resource allocation parameters. */ + f_pChipOpen->ulMaxChannels = 672; + f_pChipOpen->ulMaxTsiCncts = 0; + f_pChipOpen->ulMaxBiDirChannels = 0; + f_pChipOpen->ulMaxConfBridges = 0; + f_pChipOpen->ulMaxFlexibleConfParticipants = 0; + f_pChipOpen->ulMaxPlayoutBuffers = 0; + + f_pChipOpen->ulMaxPhasingTssts = 0; + f_pChipOpen->ulMaxAdpcmChannels = 0; + f_pChipOpen->ulMaxTdmStreams = 32; + f_pChipOpen->fUseSynchTimestamp = FALSE; + for ( i = 0; i < 4; i++ ) + { + f_pChipOpen->aulTimestampTimeslots[ i ] = cOCT6100_INVALID_TIMESLOT; + f_pChipOpen->aulTimestampStreams[ i ] = cOCT6100_INVALID_STREAM; + } + f_pChipOpen->fEnableFastH100Mode = FALSE; + + /* Configure the soft tone event buffer. */ + f_pChipOpen->ulSoftToneEventsBufSize = 2048; + f_pChipOpen->fEnableExtToneDetection = FALSE; + f_pChipOpen->fEnable2100StopEvent = FALSE; + + /* Configure the soft playout event buffer. */ + f_pChipOpen->ulSoftBufferPlayoutEventsBufSize = cOCT6100_INVALID_VALUE; + + /* Interrupt configuration. */ + f_pChipOpen->ulInterruptPolarity = cOCT6100_ACTIVE_LOW_POLARITY; + + f_pChipOpen->InterruptConfig.ulErrorMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulFatalGeneralConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulErrorH100Config = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + + f_pChipOpen->InterruptConfig.ulErrorMemoryTimeout = 100; + f_pChipOpen->InterruptConfig.ulFatalMemoryTimeout = 100; + f_pChipOpen->InterruptConfig.ulErrorH100Timeout = 100; + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsTimeout = 100; + f_pChipOpen->ulMaxRemoteDebugSessions = 1; + f_pChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_3_QUARTERS; + for ( i = 0; i < cOCT6100_TDM_STREAM_MAX_GROUPS; i++ ) + f_pChipOpen->aulTdmStreamFreqs[ i ] = cOCT6100_TDM_STREAM_FREQ_8MHZ; + + + + f_pChipOpen->fEnableChannelRecording = FALSE; + f_pChipOpen->fEnableProductionBist = FALSE; + f_pChipOpen->ulProductionBistMode = cOCT6100_PRODUCTION_BIST_STANDARD; + f_pChipOpen->ulNumProductionBistLoops = 1; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipOpen + +Description: Configures the chip according to the user specified + configuration f_pChipOpen. This function will perform all I/O + accesses necessary and initialize the API instance to reflect + the configuration. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipOpen Structure containing user chip configuration. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipOpen +UINT32 Oct6100ChipOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + tOCT6100_API_INSTANCE_SIZES *InstanceSizes; + UINT32 ulStructSize; + UINT32 ulResult; + UINT32 ulTempVar; + + /* Check user chip configuration parameters for errors. */ + ulResult = Oct6100ApiCheckChipConfiguration( f_pChipOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the host system is multi-process or not and adjust instance accordingly. */ + if ( f_pChipOpen->fMultiProcessSystem != TRUE ) + { + /* Set pointer to tOCT6100_SHARED_INFO structure within instance. */ + ulStructSize = sizeof( tOCT6100_INSTANCE_API ); + mOCT6100_ROUND_MEMORY_SIZE( ulStructSize, ulTempVar ) + + f_pApiInstance->pSharedInfo = ( tPOCT6100_SHARED_INFO )(( PUINT8 )f_pApiInstance + ulStructSize); + + /* Save the process context specified by the user. */ + f_pApiInstance->pProcessContext = f_pChipOpen->pProcessContext; + + /* Create serialization object handles. */ + ulResult = Oct6100ApiCreateSerializeObjects( f_pApiInstance, f_pChipOpen->ulUserChipId ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Copy the configuration structure. */ + ulResult = Oct6100ApiCopyChipConfiguration( f_pApiInstance, f_pChipOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Perform various calculations based on user chip configuration. */ + ulResult = Oct6100ApiInitializeMiscellaneousVariables( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + InstanceSizes = kmalloc(sizeof(tOCT6100_API_INSTANCE_SIZES), GFP_ATOMIC); + if (!InstanceSizes) + return cOCT6100_ERR_FATAL_0; + /* Calculate the amount of memory needed for the API instance structure. */ + ulResult = Oct6100ApiCalculateInstanceSizes( f_pChipOpen, InstanceSizes ); + if ( ulResult != cOCT6100_ERR_OK ) { + kfree(InstanceSizes); + return ulResult; + } + + /* Allocate the memory for the API instance structure internal pointers. */ + ulResult = Oct6100ApiAllocateInstanceMemory( f_pApiInstance, InstanceSizes ); + kfree(InstanceSizes); + + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the allocated instance structure memory. */ + ulResult = Oct6100ApiInitializeInstanceMemory( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the tone information structure. */ + ulResult = Oct6100ApiInitToneInfo( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Test the CPU registers. */ + ulResult = Oct6100ApiCpuRegisterBist( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the FC2 PLL. */ + ulResult = Oct6100ApiBootFc2Pll( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the FC1 PLL. */ + ulResult = Oct6100ApiProgramFc1Pll( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Decode the key and bist internal memories. */ + ulResult = Oct6100ApiDecodeKeyAndBist( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the FC1 PLL. */ + ulResult = Oct6100ApiBootFc1Pll( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the SDRAM. */ + ulResult = Oct6100ApiBootSdram( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Bist the external memory. */ + ulResult = Oct6100ApiExternalMemoryBist( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the external memory. */ + ulResult = Oct6100ApiExternalMemoryInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Load the image into the chip. */ + ulResult = Oct6100ApiLoadImage( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the clock distribution registers. */ + ulResult = Oct6100ApiEnableClocks( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the NLP processor. */ + ulResult = Oct6100ApiProgramNLP( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_OPEN_EGO_TIMEOUT ) + ulResult = Oct6100ApiProgramNLP( f_pApiInstance ); + } + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( f_pChipOpen->fEnableProductionBist == FALSE ) + { + /* Read all TLV fields present in external memory. */ + ulResult = Oct6100ApiProcessTlvRegion( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the H.100 interface. */ + ulResult = Oct6100ApiSetH100Register( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Write miscellaneous registers. */ + ulResult = Oct6100ApiWriteMiscellaneousRegisters( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Proceed with the rest only if the production BIST has not been requested. */ + if ( f_pChipOpen->fEnableProductionBist == FALSE ) + { + /* Initialize the errors counters. */ + ulResult = Oct6100ApiChipStatsSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get revision number of chip. */ + ulResult = Oct6100ApiGetChipRevisionNum( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + + + /* Initialize the channels. */ + ulResult = Oct6100ApiInitChannels( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the mixer memory. */ + ulResult = Oct6100ApiInitMixer( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the mixer memory. */ + ulResult = Oct6100ApiInitRecordResources( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize free external memory for buffer playout. */ + ulResult = Oct6100ApiBufferPlayoutMemorySwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + + /*Clear all interrupts that could have occured during startup*/ + ulResult = Oct6100ApiClearInterrupts( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the interrupt registers. */ + ulResult = Oct6100ApiIsrHwInit( f_pApiInstance, &f_pChipOpen->InterruptConfig ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipCloseDef + +Description: Puts the chip into soft reset. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipClose Pointer to a tOCT6100_CHIP_CLOSE structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipCloseDef +UINT32 Oct6100ChipCloseDef( + tPOCT6100_CHIP_CLOSE f_pChipClose ) +{ + f_pChipClose->ulDummyVariable = 0; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ChipClose +UINT32 Oct6100ChipClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_CLOSE f_pChipClose ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Destroy the allocated ressources used for serialization. */ + ulResult = Oct6100ApiDestroySerializeObjects( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100CreateLocalInstance + +Description: Creates a local instance for a process in a multi-process + host system. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pCreateLocal Structure used to create process' local instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100CreateLocalInstanceDef +UINT32 Oct6100CreateLocalInstanceDef( + tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ) +{ + f_pCreateLocal->pApiInstShared = NULL; + f_pCreateLocal->pApiInstLocal = NULL; + f_pCreateLocal->pProcessContext = NULL; + f_pCreateLocal->ulUserChipId = 0; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100CreateLocalInstance +UINT32 Oct6100CreateLocalInstance( + tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ) +{ + tPOCT6100_INSTANCE_API pApiInstLocal; + UINT32 ulApiInstSize; + UINT32 ulTempVar; + UINT32 ulResult; + + /* Check user's structure for errors. */ + if ( f_pCreateLocal->pApiInstShared == NULL ) + return cOCT6100_ERR_MULTIPROC_API_INST_SHARED; + + if ( f_pCreateLocal->pApiInstLocal == NULL ) + return cOCT6100_ERR_MULTIPROC_API_INST_LOCAL; + + /* Get local pointer to local instance. */ + pApiInstLocal = f_pCreateLocal->pApiInstLocal; + + /* Assign pointers to local structure. */ + ulApiInstSize = sizeof( tOCT6100_INSTANCE_API ); + mOCT6100_ROUND_MEMORY_SIZE( ulApiInstSize, ulTempVar ) + + pApiInstLocal->pSharedInfo = ( tPOCT6100_SHARED_INFO )(( PUINT8 )f_pCreateLocal->pApiInstShared + ulApiInstSize); + pApiInstLocal->pProcessContext = f_pCreateLocal->pProcessContext; + + /* Create serialization object handles needed. */ + ulResult = Oct6100ApiCreateSerializeObjects( pApiInstLocal, f_pCreateLocal->ulUserChipId ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100DestroyLocalInstance + +Description: Release local instance for a process in a multi-process + host system. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pDestroyLocal Structure used to destroy the process' local instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100DestroyLocalInstanceDef +UINT32 Oct6100DestroyLocalInstanceDef( + tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ) +{ + f_pDestroyLocal->ulDummy = 0; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100DestroyLocalInstance +UINT32 Oct6100DestroyLocalInstance( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ) +{ + UINT32 ulResult; + + /* Destroy the allocated ressources used for serialization. */ + ulResult = Oct6100ApiDestroySerializeObjects( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100GetHwRevision + +Description: Gets the hardware revision number of the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pGetHwRev Pointer to user structure in which to return revision + number. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100GetHwRevisionDef +UINT32 Oct6100GetHwRevisionDef( + tPOCT6100_GET_HW_REVISION f_pGetHwRev ) +{ + f_pGetHwRev->ulUserChipId = cOCT6100_INVALID_CHIP_ID; + f_pGetHwRev->pProcessContext = NULL; + f_pGetHwRev->ulRevisionNum = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100GetHwRevision +UINT32 Oct6100GetHwRevision( + tPOCT6100_GET_HW_REVISION f_pGetHwRev ) +{ + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + + /* Read the hardware revision register. */ + ReadParams.pProcessContext = f_pGetHwRev->pProcessContext; + + ReadParams.ulUserChipId = f_pGetHwRev->ulUserChipId; + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = 0x17E; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pGetHwRev->ulRevisionNum = ( usReadData >> 8 ) & 0xFF; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100FreeResources + +Description: This function closes all opened channels and frees all + specified global resources used by the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pFreeResources Pointer to user structure in which to choose what + to free. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100FreeResourcesDef +UINT32 Oct6100FreeResourcesDef( + tPOCT6100_FREE_RESOURCES f_pFreeResources ) +{ + f_pFreeResources->fFreeTsiConnections = FALSE; + f_pFreeResources->fFreeConferenceBridges = FALSE; + f_pFreeResources->fFreePlayoutBuffers = FALSE; + f_pFreeResources->fFreePhasingTssts = FALSE; + f_pFreeResources->fFreeAdpcmChannels = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100FreeResources +UINT32 Oct6100FreeResources( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_FREE_RESOURCES f_pFreeResources ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100FreeResourcesSer( f_pApiInstance, f_pFreeResources ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ProductionBist + +Description: This function retrieves the current BIST status of the + firmware. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pProductionBist Pointer to user structure where the bist information + will be returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ProductionBistDef +UINT32 Oct6100ProductionBistDef( + tPOCT6100_PRODUCTION_BIST f_pProductionBist ) +{ + f_pProductionBist->ulCurrentAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulCurrentLoop = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulFailedAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulReadValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulExpectedValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulBistStatus = cOCT6100_BIST_IN_PROGRESS; + f_pProductionBist->ulCurrentTest = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ProductionBist +UINT32 Oct6100ProductionBist( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_PRODUCTION_BIST f_pProductionBist ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ProductionBistSer( f_pApiInstance, f_pProductionBist ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetVersion + +Description: Retrieves the API version. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pApiGetVersion Pointer to structure that will receive version information. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetVersionDef +UINT32 Oct6100ApiGetVersionDef( + tPOCT6100_API_GET_VERSION f_pApiGetVersion ) +{ + UINT32 i; + + /* Initialize the string. */ + for ( i = 0; i < cOCT6100_API_VERSION_STRING_LENGTH; i++ ) + f_pApiGetVersion->achApiVersion[ i ] = 0; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ApiGetVersion +UINT32 Oct6100ApiGetVersion( + tPOCT6100_API_GET_VERSION f_pApiGetVersion ) +{ + /* Copy API version information to user. */ + Oct6100UserMemCopy( f_pApiGetVersion->achApiVersion, cOCT6100_API_VERSION, sizeof(cOCT6100_API_VERSION) ); + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetCapacityPins + +Description: Retrieves the Capcity Pins value. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pGetCapacityPins Pointer to the parameters structure needed + by GetCapacityPins(). + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetCapacityPinsDef +UINT32 Oct6100ApiGetCapacityPinsDef( + tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins) +{ + + f_pGetCapacityPins->pProcessContext = NULL; + f_pGetCapacityPins->ulUserChipId = 0; + f_pGetCapacityPins->ulMemoryType = cOCT6100_MEM_TYPE_DDR; + f_pGetCapacityPins->ulCapacityValue = cOCT6100_INVALID_VALUE; + f_pGetCapacityPins->fEnableMemClkOut = TRUE; + f_pGetCapacityPins->ulMemClkFreq = 133000000; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ApiGetCapacityPins +UINT32 Oct6100ApiGetCapacityPins( + tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins ) +{ + + UINT32 ulResult; + + tOCT6100_INSTANCE_API ApiInstance; + + Oct6100UserMemSet(&ApiInstance,0,sizeof(tOCT6100_INSTANCE_API)); + + /*Check parameters*/ + if ( f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_133_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_125_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_117_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_108_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_100_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_92_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_83_MHZ && + f_pGetCapacityPins->ulMemClkFreq != cOCT6100_MCLK_FREQ_75_MHZ ) + return cOCT6100_ERR_OPEN_MEM_CLK_FREQ; + + if ( f_pGetCapacityPins->fEnableMemClkOut != TRUE && + f_pGetCapacityPins->fEnableMemClkOut != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_MEM_CLK_OUT; + + if ( f_pGetCapacityPins->ulMemoryType != cOCT6100_MEM_TYPE_SDR && + f_pGetCapacityPins->ulMemoryType != cOCT6100_MEM_TYPE_DDR && + f_pGetCapacityPins->ulMemoryType != cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + return cOCT6100_ERR_OPEN_MEMORY_TYPE; + + + + ApiInstance.pProcessContext = f_pGetCapacityPins->pProcessContext; + + + + ulResult = Oct6100ApiReadCapacity(&ApiInstance, f_pGetCapacityPins); + + + + return ulResult; +} +#endif + +/*************************** PRIVATE FUNCTIONS *****************************/ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReadCapacity + +Description: Read the capacity pins using modified functions from the openchip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pChipOpen Pointer to chip configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_OCT6100ApiReadCapacity +UINT32 Oct6100ApiReadCapacity( IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins) +{ + UINT32 ulResult; + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + + /*Read capacity Pins*/ + + + ReadParams.pProcessContext = f_pGetCapacityPins->pProcessContext; + ReadParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /*Check the Reset register*/ + ReadParams.ulReadAddress = 0x100; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ((usReadData & 0xFFFF) != 0x0000) + return cOCT6100_ERR_CAP_PINS_INVALID_CHIP_STATE; + + /* Test the CPU registers. */ + ulResult = Oct6100ApiCpuRegisterBistReadCap( f_pApiInstance, f_pGetCapacityPins ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the FC2 PLL. */ + ulResult = Oct6100ApiBootFc2PllReadCap( f_pApiInstance,f_pGetCapacityPins ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the FC1 PLL. */ + ulResult = Oct6100ApiProgramFc1PllReadCap( f_pApiInstance,f_pGetCapacityPins ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR) || + (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + ReadParams.ulReadAddress = 0x168; + } + else + ReadParams.ulReadAddress = 0x166; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + switch (usReadData & 0xF) + { + case 0x9: + f_pGetCapacityPins->ulCapacityValue = 16; + break; + case 0x8: + f_pGetCapacityPins->ulCapacityValue = 32; + break; + case 0xE: + f_pGetCapacityPins->ulCapacityValue = 64; + break; + case 0x0: + f_pGetCapacityPins->ulCapacityValue = 128; + break; + case 0x2: + f_pGetCapacityPins->ulCapacityValue = 256; + break; + case 0x5: + f_pGetCapacityPins->ulCapacityValue = 512; + break; + case 0x6: + f_pGetCapacityPins->ulCapacityValue = 672; + break; + default: + f_pGetCapacityPins->ulCapacityValue = (usReadData & 0xF); + return cOCT6100_ERR_CAP_PINS_INVALID_CAPACITY_VALUE; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChipConfiguration + +Description: Checks the user chip configuration structure for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pChipOpen Pointer to chip configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckChipConfiguration +UINT32 Oct6100ApiCheckChipConfiguration( + IN tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + UINT32 ulTempVar; + UINT32 i; + + /*-----------------------------------------------------------------------------*/ + /* Check general parameters. */ + if ( f_pChipOpen->fMultiProcessSystem != TRUE && + f_pChipOpen->fMultiProcessSystem != FALSE ) + return cOCT6100_ERR_OPEN_MULTI_PROCESS_SYSTEM; + + if ( f_pChipOpen->ulMaxRwAccesses < 1 || + f_pChipOpen->ulMaxRwAccesses > 1024) + return cOCT6100_ERR_OPEN_MAX_RW_ACCESSES; + + /* Check the clocks. */ + if ( f_pChipOpen->ulUpclkFreq != cOCT6100_UPCLK_FREQ_33_33_MHZ ) + return cOCT6100_ERR_OPEN_UP_CLK_FREQ; + + if ( f_pChipOpen->ulMemClkFreq != cOCT6100_MCLK_FREQ_133_MHZ ) + return cOCT6100_ERR_OPEN_MEM_CLK_FREQ; + + if ( f_pChipOpen->fEnableMemClkOut != TRUE && + f_pChipOpen->fEnableMemClkOut != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_MEM_CLK_OUT; + + /* Check the image file. */ + if ( f_pChipOpen->ulImageSize < cOCT6100_MIN_IMAGE_SIZE || + f_pChipOpen->ulImageSize > cOCT6100_MAX_IMAGE_SIZE ) + return cOCT6100_ERR_OPEN_IMAGE_SIZE; + + if ( f_pChipOpen->pbyImageFile == NULL ) + return cOCT6100_ERR_OPEN_IMAGE_FILE; + + ulTempVar = Oct6100ApiCheckImageFileHeader(f_pChipOpen); + if (ulTempVar != cOCT6100_ERR_OK) + return ulTempVar; + + /* Check the acoustic echo activation flag. */ + if ( f_pChipOpen->fEnableAcousticEcho != TRUE && + f_pChipOpen->fEnableAcousticEcho != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_ACOUSTIC_ECHO; + + /* Check the tail displacement parameter. */ + if ( f_pChipOpen->ulTailDisplacement > cOCT6100_MAX_TAIL_DISPLACEMENT ) + return cOCT6100_ERR_OPEN_TAIL_DISPLACEMENT; + + /*-----------------------------------------------------------------------------*/ + /* Check TDM bus configuration parameters. */ + for ( i = 0; i < 8; i++ ) + { + if ( f_pChipOpen->aulTdmStreamFreqs[ i ] != cOCT6100_TDM_STREAM_FREQ_2MHZ && + f_pChipOpen->aulTdmStreamFreqs[ i ] != cOCT6100_TDM_STREAM_FREQ_4MHZ && + f_pChipOpen->aulTdmStreamFreqs[ i ] != cOCT6100_TDM_STREAM_FREQ_8MHZ) + return cOCT6100_ERR_OPEN_TDM_STREAM_FREQS; + } + + if ( f_pChipOpen->ulTdmSampling != cOCT6100_TDM_SAMPLE_AT_3_QUARTERS && + f_pChipOpen->ulTdmSampling != cOCT6100_TDM_SAMPLE_AT_RISING_EDGE && + f_pChipOpen->ulTdmSampling != cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE ) + return cOCT6100_ERR_OPEN_TDM_SAMPLING; + + if ( f_pChipOpen->fEnableFastH100Mode != TRUE && + f_pChipOpen->fEnableFastH100Mode != FALSE ) + return cOCT6100_ERR_OPEN_FAST_H100_MODE; + + /*-----------------------------------------------------------------------------*/ + /* Check external memory configuration parameters. */ + if ( f_pChipOpen->ulMemoryType != cOCT6100_MEM_TYPE_SDR && + f_pChipOpen->ulMemoryType != cOCT6100_MEM_TYPE_DDR && + f_pChipOpen->ulMemoryType != cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + return cOCT6100_ERR_OPEN_MEMORY_TYPE; + + if ( f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_8MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_16MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_32MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_64MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_128MB ) + return cOCT6100_ERR_OPEN_MEMORY_CHIP_SIZE; + + if ( f_pChipOpen->ulMemoryChipSize == cOCT6100_MEMORY_CHIP_SIZE_8MB && + f_pChipOpen->ulMemoryType == cOCT6100_MEM_TYPE_DDR ) + return cOCT6100_ERR_OPEN_MEMORY_CHIP_SIZE; + + if ( f_pChipOpen->ulNumMemoryChips < 1 || + f_pChipOpen->ulNumMemoryChips > cOCT6100_MAX_NUM_MEMORY_CHIP ) + return cOCT6100_ERR_OPEN_MEMORY_CHIPS_NUMBER; + + /* Check the total memory size. */ + ulTempVar = f_pChipOpen->ulMemoryChipSize * f_pChipOpen->ulNumMemoryChips; + if ( ulTempVar < cOCT6100_MEMORY_CHIP_SIZE_16MB || + ulTempVar > cOCT6100_MEMORY_CHIP_SIZE_128MB ) + return cOCT6100_ERR_OPEN_TOTAL_MEMORY_SIZE; + + if ( f_pChipOpen->ulMaxTdmStreams != 4 && + f_pChipOpen->ulMaxTdmStreams != 8 && + f_pChipOpen->ulMaxTdmStreams != 16 && + f_pChipOpen->ulMaxTdmStreams != 32 ) + return cOCT6100_ERR_OPEN_MAX_TDM_STREAM; + + if ( f_pChipOpen->ulMaxTdmStreams > 8 && + f_pChipOpen->ulMemClkFreq == cOCT6100_MCLK_FREQ_75_MHZ ) + return cOCT6100_ERR_OPEN_MAX_TDM_STREAM; + + if ( f_pChipOpen->fUseSynchTimestamp != TRUE && + f_pChipOpen->fUseSynchTimestamp != FALSE ) + return cOCT6100_ERR_OPEN_USE_SYNCH_TIMESTAMP; + + if ( f_pChipOpen->fUseSynchTimestamp == TRUE ) + { + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_USE_SYNCH_TIMESTAMP; + } + + /*-----------------------------------------------------------------------------*/ + /* Check soft buffer for tone events size. */ + if ( f_pChipOpen->ulSoftToneEventsBufSize < cOCT6100_NUM_PGSP_EVENT_OUT || + f_pChipOpen->ulSoftToneEventsBufSize > cOCT6100_ABSOLUTE_MAX_NUM_PGSP_EVENT_OUT ) + return cOCT6100_ERR_OPEN_SOFT_TONE_EVENT_SIZE; + + if ( f_pChipOpen->fEnableExtToneDetection != TRUE && + f_pChipOpen->fEnableExtToneDetection != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_EXT_TONE_DETECTION; + + if ( f_pChipOpen->fEnable2100StopEvent != TRUE && + f_pChipOpen->fEnable2100StopEvent != FALSE) + return cOCT6100_ERR_OPEN_ENABLE_2100_STOP_EVENT; + + /* Check soft buffer for playout events size. */ + if ( ( f_pChipOpen->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE ) + && ( f_pChipOpen->ulSoftBufferPlayoutEventsBufSize < cOCT6100_MIN_BUFFER_PLAYOUT_EVENT || + f_pChipOpen->ulSoftBufferPlayoutEventsBufSize > cOCT6100_MAX_BUFFER_PLAYOUT_EVENT ) ) + return cOCT6100_ERR_OPEN_SOFT_PLAYOUT_STOP_EVENT_SIZE; + + /*-----------------------------------------------------------------------------*/ + /* Check interrupt configuration parameters. */ + if ( f_pChipOpen->ulInterruptPolarity != cOCT6100_ACTIVE_LOW_POLARITY && + f_pChipOpen->ulInterruptPolarity != cOCT6100_ACTIVE_HIGH_POLARITY ) + return cOCT6100_ERR_OPEN_INTERRUPT_POLARITY; + + if ( f_pChipOpen->InterruptConfig.ulFatalGeneralConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulFatalGeneralConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_FATAL_GENERAL_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulFatalMemoryConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_FATAL_MEMORY_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulErrorMemoryConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorMemoryConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorMemoryConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_ERROR_MEMORY_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulErrorH100Config != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorH100Config != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorH100Config != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_ERROR_H100_CONFIG; + + /* Check the timeout value. */ + if ( f_pChipOpen->InterruptConfig.ulFatalMemoryTimeout < 10 || + f_pChipOpen->InterruptConfig.ulFatalMemoryTimeout > 10000 ) + return cOCT6100_ERR_OPEN_FATAL_MEMORY_TIMEOUT; + + if ( f_pChipOpen->InterruptConfig.ulErrorMemoryTimeout < 10 || + f_pChipOpen->InterruptConfig.ulErrorMemoryTimeout > 10000 ) + return cOCT6100_ERR_OPEN_ERROR_MEMORY_TIMEOUT; + + if ( f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsTimeout < 10 || + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsTimeout > 10000 ) + return cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_TIMEOUT; + + if ( f_pChipOpen->InterruptConfig.ulErrorH100Timeout < 10 || + f_pChipOpen->InterruptConfig.ulErrorH100Timeout > 10000 ) + return cOCT6100_ERR_OPEN_ERROR_H100_TIMEOUT; + + /*-----------------------------------------------------------------------------*/ + /* Check maximum resources. */ + + switch ( f_pChipOpen->ulMemClkFreq ) + { + case 133000000: + ulTempVar = 672; + break; + case 125000000: + ulTempVar = 624; + break; + case 117000000: + ulTempVar = 576; + break; + case 108000000: + ulTempVar = 528; + break; + case 100000000: + ulTempVar = 480; + break; + case 92000000: + ulTempVar = 432; + break; + case 83000000: + ulTempVar = 384; + break; + case 75000000: + ulTempVar = 336; + break; + default: + return cOCT6100_ERR_FATAL_DA; + } + + if ( f_pChipOpen->ulMaxChannels > ulTempVar ) + return cOCT6100_ERR_OPEN_MAX_ECHO_CHANNELS; + + if ( f_pChipOpen->ulMaxTsiCncts > cOCT6100_MAX_TSI_CNCTS ) + return cOCT6100_ERR_OPEN_MAX_TSI_CNCTS; + + + if ( f_pChipOpen->ulMaxBiDirChannels > 255 ) + return cOCT6100_ERR_OPEN_MAX_BIDIR_CHANNELS; + + if ( f_pChipOpen->ulMaxBiDirChannels > (f_pChipOpen->ulMaxChannels / 2) ) + return cOCT6100_ERR_OPEN_MAX_BIDIR_CHANNELS; + + if ( f_pChipOpen->ulMaxConfBridges > cOCT6100_MAX_CONF_BRIDGE ) + return cOCT6100_ERR_OPEN_MAX_CONF_BRIDGES; + + if ( f_pChipOpen->ulMaxFlexibleConfParticipants > cOCT6100_MAX_FLEX_CONF_PARTICIPANTS ) + return cOCT6100_ERR_OPEN_MAX_FLEXIBLE_CONF_PARTICIPANTS; + + if ( f_pChipOpen->ulMaxPlayoutBuffers > cOCT6100_MAX_PLAYOUT_BUFFERS ) + return cOCT6100_ERR_OPEN_MAX_PLAYOUT_BUFFERS; + + + + if ( f_pChipOpen->ulMaxPhasingTssts > cOCT6100_MAX_PHASING_TSST ) + return cOCT6100_ERR_OPEN_MAX_PHASING_TSSTS; + + if ( f_pChipOpen->ulMaxAdpcmChannels > cOCT6100_MAX_ADPCM_CHANNELS ) + return cOCT6100_ERR_OPEN_MAX_ADPCM_CHANNELS; + + if ( f_pChipOpen->ulMaxRemoteDebugSessions > 256 ) + return cOCT6100_ERR_OPEN_MAX_REMOTE_DEBUG_SESSIONS; + + + + + + /* Check the channel recording flag. */ + if ( f_pChipOpen->fEnableChannelRecording != TRUE && + f_pChipOpen->fEnableChannelRecording != FALSE ) + return cOCT6100_ERR_OPEN_DEBUG_CHANNEL_RECORDING; + + /* Check the enable production BIST flag. */ + if ( ( f_pChipOpen->fEnableProductionBist != TRUE ) + && ( f_pChipOpen->fEnableProductionBist != FALSE ) ) + return cOCT6100_ERR_OPEN_ENABLE_PRODUCTION_BIST; + + /* Check number of loops for the production BIST. */ + if ( f_pChipOpen->fEnableProductionBist == TRUE ) + { + if ( f_pChipOpen->ulNumProductionBistLoops == 0 ) + return cOCT6100_ERR_OPEN_NUM_PRODUCTION_BIST_LOOPS; + + if ( (f_pChipOpen->ulProductionBistMode != cOCT6100_PRODUCTION_BIST_STANDARD) && + (f_pChipOpen->ulProductionBistMode != cOCT6100_PRODUCTION_BIST_SHORT) ) + return cOCT6100_ERR_OPEN_PRODUCTION_BIST_MODE; + } + + /* If the production BIST has been requested, make sure all */ + /* other resources are disabled. */ + if ( f_pChipOpen->fEnableProductionBist == TRUE ) + { + /* All must be disabled. */ + f_pChipOpen->ulMaxChannels = 0; + f_pChipOpen->ulMaxTsiCncts = 0; + f_pChipOpen->fEnableChannelRecording = FALSE; + f_pChipOpen->ulMaxBiDirChannels = 0; + f_pChipOpen->ulMaxConfBridges = 0; + f_pChipOpen->ulMaxPlayoutBuffers = 0; + f_pChipOpen->ulSoftBufferPlayoutEventsBufSize = cOCT6100_INVALID_VALUE; + f_pChipOpen->ulMaxPhasingTssts = 0; + f_pChipOpen->ulMaxAdpcmChannels = 0; + + + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCopyChipConfiguration + +Description: Copies the chip configuration from the user supplied config + structure to the instance structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipOpen Pointer to chip configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCopyChipConfiguration +UINT32 Oct6100ApiCopyChipConfiguration( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + pSharedInfo->ChipConfig.ulUserChipId = f_pChipOpen->ulUserChipId; + pSharedInfo->ChipConfig.fMultiProcessSystem = (UINT8)( f_pChipOpen->fMultiProcessSystem & 0xFF ); + + pSharedInfo->ChipConfig.usMaxRwAccesses = (UINT16)( f_pChipOpen->ulMaxRwAccesses & 0xFFFF ); + + pSharedInfo->ChipConfig.pbyImageFile = f_pChipOpen->pbyImageFile; + pSharedInfo->ChipConfig.ulImageSize = f_pChipOpen->ulImageSize; + + pSharedInfo->ChipConfig.ulMemClkFreq = f_pChipOpen->ulMemClkFreq; + pSharedInfo->ChipConfig.ulUpclkFreq = f_pChipOpen->ulUpclkFreq; + + pSharedInfo->ChipConfig.byMemoryType = (UINT8)( f_pChipOpen->ulMemoryType & 0xFF ); + pSharedInfo->ChipConfig.byNumMemoryChips = (UINT8)( f_pChipOpen->ulNumMemoryChips & 0xFF ); + pSharedInfo->ChipConfig.ulMemoryChipSize = f_pChipOpen->ulMemoryChipSize; + + pSharedInfo->ChipConfig.usTailDisplacement = (UINT16)( f_pChipOpen->ulTailDisplacement & 0xFFFF ); + pSharedInfo->ChipConfig.fEnableAcousticEcho = (UINT8)( f_pChipOpen->fEnableAcousticEcho & 0xFF ); + /* Resource allocation parameters. */ + if ( f_pChipOpen->fEnableChannelRecording == TRUE && f_pChipOpen->ulMaxChannels == 672 ) + pSharedInfo->ChipConfig.usMaxChannels = (UINT16)( ( f_pChipOpen->ulMaxChannels - 1 ) & 0xFFFF ); + else + pSharedInfo->ChipConfig.usMaxChannels = (UINT16)( f_pChipOpen->ulMaxChannels & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxTsiCncts = (UINT16)( f_pChipOpen->ulMaxTsiCncts & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxBiDirChannels = (UINT16)( f_pChipOpen->ulMaxBiDirChannels & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxConfBridges = (UINT16)( f_pChipOpen->ulMaxConfBridges & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxFlexibleConfParticipants = (UINT16)( f_pChipOpen->ulMaxFlexibleConfParticipants & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxPlayoutBuffers = (UINT16)( f_pChipOpen->ulMaxPlayoutBuffers & 0xFFFF ); + + pSharedInfo->ChipConfig.usMaxPhasingTssts = (UINT16)( f_pChipOpen->ulMaxPhasingTssts & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxAdpcmChannels = (UINT16)( f_pChipOpen->ulMaxAdpcmChannels & 0xFFFF ); + pSharedInfo->ChipConfig.byMaxTdmStreams = (UINT8)( f_pChipOpen->ulMaxTdmStreams & 0xFF ); + pSharedInfo->ChipConfig.fUseSynchTimestamp = (UINT8)( f_pChipOpen->fUseSynchTimestamp & 0xFF ); + for ( i = 0; i < 4; i++ ) + { + pSharedInfo->ChipConfig.ausTimestampTimeslots[ i ] = (UINT16)( f_pChipOpen->aulTimestampTimeslots[ i ] & 0xFFFF ); + pSharedInfo->ChipConfig.ausTimestampStreams[ i ] = (UINT16)( f_pChipOpen->aulTimestampStreams[ i ] & 0xFFFF ); + } + pSharedInfo->ChipConfig.byInterruptPolarity = (UINT8)( f_pChipOpen->ulInterruptPolarity & 0xFF ); + + pSharedInfo->ChipConfig.byTdmSampling = (UINT8)( f_pChipOpen->ulTdmSampling & 0xFF ); + pSharedInfo->ChipConfig.fEnableFastH100Mode = (UINT8)( f_pChipOpen->fEnableFastH100Mode & 0xFF ); + + for ( i = 0; i < cOCT6100_TDM_STREAM_MAX_GROUPS; i++ ) + { + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->ChipConfig.aulTdmStreamFreqs[ i ] = cOCT6100_TDM_STREAM_FREQ_16MHZ; + else + pSharedInfo->ChipConfig.aulTdmStreamFreqs[ i ] = f_pChipOpen->aulTdmStreamFreqs[ i ]; + } + + pSharedInfo->ChipConfig.fEnableFastH100Mode = (UINT8)( f_pChipOpen->fEnableFastH100Mode & 0xFF ); + pSharedInfo->ChipConfig.fEnableMemClkOut = (UINT8)( f_pChipOpen->fEnableMemClkOut & 0xFF ); + + /* Add 1 to the circular buffer such that all user requested events can fit in the circular queue. */ + pSharedInfo->ChipConfig.ulSoftToneEventsBufSize = f_pChipOpen->ulSoftToneEventsBufSize + 1; + pSharedInfo->ChipConfig.fEnableExtToneDetection = (UINT8)( f_pChipOpen->fEnableExtToneDetection & 0xFF ); + pSharedInfo->ChipConfig.fEnable2100StopEvent = (UINT8)( f_pChipOpen->fEnable2100StopEvent & 0xFF ); + + if ( f_pChipOpen->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE ) + pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize = f_pChipOpen->ulSoftBufferPlayoutEventsBufSize + 1; + else + pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize = 0; + pSharedInfo->ChipConfig.usMaxRemoteDebugSessions = (UINT16)( f_pChipOpen->ulMaxRemoteDebugSessions & 0xFFFF ); + + pSharedInfo->ChipConfig.fEnableChannelRecording = (UINT8)( f_pChipOpen->fEnableChannelRecording & 0xFF ); + + + + pSharedInfo->ChipConfig.fEnableProductionBist = (UINT8)( f_pChipOpen->fEnableProductionBist & 0xFF ); + pSharedInfo->ChipConfig.ulProductionBistMode = f_pChipOpen->ulProductionBistMode; + pSharedInfo->ChipConfig.ulNumProductionBistLoops = f_pChipOpen->ulNumProductionBistLoops; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitializeMiscellaneousVariables + +Description: Function where all the various parameters from the API instance + are set to their defaults value. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitializeMiscellaneousVariables +UINT32 Oct6100ApiInitializeMiscellaneousVariables( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 i; + + /* Obtain pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Calculate the total memory available. */ + pSharedInfo->MiscVars.ulTotalMemSize = pSharedInfo->ChipConfig.ulMemoryChipSize * pSharedInfo->ChipConfig.byNumMemoryChips; + + /* Software buffers initialization. */ + + /* Tones */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = 0; + pSharedInfo->SoftBufs.ulToneEventBufferSize = pSharedInfo->ChipConfig.ulSoftToneEventsBufSize; + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt = 0; + + /* Playout */ + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize = pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt = 0; + + /* Set the number of conference bridges opened to zero. */ + pSharedInfo->MiscVars.usNumBridgesOpened = 0; + pSharedInfo->MiscVars.usFirstBridge = cOCT6100_INVALID_INDEX; + + /* Set the H.100 slave mode. */ + pSharedInfo->MiscVars.ulH100SlaveMode = cOCT6100_H100_TRACKA; + + /* Save the Mclk value.*/ + pSharedInfo->MiscVars.ulMclkFreq = pSharedInfo->ChipConfig.ulMemClkFreq; + + /* Init the NLP params. */ + pSharedInfo->MiscVars.usCodepoint = 0; + pSharedInfo->MiscVars.usCpuLsuWritePtr = 0; + + /* Pouch counter not present until TLVs are read. */ + pSharedInfo->DebugInfo.fPouchCounter = FALSE; + pSharedInfo->DebugInfo.fIsIsrCalledField = FALSE; + + /* Initialize the image info parameters */ + pSharedInfo->ImageInfo.fAdaptiveNoiseReduction = FALSE; + pSharedInfo->ImageInfo.fSoutNoiseBleaching = FALSE; + pSharedInfo->ImageInfo.fComfortNoise = FALSE; + pSharedInfo->ImageInfo.fBufferPlayout = TRUE; + pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip = FALSE; + pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip = FALSE; + pSharedInfo->ImageInfo.fNlpControl = FALSE; + pSharedInfo->ImageInfo.fRinAutoLevelControl = FALSE; + pSharedInfo->ImageInfo.fSoutAutoLevelControl = FALSE; + pSharedInfo->ImageInfo.fRinHighLevelCompensation = FALSE; + pSharedInfo->ImageInfo.fSoutHighLevelCompensation = FALSE; + pSharedInfo->ImageInfo.fAlcHlcStatus = FALSE; + pSharedInfo->ImageInfo.fRinDcOffsetRemoval = FALSE; + pSharedInfo->ImageInfo.fSilenceSuppression = FALSE; + pSharedInfo->ImageInfo.fSinDcOffsetRemoval = FALSE; + pSharedInfo->ImageInfo.fToneDisabler = FALSE; + pSharedInfo->ImageInfo.fAdpcm = FALSE; + pSharedInfo->ImageInfo.fTailDisplacement = FALSE; + pSharedInfo->ImageInfo.fConferencing = FALSE; + pSharedInfo->ImageInfo.fConferencingNoiseReduction = FALSE; + pSharedInfo->ImageInfo.fDominantSpeakerEnabled = FALSE; + pSharedInfo->ImageInfo.fAecEnabled = FALSE; + pSharedInfo->ImageInfo.fAcousticEcho = FALSE; + pSharedInfo->ImageInfo.fToneRemoval = FALSE; + + pSharedInfo->ImageInfo.fDefaultErl = FALSE; + pSharedInfo->ImageInfo.fMaxEchoPoint = FALSE; + pSharedInfo->ImageInfo.fNonLinearityBehaviorA = FALSE; + pSharedInfo->ImageInfo.fNonLinearityBehaviorB = FALSE; + pSharedInfo->ImageInfo.fPerChannelTailDisplacement = FALSE; + pSharedInfo->ImageInfo.fPerChannelTailLength = FALSE; + pSharedInfo->ImageInfo.fAfTailDisplacement = FALSE; + pSharedInfo->ImageInfo.fMusicProtection = FALSE; + pSharedInfo->ImageInfo.fAftControl = FALSE; + pSharedInfo->ImageInfo.fSinVoiceDetectedStat = FALSE; + pSharedInfo->ImageInfo.fRinAppliedGainStat = FALSE; + pSharedInfo->ImageInfo.fSoutAppliedGainStat = FALSE; + pSharedInfo->ImageInfo.fListenerEnhancement = FALSE; + pSharedInfo->ImageInfo.fRoutNoiseReduction = FALSE; + pSharedInfo->ImageInfo.fRoutNoiseReductionLevel = FALSE; + pSharedInfo->ImageInfo.fAnrSnrEnhancement = FALSE; + pSharedInfo->ImageInfo.fAnrVoiceNoiseSegregation = FALSE; + pSharedInfo->ImageInfo.fRinMute = FALSE; + pSharedInfo->ImageInfo.fSinMute = FALSE; + pSharedInfo->ImageInfo.fToneDisablerVqeActivationDelay = FALSE; + pSharedInfo->ImageInfo.fAecTailLength = FALSE; + pSharedInfo->ImageInfo.fMusicProtectionConfiguration= FALSE; + pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents = FALSE; + pSharedInfo->ImageInfo.fRinEnergyStat = FALSE; + pSharedInfo->ImageInfo.fSoutEnergyStat = FALSE; + pSharedInfo->ImageInfo.fDoubleTalkBehavior = FALSE; + pSharedInfo->ImageInfo.fDoubleTalkBehaviorFieldOfst = FALSE; + pSharedInfo->ImageInfo.fIdleCodeDetection = TRUE; + pSharedInfo->ImageInfo.fIdleCodeDetectionConfiguration = FALSE; + pSharedInfo->ImageInfo.fSinLevel = TRUE; + + pSharedInfo->ImageInfo.usMaxNumberOfChannels = 0; + pSharedInfo->ImageInfo.ulToneProfileNumber = cOCT6100_INVALID_VALUE; + pSharedInfo->ImageInfo.ulBuildId = cOCT6100_INVALID_VALUE; + pSharedInfo->ImageInfo.byImageType = cOCT6100_IMAGE_TYPE_WIRELINE; + pSharedInfo->ImageInfo.usMaxTailDisplacement = 0; + pSharedInfo->ImageInfo.usMaxTailLength = cOCT6100_TAIL_LENGTH_128MS; + pSharedInfo->DebugInfo.ulDebugEventSize = 0x100; + pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents = 32; + pSharedInfo->DebugInfo.ulMatrixBaseAddress = cOCT6100_MATRIX_DWORD_BASE; + pSharedInfo->DebugInfo.ulDebugChanStatsByteSize = cOCT6100_DEBUG_CHAN_STATS_EVENT_BYTE_SIZE; + pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize = cOCT6100_DEBUG_CHAN_STATS_LITE_EVENT_BYTE_SIZE; + pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress= cOCT6100_MATRIX_CHAN_SELECT_DWORD_ADD; + pSharedInfo->DebugInfo.ulMatrixTimestampBaseAddress = cOCT6100_MATRIX_TIMESTAMP_DWORD_ADD; + pSharedInfo->DebugInfo.ulMatrixWpBaseAddress = cOCT6100_MATRIX_WRITE_PTR_DWORD_ADD; + pSharedInfo->DebugInfo.ulAfWritePtrByteOffset = 206; + pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize = 4096; + pSharedInfo->DebugInfo.ulAfEventCbByteSize = 0x100000; + + /* Set all tones to invalid. */ + pSharedInfo->ImageInfo.byNumToneDetectors = 0; + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + pSharedInfo->ImageInfo.aToneInfo[ i ].ulToneID = cOCT6100_INVALID_VALUE; + pSharedInfo->ImageInfo.aToneInfo[ i ].ulDetectionPort = cOCT6100_INVALID_PORT; + Oct6100UserMemSet( pSharedInfo->ImageInfo.aToneInfo[ i ].aszToneName, 0x00, cOCT6100_TLV_MAX_TONE_NAME_SIZE ); + } + /* Initialize the channel recording info. */ + pSharedInfo->DebugInfo.usRecordChanIndex = pSharedInfo->ChipConfig.usMaxChannels; + pSharedInfo->DebugInfo.usRecordMemIndex = cOCT6100_INVALID_INDEX; + + pSharedInfo->DebugInfo.usCurrentDebugChanIndex = cOCT6100_INVALID_INDEX; + /* Initialize the mixer information. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + + pSharedInfo->MixerInfo.usRecordCopyEventIndex = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usRecordSinEventIndex = cOCT6100_INVALID_INDEX; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCalculateInstanceSizes + +Description: Calculates the amount of memory needed for the instance + structure memory block based on the user's configuration. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pChipOpen Pointer to user chip configuration structure. + +f_pInstSizes Pointer to structure containing the size of memory needed + by all pointers internal to the API instance. The memory + is needed to keep track of the present state of all the + chip's resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCalculateInstanceSizes +UINT32 Oct6100ApiCalculateInstanceSizes( + IN OUT tPOCT6100_CHIP_OPEN f_pChipOpen, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulApiInstProcessSpecific; + UINT32 ulTempVar; + UINT32 ulResult; + + /* Start with all instance sizes set to 0. */ + Oct6100UserMemSet( f_pInstSizes, 0x00, sizeof( tOCT6100_API_INSTANCE_SIZES ) ); + + /* All memory sizes are rounded up to the next multiple of 64 bytes. */ + + /*-----------------------------------------------------------------------------*/ + /* Obtain size of static members of API instance. */ + f_pInstSizes->ulApiInstStatic = sizeof( tOCT6100_SHARED_INFO ); + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulApiInstStatic, ulTempVar ) + + /* Calculate memory needed by pointers internal to the API instance. */ + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the EC channels. */ + ulResult = Oct6100ApiGetChannelsEchoSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Memory needed by the TSI structures. */ + ulResult = Oct6100ApiGetTsiCnctSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the conference bridges. */ + ulResult = Oct6100ApiGetConfBridgeSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Memory needed by the buffer playout structures. */ + ulResult = Oct6100ApiGetPlayoutBufferSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + /*-----------------------------------------------------------------------------*/ + /* Memory needed by soft Rx Event buffers. */ + ulResult = Oct6100ApiGetEventsSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for phasing tssts. */ + ulResult = Oct6100ApiGetPhasingTsstSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the ADPCM channels. */ + ulResult = Oct6100ApiGetAdpcmChanSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the management of TSSTs. */ + ulResult = Oct6100ApiGetTsstSwSizes( f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the management of the mixer. */ + ulResult = Oct6100ApiGetMixerSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Determine amount of memory needed for memory allocation softwares. These + pieces of software will be responsible for the allocation of the chip's + external memory and API memory. */ + ulResult = Oct6100ApiGetMemorySwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Memory needed for remote debugging sessions. */ + ulResult = Oct6100ApiGetRemoteDebugSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate total memory needed by pointers internal to API instance. The + total contains both the process specific portion of the instance + (tOCT6100_INSTANCE_API) and the shared portion (tOCT6100_SHARED_INFO). The + process specific portion will be used only in the case where the host system + is a single-process one. */ + + ulApiInstProcessSpecific = sizeof( tOCT6100_INSTANCE_API ); + mOCT6100_ROUND_MEMORY_SIZE( ulApiInstProcessSpecific, ulTempVar ) + + f_pInstSizes->ulApiInstTotal = + f_pInstSizes->ulChannelList + + f_pInstSizes->ulChannelAlloc + + f_pInstSizes->ulTsiCnctList + + f_pInstSizes->ulTsiCnctAlloc + + f_pInstSizes->ulSoftToneEventsBuffer + + f_pInstSizes->ulSoftBufPlayoutEventsBuffer + + f_pInstSizes->ulBiDirChannelList + + f_pInstSizes->ulBiDirChannelAlloc + + f_pInstSizes->ulConfBridgeList + + f_pInstSizes->ulConfBridgeAlloc + + f_pInstSizes->ulFlexConfParticipantsList + + f_pInstSizes->ulFlexConfParticipantsAlloc + + f_pInstSizes->ulPlayoutBufList + + f_pInstSizes->ulPlayoutBufAlloc + + f_pInstSizes->ulPlayoutBufMemoryNodeList + + + f_pInstSizes->ulCopyEventList + + f_pInstSizes->ulCopyEventAlloc + + f_pInstSizes->ulMixerEventList + + f_pInstSizes->ulMixerEventAlloc + + f_pInstSizes->ulPhasingTsstList + + f_pInstSizes->ulPhasingTsstAlloc + + f_pInstSizes->ulAdpcmChannelList + + f_pInstSizes->ulAdpcmChannelAlloc + + f_pInstSizes->ulConversionMemoryAlloc + + f_pInstSizes->ulTsiMemoryAlloc + + f_pInstSizes->ulRemoteDebugList + + f_pInstSizes->ulRemoteDebugTree + + f_pInstSizes->ulRemoteDebugPktCache + + f_pInstSizes->ulRemoteDebugDataBuf + + f_pInstSizes->ulTsstEntryList + + f_pInstSizes->ulTsstEntryAlloc + + f_pInstSizes->ulTsstAlloc + + f_pInstSizes->ulApiInstStatic + + ulApiInstProcessSpecific; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAllocateInstanceMemory + +Description: Allocates the API instance memory to the various members of + the structure f_pApiInstance according to the sizes contained + in f_pInstSizes. No initialization of this memory is + performed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pInstSizes Pointer to structure containing the size of memory needed + by all pointers internal to the API instance. The memory + is needed to keep track of the present state of all the + chip's resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAllocateInstanceMemory +UINT32 Oct6100ApiAllocateInstanceMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulOffset; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get address of first UINT32 of memory in API instance structure following */ + /* the static members of the API instance structure. */ + ulOffset = f_pInstSizes->ulApiInstStatic; + + /*===================================================================*/ + /* Allocate memory for the echo channels.*/ + pSharedInfo->ulChannelListOfst = ulOffset; + ulOffset += f_pInstSizes->ulChannelList; + pSharedInfo->ulChannelAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulChannelAlloc; + + /*===================================================================*/ + /* Allocate memory for the TSI connections */ + pSharedInfo->ulTsiCnctListOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsiCnctList; + pSharedInfo->ulTsiCnctAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsiCnctAlloc; + pSharedInfo->ulMixerEventListOfst = ulOffset; + ulOffset += f_pInstSizes->ulMixerEventList; + pSharedInfo->ulMixerEventAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulMixerEventAlloc; + + pSharedInfo->ulBiDirChannelListOfst = ulOffset; + ulOffset += f_pInstSizes->ulBiDirChannelList; + pSharedInfo->ulBiDirChannelAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulBiDirChannelAlloc; + pSharedInfo->ulCopyEventListOfst = ulOffset; + ulOffset += f_pInstSizes->ulCopyEventList; + pSharedInfo->ulCopyEventAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulCopyEventAlloc; + + /*===================================================================*/ + /* Allocate memory for the conference bridges */ + pSharedInfo->ulConfBridgeListOfst = ulOffset; + ulOffset += f_pInstSizes->ulConfBridgeList; + pSharedInfo->ulConfBridgeAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulConfBridgeAlloc; + + /*===================================================================*/ + /* Allocate memory for the flexible conferencing participants. */ + pSharedInfo->ulFlexConfParticipantListOfst = ulOffset; + ulOffset += f_pInstSizes->ulFlexConfParticipantsList; + pSharedInfo->ulFlexConfParticipantAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulFlexConfParticipantsAlloc; + + /*===================================================================*/ + /* Allocate memory for the play-out buffers */ + pSharedInfo->ulPlayoutBufListOfst = ulOffset; + ulOffset += f_pInstSizes->ulPlayoutBufList; + pSharedInfo->ulPlayoutBufAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulPlayoutBufAlloc; + pSharedInfo->ulPlayoutBufMemoryNodeListOfst = ulOffset; + ulOffset += f_pInstSizes->ulPlayoutBufMemoryNodeList; + + + + /*===================================================================*/ + /* Allocate memory for the phasing TSSTs */ + pSharedInfo->ulPhasingTsstListOfst = ulOffset; + ulOffset += f_pInstSizes->ulPhasingTsstList; + pSharedInfo->ulPhasingTsstAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulPhasingTsstAlloc; + + /*===================================================================*/ + /* Allocate memory for the ADPCM channel */ + pSharedInfo->ulAdpcmChanAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulAdpcmChannelAlloc; + pSharedInfo->ulAdpcmChanListOfst = ulOffset; + ulOffset += f_pInstSizes->ulAdpcmChannelList; + + /*===================================================================*/ + /* Allocate memory for the conversion memory */ + pSharedInfo->ulConversionMemoryAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulConversionMemoryAlloc; + + /*===================================================================*/ + /* Allocate memory for the TSI chariot memory */ + pSharedInfo->ulTsiMemoryAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsiMemoryAlloc; + + /*===================================================================*/ + /* Allocate memory for the TSST management */ + pSharedInfo->ulTsstAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsstAlloc; + pSharedInfo->ulTsstListOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsstEntryList; + pSharedInfo->ulTsstListAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsstEntryAlloc; + + /*===================================================================*/ + pSharedInfo->SoftBufs.ulToneEventBufferMemOfst = ulOffset; + ulOffset += f_pInstSizes->ulSoftToneEventsBuffer; + + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferMemOfst = ulOffset; + ulOffset += f_pInstSizes->ulSoftBufPlayoutEventsBuffer; + /*===================================================================*/ + pSharedInfo->RemoteDebugInfo.ulSessionListOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugList; + + pSharedInfo->RemoteDebugInfo.ulSessionTreeOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugTree; + + pSharedInfo->RemoteDebugInfo.ulDataBufOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugDataBuf; + + pSharedInfo->RemoteDebugInfo.ulPktCacheOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugPktCache; + /*===================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitializeInstanceMemory + +Description: Initializes the various members of the structure f_pApiInstance + to reflect the current state of the chip and its resources. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitializeInstanceMemory +UINT32 Oct6100ApiInitializeInstanceMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + UINT32 ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize API EC channels. */ + ulResult = Oct6100ApiChannelsEchoSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Initialize the API TSI connection structures. */ + ulResult = Oct6100ApiTsiCnctSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Initialize the API conference bridges. */ + ulResult = Oct6100ApiConfBridgeSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the API buffer playout structures. */ + ulResult = Oct6100ApiPlayoutBufferSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the API phasing tssts. */ + ulResult = Oct6100ApiPhasingTsstSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + /*-----------------------------------------------------------------------------*/ + /* Initialize the API ADPCM channels. */ + ulResult = Oct6100ApiAdpcmChanSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the external memory management structures. */ + ulResult = Oct6100ApiMemorySwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize TSST management stuctures. */ + ulResult = Oct6100ApiTsstSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the mixer management stuctures. */ + ulResult = Oct6100ApiMixerSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the remote debugging session management variables. */ + ulResult = Oct6100ApiRemoteDebuggingSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Configure the interrupt registers. */ + ulResult = Oct6100ApiIsrSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetChipRevisionNum + +Description: Reads the chip's revision number register. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetChipRevisionNum +UINT32 Oct6100ApiGetChipRevisionNum( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the chip revision number. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.ulReadAddress = cOCT6100_CHIP_ID_REVISION_REG; + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save the info in the API miscellaneous structure. */ + pSharedInfo->MiscVars.usChipId = (UINT16)( usReadData & 0xFF ); + pSharedInfo->MiscVars.usChipRevision = (UINT16)( usReadData >> 8 ); + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckImageFileHeader + +Description: This function check if the image loaded is valid + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckImageFileHeader +UINT32 Oct6100ApiCheckImageFileHeader( + IN tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + + PUINT8 pszImageInfoStart = NULL; + UINT32 ulStrLen; + + ulStrLen = Oct6100ApiStrLen( (PUINT8)cOCT6100_IMAGE_START_STRING ); + pszImageInfoStart = (PUINT8) Oct6100ApiStrStr(f_pChipOpen->pbyImageFile,(PUINT8)cOCT6100_IMAGE_START_STRING, + f_pChipOpen->pbyImageFile + ulStrLen); + if (pszImageInfoStart == NULL) + return cOCT6100_ERR_OPEN_IMAGE_FILE; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiDecodeKeyAndBist + +Description: This function decodes the key and runs the automatic BIST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiDecodeKeyAndBist +UINT32 Oct6100ApiDecodeKeyAndBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT16 ausBistData[ 3 ]; + UINT16 usReadData; + UINT32 ulResult; + BOOL fBitEqual; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a local pointer to the chip config structure */ + /* contained in the instance structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Set the process context and user chip ID parameters once and for all. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Write key in CPU internal memory. */ + for(i=0; i<8; i++) + { + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0x0000; + if (( i % 2 ) == 0) + { + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 2]) << 8; + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 3]) << 0; + } + else + { + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 0]) << 8; + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 1]) << 0; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x152; + WriteParams.usWriteData = (UINT16)( 0x8000 | i ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Write one in CPU internal memory. */ + for(i=0; i<8; i++) + { + WriteParams.ulWriteAddress = 0x150; + if (i == 0) + { + WriteParams.usWriteData = 0x0001; + } + else + { + WriteParams.usWriteData = 0x0000; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x152; + WriteParams.usWriteData = (UINT16)( 0x8000 | ( i + 8 )); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Clear memory access registers: */ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x152; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Run BISTs and key decode. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0081; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for the key decode PC to clear. */ + ulResult = Oct6100ApiWaitForPcRegisterBit( f_pApiInstance, 0x160, 0, 0, 100000, &fBitEqual ); + if ( TRUE != fBitEqual ) + return cOCT6100_ERR_FATAL_13; + + /* Read the key valid bit to make sure everything is ok. */ + ReadParams.ulReadAddress = 0x160; + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Either the firmware image was not loaded correctly (from pointer given by user) */ + /* or the channel capacity pins of the chip do not match what the firmware is expecting. */ + if ( ( usReadData & 0x4 ) == 0 ) + return cOCT6100_ERR_OPEN_INVALID_FIRMWARE_OR_CAPACITY_PINS; + + /* Read the result of the internal memory bist. */ + ReadParams.ulReadAddress = 0x110; + ReadParams.pusReadData = &ausBistData[ 0 ]; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.ulReadAddress = 0x114; + ReadParams.pusReadData = &ausBistData[ 1 ]; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.ulReadAddress = 0x118; + ReadParams.pusReadData = &ausBistData[ 2 ]; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if an error was reported. */ + if (ausBistData[0] != 0x0000 || ausBistData[1] != 0x0000 || ausBistData[2] != 0x0000) + return cOCT6100_ERR_OPEN_INTERNAL_MEMORY_BIST; + + /* Put key decoder in powerdown. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x008A; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootFc2PllReadCap + +Description: Configures the chip's FC2 PLL. Special version for GetcapacityPins. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiBootFc2PllReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + UINT32 ulFc2PllDivisor = 0; + UINT32 ulMtDivisor = 0; + UINT32 ulFcDivisor = 0; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pGetCapacityPins->pProcessContext; + + WriteParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + + /* First put the chip and main registers in soft-reset. */ + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulFc2PllDivisor = 0x1050; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + + /* Setup delay chains. */ + if ( (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR) || (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + /* SDRAM */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x4030; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( cOCT6100_MEM_TYPE_DDR == pChipConfig->byMemoryType ) */ + { + /* DDR */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x201F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* udqs */ + WriteParams.ulWriteAddress = 0x1B8; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BA; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* ldqs */ + WriteParams.ulWriteAddress = 0x1BC; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BE; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12C; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12E; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select fc2pll for fast_clk and mtsclk sources. Select mem_clk_i for afclk. */ + WriteParams.ulWriteAddress = 0x140; + WriteParams.usWriteData = (UINT16)ulMtDivisor; + + if ( f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData |= 0x0001; + else + WriteParams.usWriteData |= 0x0004; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x144; + WriteParams.usWriteData = (UINT16)ulFcDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x13E; + WriteParams.usWriteData = 0x0001; /* Remove reset from above divisors */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select upclk directly as ref source for fc2pll. */ + WriteParams.ulWriteAddress = 0x134; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Setup fc2pll. */ + WriteParams.ulWriteAddress = 0x132; + WriteParams.usWriteData = (UINT16)ulFc2PllDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x02; /* Raise fb divisor reset. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x80; /* Raise IDDTN signal.*/ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc2pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Drive mem_clk_o out on proper interface. */ + if ( TRUE == f_pGetCapacityPins->fEnableMemClkOut ) + { + if ( (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR) || (f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + WriteParams.ulWriteAddress = 0x128; + WriteParams.usWriteData = 0x0301; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_DDR || f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + { + WriteParams.ulWriteAddress = 0x12A; + WriteParams.usWriteData = 0x000F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootFc2Pll + +Description: Configures the chip's FC2 PLL. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBootFc2Pll +UINT32 Oct6100ApiBootFc2Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + UINT32 ulFc2PllDivisor = 0; + UINT32 ulMtDivisor = 0; + UINT32 ulFcDivisor = 0; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* First put the chip and main registers in soft-reset. */ + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select register configuration based on the memory frequency. */ + switch ( f_pApiInstance->pSharedInfo->ChipConfig.ulMemClkFreq ) + { + case 133000000: + ulFc2PllDivisor = 0x1050; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 672; + pSharedInfo->MiscVars.usMaxH100Speed = 124; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x050B; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0516; + + break; + case 125000000: + ulFc2PllDivisor = 0x0F50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 624; + pSharedInfo->MiscVars.usMaxH100Speed = 116; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x04CA; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x04D4; + + break; + case 117000000: + ulFc2PllDivisor = 0x0E50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 576; + pSharedInfo->MiscVars.usMaxH100Speed = 108; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0489; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0492; + + break; + case 108000000: + ulFc2PllDivisor = 0x0D50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 528; + pSharedInfo->MiscVars.usMaxH100Speed = 99; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0408; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0410; + + break; + case 100000000: + ulFc2PllDivisor = 0x0C50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 480; + pSharedInfo->MiscVars.usMaxH100Speed = 91; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x03C8; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x03D0; + + break; + case 92000000: + ulFc2PllDivisor = 0x0B50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 432; + pSharedInfo->MiscVars.usMaxH100Speed = 83; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0387; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x038E; + + break; + case 83000000: + ulFc2PllDivisor = 0x0A50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 384; + pSharedInfo->MiscVars.usMaxH100Speed = 74; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0346; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x034C; + + break; + case 75000000: + ulFc2PllDivisor = 0x0950; + ulMtDivisor = 0x4200; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 336; + pSharedInfo->MiscVars.usMaxH100Speed = 64; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0306; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x030C; + + break; + default: + return cOCT6100_ERR_FATAL_DB; + } + + /* Verify that the max channel is not too big based on the chip frequency. */ + if ( pSharedInfo->ChipConfig.usMaxChannels > pSharedInfo->MiscVars.usMaxNumberOfChannels ) + return cOCT6100_ERR_OPEN_MAX_ECHO_CHANNELS; + + /* Setup delay chains. */ + if ( (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR) || (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + /* SDRAM */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x4030; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( cOCT6100_MEM_TYPE_DDR == pChipConfig->byMemoryType ) */ + { + /* DDR */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x201F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* udqs */ + WriteParams.ulWriteAddress = 0x1B8; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BA; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* ldqs */ + WriteParams.ulWriteAddress = 0x1BC; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BE; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12C; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12E; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select fc2pll for fast_clk and mtsclk sources. Select mem_clk_i for afclk. */ + WriteParams.ulWriteAddress = 0x140; + WriteParams.usWriteData = (UINT16)ulMtDivisor; + + if ( f_pApiInstance->pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData |= 0x0001; + else + WriteParams.usWriteData |= 0x0004; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x144; + WriteParams.usWriteData = (UINT16)ulFcDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x13E; + WriteParams.usWriteData = 0x0001; /* Remove reset from above divisors */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select upclk directly as ref source for fc2pll. */ + WriteParams.ulWriteAddress = 0x134; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Setup fc2pll. */ + WriteParams.ulWriteAddress = 0x132; + WriteParams.usWriteData = (UINT16)ulFc2PllDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x02; /* Raise fb divisor reset. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x80; /* Raise IDDTN signal.*/ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc2pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Drive mem_clk_o out on proper interface. */ + if ( TRUE == pChipConfig->fEnableMemClkOut ) + { + if ( (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR) || (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + WriteParams.ulWriteAddress = 0x128; + WriteParams.usWriteData = 0x0301; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_DDR || pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + { + WriteParams.ulWriteAddress = 0x12A; + WriteParams.usWriteData = 0x000F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProgramFc1PllReadCap + +Description: Configures the chip's FC1 PLL. Special version for getCapacityPins. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiProgramFc1PllReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + + /* Programm P/Z bits. */ + WriteParams.ulWriteAddress = 0x130; + + if ( f_pGetCapacityPins->ulMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData = 0x0041; + else + WriteParams.usWriteData = 0x0040; + + WriteParams.usWriteData |= ( f_pGetCapacityPins->ulMemoryType << 8 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise FB divisor. */ + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise IDDTN. */ + WriteParams.usWriteData |= 0x0080; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc1pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable all the clock domains to do reset procedure. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x015F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulWaitTime[ 0 ] = 15000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProgramFc1Pll + +Description: Configures the chip's FC1 PLL. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiProgramFc1Pll +UINT32 Oct6100ApiProgramFc1Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Programm P/Z bits. */ + WriteParams.ulWriteAddress = 0x130; + + if ( f_pApiInstance->pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData = 0x0041; + else + WriteParams.usWriteData = 0x0040; + + WriteParams.usWriteData |= ( pChipConfig->byMemoryType << 8 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise FB divisor. */ + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise IDDTN. */ + WriteParams.usWriteData |= 0x0080; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc1pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable all the clock domains to do reset procedure. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x015F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulWaitTime[ 0 ] = 15000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootFc1Pll + +Description: Boot the chip's FC1 PLL. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBootFc1Pll +UINT32 Oct6100ApiBootFc1Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Force bist_clk also (it too is used on resetable flops). */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0188; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Force all cpu clocks on chariot controllers. */ + WriteParams.ulWriteAddress = 0x182; + WriteParams.usWriteData = 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x184; + WriteParams.usWriteData = 0x0202; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulWaitTime[ 0 ] = 1000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remove the reset on the entire chip and disable CPU access caching. */ + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x2003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remove the bist_clk. It is no longer needed.*/ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0088; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Disable all clks to prepare for bist clock switchover. */ + WriteParams.ulWriteAddress = 0x182; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x184; + WriteParams.usWriteData = 0x0101; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Deassert bist_active */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0008; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Change CPU interface to normal mode (from boot mode). */ + WriteParams.ulWriteAddress = 0x154; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Give a couple of BIST clock cycles to turn off the BIST permanently. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0108; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Turn BIST clock off for the last time. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0008; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reset procedure done! */ + + /* Enable mclk for cpu interface and external memory controller. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x0100; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiLoadImage + +Description: This function writes the firmware image in the external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiLoadImage +UINT32 Oct6100ApiLoadImage( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 ulTempPtr; + UINT32 ulNumWrites; + PUINT16 pusSuperArray; + unsigned char const *pbyImageFile; + UINT32 ulByteCount = 0; + UINT16 usReadData; + UINT32 ulAddressOfst; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Breakdown image into subcomponents. */ + ulTempPtr = cOCT6100_IMAGE_FILE_BASE + cOCT6100_IMAGE_AF_CST_OFFSET; + + for(i=0;iImageRegion[ i ].ulPart1Size = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 0 ]; + pSharedInfo->ImageRegion[ i ].ulPart2Size = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 1 ]; + pSharedInfo->ImageRegion[ i ].ulClockInfo = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 2 ]; + pSharedInfo->ImageRegion[ i ].ulReserved = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 3 ]; + + if (i == 0) /* AF constant. */ + { + pSharedInfo->ImageRegion[ i ].ulPart1BaseAddress = ulTempPtr & 0x07FFFFFF; + pSharedInfo->ImageRegion[ i ].ulPart2BaseAddress = 0; + + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart1Size * 612 ); + } + else if (i == 1) /* NLP image */ + { + pSharedInfo->ImageRegion[ i ].ulPart1BaseAddress = ulTempPtr & 0x07FFFFFF; + pSharedInfo->ImageRegion[ i ].ulPart2BaseAddress = 0; + + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart1Size * 2056 ); + } + else /* Others */ + { + pSharedInfo->ImageRegion[ i ].ulPart1BaseAddress = ulTempPtr & 0x07FFFFFF; + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart1Size * 2064 ); + + pSharedInfo->ImageRegion[ i ].ulPart2BaseAddress = ulTempPtr & 0x07FFFFFF; + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart2Size * 2448 ); + } + } + + /* Write the image in external memory. */ + ulNumWrites = pSharedInfo->ChipConfig.ulImageSize / 2; + + BurstParams.ulWriteAddress = cOCT6100_IMAGE_FILE_BASE; + BurstParams.pusWriteData = pSharedInfo->MiscVars.ausSuperArray; + + pusSuperArray = pSharedInfo->MiscVars.ausSuperArray; + pbyImageFile = pSharedInfo->ChipConfig.pbyImageFile; + + while ( ulNumWrites != 0 ) + { + if ( ulNumWrites >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + BurstParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + BurstParams.ulWriteLength = ulNumWrites; + + for ( i = 0; i < BurstParams.ulWriteLength; i++ ) + { + pusSuperArray[ i ] = ( UINT16 )(( pbyImageFile [ ulByteCount++ ]) << 8); + pusSuperArray[ i ] |= ( UINT16 )pbyImageFile [ ulByteCount++ ]; + } + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BurstParams.ulWriteAddress += 2 * BurstParams.ulWriteLength; + ulNumWrites -= BurstParams.ulWriteLength; + } + + /* Perform a serie of reads to make sure the image was correclty written into memory. */ + ulAddressOfst = ( pSharedInfo->ChipConfig.ulImageSize / 2 ) & 0xFFFFFFFE; + while ( ulAddressOfst != 0 ) + { + ReadParams.ulReadAddress = cOCT6100_IMAGE_FILE_BASE + ulAddressOfst; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (usReadData >> 8) != pbyImageFile[ ulAddressOfst ] ) + return cOCT6100_ERR_OPEN_IMAGE_WRITE_FAILED; + + ulAddressOfst = (ulAddressOfst / 2) & 0xFFFFFFFE; + } + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCpuRegisterBistReadCap + +Description: Tests the operation of the CPU registers. Special Version for + GetCapacityPins + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiCpuRegisterBistReadCap( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_GET_CAPACITY_PINS f_pGetCapacityPins + ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 i; + UINT16 usReadData; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pGetCapacityPins->ulUserChipId; + + /* Assign read data pointer that will be used throughout the function. */ + ReadParams.pusReadData = &usReadData; + + /* Start with a walking bit test. */ + for ( i = 0; i < 16; i ++ ) + { + /* Write at address 0x150.*/ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = (UINT16)( 0x1 << i ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180.*/ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = (UINT16)( 0x1 << ( 15 - i ) ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << i ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << ( 15 - i ) ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + } + + /* Write at address 0x150. */ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0xCAFE; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180. */ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = 0xDECA; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xCAFE ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xDECA ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + return cOCT6100_ERR_OK; +} +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCpuRegisterBist + +Description: Tests the operation of the CPU registers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCpuRegisterBist +UINT32 Oct6100ApiCpuRegisterBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 i; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Assign read data pointer that will be used throughout the function. */ + ReadParams.pusReadData = &usReadData; + + /* Start with a walking bit test. */ + for ( i = 0; i < 16; i ++ ) + { + /* Write at address 0x150.*/ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = (UINT16)( 0x1 << i ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180.*/ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = (UINT16)( 0x1 << ( 15 - i ) ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << i ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << ( 15 - i ) ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + } + + /* Write at address 0x150. */ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0xCAFE; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180. */ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = 0xDECA; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xCAFE ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xDECA ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootSdram + +Description: Configure and test the SDRAM. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiBootSdram +UINT32 Oct6100ApiBootSdram( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + UINT16 usWriteData23E; + UINT16 usWriteData230; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure.*/ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + usWriteData23E = 0x0000; + usWriteData230 = 0x0000; + + if ( (pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR) || (pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + /* SDRAM: */ + switch( pChipConfig->ulMemoryChipSize ) + { + case cOCT6100_MEMORY_CHIP_SIZE_8MB: + usWriteData230 |= ( cOCT6100_16MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_16MB: + usWriteData230 |= ( cOCT6100_32MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_32MB: + usWriteData230 |= ( cOCT6100_64MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_64MB: + usWriteData230 |= ( cOCT6100_128MB_MEMORY_BANKS << 2 ); + break; + default: + return cOCT6100_ERR_FATAL_16; + } + + usWriteData230 |= 0x0002; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Precharge all banks. */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0010; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program the mode register. */ + usWriteData23E = 0x0030; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Do CBR refresh (twice) */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0040; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* DDR: */ + switch( pChipConfig->ulMemoryChipSize ) + { + case cOCT6100_MEMORY_CHIP_SIZE_16MB: + usWriteData230 |= ( cOCT6100_16MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_32MB: + usWriteData230 |= ( cOCT6100_32MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_64MB: + usWriteData230 |= ( cOCT6100_64MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_128MB: + usWriteData230 |= ( cOCT6100_128MB_MEMORY_BANKS << 2 ); + break; + default: + return cOCT6100_ERR_FATAL_17; + } + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Precharge all banks. */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0010; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program DDR mode register. */ + usWriteData23E = 0x4000; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program SDR mode register. */ + usWriteData23E = 0x0161; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Precharge all banks. */ + usWriteData23E = 0xFFFF; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0010; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Do CBR refresh (twice) */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0040; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle.*/ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program SDR mode register. */ + usWriteData23E = 0x0061; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the refresh frequency. */ + WriteParams.ulWriteAddress = 0x242; + WriteParams.usWriteData = 0x0400; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x244; + WriteParams.usWriteData = 0x0200; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x248; + WriteParams.usWriteData = 0x800; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x246; + WriteParams.usWriteData = 0x0012; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable the SDRAM and refreshes. */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0001; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x246; + WriteParams.usWriteData = 0x0013; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiEnableClocks + +Description: This function will disable clock masking for all the modules + of the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiEnableClocks +UINT32 Oct6100ApiEnableClocks( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Enable tdmie / adpcm mclk clocks. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x015F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the DQS register for the DDR memory */ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = 0xFF00; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable pgsp chariot clocks */ + WriteParams.ulWriteAddress = 0x182; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable af/mt chariot clocks */ + WriteParams.ulWriteAddress = 0x184; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProgramNLP + +Description: This function will write image values to configure the NLP. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiProgramNLP +UINT32 Oct6100ApiProgramNLP( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + UINT32 ulResult; + UINT16 usReadData; + UINT16 usReadHighData; + BOOL fBitEqual; + UINT32 ulEgoEntry[4]; + UINT32 ulTempAddress; + UINT32 ulAfCpuUp = FALSE; + UINT32 i; + UINT32 ulLoopCounter = 0; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure.*/ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Initialize the process context and user chip ID once and for all. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + UINT32 ulReadData; + UINT32 ulBitPattern; + UINT32 j, k; + + /* Since the pouch section (256 bytes) will not be tested by the firmware, */ + /* the API has to make sure this section is working correctly. */ + for ( k = 0; k < 2; k ++ ) + { + if ( k == 0 ) + ulBitPattern = 0x1; + else + ulBitPattern = 0xFFFFFFFE; + + for ( j = 0; j < 32; j ++ ) + { + /* Write the DWORDs. */ + for ( i = 0; i < 64; i ++ ) + { + ulResult = Oct6100ApiWriteDword( f_pApiInstance, cOCT6100_POUCH_BASE + i * 4, ulBitPattern << j ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Read the DWORDs. */ + for ( i = 0; i < 64; i ++ ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, cOCT6100_POUCH_BASE + i * 4, &ulReadData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the value matches. */ + if ( ( ulBitPattern << j ) != ulReadData ) + return cOCT6100_ERR_OPEN_PRODUCTION_BIST_POUCH_ERROR; + } + } + } + } + + /* Write the image info in the chip. */ + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE; + WriteParams.usWriteData = (UINT16)( ( pSharedInfo->ImageRegion[ 0 ].ulPart1BaseAddress >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSharedInfo->ImageRegion[ 0 ].ulPart1BaseAddress & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for( i = 0; i < 8; i++ ) + { + if ( pSharedInfo->ImageRegion[ i + 2 ].ulPart1Size != 0 ) + { + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE + 0x4 + ( i * 0xC ); + WriteParams.usWriteData = (UINT16)(( pSharedInfo->ImageRegion[ i + 2 ].ulPart1BaseAddress >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSharedInfo->ImageRegion[ i + 2 ].ulPart1BaseAddress & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pSharedInfo->ImageRegion[ i + 2 ].ulPart2Size != 0 ) + { + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE + 0x4 + ( i * 0xC ) + 4; + WriteParams.usWriteData = (UINT16)(( pSharedInfo->ImageRegion[ i + 2 ].ulPart2BaseAddress >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSharedInfo->ImageRegion[ i + 2 ].ulPart2BaseAddress & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE + 0x4 + ( i * 0xC ) + 8; + WriteParams.usWriteData = 0x0000; + WriteParams.usWriteData |= ( pSharedInfo->ImageRegion[ i + 2 ].ulPart1Size << 8 ); + WriteParams.usWriteData |= pSharedInfo->ImageRegion[ i + 2 ].ulPart2Size; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0x0000; + WriteParams.usWriteData |= ( pSharedInfo->ImageRegion[ i + 2 ].ulClockInfo << 8 ); + WriteParams.usWriteData |= pSharedInfo->ImageRegion[ i + 2 ].ulReserved; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Put NLP in config mode. */ + WriteParams.ulWriteAddress = 0x2C2; + WriteParams.usWriteData = 0x160E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x692; + WriteParams.usWriteData = 0x010A; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Upload the up to 8 NLP pages + 1 AF page (for timing reasons). */ + for ( i = 0; i < pSharedInfo->ImageRegion[ 1 ].ulPart1Size; i++ ) + { + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 1 ].ulPart1BaseAddress + 1028 * ( i * 2 ), 0x1280, 1024, &(ulEgoEntry[0])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 1 ].ulPart1BaseAddress + 1028 * (( i * 2 ) + 1 ), 0x1680, 1024, &(ulEgoEntry[2])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiRunEgo( f_pApiInstance, FALSE, 2, ulEgoEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Shift mt chariot memories. This process will complete by the time */ + /* the next LSU transfer is done. */ + WriteParams.ulWriteAddress = 0x692; + WriteParams.usWriteData = 0x010B; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForPcRegisterBit( f_pApiInstance, 0x692, 0, 0, 100000, &fBitEqual ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + if ( TRUE != fBitEqual ) + return cOCT6100_ERR_FATAL_1A; + } + + /* 1 AF page (for timing reasons). */ + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 0), 0x1280, 512, &(ulEgoEntry[0])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 1), 0x1480, 512, &(ulEgoEntry[2])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiRunEgo( f_pApiInstance, FALSE, 2, ulEgoEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 2), 0x1680, 512, &(ulEgoEntry[0])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 3), 0x1880, 512, &(ulEgoEntry[2])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiRunEgo( f_pApiInstance, FALSE, 2, ulEgoEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write constant memory init context position in channel "672" for pgsp. */ + WriteParams.ulWriteAddress = 0x71A; + WriteParams.usWriteData = 0x8000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set fixed PGSP event_in base address to 800 on a 2k boundary */ + WriteParams.ulWriteAddress = 0x716; + WriteParams.usWriteData = 0x800 >> 11; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set fixed PGSP event_out to 0x2C0000h on a 16k boundary */ + WriteParams.ulWriteAddress = 0x71C; + WriteParams.usWriteData = 0x2C0000 >> 14; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Give chariot control of the chip. */ + WriteParams.ulWriteAddress = 0x712; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x2C0000 + 0xC; + ulTempAddress = 0x300000 + 0x0800; + WriteParams.usWriteData = (UINT16)( ( ulTempAddress >> 16 ) & 0x07FF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x2C0000 + 0xE; + WriteParams.usWriteData = (UINT16)( ( ulTempAddress >> 0 ) & 0xFF00 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the init PGSP event in place. */ + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x800; + WriteParams.usWriteData = 0x0200; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x802; + WriteParams.usWriteData = 0x02A0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Also write the register 710, which tells PGSP how many tones are supported. */ + WriteParams.ulWriteAddress = 0x710; + WriteParams.usWriteData = 0x0000; + WriteParams.usWriteData |= pChipConfig->pbyImageFile[ 0x7FA ] << 8; + WriteParams.usWriteData |= pChipConfig->pbyImageFile[ 0x7FB ] << 0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Start both processors in the NLP. */ + WriteParams.ulWriteAddress = 0x373FE; + WriteParams.usWriteData = 0x00FF; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37BFE; + WriteParams.usWriteData = 0x00FE; /* Tell processor 1 to just go to sleep. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37FC6; + WriteParams.usWriteData = 0x8004; /* First PC.*/ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37FD0; + WriteParams.usWriteData = 0x0002; /* Take out of reset. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37FD2; + WriteParams.usWriteData = 0x0002; /* Take out of reset. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Start processor in the AF. */ + for ( i = 0; i < 16; i ++ ) + { + WriteParams.ulWriteAddress = cOCT6100_POUCH_BASE + ( i * 2 ); + if ( i == 9 ) + { + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + if (pSharedInfo->ChipConfig.ulProductionBistMode == cOCT6100_PRODUCTION_BIST_SHORT) + WriteParams.usWriteData = cOCT6100_PRODUCTION_SHORT_BOOT_TYPE; + else + WriteParams.usWriteData = cOCT6100_PRODUCTION_BOOT_TYPE; + } + else + { + WriteParams.usWriteData = cOCT6100_AF_BOOT_TYPE; + } + } + else + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if the production BIST mode was requested. */ + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + UINT32 ulTotalElements = 3; + UINT32 ulCrcKey; + UINT32 aulMessage[ 4 ]; + UINT32 ulWriteAddress = 0x20 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + + /* Magic key. */ + aulMessage[ 0 ] = 0xCAFECAFE; + /* Memory size. */ + aulMessage[ 1 ] = pSharedInfo->MiscVars.ulTotalMemSize; + /* Loop count. */ + aulMessage[ 2 ] = pSharedInfo->ChipConfig.ulNumProductionBistLoops; + /* CRC initialized. */ + aulMessage[ 3 ] = 0; + + ulResult = Oct6100ApiProductionCrc( f_pApiInstance, aulMessage, ulTotalElements, &ulCrcKey ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulMessage[ 3 ] = ulCrcKey; + + /* Write the message to the external memory. */ + for ( i = 0; i < ulTotalElements + 1; i ++ ) + { + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulWriteAddress + i * 4, aulMessage[ i ] ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + WriteParams.ulWriteAddress = 0xFFFC6; + WriteParams.usWriteData = 0x1284; /* First PC.*/ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0xFFFD0; + WriteParams.usWriteData = 0x0002; /* Take out of reset. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + while ( ulAfCpuUp == FALSE ) + { + if ( ulAfCpuUp == FALSE ) + { + ReadParams.ulReadAddress = cOCT6100_POUCH_BASE; + ReadParams.pusReadData = &usReadHighData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.ulReadAddress += 2; + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + /* Should read 0x0007 when bisting. */ + if ( (( usReadHighData & 0xFFFF ) == cOCT6100_PRODUCTION_BOOT_TYPE) || + (( usReadHighData & 0xFFFF ) == cOCT6100_PRODUCTION_SHORT_BOOT_TYPE) ) + { + /* Verify if the bist has started successfully. */ + if ( ( usReadData & 0xFFFF ) == 0x0002 ) + return cOCT6100_ERR_OPEN_PRODUCTION_BIST_CONF_FAILED; + else if ( ( usReadData & 0xFFFF ) != 0xEEEE ) + return cOCT6100_ERR_OPEN_PRODUCTION_BOOT_FAILED; + + ulAfCpuUp = TRUE; + } + } + else /* if ( pSharedInfo->ChipConfig.fEnableProductionBist == FALSE ) */ + { + if ( ( usReadHighData & 0xFFFF ) == cOCT6100_AF_BOOT_TYPE ) + { + /* Verify if the bist succeeded. */ + if ( ( usReadData & 0xFFFF ) != 0x0000 ) + return cOCT6100_ERR_OPEN_FUNCTIONAL_BIST_FAILED; + + ulAfCpuUp = TRUE; + } + } + } + + ulLoopCounter++; + + if ( ulLoopCounter == cOCT6100_MAX_LOOP_CPU_TIMEOUT ) + return cOCT6100_ERR_OPEN_AF_CPU_TIMEOUT; + } + + /* Return NLP in operationnal mode. */ + WriteParams.ulWriteAddress = 0x2C2; + WriteParams.usWriteData = 0x060E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x692; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSetH100Register + +Description: This function will configure the H.100 registers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiSetH100Register +UINT32 Oct6100ApiSetH100Register( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + UINT32 i; + UINT32 ulOffset; + BOOL fAllStreamAt2Mhz = TRUE; + const UINT16 ausAdpcmResetContext[32] = { 0x1100, 0x0220, 0x0000, 0x0000, 0x0000, 0x0020, 0x0000, 0x0000, 0x0008, 0x0000, 0x0000, 0x0100, 0x0000, 0x0020, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0x0000, 0x0040, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x0000, 0x0010, 0x0000, 0x0000, 0x0000}; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure. */ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Set the Global OE bit. */ + WriteParams.ulWriteAddress = 0x300; + WriteParams.usWriteData = 0x0004; + + /* Set the number of streams. */ + switch( pChipConfig->byMaxTdmStreams ) + { + case 32: + WriteParams.usWriteData |= ( 0 << 3 ); + break; + case 16: + WriteParams.usWriteData |= ( 1 << 3 ); + break; + case 8: + WriteParams.usWriteData |= ( 2 << 3 ); + break; + case 4: + WriteParams.usWriteData |= ( 3 << 3 ); + break; + default: + break; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the stream frequency. */ + WriteParams.ulWriteAddress = 0x330; + WriteParams.usWriteData = 0x0000; + for ( i = 0; i < (UINT32)(pChipConfig->byMaxTdmStreams / 4); i++) + { + ulOffset = i*2; + switch( pChipConfig->aulTdmStreamFreqs[ i ] ) + { + case cOCT6100_TDM_STREAM_FREQ_2MHZ: + WriteParams.usWriteData |= ( 0x0 << ulOffset ); + break; + case cOCT6100_TDM_STREAM_FREQ_4MHZ: + WriteParams.usWriteData |= ( 0x1 << ulOffset ); + fAllStreamAt2Mhz = FALSE; + break; + case cOCT6100_TDM_STREAM_FREQ_8MHZ: + WriteParams.usWriteData |= ( 0x2 << ulOffset ); + fAllStreamAt2Mhz = FALSE; + break; + default: + break; + } + } + + /* Set the stream to 16 MHz if the fast H.100 mode is selected. */ + if ( pChipConfig->fEnableFastH100Mode == TRUE ) + { + fAllStreamAt2Mhz = FALSE; + WriteParams.usWriteData = 0xFFFF; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + { + /* Make the chip track both clock A and B to perform fast H.100 mode. */ + WriteParams.ulWriteAddress = 0x322; + WriteParams.usWriteData = 0x0004; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable the fast H.100 mode. */ + WriteParams.ulWriteAddress = 0x332; + WriteParams.usWriteData = 0x0003; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = 0x376; + WriteParams.usWriteData = (UINT16)( pSharedInfo->MiscVars.usTdmClkBoundary ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select delay for early clock (90 and 110). */ + WriteParams.ulWriteAddress = 0x378; + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + WriteParams.usWriteData = 0x000A; + else + { + /* Set the TDM sampling. */ + if ( pSharedInfo->ChipConfig.byTdmSampling == cOCT6100_TDM_SAMPLE_AT_RISING_EDGE ) + { + WriteParams.usWriteData = 0x0AF0; + } + else if ( pSharedInfo->ChipConfig.byTdmSampling == cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE ) + { + WriteParams.usWriteData = 0x0A0F; + } + else /* pSharedInfo->ChipConfig.ulTdmSampling == cOCT6100_TDM_SAMPLE_AT_3_QUARTERS */ + { + WriteParams.usWriteData = 0x0A08; + } + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Protect chip by preventing too rapid timeslot arrival (mclk == 133 MHz). */ + WriteParams.ulWriteAddress = 0x37A; + WriteParams.usWriteData = (UINT16)pSharedInfo->MiscVars.usMaxH100Speed; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Allow H.100 TS to progress. */ + WriteParams.ulWriteAddress = 0x382; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set by-pass mode. */ + WriteParams.ulWriteAddress = 0x50E; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* TDMIE bits. */ + WriteParams.ulWriteAddress = 0x500; + WriteParams.usWriteData = 0x0003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write normal ADPCM reset values in ADPCM context 1344. */ + for(i=0;i<32;i++) + { + WriteParams.ulWriteAddress = 0x140000 + ( 0x40 * 1344 ) + ( i * 2 ); + WriteParams.usWriteData = ausAdpcmResetContext[i]; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Make sure delay flops are configured correctly if all streams are at 2 MHz. */ + if ( fAllStreamAt2Mhz == TRUE ) + { + /* Setup H.100 sampling to lowest value. */ + WriteParams.ulWriteAddress = 0x144; + WriteParams.usWriteData = 0x4041; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x378; + WriteParams.usWriteData = 0x0A00; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteMiscellaneousRegisters + +Description: This function will write to various registers to activate the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiWriteMiscellaneousRegisters +UINT32 Oct6100ApiWriteMiscellaneousRegisters( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Free the interrupt pin of the chip (i.e. remove minimum time requirement between interrupts). */ + WriteParams.ulWriteAddress = 0x214; + WriteParams.usWriteData = 0x0000; + if ( f_pApiInstance->pSharedInfo->ChipConfig.byInterruptPolarity == cOCT6100_ACTIVE_HIGH_POLARITY ) + WriteParams.usWriteData |= 0x4000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write MT chariot interval */ + WriteParams.ulWriteAddress = 0x2C2; + if ( f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels > 640 ) + WriteParams.usWriteData = 0x05EA; + else if ( f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels > 513 ) + WriteParams.usWriteData = 0x0672; + else /* if ( f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels <= 513 ) */ + WriteParams.usWriteData = 0x0750; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write set second part5 time. */ + WriteParams.ulWriteAddress = 0x2C4; + WriteParams.usWriteData = 0x04A0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write CPU bucket timer to guarantee 200 cycles between each CPU access. */ + WriteParams.ulWriteAddress = 0x234; + WriteParams.usWriteData = 0x0804; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x236; + WriteParams.usWriteData = 0x0100; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCreateSerializeObjects + +Description: Creates a handle to each serialization object used by the API. + + Note that in a multi-process system the user's process context + structure pointer is needed by this function. Thus, the + pointer must be valid. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulUserChipId User chip ID for this serialization object. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCreateSerializeObjects +UINT32 Oct6100ApiCreateSerializeObjects( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulUserChipId ) +{ + tOCT6100_CREATE_SERIALIZE_OBJECT CreateSerObj; + UINT32 ulResult; + CHAR szSerObjName[ 64 ] = "Oct6100ApiXXXXXXXXApiSerObj"; + + + /* Set some parameters of the create structure once and for all. */ + CreateSerObj.pProcessContext = f_pApiInstance->pProcessContext; + CreateSerObj.pszSerialObjName = szSerObjName; + + /*----------------------------------------------------------------------*/ + /* Set the chip ID in the semaphore name. */ + szSerObjName[ 10 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 28 ) & 0xFF ); + szSerObjName[ 11 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 24 ) & 0xFF ); + szSerObjName[ 12 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 20 ) & 0xFF ); + szSerObjName[ 13 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 16 ) & 0xFF ); + szSerObjName[ 14 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 12 ) & 0xFF ); + szSerObjName[ 15 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 8 ) & 0xFF ); + szSerObjName[ 16 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 4 ) & 0xFF ); + szSerObjName[ 17 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 0 ) & 0xFF ); + + ulResult = Oct6100UserCreateSerializeObject( &CreateSerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + f_pApiInstance->ulApiSerObj = CreateSerObj.ulSerialObjHndl; + /*----------------------------------------------------------------------*/ + + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiDestroySerializeObjects + +Description: Destroy handles to each serialization object used by the API. + + Note that in a multi-process system the user's process context + structure pointer is needed by this function. Thus, the + pointer must be valid. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiDestroySerializeObjects +UINT32 Oct6100ApiDestroySerializeObjects( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_DESTROY_SERIALIZE_OBJECT DestroySerObj; + UINT32 ulResult; + + /* Set some parameters of the create structure once and for all. */ + DestroySerObj.pProcessContext = f_pApiInstance->pProcessContext; + DestroySerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + + ulResult = Oct6100UserDestroySerializeObject( &DestroySerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRunEgo + +Description: Private function used to communicate with the internal processors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_fStoreFlag Type of access performed. (Load or Store) +f_ulNumEntry Number of access. +f_aulEntry Array of access to perform. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRunEgo +UINT32 Oct6100ApiRunEgo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN BOOL f_fStoreFlag, + IN UINT32 f_ulNumEntry, + OUT PUINT32 f_aulEntry ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 aulCpuLsuCmd[ 2 ]; + UINT16 usReadData; + UINT32 i; + BOOL fConditionFlag = TRUE; + UINT32 ulLoopCounter = 0; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure. */ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* No more than 2 entries may be requested. */ + if ( f_ulNumEntry > 2 ) + return cOCT6100_ERR_FATAL_1B; + + /* Write the requested entries at address reserved for CPU. */ + for( i = 0; i < f_ulNumEntry; i++ ) + { + WriteParams.ulWriteAddress = cOCT6100_PART1_API_SCRATCH_PAD + ( 0x8 * i ); + WriteParams.usWriteData = (UINT16)(( f_aulEntry[ i * 2 ] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( f_aulEntry[ i * 2 ] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)(( f_aulEntry[ (i * 2) + 1] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( f_aulEntry[ (i * 2) + 1] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Preincrement code point. */ + pSharedInfo->MiscVars.usCodepoint++; + + /* Create DWORD 0 of command. */ + aulCpuLsuCmd[0] = 0x00000000; + if ( f_fStoreFlag == FALSE ) + aulCpuLsuCmd[0] |= 0xC0000000; /* EGO load. */ + else + aulCpuLsuCmd[0] |= 0xE0000000; /* EGO store. */ + + aulCpuLsuCmd[0] |= (f_ulNumEntry - 1) << 19; + aulCpuLsuCmd[0] |= cOCT6100_PART1_API_SCRATCH_PAD; + + /* Create DWORD 1 of command. */ + aulCpuLsuCmd[1] = 0x00000000; + aulCpuLsuCmd[1] |= ( ( cOCT6100_PART1_API_SCRATCH_PAD + 0x10 ) & 0xFFFF ) << 16; + aulCpuLsuCmd[1] |= pSharedInfo->MiscVars.usCodepoint; + + /* Write the EGO command in the LSU CB. */ + WriteParams.ulWriteAddress = cOCT6100_PART1_CPU_LSU_CB_BASE + ((pSharedInfo->MiscVars.usCpuLsuWritePtr & 0x7) * 0x8 ); + WriteParams.usWriteData = (UINT16)(( aulCpuLsuCmd[ 0 ] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( aulCpuLsuCmd[ 0 ] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)(( aulCpuLsuCmd[ 1 ] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( aulCpuLsuCmd[ 1 ] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Post increment the write pointer. */ + pSharedInfo->MiscVars.usCpuLsuWritePtr++; + + /* Indicate new write pointer position to HW. */ + WriteParams.ulWriteAddress = cOCT6100_PART1_EGO_REG + 0x5A; + WriteParams.usWriteData = (UINT16)( pSharedInfo->MiscVars.usCpuLsuWritePtr & 0x7 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for codepoint to be updated before returning. */ + while( fConditionFlag ) + { + ReadParams.ulReadAddress = cOCT6100_PART1_API_SCRATCH_PAD + 0x12; + usReadData = (UINT16)( pSharedInfo->MiscVars.usCodepoint ); + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData == pSharedInfo->MiscVars.usCodepoint ) + fConditionFlag = FALSE; + + ulLoopCounter++; + + if ( ulLoopCounter == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_OPEN_EGO_TIMEOUT; + } + + /* CRC error bit must be zero. */ + ReadParams.ulReadAddress = 0x202; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( usReadData & 0x0400 ) != 0 ) + return cOCT6100_ERR_OPEN_CORRUPTED_IMAGE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCreateEgoEntry + +Description: Private function used to create an access structure to be sent + to the internal processors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_ulExternalAddress External memory address for the access. +f_ulInternalAddress Which process should receive the command. +f_ulNumBytes Number of bytes associated to the access. +f_aulEntry Array of access to perform. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCreateEgoEntry +UINT32 Oct6100ApiCreateEgoEntry( + IN UINT32 f_ulExternalAddress, + IN UINT32 f_ulInternalAddress, + IN UINT32 f_ulNumBytes, + OUT UINT32 f_aulEntry[ 2 ] ) +{ + f_aulEntry[0] = 0x80000000; + f_aulEntry[0] |= f_ulExternalAddress & 0x07FFFFFC; + + f_aulEntry[1] = 0x0011C000; + f_aulEntry[1] |= (f_ulNumBytes / 8) << 23; + f_aulEntry[1] |= (f_ulInternalAddress >> 2) & 0x3FFF; + + return cOCT6100_ERR_OK; +} +#endif + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitChannels + +Description: This function will initialize all the channels to power down. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitChannels +UINT32 Oct6100ApiInitChannels( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 i; + UINT32 ulResult; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT16 ausWriteData[ 4 ]; + UINT16 usLoopCount = 0; + UINT16 usWriteData = 0; + UINT16 usMclkRead; + UINT16 usLastMclkRead; + UINT16 usMclkDiff; + UINT32 ulNumberOfCycleToWait; + UINT32 ulTimeoutCounter; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + BurstParams.pusWriteData = ausWriteData; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Verify that the image has enough memory to work correctly. */ + if ( ( pSharedInfo->MiscVars.ulTotalMemSize + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) < pSharedInfo->MemoryMap.ulFreeMemBaseAddress ) + return cOCT6100_ERR_OPEN_INSUFFICIENT_EXTERNAL_MEMORY; + + /* Verify that the tail length is supported by the device.*/ + if ( pSharedInfo->ChipConfig.usTailDisplacement > pSharedInfo->ImageInfo.usMaxTailDisplacement ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_TAIL_DISPLACEMENT_VALUE; + + /* Verify that acoustic echo is supported by the device. */ + if ( pSharedInfo->ChipConfig.fEnableAcousticEcho == TRUE && pSharedInfo->ImageInfo.fAcousticEcho == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_ACOUSTIC_ECHO; + + /* Verify that the image supports all the requested channels. */ + if ( pSharedInfo->ChipConfig.usMaxChannels > pSharedInfo->ImageInfo.usMaxNumberOfChannels ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_MAX_ECHO_CHANNELS_VALUE; + + /* Max number of channels the image supports + 1 for channel recording, if requested */ + if ( ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + && ( pSharedInfo->ImageInfo.usMaxNumberOfChannels < cOCT6100_MAX_ECHO_CHANNELS ) + && ( pSharedInfo->ChipConfig.usMaxChannels == pSharedInfo->ImageInfo.usMaxNumberOfChannels ) ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_MAX_ECHO_CHANNELS_VALUE; + + /* Initialize the memory for all required channels. */ + for( i = 0; i < f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + /*==============================================================================*/ + /* Configure the Global Static Configuration memory of the channel. */ + + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( i * cOCT6100_CHANNEL_ROOT_SIZE ) + cOCT6100_CHANNEL_ROOT_GLOBAL_CONF_OFFSET; + + /* Set the PGSP context base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + cOCT6100_CH_MAIN_PGSP_CONTEXT_OFFSET; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the PGSP init context base address. */ + ulTempData = ( cOCT6100_IMAGE_FILE_BASE + 0x200 ) & 0x07FFFFFF; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_INIT_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the RIN circular buffer base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainRinCBMemOfst; + + /* Set the circular buffer size. */ + ulTempData &= 0xFFFFFF00; + if (( pSharedInfo->MemoryMap.ulChanMainRinCBMemSize & 0xFFFF00FF ) != 0 ) + return cOCT6100_ERR_CHANNEL_INVALID_RIN_CB_SIZE; + ulTempData |= pSharedInfo->MemoryMap.ulChanMainRinCBMemSize >> 8; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_RIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SIN circular buffer base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSinCBMemOfst; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SOUT circular buffer base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSoutCBMemOfst;; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SOUT_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + } + + /* Put all channel in powerdown mode "3". */ + for( i = 0; i < f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + WriteParams.ulWriteAddress = 0x014000 + (i*4) + 0; + WriteParams.usWriteData = 0x85FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x014000 + (i*4) + 2; + WriteParams.usWriteData = 0xC5FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the maximum number of channels. */ + WriteParams.ulWriteAddress = 0x690; + if ( pSharedInfo->ImageInfo.usMaxNumberOfChannels < 384 ) + WriteParams.usWriteData = 384; + else + WriteParams.usWriteData = (UINT16)pSharedInfo->ImageInfo.usMaxNumberOfChannels; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set power-dowm TSI chariot memory to silence. */ + for( i = 0; i < 6; i++ ) + { + WriteParams.ulWriteAddress = 0x20000 + ( i * 0x1000 ) + ( 1534 * 2 ); + WriteParams.usWriteData = 0x3EFF; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x20000 + ( i * 0x1000 ) + ( 1535 * 2 ); + WriteParams.usWriteData = 0x3EFF; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Remove chariot hold. */ + WriteParams.ulWriteAddress = 0x500; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for( usLoopCount = 0; usLoopCount < 4096; usLoopCount++ ) + { + if ( (usLoopCount % 16) < 8 ) + { + usWriteData = (UINT16)((usLoopCount / 16) << 7); + usWriteData |= (UINT16)((usLoopCount % 8)); + } + else + { + usWriteData = (UINT16)((usLoopCount / 16) << 7); + usWriteData |= (UINT16)((usLoopCount % 8)); + usWriteData |= 0x78; + } + + /* Set timeslot pointer. */ + WriteParams.ulWriteAddress = 0x50E; + WriteParams.usWriteData = 0x0003; + WriteParams.usWriteData |= usWriteData << 2; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read the mclk counter. */ + ReadParams.ulReadAddress = 0x30A; + ReadParams.pusReadData = &usLastMclkRead; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reset loop timeout counter. */ + ulTimeoutCounter = 0x0; + + do { + ReadParams.pusReadData = &usMclkRead; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( usLoopCount % 16 ) != 15 ) + { + ulNumberOfCycleToWait = 133; + } + else + { + ulNumberOfCycleToWait = 20000; + } + + /* Evaluate the difference. */ + usMclkDiff = (UINT16)(( usMclkRead - usLastMclkRead ) & 0xFFFF); + + /* Check for loop timeout. Bad mclk? */ + ulTimeoutCounter++; + if ( ulTimeoutCounter == cOCT6100_MAX_LOOP_CPU_TIMEOUT ) + return cOCT6100_ERR_FATAL_EA; + + } while( usMclkDiff <= ulNumberOfCycleToWait ); + } + + /* Back to normal mode. */ + WriteParams.ulWriteAddress = 0x50E; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check for CRC errors. */ + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = 0x202; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (usReadData & 0x400) != 0x0000 ) + return cOCT6100_ERR_OPEN_CRC_ERROR; + + /* Clear the error rol raised by manually moving the clocks. */ + WriteParams.ulWriteAddress = 0x502; + WriteParams.usWriteData = 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*======================================================================*/ + /* Write the tail displacement value in external memory. */ + + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PouchTailDisplOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PouchTailDisplOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PouchTailDisplOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set the tail displacement. */ + ulTempData |= (pSharedInfo->ChipConfig.usTailDisplacement << ulFeatureBitOffset ); + + /* Write the DWORD where the field is located. */ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Clear the pouch counter, if present. */ + + if ( pSharedInfo->DebugInfo.fPouchCounter == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Clear counter! */ + ulTempData &= (~ulMask); + + /* Write the DWORD where the field is located.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* The ISR has not yet been called. Set the appropriate bit in external memory. */ + if ( pSharedInfo->DebugInfo.fIsIsrCalledField == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Read previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Toggle the bit to '1'. */ + ulTempData |= 1 << ulFeatureBitOffset; + + /* Write the DWORD where the field is located.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitToneInfo + +Description: This function will parse the software image and retrieve + the information about the tones that it supports. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitToneInfo +UINT32 Oct6100ApiInitToneInfo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + UINT32 ulResult; + + unsigned char const *pszToneInfoStart = NULL; + unsigned char const *pszToneInfoEnd = NULL; + + unsigned char const *pszCurrentInfo; + unsigned char const *pszNextInfo; + + UINT32 ulToneEventNumber; + UINT32 ulTempValue; + UINT32 ulNumCharForValue; + UINT32 ulUniqueToneId; + UINT32 ulToneNameSize; + UINT32 ulOffset = 0; + + UINT32 i; + + /* Init the tone detector parameter. */ + f_pApiInstance->pSharedInfo->ImageInfo.byNumToneDetectors = 0; + + /* Find the start and the end of the tone info section. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize > 4096 ) + { + /* For performance reasons, and since the tone detector information */ + /* is always located at the end of the image file, try to start from the end */ + /* of the buffer. */ + + ulOffset = f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize - 2048; + pszToneInfoStart = Oct6100ApiStrStr( f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + ulOffset, + (PUINT8)cOCT6100_TONE_INFO_START_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + + /* Check if the information was found. */ + if ( pszToneInfoStart == NULL ) + { + /* Try again, but giving a larger string to search. */ + ulOffset = f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize - 4096; + pszToneInfoStart = Oct6100ApiStrStr( f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + ulOffset, + (PUINT8)cOCT6100_TONE_INFO_START_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + + } + } + + if ( pszToneInfoStart == NULL ) + { + /* Travel through the whole file buffer. */ + pszToneInfoStart = Oct6100ApiStrStr( f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile, + (PUINT8)cOCT6100_TONE_INFO_START_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + } + /* We have to return immediatly if no tones are found. */ + if ( pszToneInfoStart == NULL ) + return cOCT6100_ERR_OK; + + /* The end of the tone detector information is after the beginning of the tone information. */ + pszToneInfoEnd = Oct6100ApiStrStr( pszToneInfoStart, + (PUINT8)cOCT6100_TONE_INFO_STOP_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + if ( pszToneInfoEnd == NULL ) + return cOCT6100_ERR_OPEN_TONE_INFO_STOP_TAG_NOT_FOUND; + + /* Find and process all tone events within the region. */ + pszCurrentInfo = Oct6100ApiStrStr( pszToneInfoStart, (PUINT8)cOCT6100_TONE_INFO_EVENT_STRING, pszToneInfoEnd ); + + while ( pszCurrentInfo != NULL ) + { + /* Skip the string. */ + pszCurrentInfo += ( Oct6100ApiStrLen( (PUINT8)cOCT6100_TONE_INFO_EVENT_STRING ) ); + + /* Extract the number of char used to represent the tone event number ( 1 or 2 ). */ + pszNextInfo = Oct6100ApiStrStr( pszCurrentInfo, (PUINT8)",", pszToneInfoEnd ); + ulNumCharForValue = (UINT32)( pszNextInfo - pszCurrentInfo ); + + /* Retreive the event number */ + ulToneEventNumber = 0; + for ( i = ulNumCharForValue; i > 0; i-- ) + { + ulResult = Oct6100ApiAsciiToHex( *pszCurrentInfo, &ulTempValue ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulToneEventNumber |= ( ulTempValue << (( i - 1) * 4 ) ); + pszCurrentInfo++; + } + + if ( ulToneEventNumber >= cOCT6100_MAX_TONE_EVENT ) + return cOCT6100_ERR_OPEN_INVALID_TONE_EVENT; + + /* Skip the comma and the 0x. */ + pszCurrentInfo += 3; + + /*======================================================================*/ + /* Retreive the unique tone id. */ + ulUniqueToneId = 0; + for ( i = 0; i < 8; i++ ) + { + ulResult = Oct6100ApiAsciiToHex( *pszCurrentInfo, &ulTempValue ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulOffset = 28 - ( i * 4 ); + ulUniqueToneId |= ( ulTempValue << ulOffset ); + pszCurrentInfo++; + } + + /*======================================================================*/ + + /* Skip the comma. */ + pszCurrentInfo++; + + /* Find out where the next event info starts */ + pszNextInfo = Oct6100ApiStrStr( pszCurrentInfo,(PUINT8) cOCT6100_TONE_INFO_EVENT_STRING, pszToneInfoEnd ); + if ( pszNextInfo == NULL ) + pszNextInfo = pszToneInfoEnd; + + /* Extract the name size. */ + ulToneNameSize = (UINT32)( pszNextInfo - pszCurrentInfo - 2 ); /* - 2 for 0x0D and 0x0A.*/ + + if ( ulToneNameSize > cOCT6100_TLV_MAX_TONE_NAME_SIZE ) + return cOCT6100_ERR_OPEN_INVALID_TONE_NAME; + + /* Copy the tone name into the image info structure. */ + ulResult = Oct6100UserMemCopy( f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].aszToneName, + pszCurrentInfo, + ulToneNameSize ); + + + + /* Update the tone info into the image info structure. */ + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulToneID = ulUniqueToneId; + /* Find out the port on which this tone detector is associated. */ + switch( (ulUniqueToneId >> 28) & 0xF ) + { + case 1: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_ROUT; + break; + + case 2: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_SIN; + break; + + case 4: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_SOUT; + break; + + case 5: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_ROUT_SOUT; + break; + + default: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_INVALID_PORT; + break; + } + + /* Find out where the next event info starts */ + pszNextInfo = Oct6100ApiStrStr( pszCurrentInfo,(PUINT8) cOCT6100_TONE_INFO_EVENT_STRING, pszToneInfoEnd ); + /* Update the current info pointer. */ + pszCurrentInfo = pszNextInfo; + + f_pApiInstance->pSharedInfo->ImageInfo.byNumToneDetectors++; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiExternalMemoryBist + +Description: Tests the functionality of the external memories. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiExternalMemoryBist +UINT32 Oct6100ApiExternalMemoryBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulMemSize = 0; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Test the external memory. */ + switch ( pSharedInfo->ChipConfig.ulMemoryChipSize ) + { + case cOCT6100_MEMORY_CHIP_SIZE_8MB: + ulMemSize = cOCT6100_SIZE_8M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_16MB: + ulMemSize = cOCT6100_SIZE_16M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_32MB: + ulMemSize = cOCT6100_SIZE_32M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_64MB: + ulMemSize = cOCT6100_SIZE_64M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_128MB: + ulMemSize = cOCT6100_SIZE_128M; + break; + default: + return cOCT6100_ERR_FATAL_D9; + } + + ulMemSize *= pSharedInfo->ChipConfig.byNumMemoryChips; + + ulResult = Oct6100ApiRandomMemoryWrite( f_pApiInstance, cOCT6100_EXTERNAL_MEM_BASE_ADDRESS, ulMemSize, 16, 1000, cOCT6100_ERR_OPEN_EXTERNAL_MEM_BIST_FAILED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Make sure the user I/O functions are working as required. */ + ulResult = Oct6100ApiUserIoTest( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGenerateNumber + +Description: Generate a number using an index. Passing the same + index generates the same number. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_ulIndex Index used to generate the random number. +f_ulDataMask Data mask to apply to generated number. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGenerateNumber +UINT16 Oct6100ApiGenerateNumber( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulIndex, + IN UINT32 f_ulDataMask ) +{ + UINT16 usGeneratedNumber; + + usGeneratedNumber = (UINT16)( ( ( ~( f_ulIndex - 1 ) ) & 0xFF00 ) | ( ( f_ulIndex + 1 ) & 0xFF ) ); + + return (UINT16)( usGeneratedNumber & f_ulDataMask ); +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRandomMemoryWrite + +Description: Writes to f_ulNumAccesses random locations in the indicated + memory and read back to test the operation of that memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_ulMemBase Base address of the memory access. +f_ulMemSize Size of the memory to be tested. +f_ulNumDataBits Number of data bits. +f_ulNumAccesses Number of random access to be perform. +f_ulErrorCode Error code to be returned if the bist fails. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiRandomMemoryWrite +UINT32 Oct6100ApiRandomMemoryWrite( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulMemBase, + IN UINT32 f_ulMemSize, + IN UINT32 f_ulNumDataBits, + IN UINT32 f_ulNumAccesses, + IN UINT32 f_ulErrorCode ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulDataMask; + UINT32 ulResult, i, j; + UINT32 ulBistAddress; + UINT16 usReadData; + UINT32 aulBistAddress[20]={0x00000000, 0x00000002, 0x00000004, 0x007FFFFE, + 0x00900000, 0x00900006, 0x00900008, 0x009FFFFE, + 0x01000000, 0x0100000A, 0x0200000C, 0x01FFFFFE, + 0x03000000, 0x03000002, 0x04000004, 0x03FFFFFE, + 0x04000000, 0x05000006, 0x06000008, 0x07FFFFFE}; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Determine mask for number of data bits. */ + ulDataMask = (1 << f_ulNumDataBits) - 1; + + /* Write specific data to specific address */ + WriteParams.ulWriteAddress = f_ulMemBase | 0x00001000; + WriteParams.usWriteData = 0xCAFE; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for(j=0; j<20; j++) + { + /* Change address to test lower and higher part of the 32 bit bus */ + ulBistAddress = aulBistAddress[j]; + ulBistAddress &= f_ulMemSize - 2; + ulBistAddress |= f_ulMemBase; + + /* Bist 16 data pins of this address */ + for ( i = 0; i < 16; i ++) + { + WriteParams.ulWriteAddress = ulBistAddress; + WriteParams.usWriteData = (UINT16)(0x1 << i); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read back the specific data to flush the data bus.*/ + ReadParams.ulReadAddress = f_ulMemBase | 0x00001000; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xCAFE ) + return f_ulErrorCode; + + /* Read back the data written.*/ + ReadParams.ulReadAddress = WriteParams.ulWriteAddress; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != (UINT16)(0x1 << i) ) + return f_ulErrorCode; + } + } + + /* Perform the first write at address 0 + mem base */ + j = 0; + WriteParams.ulWriteAddress = f_ulMemBase; + WriteParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, j, ulDataMask ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Try each address line of the memory. */ + for ( i = 2, j = 1; i < f_ulMemSize; i <<= 1, j++ ) + { + WriteParams.ulWriteAddress = ( f_ulMemBase + i ); + WriteParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, j, ulDataMask ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + for ( i = 0; i < j; i++ ) + { + if ( i > 0 ) + ReadParams.ulReadAddress = ( f_ulMemBase + ( 0x1 << i ) ); + else + ReadParams.ulReadAddress = f_ulMemBase; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != Oct6100ApiGenerateNumber( f_pApiInstance, i, ulDataMask ) ) + return f_ulErrorCode; + } + + /* Write to random addresses of the memory. */ + for ( i = 0; i < f_ulNumAccesses; i++ ) + { + ulBistAddress = (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) << 16; + ulBistAddress |= (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + ulBistAddress &= f_ulMemSize - 2; + ulBistAddress |= f_ulMemBase; + + WriteParams.ulWriteAddress = ulBistAddress; + WriteParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + for ( i = 0; i < f_ulNumAccesses; i++ ) + { + ulBistAddress = (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) << 16; + ulBistAddress |= (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + ulBistAddress &= f_ulMemSize - 2; + ulBistAddress |= f_ulMemBase; + + ReadParams.ulReadAddress = ulBistAddress; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( usReadData & ulDataMask ) != ( Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) & ulDataMask ) ) + return f_ulErrorCode; + } + + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUserIoTest + +Description: This function will verify the correct functionality of + the following user functions: + + - Oct6100UserDriverWriteBurstApi + - Oct6100UserDriverWriteSmearApi + - Oct6100UserDriverReadBurstApi + + The Oct6100UserDriverWriteApi and Oct6100UserDriverReadApi + functions do not need to be tested here as this has be done in + the external memory bisting function above. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUserIoTest +UINT32 Oct6100ApiUserIoTest( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS WriteBurstParams; + tOCT6100_WRITE_SMEAR_PARAMS WriteSmearParams; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_READ_BURST_PARAMS ReadBurstParams; + UINT32 ulResult, i; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + /* Test what the user has specified is the maximum that can be used for a burst. */ + WriteBurstParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + WriteBurstParams.pusWriteData = pSharedInfo->MiscVars.ausSuperArray; + + WriteSmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteSmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + /* Test what the user has specified is the maximum that can be used for a smear. */ + WriteSmearParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + ReadBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + /* Test what the user has specified is the maximum that can be used for a burst. */ + ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + ReadBurstParams.pusReadData = pSharedInfo->MiscVars.ausSuperArray; + + + /*======================================================================*/ + /* Write burst check. */ + + WriteBurstParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + /* Set the random data to be written. */ + for ( i = 0; i < WriteBurstParams.ulWriteLength; i++ ) + { + WriteBurstParams.pusWriteData[ i ] = Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + } + mOCT6100_DRIVER_WRITE_BURST_API( WriteBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read back pattern using simple read function and make sure we are reading what's expected. */ + ReadParams.ulReadAddress = WriteBurstParams.ulWriteAddress; + for ( i = 0; i < WriteBurstParams.ulWriteLength; i++ ) + { + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the data matches. */ + if ( usReadData != WriteBurstParams.pusWriteData[ i ] ) + { + /* The values do not match. Something seems to be wrong with the WriteBurst user function. */ + return cOCT6100_ERR_OPEN_USER_WRITE_BURST_FAILED; + } + + /* Next address to check. */ + ReadParams.ulReadAddress += 2; + } + + /*======================================================================*/ + + + /*======================================================================*/ + /* Write smear check. */ + + WriteSmearParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + ( WriteBurstParams.ulWriteLength * 2 ); + /* Set the random data to be written. */ + WriteSmearParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, Oct6100ApiRand( 0xFFFF ), 0xFFFF ); + mOCT6100_DRIVER_WRITE_SMEAR_API( WriteSmearParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read back pattern using simple read function and make sure we are reading what's expected. */ + ReadParams.ulReadAddress = WriteSmearParams.ulWriteAddress; + for ( i = 0; i < WriteSmearParams.ulWriteLength; i++ ) + { + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the data matches. */ + if ( usReadData != WriteSmearParams.usWriteData ) + { + /* The values do not match. Something seems to be wrong with the WriteSmear user function. */ + return cOCT6100_ERR_OPEN_USER_WRITE_SMEAR_FAILED; + } + + /* Next address to check. */ + ReadParams.ulReadAddress += 2; + } + + /*======================================================================*/ + + + /*======================================================================*/ + /* Read burst check. */ + + /* First check with what the WriteBurst function wrote. */ + ReadBurstParams.ulReadAddress = WriteBurstParams.ulWriteAddress; + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for ( i = 0; i < ReadBurstParams.ulReadLength; i++ ) + { + /* Check if the data matches. */ + if ( ReadBurstParams.pusReadData[ i ] != Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) ) + { + /* The values do not match. Something seems to be wrong with the ReadBurst user function. */ + return cOCT6100_ERR_OPEN_USER_READ_BURST_FAILED; + } + } + + /* Then check with what the WriteSmear function wrote. */ + ReadBurstParams.ulReadAddress = WriteSmearParams.ulWriteAddress; + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for ( i = 0; i < ReadBurstParams.ulReadLength; i++ ) + { + /* Check if the data matches. */ + if ( ReadBurstParams.pusReadData[ i ] != WriteSmearParams.usWriteData ) + { + /* The values do not match. Something seems to be wrong with the ReadBurst user function. */ + return cOCT6100_ERR_OPEN_USER_READ_BURST_FAILED; + } + } + + /*======================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiExternalMemoryInit + +Description: Initialize the external memory before uploading the image. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiExternalMemoryInit +UINT32 Oct6100ApiExternalMemoryInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_SMEAR_PARAMS SmearParams; + UINT32 ulTotalWordToWrite; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + SmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + SmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Clear the first part of the memory. */ + ulTotalWordToWrite = 0x400; + SmearParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + + while ( ulTotalWordToWrite != 0 ) + { + if ( ulTotalWordToWrite >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + SmearParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + SmearParams.ulWriteLength = ulTotalWordToWrite; + + SmearParams.usWriteData = 0x0; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the number of words to write. */ + ulTotalWordToWrite -= SmearParams.ulWriteLength; + /* Update the address. */ + SmearParams.ulWriteAddress += ( SmearParams.ulWriteLength * 2 ); + } + + /* Clear the TLV flag.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, cOCT6100_TLV_BASE, 0x0 ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitMixer + +Description: This function will initialize the mixer memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitMixer +UINT32 Oct6100ApiInitMixer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + UINT16 ausWriteData[ 4 ]; + UINT32 ulResult; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + BurstParams.pusWriteData = ausWriteData; + /*======================================================================*/ + /* Initialize the mixer memory if required. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + { + /* Modify the mixer pointer by adding the record event into the link list. */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = pSharedInfo->MixerInfo.usRecordCopyEventIndex; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = pSharedInfo->MixerInfo.usRecordCopyEventIndex; + + /* Program the Sin copy event. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordSinEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(cOCT6100_MIXER_TAIL_NODE & 0x7FF); /* Head node.*/ + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the Sout copy event. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(pSharedInfo->MixerInfo.usRecordSinEventIndex & 0x7FF); + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the head node. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE; + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(pSharedInfo->MixerInfo.usRecordCopyEventIndex & 0x7FF); + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Init the mixer pointer */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + } + else + { + /* Configure the head node. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE; + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(cOCT6100_MIXER_TAIL_NODE & 0x7FF); /* Head node. */ + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the tail node. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + 0x10; + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(cOCT6100_MIXER_HEAD_NODE & 0x7FF); /* Head node. */ + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitRecordResources + +Description: This function will initialize the resources required to + perform recording on a debug channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiInitRecordResources +UINT32 Oct6100ApiInitRecordResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check if recording is enabled. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE ) + return cOCT6100_ERR_OK; + + if ( pSharedInfo->DebugInfo.usRecordMemIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_DEBUG_RECORD; + + /* Check the provided recording memory index within the SSPX. */ + if ( pSharedInfo->DebugInfo.usRecordMemIndex != ( pSharedInfo->ImageInfo.usMaxNumberOfChannels - 1 ) ) + return cOCT6100_ERR_OPEN_DEBUG_MEM_INDEX; + + /* Reserve the TSI entries for the channel. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, &pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, &pSharedInfo->DebugInfo.usRecordSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Open the debug channel. */ + ulResult = Oct6100ApiDebugChannelOpen( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100FreeResourcesSer + +Description: This function closes all opened channels and frees all + specified global resources used by the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pFreeResources Pointer to user structure in which to choose what + to free. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100FreeResourcesSer +UINT32 Oct6100FreeResourcesSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_FREE_RESOURCES f_pFreeResources ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + + UINT32 ulResult; + UINT32 i; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Close all bidirectional channels. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxBiDirChannels; i ++ ) + { + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, i ); + + if ( pBiDirChanEntry->fReserved == TRUE ) + { + tOCT6100_CHANNEL_DESTROY_BIDIR DestroyBidir; + + Oct6100ChannelDestroyBiDirDef( &DestroyBidir ); + + DestroyBidir.ulBiDirChannelHndl = cOCT6100_HNDL_TAG_BIDIR_CHANNEL | (pBiDirChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100ChannelDestroyBiDirSer( f_pApiInstance, &DestroyBidir ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Close all bridge participants. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i ++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, i ); + if ( pChanEntry->fReserved == TRUE && pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + { + /* This channel is on a bridge. */ + tOCT6100_CONF_BRIDGE_CHAN_REMOVE BridgeChanRemove; + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + Oct6100ConfBridgeChanRemoveDef( &BridgeChanRemove ); + + /* Obtain a pointer to the conference bridge's list entry. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, pChanEntry->usBridgeIndex ); + + BridgeChanRemove.fRemoveAll = TRUE; + BridgeChanRemove.ulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pBridgeEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pChanEntry->usBridgeIndex; + + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Close all opened channels. This will bring the broadcast TSSTs with it. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i ++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, i ); + + if ( pChanEntry->fReserved == TRUE ) + { + tOCT6100_CHANNEL_CLOSE ChannelClose; + + /* Generate handle. */ + ChannelClose.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | (pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + /* Call serialized close channel function. */ + ulResult = Oct6100ChannelCloseSer( f_pApiInstance, &ChannelClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + /* Close all TSI connections. */ + if ( f_pFreeResources->fFreeTsiConnections == TRUE ) + { + tPOCT6100_API_TSI_CNCT pTsiCnct; + tOCT6100_TSI_CNCT_CLOSE TsiCnctClose; + + Oct6100TsiCnctCloseDef( &TsiCnctClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxTsiCncts; i ++ ) + { + /* Obtain a pointer to the TSI connection list entry. */ + mOCT6100_GET_TSI_CNCT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsiCnct, i ); + + if ( pTsiCnct->fReserved == TRUE ) + { + TsiCnctClose.ulTsiCnctHndl = cOCT6100_HNDL_TAG_TSI_CNCT | (pTsiCnct->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100TsiCnctCloseSer( f_pApiInstance, &TsiCnctClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + /* Close all conference bridges. */ + if ( f_pFreeResources->fFreeConferenceBridges == TRUE ) + { + tPOCT6100_API_CONF_BRIDGE pConfBridge; + tOCT6100_CONF_BRIDGE_CLOSE ConfBridgeClose; + + Oct6100ConfBridgeCloseDef( &ConfBridgeClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxConfBridges; i ++ ) + { + /* Obtain a pointer to the conference bridge's list entry. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pConfBridge, i ); + + if ( pConfBridge->fReserved == TRUE ) + { + ConfBridgeClose.ulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pConfBridge->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100ConfBridgeCloseSer( f_pApiInstance, &ConfBridgeClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Free all playout buffers loaded in external memory. */ + if ( f_pFreeResources->fFreePlayoutBuffers == TRUE ) + { + tPOCT6100_API_BUFFER pBuffer; + tOCT6100_BUFFER_UNLOAD BufferUnload; + + Oct6100BufferPlayoutUnloadDef( &BufferUnload ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxPlayoutBuffers; i ++ ) + { + + + /* Obtain a pointer to the buffer list entry. */ + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBuffer, i ); + + if ( pBuffer->fReserved == TRUE ) + { + BufferUnload.ulBufferIndex = i; + ulResult = Oct6100BufferUnloadSer( f_pApiInstance, &BufferUnload, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Close all phasing TSSTs. */ + if ( f_pFreeResources->fFreePhasingTssts == TRUE ) + { + tPOCT6100_API_PHASING_TSST pPhasingTsst; + tOCT6100_PHASING_TSST_CLOSE PhasingTsstClose; + + Oct6100PhasingTsstCloseDef( &PhasingTsstClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxPhasingTssts; i ++ ) + { + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingTsst, i ); + + if ( pPhasingTsst->fReserved == TRUE ) + { + PhasingTsstClose.ulPhasingTsstHndl = cOCT6100_HNDL_TAG_PHASING_TSST | (pPhasingTsst->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100PhasingTsstCloseSer( f_pApiInstance, &PhasingTsstClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + /* Close all ADPCM channels. */ + if ( f_pFreeResources->fFreeAdpcmChannels == TRUE ) + { + tPOCT6100_API_ADPCM_CHAN pAdpcmChannel; + tOCT6100_ADPCM_CHAN_CLOSE AdpcmChanClose; + + Oct6100AdpcmChanCloseDef( &AdpcmChanClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxAdpcmChannels; i ++ ) + { + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pAdpcmChannel, i ); + if ( pAdpcmChannel->fReserved == TRUE ) + { + AdpcmChanClose.ulChanHndl = cOCT6100_HNDL_TAG_ADPCM_CHANNEL | (pAdpcmChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100AdpcmChanCloseSer( f_pApiInstance, &AdpcmChanClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ProductionBistSer + +Description: This function returns the instantaneous production BIST status. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pProductionBist Pointer to user structure in which BIST status will + be returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ProductionBistSer +UINT32 Oct6100ProductionBistSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PRODUCTION_BIST f_pProductionBist ) +{ + UINT32 ulCalculatedCrc = cOCT6100_INVALID_VALUE; + UINT32 ulResult; + UINT32 ulLoopCnt = 0x0; + UINT32 i = 1; + UINT32 ulTotalElements = 4; + UINT32 ulReadAddress = cOCT6100_POUCH_BASE; + UINT32 aulMessage[ 5 ]; + + /* Check if the production bist has been activated. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableProductionBist == FALSE ) + return cOCT6100_ERR_PRODUCTION_BIST_DISABLED; + + f_pProductionBist->ulCurrentAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulCurrentLoop = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulCurrentTest = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulFailedAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulReadValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulExpectedValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulBistStatus = cOCT6100_BIST_IN_PROGRESS; + + /* The API knows that the firmware might be writing a status event. */ + /* The firmware does write a status event every 200ms (approximately). */ + /* So the status is read a couple of times to make sure an event was not read while */ + /* it was written. */ + while ( ulLoopCnt != 2 ) + { + /* Read the BIST status in the external memory. */ + for ( i = 0; i < ulTotalElements + 1; i ++ ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, ulReadAddress + i * 4, &aulMessage[ i ] ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Calculate the CRC of this message. */ + ulResult = Oct6100ApiProductionCrc( f_pApiInstance, aulMessage, ulTotalElements, &ulCalculatedCrc ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* If the CRCs do match, break off the while. We have a valid status event. */ + if ( aulMessage[ i - 1 ] == ulCalculatedCrc ) + break; + + ulLoopCnt++; + } + + /* Check if the CRC matches */ + if ( aulMessage[ i - 1 ] != ulCalculatedCrc ) + { + /* Well, the exchange memory at the base of the external memory is corrupted. */ + /* Something very basic is not working correctly with this chip! */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_STATUS_CRC_FAILED; + } + else + { + /* Check for problems. */ + switch ( aulMessage[ 0 ] & 0xFFFF ) + { + case ( 0x2 ): + + /* The initial configuration failed. */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_CONFIGURATION_FAILED; + break; + + case ( 0x1 ): + + /* A memory location failed. Return useful information to the user. */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_MEMORY_FAILED; + + f_pProductionBist->ulFailedAddress = ( aulMessage[ 1 ] & ( ~0x80000000 ) ) + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + f_pProductionBist->ulReadValue = aulMessage[ 2 ]; + f_pProductionBist->ulExpectedValue = aulMessage[ 3 ]; + break; + + case ( 0xFFFF ): + + /* Bist is completed! */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_SUCCESS; + break; + + default: + /* Bist is in progress. All seems to be working fine up to now. */ + + /* Return progress status. */ + f_pProductionBist->ulCurrentAddress = ( aulMessage[ 1 ] & ( ~0x80000000 ) ) + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + f_pProductionBist->ulCurrentTest = aulMessage[ 2 ]; + f_pProductionBist->ulCurrentLoop = aulMessage[ 3 ]; + break; + } + } + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProductionCrc + +Description: This function calculates the crc for a production BIST + message. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pulMessage Message to be exchanged with the firmware. The CRC + will be calculated on this. +f_ulMessageLength Length of the message to be exchanged. This value + does not include the CRC value at the end +f_pulCrcResult Resulting calculated CRC value. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiProductionCrc +UINT32 Oct6100ApiProductionCrc( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulMessage, + IN UINT32 f_ulMessageLength, + OUT PUINT32 f_pulCrcResult ) +{ + UINT32 ulWidth = 32; + UINT32 ulKey, i, j; + UINT32 ulRemainder = 0; + + /* CRC the message. */ + ulRemainder = f_pulMessage[ f_ulMessageLength - 1 ]; + for ( j = f_ulMessageLength - 1; j != 0xFFFFFFFF ; j-- ) + { + for ( i = 0; i < ulWidth; i++ ) + { + if ( ( ( ulRemainder >> 0x1F ) & 0x1 ) == 0x1 ) + { + /* Division is by something meaningful */ + ulKey = 0x8765DCBA; + } + else + { + /* Remainder is less than our divisor */ + ulKey = 0; + } + ulRemainder = ulRemainder ^ ulKey; + + ulRemainder = ulRemainder << 1; + if ( j != 0 ) + { + ulRemainder = ulRemainder | ( ( f_pulMessage[ j - 1 ] ) >> ( 0x1F - i ) ); + } + } + } + + *f_pulCrcResult = ulRemainder; + + return cOCT6100_ERR_OK; +} +#endif + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiClearInterrupts + +Description: Called only by the Oct6100OpenChip function, this function + writes to all register ROLs to clear them. This is necessary + because some ROLs are set during the startup. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +IN f_pApiInst Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiClearInterrupts +UINT32 Oct6100ApiClearInterrupts( + IN tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + WriteParams.ulWriteAddress = 0x102; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_102H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x202; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_202H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x302; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_302H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x502; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_502H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x702; + WriteParams.usWriteData = cOCT6100_INTRPT_MASK_REG_702H; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; + +} +#endif diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.c 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,440 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_stats.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains functions used to retreive the OCT6100 chip stats. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 89 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_chip_stats_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_chip_stats_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_chip_stats_priv.h" + +/**************************** PUBLIC FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipGetStats + +Description: Retreives the chip statistics and configuration. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipStats Pointer to a tOCT6100_CHIP_STATS structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipGetStatsDef +UINT32 Oct6100ChipGetStatsDef( + tPOCT6100_CHIP_STATS f_pChipStats ) +{ + f_pChipStats->fResetChipStats = FALSE; + + f_pChipStats->ulNumberChannels = cOCT6100_INVALID_STAT; + f_pChipStats->ulNumberTsiCncts = cOCT6100_INVALID_STAT; + f_pChipStats->ulNumberConfBridges = cOCT6100_INVALID_STAT; + f_pChipStats->ulNumberPlayoutBuffers = cOCT6100_INVALID_STAT; + f_pChipStats->ulPlayoutFreeMemSize = cOCT6100_INVALID_STAT; + + f_pChipStats->ulNumberPhasingTssts = cOCT6100_INVALID_STAT; + f_pChipStats->ulNumberAdpcmChannels = cOCT6100_INVALID_STAT; + + f_pChipStats->ulH100OutOfSynchCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulH100ClockABadCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulH100FrameABadCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulH100ClockBBadCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulInternalReadTimeoutCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulSdramRefreshTooLateCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulPllJitterErrorCount = cOCT6100_INVALID_STAT; + + f_pChipStats->ulOverflowToneEventsCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulSoftOverflowToneEventsCount = cOCT6100_INVALID_STAT; + f_pChipStats->ulSoftOverflowBufferPlayoutEventsCount = cOCT6100_INVALID_STAT; + + + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ChipGetStats +UINT32 Oct6100ChipGetStats( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_STATS f_pChipStats ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ChipGetStatsSer( f_pApiInstance, f_pChipStats ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipGetImageInfo + +Description: Retrieves the chip image information indicating the supported + features and tones. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipImageInfo Pointer to a tPOCT6100_CHIP_IMAGE_INFO structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipGetImageInfoDef +UINT32 Oct6100ChipGetImageInfoDef( + tPOCT6100_CHIP_IMAGE_INFO f_pChipImageInfo ) +{ + UINT32 i; + + Oct6100UserMemSet( f_pChipImageInfo->szVersionNumber, 0x0, cOCT6100_VERSION_NUMBER_MAX_SIZE ); + + f_pChipImageInfo->fBufferPlayout = FALSE; + f_pChipImageInfo->fAdaptiveNoiseReduction = FALSE; + f_pChipImageInfo->fSoutNoiseBleaching = FALSE; + f_pChipImageInfo->fConferencingNoiseReduction = FALSE; + f_pChipImageInfo->fAutoLevelControl = FALSE; + f_pChipImageInfo->fHighLevelCompensation = FALSE; + f_pChipImageInfo->fSilenceSuppression = FALSE; + + f_pChipImageInfo->fAdpcm = FALSE; + f_pChipImageInfo->fConferencing = FALSE; + f_pChipImageInfo->fDominantSpeaker = FALSE; + f_pChipImageInfo->ulMaxChannels = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulNumTonesAvailable = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulToneProfileNumber = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulMaxTailDisplacement = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulBuildId = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulMaxTailLength = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulDebugEventSize = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulMaxPlayoutEvents = cOCT6100_INVALID_VALUE; + f_pChipImageInfo->ulImageType = cOCT6100_INVALID_VALUE; + + f_pChipImageInfo->fAcousticEcho = FALSE; + f_pChipImageInfo->fAecTailLength = FALSE; + f_pChipImageInfo->fToneRemoval = FALSE; + + f_pChipImageInfo->fDefaultErl = FALSE; + f_pChipImageInfo->fNonLinearityBehaviorA = FALSE; + f_pChipImageInfo->fNonLinearityBehaviorB = FALSE; + f_pChipImageInfo->fPerChannelTailDisplacement = FALSE; + f_pChipImageInfo->fPerChannelTailLength = FALSE; + f_pChipImageInfo->fListenerEnhancement = FALSE; + f_pChipImageInfo->fRoutNoiseReduction = FALSE; + f_pChipImageInfo->fRoutNoiseReductionLevel = FALSE; + f_pChipImageInfo->fAnrSnrEnhancement = FALSE; + f_pChipImageInfo->fAnrVoiceNoiseSegregation = FALSE; + f_pChipImageInfo->fToneDisablerVqeActivationDelay = FALSE; + f_pChipImageInfo->fMusicProtection = FALSE; + f_pChipImageInfo->fDoubleTalkBehavior = FALSE; + f_pChipImageInfo->fIdleCodeDetection = TRUE; + f_pChipImageInfo->fSinLevel = TRUE; + + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + Oct6100UserMemSet( f_pChipImageInfo->aToneInfo[ i ].aszToneName, 0x00, cOCT6100_TLV_MAX_TONE_NAME_SIZE ); + f_pChipImageInfo->aToneInfo[ i ].ulDetectionPort = cOCT6100_INVALID_PORT; + f_pChipImageInfo->aToneInfo[ i ].ulToneID = cOCT6100_INVALID_VALUE; + } + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ChipGetImageInfo +UINT32 Oct6100ChipGetImageInfo( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_IMAGE_INFO f_pChipImageInfo ) +{ + tPOCT6100_API_IMAGE_INFO pImageInfo; + UINT32 i; + + /* Get local pointer(s). */ + pImageInfo = &f_pApiInstance->pSharedInfo->ImageInfo; + + Oct6100UserMemCopy( f_pChipImageInfo->szVersionNumber, pImageInfo->szVersionNumber, cOCT6100_VERSION_NUMBER_MAX_SIZE ); + + /* Copy the customer info. */ + f_pChipImageInfo->ulBuildId = pImageInfo->ulBuildId; + + /* Copy the features list. */ + f_pChipImageInfo->fBufferPlayout = pImageInfo->fBufferPlayout; + f_pChipImageInfo->fAdaptiveNoiseReduction = pImageInfo->fAdaptiveNoiseReduction; + f_pChipImageInfo->fSoutNoiseBleaching = pImageInfo->fSoutNoiseBleaching; + f_pChipImageInfo->fSilenceSuppression = pImageInfo->fSilenceSuppression; + + f_pChipImageInfo->fAdpcm = pImageInfo->fAdpcm; + f_pChipImageInfo->fConferencing = pImageInfo->fConferencing; + f_pChipImageInfo->fDominantSpeaker = pImageInfo->fDominantSpeakerEnabled; + f_pChipImageInfo->fConferencingNoiseReduction = pImageInfo->fConferencingNoiseReduction; + f_pChipImageInfo->fAcousticEcho = pImageInfo->fAcousticEcho; + f_pChipImageInfo->fAecTailLength = pImageInfo->fAecTailLength; + f_pChipImageInfo->fDefaultErl = pImageInfo->fDefaultErl; + f_pChipImageInfo->fToneRemoval = pImageInfo->fToneRemoval; + + f_pChipImageInfo->fNonLinearityBehaviorA = pImageInfo->fNonLinearityBehaviorA; + f_pChipImageInfo->fNonLinearityBehaviorB = pImageInfo->fNonLinearityBehaviorB; + f_pChipImageInfo->fPerChannelTailDisplacement = pImageInfo->fPerChannelTailDisplacement; + f_pChipImageInfo->fListenerEnhancement = pImageInfo->fListenerEnhancement; + f_pChipImageInfo->fRoutNoiseReduction = pImageInfo->fRoutNoiseReduction; + f_pChipImageInfo->fRoutNoiseReductionLevel = pImageInfo->fRoutNoiseReductionLevel; + f_pChipImageInfo->fAnrSnrEnhancement = pImageInfo->fAnrSnrEnhancement; + f_pChipImageInfo->fAnrVoiceNoiseSegregation = pImageInfo->fAnrVoiceNoiseSegregation; + f_pChipImageInfo->fMusicProtection = pImageInfo->fMusicProtection; + f_pChipImageInfo->fIdleCodeDetection = pImageInfo->fIdleCodeDetection; + f_pChipImageInfo->fSinLevel = pImageInfo->fSinLevel; + f_pChipImageInfo->fDoubleTalkBehavior = pImageInfo->fDoubleTalkBehavior; + f_pChipImageInfo->fHighLevelCompensation = pImageInfo->fRinHighLevelCompensation; + + if ( ( pImageInfo->fRinAutoLevelControl == TRUE ) && ( pImageInfo->fSoutAutoLevelControl == TRUE ) ) + f_pChipImageInfo->fAutoLevelControl = TRUE; + else + f_pChipImageInfo->fAutoLevelControl = FALSE; + + f_pChipImageInfo->ulMaxChannels = pImageInfo->usMaxNumberOfChannels; + f_pChipImageInfo->ulNumTonesAvailable = pImageInfo->byNumToneDetectors; + f_pChipImageInfo->ulToneProfileNumber = pImageInfo->ulToneProfileNumber; + f_pChipImageInfo->ulMaxTailDisplacement = pImageInfo->usMaxTailDisplacement; + f_pChipImageInfo->ulMaxTailLength = pImageInfo->usMaxTailLength; + f_pChipImageInfo->fPerChannelTailLength = pImageInfo->fPerChannelTailLength; + f_pChipImageInfo->ulDebugEventSize = f_pApiInstance->pSharedInfo->DebugInfo.ulDebugEventSize; + f_pChipImageInfo->fToneDisablerVqeActivationDelay = pImageInfo->fToneDisablerVqeActivationDelay; + f_pChipImageInfo->ulMaxPlayoutEvents = pImageInfo->byMaxNumberPlayoutEvents - 1; /* 127 or 31 */ + f_pChipImageInfo->ulImageType = pImageInfo->byImageType; + + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + Oct6100UserMemCopy( f_pChipImageInfo->aToneInfo[ i ].aszToneName, pImageInfo->aToneInfo[ i ].aszToneName, cOCT6100_TLV_MAX_TONE_NAME_SIZE ); + f_pChipImageInfo->aToneInfo[ i ].ulDetectionPort = pImageInfo->aToneInfo[ i ].ulDetectionPort; + f_pChipImageInfo->aToneInfo[ i ].ulToneID = pImageInfo->aToneInfo[ i ].ulToneID; + } + + return cOCT6100_ERR_OK; +} +#endif + + +/**************************** PRIVATE FUNCTIONS ****************************/ + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiChipStatsSwInit + +Description: Initializes portions of API instance associated to chip stats. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiChipStatsSwInit +UINT32 Oct6100ApiChipStatsSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + + /* Get local pointer to shared portion of API instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Initialize chip stats. */ + pSharedInfo->ErrorStats.fFatalChipError = FALSE; + + pSharedInfo->ErrorStats.ulH100ClkABadCnt = 0; + pSharedInfo->ErrorStats.ulH100ClkBBadCnt = 0; + pSharedInfo->ErrorStats.ulH100FrameABadCnt = 0; + pSharedInfo->ErrorStats.ulH100OutOfSyncCnt = 0; + + pSharedInfo->ErrorStats.ulInternalReadTimeoutCnt = 0; + pSharedInfo->ErrorStats.ulSdramRefreshTooLateCnt = 0; + pSharedInfo->ErrorStats.ulPllJitterErrorCnt = 0; + pSharedInfo->ErrorStats.ulOverflowToneEventsCnt = 0; + + + + pSharedInfo->ErrorStats.ulToneDetectorErrorCnt = 0; + + /* Init the chip stats. */ + pSharedInfo->ChipStats.usNumberChannels = 0; + pSharedInfo->ChipStats.usNumberBiDirChannels = 0; + pSharedInfo->ChipStats.usNumberTsiCncts = 0; + pSharedInfo->ChipStats.usNumberConfBridges = 0; + pSharedInfo->ChipStats.usNumberPlayoutBuffers = 0; + pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts = 0; + pSharedInfo->ChipStats.ulPlayoutMemUsed = 0; + pSharedInfo->ChipStats.usNumEcChanUsingMixer = 0; + + pSharedInfo->ChipStats.usNumberPhasingTssts = 0; + pSharedInfo->ChipStats.usNumberAdpcmChans = 0; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipGetStatsSer + +Description: Serialized function retreiving the chip statistics. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipStats Pointer to master mode configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ChipGetStatsSer +UINT32 Oct6100ChipGetStatsSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT tPOCT6100_CHIP_STATS f_pChipStats ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + + /* Get local pointer(s). */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + f_pChipStats->ulNumberChannels = pSharedInfo->ChipStats.usNumberChannels; + f_pChipStats->ulNumberTsiCncts = pSharedInfo->ChipStats.usNumberTsiCncts; + f_pChipStats->ulNumberConfBridges = pSharedInfo->ChipStats.usNumberConfBridges; + f_pChipStats->ulNumberPlayoutBuffers = pSharedInfo->ChipStats.usNumberPlayoutBuffers; + f_pChipStats->ulPlayoutFreeMemSize = ( f_pApiInstance->pSharedInfo->MiscVars.ulTotalMemSize - ( f_pApiInstance->pSharedInfo->MemoryMap.ulFreeMemBaseAddress - cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) ) - ( pSharedInfo->ChipStats.ulPlayoutMemUsed ); + + f_pChipStats->ulNumberPhasingTssts = pSharedInfo->ChipStats.usNumberPhasingTssts; + f_pChipStats->ulNumberAdpcmChannels = pSharedInfo->ChipStats.usNumberAdpcmChans; + + /* Check the input parameters. */ + if ( f_pChipStats->fResetChipStats != TRUE && + f_pChipStats->fResetChipStats != FALSE ) + return cOCT6100_ERR_CHIP_STATS_RESET; + + if ( f_pChipStats->fResetChipStats == TRUE ) + { + pSharedInfo->ErrorStats.ulH100OutOfSyncCnt = 0; + pSharedInfo->ErrorStats.ulH100ClkABadCnt = 0; + pSharedInfo->ErrorStats.ulH100FrameABadCnt = 0; + pSharedInfo->ErrorStats.ulH100ClkBBadCnt = 0; + + pSharedInfo->ErrorStats.ulInternalReadTimeoutCnt = 0; + pSharedInfo->ErrorStats.ulPllJitterErrorCnt = 0; + pSharedInfo->ErrorStats.ulSdramRefreshTooLateCnt = 0; + + pSharedInfo->ErrorStats.ulOverflowToneEventsCnt = 0; + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt = 0; + + + } + + f_pChipStats->ulH100OutOfSynchCount = pSharedInfo->ErrorStats.ulH100OutOfSyncCnt; + f_pChipStats->ulH100ClockABadCount = pSharedInfo->ErrorStats.ulH100ClkABadCnt; + f_pChipStats->ulH100FrameABadCount = pSharedInfo->ErrorStats.ulH100FrameABadCnt; + f_pChipStats->ulH100ClockBBadCount = pSharedInfo->ErrorStats.ulH100ClkBBadCnt; + + f_pChipStats->ulInternalReadTimeoutCount = pSharedInfo->ErrorStats.ulInternalReadTimeoutCnt; + f_pChipStats->ulPllJitterErrorCount = pSharedInfo->ErrorStats.ulPllJitterErrorCnt; + f_pChipStats->ulSdramRefreshTooLateCount = pSharedInfo->ErrorStats.ulSdramRefreshTooLateCnt; + + f_pChipStats->ulOverflowToneEventsCount = pSharedInfo->ErrorStats.ulOverflowToneEventsCnt; + f_pChipStats->ulSoftOverflowToneEventsCount = pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt; + f_pChipStats->ulSoftOverflowBufferPlayoutEventsCount = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt; + + + + return cOCT6100_ERR_OK; +} +#endif + diff -Nru dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.c dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.c --- dahdi-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.c 1969-12-31 18:00:00.000000000 -0600 +++ dahdi-cnet-linux-2.2.1-rc2/drivers/dahdi/oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.c 2007-10-02 14:07:04.000000000 -0500 @@ -0,0 +1,7687 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_conf_bridge.c + + Copyright (c) 2001-2007 Octasic Inc. + +Description: + + This file contains all functions related to a conference bridge. Procedures + needed to open/close a bridge, add/remove a participant to a conference + bridge, mute/unmute a participant, etc.. are all present in this source + file. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR49 $ + +$Octasic_Revision: 146 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" +#include "oct6100api/oct6100_apiud.h" + +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_api_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_mixer_inst.h" +#include "oct6100api/oct6100_conf_bridge_inst.h" + +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" +#include "oct6100api/oct6100_conf_bridge_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_channel_priv.h" +#include "oct6100_mixer_priv.h" +#include "oct6100_conf_bridge_priv.h" + + +/**************************** PUBLIC FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeOpen + +Description: This function opens a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeOpen Pointer to conference bridge open structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeOpenDef +UINT32 Oct6100ConfBridgeOpenDef( + tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ) +{ + f_pConfBridgeOpen->pulConfBridgeHndl = NULL; + f_pConfBridgeOpen->fFlexibleConferencing = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeOpen +UINT32 Oct6100ConfBridgeOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeOpenSer( f_pApiInstance, f_pConfBridgeOpen ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeClose + +Description: This function closes a conference bridge. A conference + bridge can only be closed if no participants are present on + the bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeClose Pointer to conference bridge close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeCloseDef +UINT32 Oct6100ConfBridgeCloseDef( + tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ) +{ + f_pConfBridgeClose->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeClose +UINT32 Oct6100ConfBridgeClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeCloseSer( f_pApiInstance, f_pConfBridgeClose ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanAdd + +Description: This function adds an echo channel (participant) to a + conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeAdd Pointer to conference bridge channel addition structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanAddDef +UINT32 Oct6100ConfBridgeChanAddDef( + tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ) +{ + f_pConfBridgeAdd->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeAdd->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeAdd->ulInputPort = cOCT6100_CHANNEL_PORT_SOUT; + f_pConfBridgeAdd->ulListenerMaskIndex = cOCT6100_INVALID_VALUE; + f_pConfBridgeAdd->ulListenerMask = 0; + f_pConfBridgeAdd->fMute = FALSE; + f_pConfBridgeAdd->ulTappedChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeChanAdd +UINT32 Oct6100ConfBridgeChanAdd( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CHAN_ADD f_pConfBridgeAdd ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeChanAddSer( f_pApiInstance, f_pConfBridgeAdd ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanRemove + +Description: This function removes an echo channel (participant) from a + conference bridge. All participants can be removed from + the bridge if a special flag (fRemoveAll) is set to TRUE. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeRemove Pointer to conference bridge channel removal structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanRemoveDef +UINT32 Oct6100ConfBridgeChanRemoveDef( + tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ) +{ + f_pConfBridgeRemove->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeRemove->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeRemove->fRemoveAll = FALSE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeChanRemove +UINT32 Oct6100ConfBridgeChanRemove( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CHAN_REMOVE f_pConfBridgeRemove ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, f_pConfBridgeRemove ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanMute + +Description: This function mutes a participant present on a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeMute Pointer to conference bridge channel mute structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanMuteDef +UINT32 Oct6100ConfBridgeChanMuteDef( + tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ) +{ + f_pConfBridgeMute->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeChanMute +UINT32 Oct6100ConfBridgeChanMute( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CHAN_MUTE f_pConfBridgeMute ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeChanMuteSer( f_pApiInstance, f_pConfBridgeMute ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeChanUnMute + +Description: This function unmutes a channel on a bridge. The other member + of the conference will start to hear this participant again. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeUnMute Pointer to conference bridge channel unmute structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeChanUnMuteDef +UINT32 Oct6100ConfBridgeChanUnMuteDef( + tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ) +{ + f_pConfBridgeUnMute->ulChannelHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + +#if !SKIP_Oct6100ConfBridgeChanUnMute +UINT32 Oct6100ConfBridgeChanUnMute( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_CHAN_UNMUTE f_pConfBridgeUnMute ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeChanUnMuteSer( f_pApiInstance, f_pConfBridgeUnMute ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeDominantSpeakerSet + +Description: This function sets a participant present on a conference + bridge as the dominant speaker. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_pConfBridgeDominant Pointer to conference bridge dominant speaker + structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeDominantSpeakerSetDef +UINT32 Oct6100ConfBridgeDominantSpeakerSetDef( + tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ) +{ + f_pConfBridgeDominantSpeaker->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeDominantSpeaker->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeDominantSpeakerSet +UINT32 Oct6100ConfBridgeDominantSpeakerSet( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET f_pConfBridgeDominantSpeaker ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure.*/ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeDominantSpeakerSetSer( f_pApiInstance, f_pConfBridgeDominantSpeaker ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeMaskChange + +Description: This function changes the mask of a flexible bridge participant. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to + keep the present state of the chip and all its + resources. + +f_pConfBridgeMaskChange Pointer to conference bridge change of mask + structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeMaskChangeDef +UINT32 Oct6100ConfBridgeMaskChangeDef( + tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ) +{ + f_pConfBridgeMaskChange->ulChannelHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeMaskChange->ulNewListenerMask = 0x0; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeMaskChange +UINT32 Oct6100ConfBridgeMaskChange( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_MASK_CHANGE f_pConfBridgeMaskChange ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeMaskChangeSer( f_pApiInstance, f_pConfBridgeMaskChange ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeGetStats + +Description: This function returns the stats for a conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeStats Pointer to conference bridge channel stats structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeGetStatsDef +UINT32 Oct6100ConfBridgeGetStatsDef( + tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ) +{ + f_pConfBridgeStats->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + f_pConfBridgeStats->ulNumChannels = cOCT6100_INVALID_STAT; + f_pConfBridgeStats->ulNumTappedChannels = cOCT6100_INVALID_STAT; + f_pConfBridgeStats->fFlexibleConferencing = cOCT6100_INVALID_STAT; + + return cOCT6100_ERR_OK; +} +#endif + + +#if !SKIP_Oct6100ConfBridgeGetStats +UINT32 Oct6100ConfBridgeGetStats( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CONF_BRIDGE_STATS f_pConfBridgeStats ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ConfBridgeGetStatsSer( f_pApiInstance, f_pConfBridgeStats ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} +#endif + +/**************************** PRIVATE FUNCTIONS ****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetConfBridgeSwSizes + +Description: Gets the sizes of all portions of the API instance pertinent + to the management of conference bridges. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pOpenChip Pointer to chip configuration struct. +f_pInstSizes Pointer to struct containing instance sizes. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiGetConfBridgeSwSizes +UINT32 Oct6100ApiGetConfBridgeSwSizes( + IN tPOCT6100_CHIP_OPEN f_pOpenChip, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulTempVar; + UINT32 ulResult; + + /* Calculate memory needed for conference bridge list. */ + if ( f_pOpenChip->ulMaxConfBridges == 0 && f_pOpenChip->fEnableChannelRecording == TRUE ) + f_pOpenChip->ulMaxConfBridges = 1; + f_pInstSizes->ulConfBridgeList = f_pOpenChip->ulMaxConfBridges * sizeof( tOCT6100_API_CONF_BRIDGE ); + + /* Calculate memory needed for conference bridge allocation software. */ + if ( f_pOpenChip->ulMaxConfBridges > 0 ) + { + /* Get size of bridge allocation memory */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxConfBridges, &f_pInstSizes->ulConfBridgeAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1C; + + /* Check if the user wants to build flexible conference bridges. */ + if ( f_pOpenChip->ulMaxFlexibleConfParticipants > 0 ) + { + /* Allocate the lowest quantity according to what the user requested. */ + if ( f_pOpenChip->ulMaxFlexibleConfParticipants < ( f_pOpenChip->ulMaxConfBridges * cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE ) ) + f_pInstSizes->ulFlexConfParticipantsList = f_pOpenChip->ulMaxFlexibleConfParticipants * sizeof( tOCT6100_API_FLEX_CONF_PARTICIPANT ); + else + { + f_pOpenChip->ulMaxFlexibleConfParticipants = f_pOpenChip->ulMaxConfBridges * cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; + f_pInstSizes->ulFlexConfParticipantsList = f_pOpenChip->ulMaxConfBridges * cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE * sizeof( tOCT6100_API_FLEX_CONF_PARTICIPANT ); + } + + /* Get size of flexible conferencing participants allocation memory */ + ulResult = OctapiLlmAllocGetSize( f_pOpenChip->ulMaxFlexibleConfParticipants, &f_pInstSizes->ulFlexConfParticipantsAlloc ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1C; + } + else + { + f_pInstSizes->ulFlexConfParticipantsList = 0; + f_pInstSizes->ulFlexConfParticipantsAlloc = 0; + } + } + else + { + f_pInstSizes->ulMixerEventList = 0; + f_pInstSizes->ulMixerEventAlloc = 0; + f_pInstSizes->ulConfBridgeAlloc = 0; + + /* Make sure flexible conferencing is not used. */ + f_pInstSizes->ulFlexConfParticipantsList = 0; + f_pInstSizes->ulFlexConfParticipantsAlloc = 0; + } + + /* Calculate memory needed for list and allocation software serialization. */ + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulConfBridgeList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulConfBridgeAlloc, ulTempVar ) + + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulFlexConfParticipantsList, ulTempVar ) + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulFlexConfParticipantsAlloc, ulTempVar ) + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiConfBridgeSwInit + +Description: Initializes all elements of the instance structure associated + to conference bridges. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiConfBridgeSwInit +UINT32 Oct6100ApiConfBridgeSwInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CONF_BRIDGE pConfBridgeList; + tPOCT6100_API_FLEX_CONF_PARTICIPANT pFlexConfParticipantList; + PVOID pFlexConfPartipantsAlloc; + UINT32 ulMaxFlexConfParicipants; + PVOID pConfBridgeAlloc; + UINT32 ulMaxConfBridges; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the maximum number of conference bridges. */ + ulMaxConfBridges = pSharedInfo->ChipConfig.usMaxConfBridges; + + /*===================================================================*/ + /* Set all entries in the conference bridge list to unused. */ + + mOCT6100_GET_CONF_BRIDGE_LIST_PNT( pSharedInfo, pConfBridgeList ); + + /* Initialize the conference bridge allocation software to "all free". */ + if ( ulMaxConfBridges > 0 ) + { + /* Clear the bridge memory */ + Oct6100UserMemSet( pConfBridgeList, 0x00, ulMaxConfBridges * sizeof( tOCT6100_API_CONF_BRIDGE )); + + mOCT6100_GET_CONF_BRIDGE_ALLOC_PNT( pSharedInfo, pConfBridgeAlloc ) + + ulResult = OctapiLlmAllocInit( &pConfBridgeAlloc, ulMaxConfBridges ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1E; + } + /*===================================================================*/ + + + /*===================================================================*/ + /* Set all entries in the flexible conferencing participant list to unused. */ + + /* Get the maximum number of flexible conferencing participants. */ + ulMaxFlexConfParicipants = pSharedInfo->ChipConfig.usMaxFlexibleConfParticipants; + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_LIST_PNT( pSharedInfo, pFlexConfParticipantList ); + + /* Initialize the flexible conferencing allocation software. */ + if ( ulMaxFlexConfParicipants > 0 ) + { + UINT32 i, ulEventIndex; + + /* Clear the participants memory */ + Oct6100UserMemSet( pFlexConfParticipantList, 0x00, ulMaxFlexConfParicipants * sizeof( tOCT6100_API_FLEX_CONF_PARTICIPANT )); + + mOCT6100_GET_FLEX_CONF_PARTICIPANT_ALLOC_PNT( pSharedInfo, pFlexConfPartipantsAlloc ) + + ulResult = OctapiLlmAllocInit( &pFlexConfPartipantsAlloc, ulMaxFlexConfParicipants ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_1E; + + /* Initialize the conferencing indexes. */ + for ( i = 0; i < ulMaxFlexConfParicipants; i ++ ) + { + for ( ulEventIndex = 0; ulEventIndex < cOCT6100_MAX_FLEX_CONF_PARTICIPANTS_PER_BRIDGE; ulEventIndex ++ ) + pFlexConfParticipantList[ i ].ausLoadOrAccumulateEventIndex[ ulEventIndex ] = cOCT6100_INVALID_INDEX; + } + } + + /*===================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeOpenSer + +Description: Open a conference bridge. Note that no chip resources are + allocated until a channel is added to the bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeOpen Pointer to conference bridge configuration structure. + The handle identifying the conference bridge in all + future function calls is returned in this structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeOpenSer +UINT32 Oct6100ConfBridgeOpenSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ) +{ + UINT16 usBridgeIndex; + UINT32 ulResult; + + /* Check the user's configuration of the conference bridge for errors. */ + ulResult = Oct6100ApiCheckBridgeParams( f_pApiInstance, f_pConfBridgeOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reserve all resources needed by the conference bridge. */ + ulResult = Oct6100ApiReserveBridgeResources( f_pApiInstance, &usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the new conference bridge's entry in the conference bridge list. */ + ulResult = Oct6100ApiUpdateBridgeEntry( f_pApiInstance, f_pConfBridgeOpen, usBridgeIndex); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckBridgeParams + +Description: Checks the user's conference bridge open configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeOpen Pointer to conference bridge configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiCheckBridgeParams +UINT32 Oct6100ApiCheckBridgeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen ) +{ + /* Check for errors. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges == 0 ) + return cOCT6100_ERR_CONF_BRIDGE_DISABLED; + + if ( f_pConfBridgeOpen->pulConfBridgeHndl == NULL ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + if ( f_pApiInstance->pSharedInfo->ImageInfo.fConferencing == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_CONF_BRIDGE; + + if ( f_pConfBridgeOpen->fFlexibleConferencing != FALSE + && f_pConfBridgeOpen->fFlexibleConferencing != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_FLEX_CONF; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReserveBridgeResources + +Description: Reserves all resources needed for the new conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pusBridgeIndex Allocated entry in the API conference bridge list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReserveBridgeResources +UINT32 Oct6100ApiReserveBridgeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusBridgeIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Reserve an entry in the conference bridge list. */ + ulResult = Oct6100ApiReserveBridgeEntry( f_pApiInstance, f_pusBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUpdateBridgeEntry + +Description: Updates the new conference bridge's entry in the conference + bridge list. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pConfBridgeOpen Pointer to conference bridge configuration structure. +f_usBridgeIndex Allocated entry in API conference bridge list. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiUpdateBridgeEntry +UINT32 Oct6100ApiUpdateBridgeEntry( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_CONF_BRIDGE_OPEN f_pConfBridgeOpen, + IN UINT16 f_usBridgeIndex ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CONF_BRIDGE pTempBridgeEntry; + + /*================================================================================*/ + /* Obtain a pointer to the new conference bridge's list entry. */ + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex ) + + /* No clients are currently connected to the bridge. */ + pBridgeEntry->usNumClients = 0; + /* Nobody is tapped for now. */ + pBridgeEntry->usNumTappedClients = 0; + pBridgeEntry->usFirstLoadEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usFirstSubStoreEventPtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usLastSubStoreEventPtr = cOCT6100_INVALID_INDEX; + + pBridgeEntry->usSilenceLoadEventPtr = cOCT6100_INVALID_INDEX; + + pBridgeEntry->usLoadIndex = cOCT6100_INVALID_INDEX; + + /* Now update the bridge pointer. */ + if ( f_pApiInstance->pSharedInfo->MiscVars.usNumBridgesOpened == 0 ) + { + pBridgeEntry->usNextBridgePtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usPrevBridgePtr = cOCT6100_INVALID_INDEX; + + /* Set the global first bridge to this bridge. */ + f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge = f_usBridgeIndex; + } + else /* Insert this bridge at the head of the bridge list.*/ + { + if ( f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_FATAL_22; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTempBridgeEntry, f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge ) + + if ( pTempBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_FATAL_23; + + /* Modify the old first entry. */ + pTempBridgeEntry->usPrevBridgePtr = f_usBridgeIndex; + + /* Modify current pointer. */ + pBridgeEntry->usPrevBridgePtr = cOCT6100_INVALID_INDEX; + pBridgeEntry->usNextBridgePtr = f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge; + + /* Set the new first bridge of the list. */ + f_pApiInstance->pSharedInfo->MiscVars.usFirstBridge = f_usBridgeIndex; + } + + /* Form handle returned to user. */ + *f_pConfBridgeOpen->pulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pBridgeEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_usBridgeIndex; + + /* Remember whether or not we are a flexible conference bridge. */ + pBridgeEntry->fFlexibleConferencing = (UINT8)( f_pConfBridgeOpen->fFlexibleConferencing & 0xFF ); + + /* Finally, mark the conference bridge as opened. */ + pBridgeEntry->fReserved = TRUE; + + /* Increment the number of conference bridge opened. */ + f_pApiInstance->pSharedInfo->ChipStats.usNumberConfBridges++; + f_pApiInstance->pSharedInfo->MiscVars.usNumBridgesOpened++; + + /*================================================================================*/ + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ConfBridgeCloseSer + +Description: Closes a conference bridge. Note that no client must be present + on the bridge for the bridge to be closed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeClose Pointer to conference bridge close structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ConfBridgeCloseSer +UINT32 Oct6100ConfBridgeCloseSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose ) +{ + UINT16 usBridgeIndex; + UINT32 ulResult; + + /* Verify that all the parameters given match the state of the API. */ + ulResult = Oct6100ApiAssertBridgeParams( f_pApiInstance, f_pConfBridgeClose, &usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Release all resources associated to the conference bridge. */ + ulResult = Oct6100ApiReleaseBridgeResources( f_pApiInstance, usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Invalidate the handle. */ + f_pConfBridgeClose->ulConfBridgeHndl = cOCT6100_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAssertBridgeParams + +Description: Checks the user's conference bridge close configuration for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pConfBridgeClose Pointer to conference bridge close structure. +f_pusBridgeIndex Pointer to API instance conference bridge index. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiAssertBridgeParams +UINT32 Oct6100ApiAssertBridgeParams( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CONF_BRIDGE_CLOSE f_pConfBridgeClose, + OUT PUINT16 f_pusBridgeIndex ) +{ + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + UINT32 ulEntryOpenCnt; + + /* Check the provided handle. */ + if ( (f_pConfBridgeClose->ulConfBridgeHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CONF_BRIDGE ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + *f_pusBridgeIndex = (UINT16)( f_pConfBridgeClose->ulConfBridgeHndl & cOCT6100_HNDL_INDEX_MASK ); + if ( *f_pusBridgeIndex >= f_pApiInstance->pSharedInfo->ChipConfig.usMaxConfBridges ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, *f_pusBridgeIndex ) + + /* Extract the entry open count from the provided handle. */ + ulEntryOpenCnt = (f_pConfBridgeClose->ulConfBridgeHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK; + + /* Check for errors. */ + if ( pBridgeEntry->fReserved != TRUE ) + return cOCT6100_ERR_CONF_BRIDGE_NOT_OPEN; + if ( pBridgeEntry->usNumClients != 0 ) + return cOCT6100_ERR_CONF_BRIDGE_ACTIVE_DEPENDENCIES; + if ( ulEntryOpenCnt != pBridgeEntry->byEntryOpenCnt ) + return cOCT6100_ERR_CONF_BRIDGE_INVALID_HANDLE; + + return cOCT6100_ERR_OK; +} +#endif + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiReleaseBridgeResources + +Description: Release all resources reserved for the conference bridge. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_usBridgeIndex Allocated external memory block for the conference bridge. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +#if !SKIP_Oct6100ApiReleaseBridgeResources +UINT32 Oct6100ApiReleaseBridgeResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT16 f_usBridgeIndex ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + tPOCT6100_API_CONF_BRIDGE pTempBridgeEntry; + UINT32 ulResult; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Release the entry from the conference bridge list. */ + ulResult = Oct6100ApiReleaseBridgeEntry( f_pApiInstance, f_usBridgeIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return cOCT6100_ERR_FATAL_24; + + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pShare