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