cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dsp_cmx.c (53629B)


      1/*
      2 * Audio crossconnecting/conferrencing (hardware level).
      3 *
      4 * Copyright 2002 by Andreas Eversberg (jolly@eversberg.eu)
      5 *
      6 * This software may be used and distributed according to the terms
      7 * of the GNU General Public License, incorporated herein by reference.
      8 *
      9 */
     10
     11/*
     12 * The process of adding and removing parties to/from a conference:
     13 *
     14 * There is a chain of struct dsp_conf which has one or more members in a chain
     15 * of struct dsp_conf_member.
     16 *
     17 * After a party is added, the conference is checked for hardware capability.
     18 * Also if a party is removed, the conference is checked again.
     19 *
     20 * There are 3 different solutions: -1 = software, 0 = hardware-crossconnect
     21 * 1-n = hardware-conference. The n will give the conference number.
     22 *
     23 * Depending on the change after removal or insertion of a party, hardware
     24 * commands are given.
     25 *
     26 * The current solution is stored within the struct dsp_conf entry.
     27 */
     28
     29/*
     30 * HOW THE CMX WORKS:
     31 *
     32 * There are 3 types of interaction: One member is alone, in this case only
     33 * data flow from upper to lower layer is done.
     34 * Two members will also exchange their data so they are crossconnected.
     35 * Three or more members will be added in a conference and will hear each
     36 * other but will not receive their own speech (echo) if not enabled.
     37 *
     38 * Features of CMX are:
     39 *  - Crossconnecting or even conference, if more than two members are together.
     40 *  - Force mixing of transmit data with other crossconnect/conference members.
     41 *  - Echo generation to benchmark the delay of audio processing.
     42 *  - Use hardware to minimize cpu load, disable FIFO load and minimize delay.
     43 *  - Dejittering and clock generation.
     44 *
     45 * There are 2 buffers:
     46 *
     47 *
     48 * RX-Buffer
     49 *                 R             W
     50 *                 |             |
     51 * ----------------+-------------+-------------------
     52 *
     53 * The rx-buffer is a ring buffer used to store the received data for each
     54 * individual member. This is only the case if data needs to be dejittered
     55 * or in case of a conference where different clocks require reclocking.
     56 * The transmit-clock (R) will read the buffer.
     57 * If the clock overruns the write-pointer, we will have a buffer underrun.
     58 * If the write pointer always has a certain distance from the transmit-
     59 * clock, we will have a delay. The delay will dynamically be increased and
     60 * reduced.
     61 *
     62 *
     63 * TX-Buffer
     64 *                  R        W
     65 *                  |        |
     66 * -----------------+--------+-----------------------
     67 *
     68 * The tx-buffer is a ring buffer to queue the transmit data from user space
     69 * until it will be mixed or sent. There are two pointers, R and W. If the write
     70 * pointer W would reach or overrun R, the buffer would overrun. In this case
     71 * (some) data is dropped so that it will not overrun.
     72 * Additionally a dynamic dejittering can be enabled. this allows data from
     73 * user space that have jitter and different clock source.
     74 *
     75 *
     76 * Clock:
     77 *
     78 * A Clock is not required, if the data source has exactly one clock. In this
     79 * case the data source is forwarded to the destination.
     80 *
     81 * A Clock is required, because the data source
     82 *  - has multiple clocks.
     83 *  - has no usable clock due to jitter or packet loss (VoIP).
     84 * In this case the system's clock is used. The clock resolution depends on
     85 * the jiffie resolution.
     86 *
     87 * If a member joins a conference:
     88 *
     89 * - If a member joins, its rx_buff is set to silence and change read pointer
     90 *   to transmit clock.
     91 *
     92 * The procedure of received data from card is explained in cmx_receive.
     93 * The procedure of received data from user space is explained in cmx_transmit.
     94 * The procedure of transmit data to card is cmx_send.
     95 *
     96 *
     97 * Interaction with other features:
     98 *
     99 * DTMF:
    100 * DTMF decoding is done before the data is crossconnected.
    101 *
    102 * Volume change:
    103 * Changing rx-volume is done before the data is crossconnected. The tx-volume
    104 * must be changed whenever data is transmitted to the card by the cmx.
    105 *
    106 * Tones:
    107 * If a tone is enabled, it will be processed whenever data is transmitted to
    108 * the card. It will replace the tx-data from the user space.
    109 * If tones are generated by hardware, this conference member is removed for
    110 * this time.
    111 *
    112 * Disable rx-data:
    113 * If cmx is realized in hardware, rx data will be disabled if requested by
    114 * the upper layer. If dtmf decoding is done by software and enabled, rx data
    115 * will not be disabled but blocked to the upper layer.
    116 *
    117 * HFC conference engine:
    118 * If it is possible to realize all features using hardware, hardware will be
    119 * used if not forbidden by control command. Disabling rx-data provides
    120 * absolutely traffic free audio processing. (except for the quick 1-frame
    121 * upload of a tone loop, only once for a new tone)
    122 *
    123 */
    124
    125/* delay.h is required for hw_lock.h */
    126
    127#include <linux/slab.h>
    128#include <linux/delay.h>
    129#include <linux/mISDNif.h>
    130#include <linux/mISDNdsp.h>
    131#include "core.h"
    132#include "dsp.h"
    133/*
    134 * debugging of multi party conference,
    135 * by using conference even with two members
    136 */
    137
    138/* #define CMX_CONF_DEBUG */
    139
    140/*#define CMX_DEBUG * massive read/write pointer output */
    141/*#define CMX_DELAY_DEBUG * gives rx-buffer delay overview */
    142/*#define CMX_TX_DEBUG * massive read/write on tx-buffer with content */
    143
    144static inline int
    145count_list_member(struct list_head *head)
    146{
    147	int			cnt = 0;
    148	struct list_head	*m;
    149
    150	list_for_each(m, head)
    151		cnt++;
    152	return cnt;
    153}
    154
    155/*
    156 * debug cmx memory structure
    157 */
    158void
    159dsp_cmx_debug(struct dsp *dsp)
    160{
    161	struct dsp_conf	*conf;
    162	struct dsp_conf_member	*member;
    163	struct dsp		*odsp;
    164
    165	printk(KERN_DEBUG "-----Current DSP\n");
    166	list_for_each_entry(odsp, &dsp_ilist, list) {
    167		printk(KERN_DEBUG "* %s hardecho=%d softecho=%d txmix=%d",
    168		       odsp->name, odsp->echo.hardware, odsp->echo.software,
    169		       odsp->tx_mix);
    170		if (odsp->conf)
    171			printk(" (Conf %d)", odsp->conf->id);
    172		if (dsp == odsp)
    173			printk(" *this*");
    174		printk("\n");
    175	}
    176	printk(KERN_DEBUG "-----Current Conf:\n");
    177	list_for_each_entry(conf, &conf_ilist, list) {
    178		printk(KERN_DEBUG "* Conf %d (%p)\n", conf->id, conf);
    179		list_for_each_entry(member, &conf->mlist, list) {
    180			printk(KERN_DEBUG
    181			       "  - member = %s (slot_tx %d, bank_tx %d, "
    182			       "slot_rx %d, bank_rx %d hfc_conf %d "
    183			       "tx_data %d rx_is_off %d)%s\n",
    184			       member->dsp->name, member->dsp->pcm_slot_tx,
    185			       member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx,
    186			       member->dsp->pcm_bank_rx, member->dsp->hfc_conf,
    187			       member->dsp->tx_data, member->dsp->rx_is_off,
    188			       (member->dsp == dsp) ? " *this*" : "");
    189		}
    190	}
    191	printk(KERN_DEBUG "-----end\n");
    192}
    193
    194/*
    195 * search conference
    196 */
    197static struct dsp_conf *
    198dsp_cmx_search_conf(u32 id)
    199{
    200	struct dsp_conf *conf;
    201
    202	if (!id) {
    203		printk(KERN_WARNING "%s: conference ID is 0.\n", __func__);
    204		return NULL;
    205	}
    206
    207	/* search conference */
    208	list_for_each_entry(conf, &conf_ilist, list)
    209		if (conf->id == id)
    210			return conf;
    211
    212	return NULL;
    213}
    214
    215
    216/*
    217 * add member to conference
    218 */
    219static int
    220dsp_cmx_add_conf_member(struct dsp *dsp, struct dsp_conf *conf)
    221{
    222	struct dsp_conf_member *member;
    223
    224	if (!conf || !dsp) {
    225		printk(KERN_WARNING "%s: conf or dsp is 0.\n", __func__);
    226		return -EINVAL;
    227	}
    228	if (dsp->member) {
    229		printk(KERN_WARNING "%s: dsp is already member in a conf.\n",
    230		       __func__);
    231		return -EINVAL;
    232	}
    233
    234	if (dsp->conf) {
    235		printk(KERN_WARNING "%s: dsp is already in a conf.\n",
    236		       __func__);
    237		return -EINVAL;
    238	}
    239
    240	member = kzalloc(sizeof(struct dsp_conf_member), GFP_ATOMIC);
    241	if (!member) {
    242		printk(KERN_ERR "kzalloc struct dsp_conf_member failed\n");
    243		return -ENOMEM;
    244	}
    245	member->dsp = dsp;
    246	/* clear rx buffer */
    247	memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
    248	dsp->rx_init = 1; /* rx_W and rx_R will be adjusted on first frame */
    249	dsp->rx_W = 0;
    250	dsp->rx_R = 0;
    251
    252	list_add_tail(&member->list, &conf->mlist);
    253
    254	dsp->conf = conf;
    255	dsp->member = member;
    256
    257	return 0;
    258}
    259
    260
    261/*
    262 * del member from conference
    263 */
    264int
    265dsp_cmx_del_conf_member(struct dsp *dsp)
    266{
    267	struct dsp_conf_member *member;
    268
    269	if (!dsp) {
    270		printk(KERN_WARNING "%s: dsp is 0.\n",
    271		       __func__);
    272		return -EINVAL;
    273	}
    274
    275	if (!dsp->conf) {
    276		printk(KERN_WARNING "%s: dsp is not in a conf.\n",
    277		       __func__);
    278		return -EINVAL;
    279	}
    280
    281	if (list_empty(&dsp->conf->mlist)) {
    282		printk(KERN_WARNING "%s: dsp has linked an empty conf.\n",
    283		       __func__);
    284		return -EINVAL;
    285	}
    286
    287	/* find us in conf */
    288	list_for_each_entry(member, &dsp->conf->mlist, list) {
    289		if (member->dsp == dsp) {
    290			list_del(&member->list);
    291			dsp->conf = NULL;
    292			dsp->member = NULL;
    293			kfree(member);
    294			return 0;
    295		}
    296	}
    297	printk(KERN_WARNING
    298	       "%s: dsp is not present in its own conf_member list.\n",
    299	       __func__);
    300
    301	return -EINVAL;
    302}
    303
    304
    305/*
    306 * new conference
    307 */
    308static struct dsp_conf
    309*dsp_cmx_new_conf(u32 id)
    310{
    311	struct dsp_conf *conf;
    312
    313	if (!id) {
    314		printk(KERN_WARNING "%s: id is 0.\n",
    315		       __func__);
    316		return NULL;
    317	}
    318
    319	conf = kzalloc(sizeof(struct dsp_conf), GFP_ATOMIC);
    320	if (!conf) {
    321		printk(KERN_ERR "kzalloc struct dsp_conf failed\n");
    322		return NULL;
    323	}
    324	INIT_LIST_HEAD(&conf->mlist);
    325	conf->id = id;
    326
    327	list_add_tail(&conf->list, &conf_ilist);
    328
    329	return conf;
    330}
    331
    332
    333/*
    334 * del conference
    335 */
    336int
    337dsp_cmx_del_conf(struct dsp_conf *conf)
    338{
    339	if (!conf) {
    340		printk(KERN_WARNING "%s: conf is null.\n",
    341		       __func__);
    342		return -EINVAL;
    343	}
    344
    345	if (!list_empty(&conf->mlist)) {
    346		printk(KERN_WARNING "%s: conf not empty.\n",
    347		       __func__);
    348		return -EINVAL;
    349	}
    350	list_del(&conf->list);
    351	kfree(conf);
    352
    353	return 0;
    354}
    355
    356
    357/*
    358 * send HW message to hfc card
    359 */
    360static void
    361dsp_cmx_hw_message(struct dsp *dsp, u32 message, u32 param1, u32 param2,
    362		   u32 param3, u32 param4)
    363{
    364	struct mISDN_ctrl_req cq;
    365
    366	memset(&cq, 0, sizeof(cq));
    367	cq.op = message;
    368	cq.p1 = param1 | (param2 << 8);
    369	cq.p2 = param3 | (param4 << 8);
    370	if (dsp->ch.peer)
    371		dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq);
    372}
    373
    374
    375/*
    376 * do hardware update and set the software/hardware flag
    377 *
    378 * either a conference or a dsp instance can be given
    379 * if only dsp instance is given, the instance is not associated with a conf
    380 * and therefore removed. if a conference is given, the dsp is expected to
    381 * be member of that conference.
    382 */
    383void
    384dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
    385{
    386	struct dsp_conf_member	*member, *nextm;
    387	struct dsp		*finddsp;
    388	int		memb = 0, i, ii, i1, i2;
    389	int		freeunits[8];
    390	u_char		freeslots[256];
    391	int		same_hfc = -1, same_pcm = -1, current_conf = -1,
    392		all_conf = 1, tx_data = 0;
    393
    394	/* dsp gets updated (no conf) */
    395	if (!conf) {
    396		if (!dsp)
    397			return;
    398		if (dsp_debug & DEBUG_DSP_CMX)
    399			printk(KERN_DEBUG "%s checking dsp %s\n",
    400			       __func__, dsp->name);
    401	one_member:
    402		/* remove HFC conference if enabled */
    403		if (dsp->hfc_conf >= 0) {
    404			if (dsp_debug & DEBUG_DSP_CMX)
    405				printk(KERN_DEBUG
    406				       "%s removing %s from HFC conf %d "
    407				       "because dsp is split\n", __func__,
    408				       dsp->name, dsp->hfc_conf);
    409			dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_CONF_SPLIT,
    410					   0, 0, 0, 0);
    411			dsp->hfc_conf = -1;
    412		}
    413		/* process hw echo */
    414		if (dsp->features.pcm_banks < 1)
    415			return;
    416		if (!dsp->echo.software && !dsp->echo.hardware) {
    417			/* NO ECHO: remove PCM slot if assigned */
    418			if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) {
    419				if (dsp_debug & DEBUG_DSP_CMX)
    420					printk(KERN_DEBUG "%s removing %s from"
    421					       " PCM slot %d (TX) %d (RX) because"
    422					       " dsp is split (no echo)\n",
    423					       __func__, dsp->name,
    424					       dsp->pcm_slot_tx, dsp->pcm_slot_rx);
    425				dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_DISC,
    426						   0, 0, 0, 0);
    427				dsp->pcm_slot_tx = -1;
    428				dsp->pcm_bank_tx = -1;
    429				dsp->pcm_slot_rx = -1;
    430				dsp->pcm_bank_rx = -1;
    431			}
    432			return;
    433		}
    434		/* echo is enabled, find out if we use soft or hardware */
    435		dsp->echo.software = dsp->tx_data;
    436		dsp->echo.hardware = 0;
    437		/* ECHO: already echo */
    438		if (dsp->pcm_slot_tx >= 0 && dsp->pcm_slot_rx < 0 &&
    439		    dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2) {
    440			dsp->echo.hardware = 1;
    441			return;
    442		}
    443		/* ECHO: if slot already assigned */
    444		if (dsp->pcm_slot_tx >= 0) {
    445			dsp->pcm_slot_rx = dsp->pcm_slot_tx;
    446			dsp->pcm_bank_tx = 2; /* 2 means loop */
    447			dsp->pcm_bank_rx = 2;
    448			if (dsp_debug & DEBUG_DSP_CMX)
    449				printk(KERN_DEBUG
    450				       "%s refresh %s for echo using slot %d\n",
    451				       __func__, dsp->name,
    452				       dsp->pcm_slot_tx);
    453			dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
    454					   dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
    455			dsp->echo.hardware = 1;
    456			return;
    457		}
    458		/* ECHO: find slot */
    459		dsp->pcm_slot_tx = -1;
    460		dsp->pcm_slot_rx = -1;
    461		memset(freeslots, 1, sizeof(freeslots));
    462		list_for_each_entry(finddsp, &dsp_ilist, list) {
    463			if (finddsp->features.pcm_id == dsp->features.pcm_id) {
    464				if (finddsp->pcm_slot_rx >= 0 &&
    465				    finddsp->pcm_slot_rx < sizeof(freeslots))
    466					freeslots[finddsp->pcm_slot_rx] = 0;
    467				if (finddsp->pcm_slot_tx >= 0 &&
    468				    finddsp->pcm_slot_tx < sizeof(freeslots))
    469					freeslots[finddsp->pcm_slot_tx] = 0;
    470			}
    471		}
    472		i = 0;
    473		ii = dsp->features.pcm_slots;
    474		while (i < ii) {
    475			if (freeslots[i])
    476				break;
    477			i++;
    478		}
    479		if (i == ii) {
    480			if (dsp_debug & DEBUG_DSP_CMX)
    481				printk(KERN_DEBUG
    482				       "%s no slot available for echo\n",
    483				       __func__);
    484			/* no more slots available */
    485			dsp->echo.software = 1;
    486			return;
    487		}
    488		/* assign free slot */
    489		dsp->pcm_slot_tx = i;
    490		dsp->pcm_slot_rx = i;
    491		dsp->pcm_bank_tx = 2; /* loop */
    492		dsp->pcm_bank_rx = 2;
    493		if (dsp_debug & DEBUG_DSP_CMX)
    494			printk(KERN_DEBUG
    495			       "%s assign echo for %s using slot %d\n",
    496			       __func__, dsp->name, dsp->pcm_slot_tx);
    497		dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
    498				   dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
    499		dsp->echo.hardware = 1;
    500		return;
    501	}
    502
    503	/* conf gets updated (all members) */
    504	if (dsp_debug & DEBUG_DSP_CMX)
    505		printk(KERN_DEBUG "%s checking conference %d\n",
    506		       __func__, conf->id);
    507
    508	if (list_empty(&conf->mlist)) {
    509		printk(KERN_ERR "%s: conference without members\n",
    510		       __func__);
    511		return;
    512	}
    513	member = list_entry(conf->mlist.next, struct dsp_conf_member, list);
    514	same_hfc = member->dsp->features.hfc_id;
    515	same_pcm = member->dsp->features.pcm_id;
    516	/* check all members in our conference */
    517	list_for_each_entry(member, &conf->mlist, list) {
    518		/* check if member uses mixing */
    519		if (member->dsp->tx_mix) {
    520			if (dsp_debug & DEBUG_DSP_CMX)
    521				printk(KERN_DEBUG
    522				       "%s dsp %s cannot form a conf, because "
    523				       "tx_mix is turned on\n", __func__,
    524				       member->dsp->name);
    525		conf_software:
    526			list_for_each_entry(member, &conf->mlist, list) {
    527				dsp = member->dsp;
    528				/* remove HFC conference if enabled */
    529				if (dsp->hfc_conf >= 0) {
    530					if (dsp_debug & DEBUG_DSP_CMX)
    531						printk(KERN_DEBUG
    532						       "%s removing %s from HFC "
    533						       "conf %d because not "
    534						       "possible with hardware\n",
    535						       __func__,
    536						       dsp->name,
    537						       dsp->hfc_conf);
    538					dsp_cmx_hw_message(dsp,
    539							   MISDN_CTRL_HFC_CONF_SPLIT,
    540							   0, 0, 0, 0);
    541					dsp->hfc_conf = -1;
    542				}
    543				/* remove PCM slot if assigned */
    544				if (dsp->pcm_slot_tx >= 0 ||
    545				    dsp->pcm_slot_rx >= 0) {
    546					if (dsp_debug & DEBUG_DSP_CMX)
    547						printk(KERN_DEBUG "%s removing "
    548						       "%s from PCM slot %d (TX)"
    549						       " slot %d (RX) because not"
    550						       " possible with hardware\n",
    551						       __func__,
    552						       dsp->name,
    553						       dsp->pcm_slot_tx,
    554						       dsp->pcm_slot_rx);
    555					dsp_cmx_hw_message(dsp,
    556							   MISDN_CTRL_HFC_PCM_DISC,
    557							   0, 0, 0, 0);
    558					dsp->pcm_slot_tx = -1;
    559					dsp->pcm_bank_tx = -1;
    560					dsp->pcm_slot_rx = -1;
    561					dsp->pcm_bank_rx = -1;
    562				}
    563			}
    564			conf->hardware = 0;
    565			conf->software = 1;
    566			return;
    567		}
    568		/* check if member has echo turned on */
    569		if (member->dsp->echo.hardware || member->dsp->echo.software) {
    570			if (dsp_debug & DEBUG_DSP_CMX)
    571				printk(KERN_DEBUG
    572				       "%s dsp %s cannot form a conf, because "
    573				       "echo is turned on\n", __func__,
    574				       member->dsp->name);
    575			goto conf_software;
    576		}
    577		/* check if member has tx_mix turned on */
    578		if (member->dsp->tx_mix) {
    579			if (dsp_debug & DEBUG_DSP_CMX)
    580				printk(KERN_DEBUG
    581				       "%s dsp %s cannot form a conf, because "
    582				       "tx_mix is turned on\n",
    583				       __func__, member->dsp->name);
    584			goto conf_software;
    585		}
    586		/* check if member changes volume at an not suppoted level */
    587		if (member->dsp->tx_volume) {
    588			if (dsp_debug & DEBUG_DSP_CMX)
    589				printk(KERN_DEBUG
    590				       "%s dsp %s cannot form a conf, because "
    591				       "tx_volume is changed\n",
    592				       __func__, member->dsp->name);
    593			goto conf_software;
    594		}
    595		if (member->dsp->rx_volume) {
    596			if (dsp_debug & DEBUG_DSP_CMX)
    597				printk(KERN_DEBUG
    598				       "%s dsp %s cannot form a conf, because "
    599				       "rx_volume is changed\n",
    600				       __func__, member->dsp->name);
    601			goto conf_software;
    602		}
    603		/* check if tx-data turned on */
    604		if (member->dsp->tx_data) {
    605			if (dsp_debug & DEBUG_DSP_CMX)
    606				printk(KERN_DEBUG
    607				       "%s dsp %s tx_data is turned on\n",
    608				       __func__, member->dsp->name);
    609			tx_data = 1;
    610		}
    611		/* check if pipeline exists */
    612		if (member->dsp->pipeline.inuse) {
    613			if (dsp_debug & DEBUG_DSP_CMX)
    614				printk(KERN_DEBUG
    615				       "%s dsp %s cannot form a conf, because "
    616				       "pipeline exists\n", __func__,
    617				       member->dsp->name);
    618			goto conf_software;
    619		}
    620		/* check if encryption is enabled */
    621		if (member->dsp->bf_enable) {
    622			if (dsp_debug & DEBUG_DSP_CMX)
    623				printk(KERN_DEBUG "%s dsp %s cannot form a "
    624				       "conf, because encryption is enabled\n",
    625				       __func__, member->dsp->name);
    626			goto conf_software;
    627		}
    628		/* check if member is on a card with PCM support */
    629		if (member->dsp->features.pcm_id < 0) {
    630			if (dsp_debug & DEBUG_DSP_CMX)
    631				printk(KERN_DEBUG
    632				       "%s dsp %s cannot form a conf, because "
    633				       "dsp has no PCM bus\n",
    634				       __func__, member->dsp->name);
    635			goto conf_software;
    636		}
    637		/* check if relations are on the same PCM bus */
    638		if (member->dsp->features.pcm_id != same_pcm) {
    639			if (dsp_debug & DEBUG_DSP_CMX)
    640				printk(KERN_DEBUG
    641				       "%s dsp %s cannot form a conf, because "
    642				       "dsp is on a different PCM bus than the "
    643				       "first dsp\n",
    644				       __func__, member->dsp->name);
    645			goto conf_software;
    646		}
    647		/* determine if members are on the same hfc chip */
    648		if (same_hfc != member->dsp->features.hfc_id)
    649			same_hfc = -1;
    650		/* if there are members already in a conference */
    651		if (current_conf < 0 && member->dsp->hfc_conf >= 0)
    652			current_conf = member->dsp->hfc_conf;
    653		/* if any member is not in a conference */
    654		if (member->dsp->hfc_conf < 0)
    655			all_conf = 0;
    656
    657		memb++;
    658	}
    659
    660	/* if no member, this is an error */
    661	if (memb < 1)
    662		return;
    663
    664	/* one member */
    665	if (memb == 1) {
    666		if (dsp_debug & DEBUG_DSP_CMX)
    667			printk(KERN_DEBUG
    668			       "%s conf %d cannot form a HW conference, "
    669			       "because dsp is alone\n", __func__, conf->id);
    670		conf->hardware = 0;
    671		conf->software = 0;
    672		member = list_entry(conf->mlist.next, struct dsp_conf_member,
    673				    list);
    674		dsp = member->dsp;
    675		goto one_member;
    676	}
    677
    678	/*
    679	 * ok, now we are sure that all members are on the same pcm.
    680	 * now we will see if we have only two members, so we can do
    681	 * crossconnections, which don't have any limitations.
    682	 */
    683
    684	/* if we have only two members */
    685	if (memb == 2) {
    686		member = list_entry(conf->mlist.next, struct dsp_conf_member,
    687				    list);
    688		nextm = list_entry(member->list.next, struct dsp_conf_member,
    689				   list);
    690		/* remove HFC conference if enabled */
    691		if (member->dsp->hfc_conf >= 0) {
    692			if (dsp_debug & DEBUG_DSP_CMX)
    693				printk(KERN_DEBUG
    694				       "%s removing %s from HFC conf %d because "
    695				       "two parties require only a PCM slot\n",
    696				       __func__, member->dsp->name,
    697				       member->dsp->hfc_conf);
    698			dsp_cmx_hw_message(member->dsp,
    699					   MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0);
    700			member->dsp->hfc_conf = -1;
    701		}
    702		if (nextm->dsp->hfc_conf >= 0) {
    703			if (dsp_debug & DEBUG_DSP_CMX)
    704				printk(KERN_DEBUG
    705				       "%s removing %s from HFC conf %d because "
    706				       "two parties require only a PCM slot\n",
    707				       __func__, nextm->dsp->name,
    708				       nextm->dsp->hfc_conf);
    709			dsp_cmx_hw_message(nextm->dsp,
    710					   MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0);
    711			nextm->dsp->hfc_conf = -1;
    712		}
    713		/* if members have two banks (and not on the same chip) */
    714		if (member->dsp->features.pcm_banks > 1 &&
    715		    nextm->dsp->features.pcm_banks > 1 &&
    716		    member->dsp->features.hfc_id !=
    717		    nextm->dsp->features.hfc_id) {
    718			/* if both members have same slots with crossed banks */
    719			if (member->dsp->pcm_slot_tx >= 0 &&
    720			    member->dsp->pcm_slot_rx >= 0 &&
    721			    nextm->dsp->pcm_slot_tx >= 0 &&
    722			    nextm->dsp->pcm_slot_rx >= 0 &&
    723			    nextm->dsp->pcm_slot_tx ==
    724			    member->dsp->pcm_slot_rx &&
    725			    nextm->dsp->pcm_slot_rx ==
    726			    member->dsp->pcm_slot_tx &&
    727			    nextm->dsp->pcm_slot_tx ==
    728			    member->dsp->pcm_slot_tx &&
    729			    member->dsp->pcm_bank_tx !=
    730			    member->dsp->pcm_bank_rx &&
    731			    nextm->dsp->pcm_bank_tx !=
    732			    nextm->dsp->pcm_bank_rx) {
    733				/* all members have same slot */
    734				if (dsp_debug & DEBUG_DSP_CMX)
    735					printk(KERN_DEBUG
    736					       "%s dsp %s & %s stay joined on "
    737					       "PCM slot %d bank %d (TX) bank %d "
    738					       "(RX) (on different chips)\n",
    739					       __func__,
    740					       member->dsp->name,
    741					       nextm->dsp->name,
    742					       member->dsp->pcm_slot_tx,
    743					       member->dsp->pcm_bank_tx,
    744					       member->dsp->pcm_bank_rx);
    745				conf->hardware = 1;
    746				conf->software = tx_data;
    747				return;
    748			}
    749			/* find a new slot */
    750			memset(freeslots, 1, sizeof(freeslots));
    751			list_for_each_entry(dsp, &dsp_ilist, list) {
    752				if (dsp != member->dsp &&
    753				    dsp != nextm->dsp &&
    754				    member->dsp->features.pcm_id ==
    755				    dsp->features.pcm_id) {
    756					if (dsp->pcm_slot_rx >= 0 &&
    757					    dsp->pcm_slot_rx <
    758					    sizeof(freeslots))
    759						freeslots[dsp->pcm_slot_rx] = 0;
    760					if (dsp->pcm_slot_tx >= 0 &&
    761					    dsp->pcm_slot_tx <
    762					    sizeof(freeslots))
    763						freeslots[dsp->pcm_slot_tx] = 0;
    764				}
    765			}
    766			i = 0;
    767			ii = member->dsp->features.pcm_slots;
    768			while (i < ii) {
    769				if (freeslots[i])
    770					break;
    771				i++;
    772			}
    773			if (i == ii) {
    774				if (dsp_debug & DEBUG_DSP_CMX)
    775					printk(KERN_DEBUG
    776					       "%s no slot available for "
    777					       "%s & %s\n", __func__,
    778					       member->dsp->name,
    779					       nextm->dsp->name);
    780				/* no more slots available */
    781				goto conf_software;
    782			}
    783			/* assign free slot */
    784			member->dsp->pcm_slot_tx = i;
    785			member->dsp->pcm_slot_rx = i;
    786			nextm->dsp->pcm_slot_tx = i;
    787			nextm->dsp->pcm_slot_rx = i;
    788			member->dsp->pcm_bank_rx = 0;
    789			member->dsp->pcm_bank_tx = 1;
    790			nextm->dsp->pcm_bank_rx = 1;
    791			nextm->dsp->pcm_bank_tx = 0;
    792			if (dsp_debug & DEBUG_DSP_CMX)
    793				printk(KERN_DEBUG
    794				       "%s adding %s & %s to new PCM slot %d "
    795				       "(TX and RX on different chips) because "
    796				       "both members have not same slots\n",
    797				       __func__,
    798				       member->dsp->name,
    799				       nextm->dsp->name,
    800				       member->dsp->pcm_slot_tx);
    801			dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
    802					   member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
    803					   member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
    804			dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN,
    805					   nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
    806					   nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
    807			conf->hardware = 1;
    808			conf->software = tx_data;
    809			return;
    810			/* if members have one bank (or on the same chip) */
    811		} else {
    812			/* if both members have different crossed slots */
    813			if (member->dsp->pcm_slot_tx >= 0 &&
    814			    member->dsp->pcm_slot_rx >= 0 &&
    815			    nextm->dsp->pcm_slot_tx >= 0 &&
    816			    nextm->dsp->pcm_slot_rx >= 0 &&
    817			    nextm->dsp->pcm_slot_tx ==
    818			    member->dsp->pcm_slot_rx &&
    819			    nextm->dsp->pcm_slot_rx ==
    820			    member->dsp->pcm_slot_tx &&
    821			    member->dsp->pcm_slot_tx !=
    822			    member->dsp->pcm_slot_rx &&
    823			    member->dsp->pcm_bank_tx == 0 &&
    824			    member->dsp->pcm_bank_rx == 0 &&
    825			    nextm->dsp->pcm_bank_tx == 0 &&
    826			    nextm->dsp->pcm_bank_rx == 0) {
    827				/* all members have same slot */
    828				if (dsp_debug & DEBUG_DSP_CMX)
    829					printk(KERN_DEBUG
    830					       "%s dsp %s & %s stay joined on PCM "
    831					       "slot %d (TX) %d (RX) on same chip "
    832					       "or one bank PCM)\n", __func__,
    833					       member->dsp->name,
    834					       nextm->dsp->name,
    835					       member->dsp->pcm_slot_tx,
    836					       member->dsp->pcm_slot_rx);
    837				conf->hardware = 1;
    838				conf->software = tx_data;
    839				return;
    840			}
    841			/* find two new slot */
    842			memset(freeslots, 1, sizeof(freeslots));
    843			list_for_each_entry(dsp, &dsp_ilist, list) {
    844				if (dsp != member->dsp &&
    845				    dsp != nextm->dsp &&
    846				    member->dsp->features.pcm_id ==
    847				    dsp->features.pcm_id) {
    848					if (dsp->pcm_slot_rx >= 0 &&
    849					    dsp->pcm_slot_rx <
    850					    sizeof(freeslots))
    851						freeslots[dsp->pcm_slot_rx] = 0;
    852					if (dsp->pcm_slot_tx >= 0 &&
    853					    dsp->pcm_slot_tx <
    854					    sizeof(freeslots))
    855						freeslots[dsp->pcm_slot_tx] = 0;
    856				}
    857			}
    858			i1 = 0;
    859			ii = member->dsp->features.pcm_slots;
    860			while (i1 < ii) {
    861				if (freeslots[i1])
    862					break;
    863				i1++;
    864			}
    865			if (i1 == ii) {
    866				if (dsp_debug & DEBUG_DSP_CMX)
    867					printk(KERN_DEBUG
    868					       "%s no slot available "
    869					       "for %s & %s\n", __func__,
    870					       member->dsp->name,
    871					       nextm->dsp->name);
    872				/* no more slots available */
    873				goto conf_software;
    874			}
    875			i2 = i1 + 1;
    876			while (i2 < ii) {
    877				if (freeslots[i2])
    878					break;
    879				i2++;
    880			}
    881			if (i2 == ii) {
    882				if (dsp_debug & DEBUG_DSP_CMX)
    883					printk(KERN_DEBUG
    884					       "%s no slot available "
    885					       "for %s & %s\n",
    886					       __func__,
    887					       member->dsp->name,
    888					       nextm->dsp->name);
    889				/* no more slots available */
    890				goto conf_software;
    891			}
    892			/* assign free slots */
    893			member->dsp->pcm_slot_tx = i1;
    894			member->dsp->pcm_slot_rx = i2;
    895			nextm->dsp->pcm_slot_tx = i2;
    896			nextm->dsp->pcm_slot_rx = i1;
    897			member->dsp->pcm_bank_rx = 0;
    898			member->dsp->pcm_bank_tx = 0;
    899			nextm->dsp->pcm_bank_rx = 0;
    900			nextm->dsp->pcm_bank_tx = 0;
    901			if (dsp_debug & DEBUG_DSP_CMX)
    902				printk(KERN_DEBUG
    903				       "%s adding %s & %s to new PCM slot %d "
    904				       "(TX) %d (RX) on same chip or one bank "
    905				       "PCM, because both members have not "
    906				       "crossed slots\n", __func__,
    907				       member->dsp->name,
    908				       nextm->dsp->name,
    909				       member->dsp->pcm_slot_tx,
    910				       member->dsp->pcm_slot_rx);
    911			dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
    912					   member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
    913					   member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
    914			dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN,
    915					   nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
    916					   nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
    917			conf->hardware = 1;
    918			conf->software = tx_data;
    919			return;
    920		}
    921	}
    922
    923	/*
    924	 * if we have more than two, we may check if we have a conference
    925	 * unit available on the chip. also all members must be on the same
    926	 */
    927
    928	/* if not the same HFC chip */
    929	if (same_hfc < 0) {
    930		if (dsp_debug & DEBUG_DSP_CMX)
    931			printk(KERN_DEBUG
    932			       "%s conference %d cannot be formed, because "
    933			       "members are on different chips or not "
    934			       "on HFC chip\n",
    935			       __func__, conf->id);
    936		goto conf_software;
    937	}
    938
    939	/* for more than two members.. */
    940
    941	/* if all members already have the same conference */
    942	if (all_conf) {
    943		conf->hardware = 1;
    944		conf->software = tx_data;
    945		return;
    946	}
    947
    948	/*
    949	 * if there is an existing conference, but not all members have joined
    950	 */
    951	if (current_conf >= 0) {
    952	join_members:
    953		list_for_each_entry(member, &conf->mlist, list) {
    954			/* if no conference engine on our chip, change to
    955			 * software */
    956			if (!member->dsp->features.hfc_conf)
    957				goto conf_software;
    958			/* in case of hdlc, change to software */
    959			if (member->dsp->hdlc)
    960				goto conf_software;
    961			/* join to current conference */
    962			if (member->dsp->hfc_conf == current_conf)
    963				continue;
    964			/* get a free timeslot first */
    965			memset(freeslots, 1, sizeof(freeslots));
    966			list_for_each_entry(dsp, &dsp_ilist, list) {
    967				/*
    968				 * not checking current member, because
    969				 * slot will be overwritten.
    970				 */
    971				if (
    972					dsp != member->dsp &&
    973					/* dsp must be on the same PCM */
    974					member->dsp->features.pcm_id ==
    975					dsp->features.pcm_id) {
    976					/* dsp must be on a slot */
    977					if (dsp->pcm_slot_tx >= 0 &&
    978					    dsp->pcm_slot_tx <
    979					    sizeof(freeslots))
    980						freeslots[dsp->pcm_slot_tx] = 0;
    981					if (dsp->pcm_slot_rx >= 0 &&
    982					    dsp->pcm_slot_rx <
    983					    sizeof(freeslots))
    984						freeslots[dsp->pcm_slot_rx] = 0;
    985				}
    986			}
    987			i = 0;
    988			ii = member->dsp->features.pcm_slots;
    989			while (i < ii) {
    990				if (freeslots[i])
    991					break;
    992				i++;
    993			}
    994			if (i == ii) {
    995				/* no more slots available */
    996				if (dsp_debug & DEBUG_DSP_CMX)
    997					printk(KERN_DEBUG
    998					       "%s conference %d cannot be formed,"
    999					       " because no slot free\n",
   1000					       __func__, conf->id);
   1001				goto conf_software;
   1002			}
   1003			if (dsp_debug & DEBUG_DSP_CMX)
   1004				printk(KERN_DEBUG
   1005				       "%s changing dsp %s to HW conference "
   1006				       "%d slot %d\n", __func__,
   1007				       member->dsp->name, current_conf, i);
   1008			/* assign free slot & set PCM & join conf */
   1009			member->dsp->pcm_slot_tx = i;
   1010			member->dsp->pcm_slot_rx = i;
   1011			member->dsp->pcm_bank_tx = 2; /* loop */
   1012			member->dsp->pcm_bank_rx = 2;
   1013			member->dsp->hfc_conf = current_conf;
   1014			dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
   1015					   i, 2, i, 2);
   1016			dsp_cmx_hw_message(member->dsp,
   1017					   MISDN_CTRL_HFC_CONF_JOIN, current_conf, 0, 0, 0);
   1018		}
   1019		conf->hardware = 1;
   1020		conf->software = tx_data;
   1021		return;
   1022	}
   1023
   1024	/*
   1025	 * no member is in a conference yet, so we find a free one
   1026	 */
   1027	memset(freeunits, 1, sizeof(freeunits));
   1028	list_for_each_entry(dsp, &dsp_ilist, list) {
   1029		/* dsp must be on the same chip */
   1030		if (dsp->features.hfc_id == same_hfc &&
   1031		    /* dsp must have joined a HW conference */
   1032		    dsp->hfc_conf >= 0 &&
   1033		    /* slot must be within range */
   1034		    dsp->hfc_conf < 8)
   1035			freeunits[dsp->hfc_conf] = 0;
   1036	}
   1037	i = 0;
   1038	ii = 8;
   1039	while (i < ii) {
   1040		if (freeunits[i])
   1041			break;
   1042		i++;
   1043	}
   1044	if (i == ii) {
   1045		/* no more conferences available */
   1046		if (dsp_debug & DEBUG_DSP_CMX)
   1047			printk(KERN_DEBUG
   1048			       "%s conference %d cannot be formed, because "
   1049			       "no conference number free\n",
   1050			       __func__, conf->id);
   1051		goto conf_software;
   1052	}
   1053	/* join all members */
   1054	current_conf = i;
   1055	goto join_members;
   1056}
   1057
   1058
   1059/*
   1060 * conf_id != 0: join or change conference
   1061 * conf_id == 0: split from conference if not already
   1062 */
   1063int
   1064dsp_cmx_conf(struct dsp *dsp, u32 conf_id)
   1065{
   1066	int err;
   1067	struct dsp_conf *conf;
   1068	struct dsp_conf_member	*member;
   1069
   1070	/* if conference doesn't change */
   1071	if (dsp->conf_id == conf_id)
   1072		return 0;
   1073
   1074	/* first remove us from current conf */
   1075	if (dsp->conf_id) {
   1076		if (dsp_debug & DEBUG_DSP_CMX)
   1077			printk(KERN_DEBUG "removing us from conference %d\n",
   1078			       dsp->conf->id);
   1079		/* remove us from conf */
   1080		conf = dsp->conf;
   1081		err = dsp_cmx_del_conf_member(dsp);
   1082		if (err)
   1083			return err;
   1084		dsp->conf_id = 0;
   1085
   1086		/* update hardware */
   1087		dsp_cmx_hardware(NULL, dsp);
   1088
   1089		/* conf now empty? */
   1090		if (list_empty(&conf->mlist)) {
   1091			if (dsp_debug & DEBUG_DSP_CMX)
   1092				printk(KERN_DEBUG
   1093				       "conference is empty, so we remove it.\n");
   1094			err = dsp_cmx_del_conf(conf);
   1095			if (err)
   1096				return err;
   1097		} else {
   1098			/* update members left on conf */
   1099			dsp_cmx_hardware(conf, NULL);
   1100		}
   1101	}
   1102
   1103	/* if split */
   1104	if (!conf_id)
   1105		return 0;
   1106
   1107	/* now add us to conf */
   1108	if (dsp_debug & DEBUG_DSP_CMX)
   1109		printk(KERN_DEBUG "searching conference %d\n",
   1110		       conf_id);
   1111	conf = dsp_cmx_search_conf(conf_id);
   1112	if (!conf) {
   1113		if (dsp_debug & DEBUG_DSP_CMX)
   1114			printk(KERN_DEBUG
   1115			       "conference doesn't exist yet, creating.\n");
   1116		/* the conference doesn't exist, so we create */
   1117		conf = dsp_cmx_new_conf(conf_id);
   1118		if (!conf)
   1119			return -EINVAL;
   1120	} else if (!list_empty(&conf->mlist)) {
   1121		member = list_entry(conf->mlist.next, struct dsp_conf_member,
   1122				    list);
   1123		if (dsp->hdlc && !member->dsp->hdlc) {
   1124			if (dsp_debug & DEBUG_DSP_CMX)
   1125				printk(KERN_DEBUG
   1126				       "cannot join transparent conference.\n");
   1127			return -EINVAL;
   1128		}
   1129		if (!dsp->hdlc && member->dsp->hdlc) {
   1130			if (dsp_debug & DEBUG_DSP_CMX)
   1131				printk(KERN_DEBUG
   1132				       "cannot join hdlc conference.\n");
   1133			return -EINVAL;
   1134		}
   1135	}
   1136	/* add conference member */
   1137	err = dsp_cmx_add_conf_member(dsp, conf);
   1138	if (err)
   1139		return err;
   1140	dsp->conf_id = conf_id;
   1141
   1142	/* if we are alone, we do nothing! */
   1143	if (list_empty(&conf->mlist)) {
   1144		if (dsp_debug & DEBUG_DSP_CMX)
   1145			printk(KERN_DEBUG
   1146			       "we are alone in this conference, so exit.\n");
   1147		/* update hardware */
   1148		dsp_cmx_hardware(NULL, dsp);
   1149		return 0;
   1150	}
   1151
   1152	/* update members on conf */
   1153	dsp_cmx_hardware(conf, NULL);
   1154
   1155	return 0;
   1156}
   1157
   1158#ifdef CMX_DELAY_DEBUG
   1159int delaycount;
   1160static void
   1161showdelay(struct dsp *dsp, int samples, int delay)
   1162{
   1163	char bar[] = "--------------------------------------------------|";
   1164	int sdelay;
   1165
   1166	delaycount += samples;
   1167	if (delaycount < 8000)
   1168		return;
   1169	delaycount = 0;
   1170
   1171	sdelay = delay * 50 / (dsp_poll << 2);
   1172
   1173	printk(KERN_DEBUG "DELAY (%s) %3d >%s\n", dsp->name, delay,
   1174	       sdelay > 50 ? "..." : bar + 50 - sdelay);
   1175}
   1176#endif
   1177
   1178/*
   1179 * audio data is received from card
   1180 */
   1181void
   1182dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
   1183{
   1184	u8 *d, *p;
   1185	int len = skb->len;
   1186	struct mISDNhead *hh = mISDN_HEAD_P(skb);
   1187	int w, i, ii;
   1188
   1189	/* check if we have sompen */
   1190	if (len < 1)
   1191		return;
   1192
   1193	/* half of the buffer should be larger than maximum packet size */
   1194	if (len >= CMX_BUFF_HALF) {
   1195		printk(KERN_ERR
   1196		       "%s line %d: packet from card is too large (%d bytes). "
   1197		       "please make card send smaller packets OR increase "
   1198		       "CMX_BUFF_SIZE\n", __FILE__, __LINE__, len);
   1199		return;
   1200	}
   1201
   1202	/*
   1203	 * initialize pointers if not already -
   1204	 * also add delay if requested by PH_SIGNAL
   1205	 */
   1206	if (dsp->rx_init) {
   1207		dsp->rx_init = 0;
   1208		if (dsp->features.unordered) {
   1209			dsp->rx_R = (hh->id & CMX_BUFF_MASK);
   1210			if (dsp->cmx_delay)
   1211				dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
   1212					& CMX_BUFF_MASK;
   1213			else
   1214				dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
   1215					& CMX_BUFF_MASK;
   1216		} else {
   1217			dsp->rx_R = 0;
   1218			if (dsp->cmx_delay)
   1219				dsp->rx_W = dsp->cmx_delay;
   1220			else
   1221				dsp->rx_W = dsp_poll >> 1;
   1222		}
   1223	}
   1224	/* if frame contains time code, write directly */
   1225	if (dsp->features.unordered) {
   1226		dsp->rx_W = (hh->id & CMX_BUFF_MASK);
   1227		/* printk(KERN_DEBUG "%s %08x\n", dsp->name, hh->id); */
   1228	}
   1229	/*
   1230	 * if we underrun (or maybe overrun),
   1231	 * we set our new read pointer, and write silence to buffer
   1232	 */
   1233	if (((dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK) >= CMX_BUFF_HALF) {
   1234		if (dsp_debug & DEBUG_DSP_CLOCK)
   1235			printk(KERN_DEBUG
   1236			       "cmx_receive(dsp=%lx): UNDERRUN (or overrun the "
   1237			       "maximum delay), adjusting read pointer! "
   1238			       "(inst %s)\n", (u_long)dsp, dsp->name);
   1239		/* flush rx buffer and set delay to dsp_poll / 2 */
   1240		if (dsp->features.unordered) {
   1241			dsp->rx_R = (hh->id & CMX_BUFF_MASK);
   1242			if (dsp->cmx_delay)
   1243				dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
   1244					& CMX_BUFF_MASK;
   1245			else
   1246				dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
   1247					& CMX_BUFF_MASK;
   1248		} else {
   1249			dsp->rx_R = 0;
   1250			if (dsp->cmx_delay)
   1251				dsp->rx_W = dsp->cmx_delay;
   1252			else
   1253				dsp->rx_W = dsp_poll >> 1;
   1254		}
   1255		memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
   1256	}
   1257	/* if we have reached double delay, jump back to middle */
   1258	if (dsp->cmx_delay)
   1259		if (((dsp->rx_W - dsp->rx_R) & CMX_BUFF_MASK) >=
   1260		    (dsp->cmx_delay << 1)) {
   1261			if (dsp_debug & DEBUG_DSP_CLOCK)
   1262				printk(KERN_DEBUG
   1263				       "cmx_receive(dsp=%lx): OVERRUN (because "
   1264				       "twice the delay is reached), adjusting "
   1265				       "read pointer! (inst %s)\n",
   1266				       (u_long)dsp, dsp->name);
   1267			/* flush buffer */
   1268			if (dsp->features.unordered) {
   1269				dsp->rx_R = (hh->id & CMX_BUFF_MASK);
   1270				dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
   1271					& CMX_BUFF_MASK;
   1272			} else {
   1273				dsp->rx_R = 0;
   1274				dsp->rx_W = dsp->cmx_delay;
   1275			}
   1276			memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
   1277		}
   1278
   1279	/* show where to write */
   1280#ifdef CMX_DEBUG
   1281	printk(KERN_DEBUG
   1282	       "cmx_receive(dsp=%lx): rx_R(dsp)=%05x rx_W(dsp)=%05x len=%d %s\n",
   1283	       (u_long)dsp, dsp->rx_R, dsp->rx_W, len, dsp->name);
   1284#endif
   1285
   1286	/* write data into rx_buffer */
   1287	p = skb->data;
   1288	d = dsp->rx_buff;
   1289	w = dsp->rx_W;
   1290	i = 0;
   1291	ii = len;
   1292	while (i < ii) {
   1293		d[w++ & CMX_BUFF_MASK] = *p++;
   1294		i++;
   1295	}
   1296
   1297	/* increase write-pointer */
   1298	dsp->rx_W = ((dsp->rx_W + len) & CMX_BUFF_MASK);
   1299#ifdef CMX_DELAY_DEBUG
   1300	showdelay(dsp, len, (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK);
   1301#endif
   1302}
   1303
   1304
   1305/*
   1306 * send (mixed) audio data to card and control jitter
   1307 */
   1308static void
   1309dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
   1310{
   1311	struct dsp_conf *conf = dsp->conf;
   1312	struct dsp *member, *other;
   1313	register s32 sample;
   1314	u8 *d, *p, *q, *o_q;
   1315	struct sk_buff *nskb, *txskb;
   1316	int r, rr, t, tt, o_r, o_rr;
   1317	int preload = 0;
   1318	struct mISDNhead *hh, *thh;
   1319	int tx_data_only = 0;
   1320
   1321	/* don't process if: */
   1322	if (!dsp->b_active) { /* if not active */
   1323		dsp->last_tx = 0;
   1324		return;
   1325	}
   1326	if (((dsp->conf && dsp->conf->hardware) || /* hardware conf */
   1327	     dsp->echo.hardware) && /* OR hardware echo */
   1328	    dsp->tx_R == dsp->tx_W && /* AND no tx-data */
   1329	    !(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */
   1330		if (!dsp->tx_data) { /* no tx_data for user space required */
   1331			dsp->last_tx = 0;
   1332			return;
   1333		}
   1334		if (dsp->conf && dsp->conf->software && dsp->conf->hardware)
   1335			tx_data_only = 1;
   1336		if (dsp->echo.software && dsp->echo.hardware)
   1337			tx_data_only = 1;
   1338	}
   1339
   1340#ifdef CMX_DEBUG
   1341	printk(KERN_DEBUG
   1342	       "SEND members=%d dsp=%s, conf=%p, rx_R=%05x rx_W=%05x\n",
   1343	       members, dsp->name, conf, dsp->rx_R, dsp->rx_W);
   1344#endif
   1345
   1346	/* preload if we have delay set */
   1347	if (dsp->cmx_delay && !dsp->last_tx) {
   1348		preload = len;
   1349		if (preload < 128)
   1350			preload = 128;
   1351	}
   1352
   1353	/* PREPARE RESULT */
   1354	nskb = mI_alloc_skb(len + preload, GFP_ATOMIC);
   1355	if (!nskb) {
   1356		printk(KERN_ERR
   1357		       "FATAL ERROR in mISDN_dsp.o: cannot alloc %d bytes\n",
   1358		       len + preload);
   1359		return;
   1360	}
   1361	hh = mISDN_HEAD_P(nskb);
   1362	hh->prim = PH_DATA_REQ;
   1363	hh->id = 0;
   1364	dsp->last_tx = 1;
   1365
   1366	/* set pointers, indexes and stuff */
   1367	member = dsp;
   1368	p = dsp->tx_buff; /* transmit data */
   1369	q = dsp->rx_buff; /* received data */
   1370	d = skb_put(nskb, preload + len); /* result */
   1371	t = dsp->tx_R; /* tx-pointers */
   1372	tt = dsp->tx_W;
   1373	r = dsp->rx_R; /* rx-pointers */
   1374	rr = (r + len) & CMX_BUFF_MASK;
   1375
   1376	/* preload with silence, if required */
   1377	if (preload) {
   1378		memset(d, dsp_silence, preload);
   1379		d += preload;
   1380	}
   1381
   1382	/* PROCESS TONES/TX-DATA ONLY */
   1383	if (dsp->tone.tone && dsp->tone.software) {
   1384		/* -> copy tone */
   1385		dsp_tone_copy(dsp, d, len);
   1386		dsp->tx_R = 0; /* clear tx buffer */
   1387		dsp->tx_W = 0;
   1388		goto send_packet;
   1389	}
   1390	/* if we have tx-data but do not use mixing */
   1391	if (!dsp->tx_mix && t != tt) {
   1392		/* -> send tx-data and continue when not enough */
   1393#ifdef CMX_TX_DEBUG
   1394		sprintf(debugbuf, "TX sending (%04x-%04x)%p: ", t, tt, p);
   1395#endif
   1396		while (r != rr && t != tt) {
   1397#ifdef CMX_TX_DEBUG
   1398			if (strlen(debugbuf) < 48)
   1399				sprintf(debugbuf + strlen(debugbuf), " %02x",
   1400					p[t]);
   1401#endif
   1402			*d++ = p[t]; /* write tx_buff */
   1403			t = (t + 1) & CMX_BUFF_MASK;
   1404			r = (r + 1) & CMX_BUFF_MASK;
   1405		}
   1406		if (r == rr) {
   1407			dsp->tx_R = t;
   1408#ifdef CMX_TX_DEBUG
   1409			printk(KERN_DEBUG "%s\n", debugbuf);
   1410#endif
   1411			goto send_packet;
   1412		}
   1413	}
   1414#ifdef CMX_TX_DEBUG
   1415	printk(KERN_DEBUG "%s\n", debugbuf);
   1416#endif
   1417
   1418	/* PROCESS DATA (one member / no conf) */
   1419	if (!conf || members <= 1) {
   1420		/* -> if echo is NOT enabled */
   1421		if (!dsp->echo.software) {
   1422			/* -> send tx-data if available or use 0-volume */
   1423			while (r != rr && t != tt) {
   1424				*d++ = p[t]; /* write tx_buff */
   1425				t = (t + 1) & CMX_BUFF_MASK;
   1426				r = (r + 1) & CMX_BUFF_MASK;
   1427			}
   1428			if (r != rr) {
   1429				if (dsp_debug & DEBUG_DSP_CLOCK)
   1430					printk(KERN_DEBUG "%s: RX empty\n",
   1431					       __func__);
   1432				memset(d, dsp_silence, (rr - r) & CMX_BUFF_MASK);
   1433			}
   1434			/* -> if echo is enabled */
   1435		} else {
   1436			/*
   1437			 * -> mix tx-data with echo if available,
   1438			 * or use echo only
   1439			 */
   1440			while (r != rr && t != tt) {
   1441				*d++ = dsp_audio_mix_law[(p[t] << 8) | q[r]];
   1442				t = (t + 1) & CMX_BUFF_MASK;
   1443				r = (r + 1) & CMX_BUFF_MASK;
   1444			}
   1445			while (r != rr) {
   1446				*d++ = q[r]; /* echo */
   1447				r = (r + 1) & CMX_BUFF_MASK;
   1448			}
   1449		}
   1450		dsp->tx_R = t;
   1451		goto send_packet;
   1452	}
   1453	/* PROCESS DATA (two members) */
   1454#ifdef CMX_CONF_DEBUG
   1455	if (0) {
   1456#else
   1457	if (members == 2) {
   1458#endif
   1459		/* "other" becomes other party */
   1460		other = (list_entry(conf->mlist.next,
   1461				    struct dsp_conf_member, list))->dsp;
   1462		if (other == member)
   1463			other = (list_entry(conf->mlist.prev,
   1464				    struct dsp_conf_member, list))->dsp;
   1465		o_q = other->rx_buff; /* received data */
   1466		o_rr = (other->rx_R + len) & CMX_BUFF_MASK;
   1467		/* end of rx-pointer */
   1468		o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
   1469		/* start rx-pointer at current read position*/
   1470		/* -> if echo is NOT enabled */
   1471		if (!dsp->echo.software) {
   1472			/*
   1473			 * -> copy other member's rx-data,
   1474			 * if tx-data is available, mix
   1475			 */
   1476			while (o_r != o_rr && t != tt) {
   1477				*d++ = dsp_audio_mix_law[(p[t] << 8) | o_q[o_r]];
   1478				t = (t + 1) & CMX_BUFF_MASK;
   1479				o_r = (o_r + 1) & CMX_BUFF_MASK;
   1480			}
   1481			while (o_r != o_rr) {
   1482				*d++ = o_q[o_r];
   1483				o_r = (o_r + 1) & CMX_BUFF_MASK;
   1484			}
   1485			/* -> if echo is enabled */
   1486		} else {
   1487			/*
   1488			 * -> mix other member's rx-data with echo,
   1489			 * if tx-data is available, mix
   1490			 */
   1491			while (r != rr && t != tt) {
   1492				sample = dsp_audio_law_to_s32[p[t]] +
   1493					dsp_audio_law_to_s32[q[r]] +
   1494					dsp_audio_law_to_s32[o_q[o_r]];
   1495				if (sample < -32768)
   1496					sample = -32768;
   1497				else if (sample > 32767)
   1498					sample = 32767;
   1499				*d++ = dsp_audio_s16_to_law[sample & 0xffff];
   1500				/* tx-data + rx_data + echo */
   1501				t = (t + 1) & CMX_BUFF_MASK;
   1502				r = (r + 1) & CMX_BUFF_MASK;
   1503				o_r = (o_r + 1) & CMX_BUFF_MASK;
   1504			}
   1505			while (r != rr) {
   1506				*d++ = dsp_audio_mix_law[(q[r] << 8) | o_q[o_r]];
   1507				r = (r + 1) & CMX_BUFF_MASK;
   1508				o_r = (o_r + 1) & CMX_BUFF_MASK;
   1509			}
   1510		}
   1511		dsp->tx_R = t;
   1512		goto send_packet;
   1513	}
   1514	/* PROCESS DATA (three or more members) */
   1515	/* -> if echo is NOT enabled */
   1516	if (!dsp->echo.software) {
   1517		/*
   1518		 * -> subtract rx-data from conf-data,
   1519		 * if tx-data is available, mix
   1520		 */
   1521		while (r != rr && t != tt) {
   1522			sample = dsp_audio_law_to_s32[p[t]] + *c++ -
   1523				dsp_audio_law_to_s32[q[r]];
   1524			if (sample < -32768)
   1525				sample = -32768;
   1526			else if (sample > 32767)
   1527				sample = 32767;
   1528			*d++ = dsp_audio_s16_to_law[sample & 0xffff];
   1529			/* conf-rx+tx */
   1530			r = (r + 1) & CMX_BUFF_MASK;
   1531			t = (t + 1) & CMX_BUFF_MASK;
   1532		}
   1533		while (r != rr) {
   1534			sample = *c++ - dsp_audio_law_to_s32[q[r]];
   1535			if (sample < -32768)
   1536				sample = -32768;
   1537			else if (sample > 32767)
   1538				sample = 32767;
   1539			*d++ = dsp_audio_s16_to_law[sample & 0xffff];
   1540			/* conf-rx */
   1541			r = (r + 1) & CMX_BUFF_MASK;
   1542		}
   1543		/* -> if echo is enabled */
   1544	} else {
   1545		/*
   1546		 * -> encode conf-data, if tx-data
   1547		 * is available, mix
   1548		 */
   1549		while (r != rr && t != tt) {
   1550			sample = dsp_audio_law_to_s32[p[t]] + *c++;
   1551			if (sample < -32768)
   1552				sample = -32768;
   1553			else if (sample > 32767)
   1554				sample = 32767;
   1555			*d++ = dsp_audio_s16_to_law[sample & 0xffff];
   1556			/* conf(echo)+tx */
   1557			t = (t + 1) & CMX_BUFF_MASK;
   1558			r = (r + 1) & CMX_BUFF_MASK;
   1559		}
   1560		while (r != rr) {
   1561			sample = *c++;
   1562			if (sample < -32768)
   1563				sample = -32768;
   1564			else if (sample > 32767)
   1565				sample = 32767;
   1566			*d++ = dsp_audio_s16_to_law[sample & 0xffff];
   1567			/* conf(echo) */
   1568			r = (r + 1) & CMX_BUFF_MASK;
   1569		}
   1570	}
   1571	dsp->tx_R = t;
   1572	goto send_packet;
   1573
   1574send_packet:
   1575	/*
   1576	 * send tx-data if enabled - don't filter,
   1577	 * because we want what we send, not what we filtered
   1578	 */
   1579	if (dsp->tx_data) {
   1580		if (tx_data_only) {
   1581			hh->prim = DL_DATA_REQ;
   1582			hh->id = 0;
   1583			/* queue and trigger */
   1584			skb_queue_tail(&dsp->sendq, nskb);
   1585			schedule_work(&dsp->workq);
   1586			/* exit because only tx_data is used */
   1587			return;
   1588		} else {
   1589			txskb = mI_alloc_skb(len, GFP_ATOMIC);
   1590			if (!txskb) {
   1591				printk(KERN_ERR
   1592				       "FATAL ERROR in mISDN_dsp.o: "
   1593				       "cannot alloc %d bytes\n", len);
   1594			} else {
   1595				thh = mISDN_HEAD_P(txskb);
   1596				thh->prim = DL_DATA_REQ;
   1597				thh->id = 0;
   1598				skb_put_data(txskb, nskb->data + preload, len);
   1599				/* queue (trigger later) */
   1600				skb_queue_tail(&dsp->sendq, txskb);
   1601			}
   1602		}
   1603	}
   1604
   1605	/* send data only to card, if we don't just calculated tx_data */
   1606	/* adjust volume */
   1607	if (dsp->tx_volume)
   1608		dsp_change_volume(nskb, dsp->tx_volume);
   1609	/* pipeline */
   1610	if (dsp->pipeline.inuse)
   1611		dsp_pipeline_process_tx(&dsp->pipeline, nskb->data,
   1612					nskb->len);
   1613	/* crypt */
   1614	if (dsp->bf_enable)
   1615		dsp_bf_encrypt(dsp, nskb->data, nskb->len);
   1616	/* queue and trigger */
   1617	skb_queue_tail(&dsp->sendq, nskb);
   1618	schedule_work(&dsp->workq);
   1619}
   1620
   1621static u32	jittercount; /* counter for jitter check */
   1622struct timer_list dsp_spl_tl;
   1623unsigned long	dsp_spl_jiffies; /* calculate the next time to fire */
   1624static u16	dsp_count; /* last sample count */
   1625static int	dsp_count_valid; /* if we have last sample count */
   1626
   1627void
   1628dsp_cmx_send(void *arg)
   1629{
   1630	struct dsp_conf *conf;
   1631	struct dsp_conf_member *member;
   1632	struct dsp *dsp;
   1633	int mustmix, members;
   1634	static s32 mixbuffer[MAX_POLL + 100];
   1635	s32 *c;
   1636	u8 *p, *q;
   1637	int r, rr;
   1638	int jittercheck = 0, delay, i;
   1639	u_long flags;
   1640	u16 length, count;
   1641
   1642	/* lock */
   1643	spin_lock_irqsave(&dsp_lock, flags);
   1644
   1645	if (!dsp_count_valid) {
   1646		dsp_count = mISDN_clock_get();
   1647		length = dsp_poll;
   1648		dsp_count_valid = 1;
   1649	} else {
   1650		count = mISDN_clock_get();
   1651		length = count - dsp_count;
   1652		dsp_count = count;
   1653	}
   1654	if (length > MAX_POLL + 100)
   1655		length = MAX_POLL + 100;
   1656	/* printk(KERN_DEBUG "len=%d dsp_count=0x%x\n", length, dsp_count); */
   1657
   1658	/*
   1659	 * check if jitter needs to be checked (this is every second)
   1660	 */
   1661	jittercount += length;
   1662	if (jittercount >= 8000) {
   1663		jittercount -= 8000;
   1664		jittercheck = 1;
   1665	}
   1666
   1667	/* loop all members that do not require conference mixing */
   1668	list_for_each_entry(dsp, &dsp_ilist, list) {
   1669		if (dsp->hdlc)
   1670			continue;
   1671		conf = dsp->conf;
   1672		mustmix = 0;
   1673		members = 0;
   1674		if (conf) {
   1675			members = count_list_member(&conf->mlist);
   1676#ifdef CMX_CONF_DEBUG
   1677			if (conf->software && members > 1)
   1678#else
   1679			if (conf->software && members > 2)
   1680#endif
   1681				mustmix = 1;
   1682		}
   1683
   1684		/* transmission required */
   1685		if (!mustmix) {
   1686			dsp_cmx_send_member(dsp, length, mixbuffer, members);
   1687
   1688			/*
   1689			 * unused mixbuffer is given to prevent a
   1690			 * potential null-pointer-bug
   1691			 */
   1692		}
   1693	}
   1694
   1695	/* loop all members that require conference mixing */
   1696	list_for_each_entry(conf, &conf_ilist, list) {
   1697		/* count members and check hardware */
   1698		members = count_list_member(&conf->mlist);
   1699#ifdef CMX_CONF_DEBUG
   1700		if (conf->software && members > 1) {
   1701#else
   1702		if (conf->software && members > 2) {
   1703#endif
   1704			/* check for hdlc conf */
   1705			member = list_entry(conf->mlist.next,
   1706					    struct dsp_conf_member, list);
   1707			if (member->dsp->hdlc)
   1708				continue;
   1709			/* mix all data */
   1710			memset(mixbuffer, 0, length * sizeof(s32));
   1711			list_for_each_entry(member, &conf->mlist, list) {
   1712				dsp = member->dsp;
   1713				/* get range of data to mix */
   1714				c = mixbuffer;
   1715				q = dsp->rx_buff;
   1716				r = dsp->rx_R;
   1717				rr = (r + length) & CMX_BUFF_MASK;
   1718				/* add member's data */
   1719				while (r != rr) {
   1720					*c++ += dsp_audio_law_to_s32[q[r]];
   1721					r = (r + 1) & CMX_BUFF_MASK;
   1722				}
   1723			}
   1724
   1725			/* process each member */
   1726			list_for_each_entry(member, &conf->mlist, list) {
   1727				/* transmission */
   1728				dsp_cmx_send_member(member->dsp, length,
   1729						    mixbuffer, members);
   1730			}
   1731		}
   1732	}
   1733
   1734	/* delete rx-data, increment buffers, change pointers */
   1735	list_for_each_entry(dsp, &dsp_ilist, list) {
   1736		if (dsp->hdlc)
   1737			continue;
   1738		p = dsp->rx_buff;
   1739		q = dsp->tx_buff;
   1740		r = dsp->rx_R;
   1741		/* move receive pointer when receiving */
   1742		if (!dsp->rx_is_off) {
   1743			rr = (r + length) & CMX_BUFF_MASK;
   1744			/* delete rx-data */
   1745			while (r != rr) {
   1746				p[r] = dsp_silence;
   1747				r = (r + 1) & CMX_BUFF_MASK;
   1748			}
   1749			/* increment rx-buffer pointer */
   1750			dsp->rx_R = r; /* write incremented read pointer */
   1751		}
   1752
   1753		/* check current rx_delay */
   1754		delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK;
   1755		if (delay >= CMX_BUFF_HALF)
   1756			delay = 0; /* will be the delay before next write */
   1757		/* check for lower delay */
   1758		if (delay < dsp->rx_delay[0])
   1759			dsp->rx_delay[0] = delay;
   1760		/* check current tx_delay */
   1761		delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK;
   1762		if (delay >= CMX_BUFF_HALF)
   1763			delay = 0; /* will be the delay before next write */
   1764		/* check for lower delay */
   1765		if (delay < dsp->tx_delay[0])
   1766			dsp->tx_delay[0] = delay;
   1767		if (jittercheck) {
   1768			/* find the lowest of all rx_delays */
   1769			delay = dsp->rx_delay[0];
   1770			i = 1;
   1771			while (i < MAX_SECONDS_JITTER_CHECK) {
   1772				if (delay > dsp->rx_delay[i])
   1773					delay = dsp->rx_delay[i];
   1774				i++;
   1775			}
   1776			/*
   1777			 * remove rx_delay only if we have delay AND we
   1778			 * have not preset cmx_delay AND
   1779			 * the delay is greater dsp_poll
   1780			 */
   1781			if (delay > dsp_poll && !dsp->cmx_delay) {
   1782				if (dsp_debug & DEBUG_DSP_CLOCK)
   1783					printk(KERN_DEBUG
   1784					       "%s lowest rx_delay of %d bytes for"
   1785					       " dsp %s are now removed.\n",
   1786					       __func__, delay,
   1787					       dsp->name);
   1788				r = dsp->rx_R;
   1789				rr = (r + delay - (dsp_poll >> 1))
   1790					& CMX_BUFF_MASK;
   1791				/* delete rx-data */
   1792				while (r != rr) {
   1793					p[r] = dsp_silence;
   1794					r = (r + 1) & CMX_BUFF_MASK;
   1795				}
   1796				/* increment rx-buffer pointer */
   1797				dsp->rx_R = r;
   1798				/* write incremented read pointer */
   1799			}
   1800			/* find the lowest of all tx_delays */
   1801			delay = dsp->tx_delay[0];
   1802			i = 1;
   1803			while (i < MAX_SECONDS_JITTER_CHECK) {
   1804				if (delay > dsp->tx_delay[i])
   1805					delay = dsp->tx_delay[i];
   1806				i++;
   1807			}
   1808			/*
   1809			 * remove delay only if we have delay AND we
   1810			 * have enabled tx_dejitter
   1811			 */
   1812			if (delay > dsp_poll && dsp->tx_dejitter) {
   1813				if (dsp_debug & DEBUG_DSP_CLOCK)
   1814					printk(KERN_DEBUG
   1815					       "%s lowest tx_delay of %d bytes for"
   1816					       " dsp %s are now removed.\n",
   1817					       __func__, delay,
   1818					       dsp->name);
   1819				r = dsp->tx_R;
   1820				rr = (r + delay - (dsp_poll >> 1))
   1821					& CMX_BUFF_MASK;
   1822				/* delete tx-data */
   1823				while (r != rr) {
   1824					q[r] = dsp_silence;
   1825					r = (r + 1) & CMX_BUFF_MASK;
   1826				}
   1827				/* increment rx-buffer pointer */
   1828				dsp->tx_R = r;
   1829				/* write incremented read pointer */
   1830			}
   1831			/* scroll up delays */
   1832			i = MAX_SECONDS_JITTER_CHECK - 1;
   1833			while (i) {
   1834				dsp->rx_delay[i] = dsp->rx_delay[i - 1];
   1835				dsp->tx_delay[i] = dsp->tx_delay[i - 1];
   1836				i--;
   1837			}
   1838			dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
   1839			dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
   1840		}
   1841	}
   1842
   1843	/* if next event would be in the past ... */
   1844	if ((s32)(dsp_spl_jiffies + dsp_tics-jiffies) <= 0)
   1845		dsp_spl_jiffies = jiffies + 1;
   1846	else
   1847		dsp_spl_jiffies += dsp_tics;
   1848
   1849	dsp_spl_tl.expires = dsp_spl_jiffies;
   1850	add_timer(&dsp_spl_tl);
   1851
   1852	/* unlock */
   1853	spin_unlock_irqrestore(&dsp_lock, flags);
   1854}
   1855
   1856/*
   1857 * audio data is transmitted from upper layer to the dsp
   1858 */
   1859void
   1860dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb)
   1861{
   1862	u_int w, ww;
   1863	u8 *d, *p;
   1864	int space; /* todo: , l = skb->len; */
   1865#ifdef CMX_TX_DEBUG
   1866	char debugbuf[256] = "";
   1867#endif
   1868
   1869	/* check if there is enough space, and then copy */
   1870	w = dsp->tx_W;
   1871	ww = dsp->tx_R;
   1872	p = dsp->tx_buff;
   1873	d = skb->data;
   1874	space = (ww - w - 1) & CMX_BUFF_MASK;
   1875	/* write-pointer should not overrun nor reach read pointer */
   1876	if (space < skb->len) {
   1877		/* write to the space we have left */
   1878		ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */
   1879		if (dsp_debug & DEBUG_DSP_CLOCK)
   1880			printk(KERN_DEBUG "%s: TX overflow space=%d skb->len="
   1881			       "%d, w=0x%04x, ww=0x%04x\n", __func__, space,
   1882			       skb->len, w, ww);
   1883	} else
   1884		/* write until all byte are copied */
   1885		ww = (w + skb->len) & CMX_BUFF_MASK;
   1886	dsp->tx_W = ww;
   1887		/* show current buffer */
   1888#ifdef CMX_DEBUG
   1889	printk(KERN_DEBUG
   1890	       "cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n",
   1891	       (u_long)dsp, (ww - w) & CMX_BUFF_MASK, w, ww, dsp->name);
   1892#endif
   1893
   1894	/* copy transmit data to tx-buffer */
   1895#ifdef CMX_TX_DEBUG
   1896	sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p);
   1897#endif
   1898	while (w != ww) {
   1899#ifdef CMX_TX_DEBUG
   1900		if (strlen(debugbuf) < 48)
   1901			sprintf(debugbuf + strlen(debugbuf), " %02x", *d);
   1902#endif
   1903		p[w] = *d++;
   1904		w = (w + 1) & CMX_BUFF_MASK;
   1905	}
   1906#ifdef CMX_TX_DEBUG
   1907	printk(KERN_DEBUG "%s\n", debugbuf);
   1908#endif
   1909
   1910}
   1911
   1912/*
   1913 * hdlc data is received from card and sent to all members.
   1914 */
   1915void
   1916dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
   1917{
   1918	struct sk_buff *nskb = NULL;
   1919	struct dsp_conf_member *member;
   1920	struct mISDNhead *hh;
   1921
   1922	/* not if not active */
   1923	if (!dsp->b_active)
   1924		return;
   1925
   1926	/* check if we have sompen */
   1927	if (skb->len < 1)
   1928		return;
   1929
   1930	/* no conf */
   1931	if (!dsp->conf) {
   1932		/* in case of software echo */
   1933		if (dsp->echo.software) {
   1934			nskb = skb_clone(skb, GFP_ATOMIC);
   1935			if (nskb) {
   1936				hh = mISDN_HEAD_P(nskb);
   1937				hh->prim = PH_DATA_REQ;
   1938				hh->id = 0;
   1939				skb_queue_tail(&dsp->sendq, nskb);
   1940				schedule_work(&dsp->workq);
   1941			}
   1942		}
   1943		return;
   1944	}
   1945	/* in case of hardware conference */
   1946	if (dsp->conf->hardware)
   1947		return;
   1948	list_for_each_entry(member, &dsp->conf->mlist, list) {
   1949		if (dsp->echo.software || member->dsp != dsp) {
   1950			nskb = skb_clone(skb, GFP_ATOMIC);
   1951			if (nskb) {
   1952				hh = mISDN_HEAD_P(nskb);
   1953				hh->prim = PH_DATA_REQ;
   1954				hh->id = 0;
   1955				skb_queue_tail(&member->dsp->sendq, nskb);
   1956				schedule_work(&member->dsp->workq);
   1957			}
   1958		}
   1959	}
   1960}