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