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