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