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