]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/isdn/mISDN/dsp_cmx.c
c884511e2d49038a465ab9e550a8e04739463de0
[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_tx] = 0;
748                                         if (dsp->pcm_slot_tx >= 0 &&
749                                             dsp->pcm_slot_tx <
750                                             sizeof(freeslots))
751                                                 freeslots[dsp->pcm_slot_rx] = 0;
752                                 }
753                         }
754                         i = 0;
755                         ii = member->dsp->features.pcm_slots;
756                         while (i < ii) {
757                                 if (freeslots[i])
758                                         break;
759                                 i++;
760                         }
761                         if (i == ii) {
762                                 if (dsp_debug & DEBUG_DSP_CMX)
763                                         printk(KERN_DEBUG
764                                             "%s no slot available for "
765                                             "%s & %s\n", __func__,
766                                             member->dsp->name,
767                                             nextm->dsp->name);
768                                 /* no more slots available */
769                                 goto conf_software;
770                         }
771                         /* assign free slot */
772                         member->dsp->pcm_slot_tx = i;
773                         member->dsp->pcm_slot_rx = i;
774                         nextm->dsp->pcm_slot_tx = i;
775                         nextm->dsp->pcm_slot_rx = i;
776                         member->dsp->pcm_bank_rx = 0;
777                         member->dsp->pcm_bank_tx = 1;
778                         nextm->dsp->pcm_bank_rx = 1;
779                         nextm->dsp->pcm_bank_tx = 0;
780                         if (dsp_debug & DEBUG_DSP_CMX)
781                                 printk(KERN_DEBUG
782                                     "%s adding %s & %s to new PCM slot %d "
783                                     "(TX and RX on different chips) because "
784                                     "both members have not same slots\n",
785                                     __func__,
786                                     member->dsp->name,
787                                     nextm->dsp->name,
788                                     member->dsp->pcm_slot_tx);
789                         dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
790                             member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
791                             member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
792                         dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN,
793                             nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
794                             nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
795                         conf->hardware = 1;
796                         conf->software = 0;
797                         return;
798                 /* if members have one bank (or on the same chip) */
799                 } else {
800                         /* if both members have different crossed slots */
801                         if (member->dsp->pcm_slot_tx >= 0 &&
802                             member->dsp->pcm_slot_rx >= 0 &&
803                             nextm->dsp->pcm_slot_tx >= 0 &&
804                             nextm->dsp->pcm_slot_rx >= 0 &&
805                             nextm->dsp->pcm_slot_tx ==
806                             member->dsp->pcm_slot_rx &&
807                             nextm->dsp->pcm_slot_rx ==
808                             member->dsp->pcm_slot_tx &&
809                             member->dsp->pcm_slot_tx !=
810                             member->dsp->pcm_slot_rx &&
811                             member->dsp->pcm_bank_tx == 0 &&
812                             member->dsp->pcm_bank_rx == 0 &&
813                             nextm->dsp->pcm_bank_tx == 0 &&
814                             nextm->dsp->pcm_bank_rx == 0) {
815                                 /* all members have same slot */
816                                 if (dsp_debug & DEBUG_DSP_CMX)
817                                         printk(KERN_DEBUG
818                                             "%s dsp %s & %s stay joined on PCM "
819                                             "slot %d (TX) %d (RX) on same chip "
820                                             "or one bank PCM)\n", __func__,
821                                             member->dsp->name,
822                                             nextm->dsp->name,
823                                             member->dsp->pcm_slot_tx,
824                                             member->dsp->pcm_slot_rx);
825                                 conf->hardware = 0;
826                                 conf->software = 1;
827                                 return;
828                         }
829                         /* find two new slot */
830                         memset(freeslots, 1, sizeof(freeslots));
831                         list_for_each_entry(dsp, &dsp_ilist, list) {
832                                 if (dsp != member->dsp &&
833                                     dsp != nextm->dsp &&
834                                     member->dsp->features.pcm_id ==
835                                     dsp->features.pcm_id) {
836                                         if (dsp->pcm_slot_rx >= 0 &&
837                                             dsp->pcm_slot_rx <
838                                             sizeof(freeslots))
839                                                 freeslots[dsp->pcm_slot_tx] = 0;
840                                         if (dsp->pcm_slot_tx >= 0 &&
841                                             dsp->pcm_slot_tx <
842                                             sizeof(freeslots))
843                                                 freeslots[dsp->pcm_slot_rx] = 0;
844                                 }
845                         }
846                         i1 = 0;
847                         ii = member->dsp->features.pcm_slots;
848                         while (i1 < ii) {
849                                 if (freeslots[i1])
850                                         break;
851                                 i1++;
852                         }
853                         if (i1 == ii) {
854                                 if (dsp_debug & DEBUG_DSP_CMX)
855                                         printk(KERN_DEBUG
856                                             "%s no slot available "
857                                             "for %s & %s\n", __func__,
858                                             member->dsp->name,
859                                             nextm->dsp->name);
860                                 /* no more slots available */
861                                 goto conf_software;
862                         }
863                         i2 = i1+1;
864                         while (i2 < ii) {
865                                 if (freeslots[i2])
866                                         break;
867                                 i2++;
868                         }
869                         if (i2 == ii) {
870                                 if (dsp_debug & DEBUG_DSP_CMX)
871                                         printk(KERN_DEBUG
872                                             "%s no slot available "
873                                             "for %s & %s\n",
874                                             __func__,
875                                             member->dsp->name,
876                                             nextm->dsp->name);
877                                 /* no more slots available */
878                                 goto conf_software;
879                         }
880                         /* assign free slots */
881                         member->dsp->pcm_slot_tx = i1;
882                         member->dsp->pcm_slot_rx = i2;
883                         nextm->dsp->pcm_slot_tx = i2;
884                         nextm->dsp->pcm_slot_rx = i1;
885                         member->dsp->pcm_bank_rx = 0;
886                         member->dsp->pcm_bank_tx = 0;
887                         nextm->dsp->pcm_bank_rx = 0;
888                         nextm->dsp->pcm_bank_tx = 0;
889                         if (dsp_debug & DEBUG_DSP_CMX)
890                                 printk(KERN_DEBUG
891                                     "%s adding %s & %s to new PCM slot %d "
892                                     "(TX) %d (RX) on same chip or one bank "
893                                     "PCM, because both members have not "
894                                     "crossed slots\n", __func__,
895                                     member->dsp->name,
896                                     nextm->dsp->name,
897                                     member->dsp->pcm_slot_tx,
898                                     member->dsp->pcm_slot_rx);
899                         dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
900                             member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
901                             member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
902                         dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN,
903                             nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
904                             nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
905                         conf->hardware = 1;
906                         conf->software = 0;
907                         return;
908                 }
909         }
910
911         /*
912          * if we have more than two, we may check if we have a conference
913          * unit available on the chip. also all members must be on the same
914          */
915
916         /* if not the same HFC chip */
917         if (same_hfc < 0) {
918                 if (dsp_debug & DEBUG_DSP_CMX)
919                         printk(KERN_DEBUG
920                             "%s conference %d cannot be formed, because "
921                             "members are on different chips or not "
922                             "on HFC chip\n",
923                             __func__, conf->id);
924                 goto conf_software;
925         }
926
927         /* for more than two members.. */
928
929         /* in case of hdlc, we change to software */
930         if (dsp->hdlc)
931                 goto conf_software;
932
933         /* if all members already have the same conference */
934         if (all_conf)
935                 return;
936
937         /*
938          * if there is an existing conference, but not all members have joined
939          */
940         if (current_conf >= 0) {
941 join_members:
942                 list_for_each_entry(member, &conf->mlist, list) {
943                         /* join to current conference */
944                         if (member->dsp->hfc_conf == current_conf)
945                                 continue;
946                         /* get a free timeslot first */
947                         memset(freeslots, 1, sizeof(freeslots));
948                         list_for_each_entry(dsp, &dsp_ilist, list) {
949                                 /*
950                                  * not checking current member, because
951                                  * slot will be overwritten.
952                                  */
953                                 if (
954                                     dsp != member->dsp &&
955                                 /* dsp must be on the same PCM */
956                                     member->dsp->features.pcm_id ==
957                                     dsp->features.pcm_id) {
958                                         /* dsp must be on a slot */
959                                         if (dsp->pcm_slot_tx >= 0 &&
960                                             dsp->pcm_slot_tx <
961                                             sizeof(freeslots))
962                                                 freeslots[dsp->pcm_slot_tx] = 0;
963                                         if (dsp->pcm_slot_rx >= 0 &&
964                                             dsp->pcm_slot_rx <
965                                             sizeof(freeslots))
966                                                 freeslots[dsp->pcm_slot_rx] = 0;
967                                 }
968                         }
969                         i = 0;
970                         ii = member->dsp->features.pcm_slots;
971                         while (i < ii) {
972                                 if (freeslots[i])
973                                         break;
974                                 i++;
975                         }
976                         if (i == ii) {
977                                 /* no more slots available */
978                                 if (dsp_debug & DEBUG_DSP_CMX)
979                                         printk(KERN_DEBUG
980                                             "%s conference %d cannot be formed,"
981                                             " because no slot free\n",
982                                             __func__, conf->id);
983                                 goto conf_software;
984                         }
985                         if (dsp_debug & DEBUG_DSP_CMX)
986                                 printk(KERN_DEBUG
987                                     "%s changing dsp %s to HW conference "
988                                     "%d slot %d\n", __func__,
989                                     member->dsp->name, current_conf, i);
990                         /* assign free slot & set PCM & join conf */
991                         member->dsp->pcm_slot_tx = i;
992                         member->dsp->pcm_slot_rx = i;
993                         member->dsp->pcm_bank_tx = 2; /* loop */
994                         member->dsp->pcm_bank_rx = 2;
995                         member->dsp->hfc_conf = current_conf;
996                         dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
997                             i, 2, i, 2);
998                         dsp_cmx_hw_message(member->dsp,
999                             MISDN_CTRL_HFC_CONF_JOIN, current_conf, 0, 0, 0);
1000                 }
1001                 return;
1002         }
1003
1004         /*
1005          * no member is in a conference yet, so we find a free one
1006          */
1007         memset(freeunits, 1, sizeof(freeunits));
1008         list_for_each_entry(dsp, &dsp_ilist, list) {
1009                 /* dsp must be on the same chip */
1010                 if (dsp->features.hfc_id == same_hfc &&
1011                     /* dsp must have joined a HW conference */
1012                     dsp->hfc_conf >= 0 &&
1013                     /* slot must be within range */
1014                     dsp->hfc_conf < 8)
1015                         freeunits[dsp->hfc_conf] = 0;
1016         }
1017         i = 0;
1018         ii = 8;
1019         while (i < ii) {
1020                 if (freeunits[i])
1021                         break;
1022                 i++;
1023         }
1024         if (i == ii) {
1025                 /* no more conferences available */
1026                 if (dsp_debug & DEBUG_DSP_CMX)
1027                         printk(KERN_DEBUG
1028                             "%s conference %d cannot be formed, because "
1029                             "no conference number free\n",
1030                             __func__, conf->id);
1031                 goto conf_software;
1032         }
1033         /* join all members */
1034         current_conf = i;
1035         goto join_members;
1036 }
1037
1038
1039 /*
1040  * conf_id != 0: join or change conference
1041  * conf_id == 0: split from conference if not already
1042  */
1043 int
1044 dsp_cmx_conf(struct dsp *dsp, u32 conf_id)
1045 {
1046         int err;
1047         struct dsp_conf *conf;
1048         struct dsp_conf_member  *member;
1049
1050         /* if conference doesn't change */
1051         if (dsp->conf_id == conf_id)
1052                 return 0;
1053
1054         /* first remove us from current conf */
1055         if (dsp->conf_id) {
1056                 if (dsp_debug & DEBUG_DSP_CMX)
1057                         printk(KERN_DEBUG "removing us from conference %d\n",
1058                                 dsp->conf->id);
1059                 /* remove us from conf */
1060                 conf = dsp->conf;
1061                 err = dsp_cmx_del_conf_member(dsp);
1062                 if (err)
1063                         return err;
1064                 dsp->conf_id = 0;
1065
1066                 /* update hardware */
1067                 dsp_cmx_hardware(NULL, dsp);
1068
1069                 /* conf now empty? */
1070                 if (list_empty(&conf->mlist)) {
1071                         if (dsp_debug & DEBUG_DSP_CMX)
1072                                 printk(KERN_DEBUG
1073                                     "conference is empty, so we remove it.\n");
1074                         err = dsp_cmx_del_conf(conf);
1075                         if (err)
1076                                 return err;
1077                 } else {
1078                         /* update members left on conf */
1079                         dsp_cmx_hardware(conf, NULL);
1080                 }
1081         }
1082
1083         /* if split */
1084         if (!conf_id)
1085                 return 0;
1086
1087         /* now add us to conf */
1088         if (dsp_debug & DEBUG_DSP_CMX)
1089                 printk(KERN_DEBUG "searching conference %d\n",
1090                         conf_id);
1091         conf = dsp_cmx_search_conf(conf_id);
1092         if (!conf) {
1093                 if (dsp_debug & DEBUG_DSP_CMX)
1094                         printk(KERN_DEBUG
1095                             "conference doesn't exist yet, creating.\n");
1096                 /* the conference doesn't exist, so we create */
1097                 conf = dsp_cmx_new_conf(conf_id);
1098                 if (!conf)
1099                         return -EINVAL;
1100         } else if (!list_empty(&conf->mlist)) {
1101                 member = list_entry(conf->mlist.next, struct dsp_conf_member,
1102                         list);
1103                 if (dsp->hdlc && !member->dsp->hdlc) {
1104                         if (dsp_debug & DEBUG_DSP_CMX)
1105                                 printk(KERN_DEBUG
1106                                     "cannot join transparent conference.\n");
1107                         return -EINVAL;
1108                 }
1109                 if (!dsp->hdlc && member->dsp->hdlc) {
1110                         if (dsp_debug & DEBUG_DSP_CMX)
1111                                 printk(KERN_DEBUG
1112                                     "cannot join hdlc conference.\n");
1113                         return -EINVAL;
1114                 }
1115         }
1116         /* add conference member */
1117         err = dsp_cmx_add_conf_member(dsp, conf);
1118         if (err)
1119                 return err;
1120         dsp->conf_id = conf_id;
1121
1122         /* if we are alone, we do nothing! */
1123         if (list_empty(&conf->mlist)) {
1124                 if (dsp_debug & DEBUG_DSP_CMX)
1125                         printk(KERN_DEBUG
1126                             "we are alone in this conference, so exit.\n");
1127                 /* update hardware */
1128                 dsp_cmx_hardware(NULL, dsp);
1129                 return 0;
1130         }
1131
1132         /* update members on conf */
1133         dsp_cmx_hardware(conf, NULL);
1134
1135         return 0;
1136 }
1137
1138
1139 /*
1140  * audio data is received from card
1141  */
1142 void
1143 dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
1144 {
1145         u8 *d, *p;
1146         int len = skb->len;
1147         struct mISDNhead *hh = mISDN_HEAD_P(skb);
1148         int w, i, ii;
1149
1150         /* check if we have sompen */
1151         if (len < 1)
1152                 return;
1153
1154         /* half of the buffer should be larger than maximum packet size */
1155         if (len >= CMX_BUFF_HALF) {
1156                 printk(KERN_ERR
1157                     "%s line %d: packet from card is too large (%d bytes). "
1158                     "please make card send smaller packets OR increase "
1159                     "CMX_BUFF_SIZE\n", __FILE__, __LINE__, len);
1160                 return;
1161         }
1162
1163         /*
1164          * initialize pointers if not already -
1165          * also add delay if requested by PH_SIGNAL
1166          */
1167         if (dsp->rx_init) {
1168                 dsp->rx_init = 0;
1169                 if (dsp->features.unordered) {
1170                         dsp->rx_R = (hh->id & CMX_BUFF_MASK);
1171                         dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
1172                                 & CMX_BUFF_MASK;
1173                 } else {
1174                         dsp->rx_R = 0;
1175                         dsp->rx_W = dsp->cmx_delay;
1176                 }
1177         }
1178         /* if frame contains time code, write directly */
1179         if (dsp->features.unordered) {
1180                 dsp->rx_W = (hh->id & CMX_BUFF_MASK);
1181                 /* printk(KERN_DEBUG "%s %08x\n", dsp->name, hh->id); */
1182         }
1183         /*
1184          * if we underrun (or maybe overrun),
1185          * we set our new read pointer, and write silence to buffer
1186          */
1187         if (((dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK) >= CMX_BUFF_HALF) {
1188                 if (dsp_debug & DEBUG_DSP_CMX)
1189                         printk(KERN_DEBUG
1190                             "cmx_receive(dsp=%lx): UNDERRUN (or overrun the "
1191                             "maximum delay), adjusting read pointer! "
1192                             "(inst %s)\n", (u_long)dsp, dsp->name);
1193                 /* flush buffer */
1194                 if (dsp->features.unordered) {
1195                         dsp->rx_R = (hh->id & CMX_BUFF_MASK);
1196                         dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
1197                                 & CMX_BUFF_MASK;
1198                 } else {
1199                         dsp->rx_R = 0;
1200                         dsp->rx_W = dsp->cmx_delay;
1201                 }
1202                 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
1203         }
1204         /* if we have reached double delay, jump back to middle */
1205         if (dsp->cmx_delay)
1206                 if (((dsp->rx_W - dsp->rx_R) & CMX_BUFF_MASK) >=
1207                     (dsp->cmx_delay << 1)) {
1208                         if (dsp_debug & DEBUG_DSP_CMX)
1209                                 printk(KERN_DEBUG
1210                                     "cmx_receive(dsp=%lx): OVERRUN (because "
1211                                     "twice the delay is reached), adjusting "
1212                                     "read pointer! (inst %s)\n",
1213                                     (u_long)dsp, dsp->name);
1214                 /* flush buffer */
1215                 if (dsp->features.unordered) {
1216                         dsp->rx_R = (hh->id & CMX_BUFF_MASK);
1217                         dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
1218                                 & CMX_BUFF_MASK;
1219                 } else {
1220                         dsp->rx_R = 0;
1221                         dsp->rx_W = dsp->cmx_delay;
1222                 }
1223                 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
1224         }
1225
1226         /* show where to write */
1227 #ifdef CMX_DEBUG
1228         printk(KERN_DEBUG
1229             "cmx_receive(dsp=%lx): rx_R(dsp)=%05x rx_W(dsp)=%05x len=%d %s\n",
1230             (u_long)dsp, dsp->rx_R, dsp->rx_W, len, dsp->name);
1231 #endif
1232
1233         /* write data into rx_buffer */
1234         p = skb->data;
1235         d = dsp->rx_buff;
1236         w = dsp->rx_W;
1237         i = 0;
1238         ii = len;
1239         while (i < ii) {
1240                 d[w++ & CMX_BUFF_MASK] = *p++;
1241                 i++;
1242         }
1243
1244         /* increase write-pointer */
1245         dsp->rx_W = ((dsp->rx_W+len) & CMX_BUFF_MASK);
1246 }
1247
1248
1249 /*
1250  * send (mixed) audio data to card and control jitter
1251  */
1252 static void
1253 dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
1254 {
1255         struct dsp_conf *conf = dsp->conf;
1256         struct dsp *member, *other;
1257         register s32 sample;
1258         u8 *d, *p, *q, *o_q;
1259         struct sk_buff *nskb, *txskb;
1260         int r, rr, t, tt, o_r, o_rr;
1261         int preload = 0;
1262         struct mISDNhead *hh, *thh;
1263
1264         /* don't process if: */
1265         if (!dsp->b_active) { /* if not active */
1266                 dsp->last_tx = 0;
1267                 return;
1268         }
1269         if (dsp->pcm_slot_tx >= 0 && /* connected to pcm slot */
1270             dsp->tx_R == dsp->tx_W && /* AND no tx-data */
1271             !(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */
1272                 dsp->last_tx = 0;
1273                 return;
1274         }
1275
1276 #ifdef CMX_DEBUG
1277         printk(KERN_DEBUG
1278             "SEND members=%d dsp=%s, conf=%p, rx_R=%05x rx_W=%05x\n",
1279             members, dsp->name, conf, dsp->rx_R, dsp->rx_W);
1280 #endif
1281
1282         /* preload if we have delay set */
1283         if (dsp->cmx_delay && !dsp->last_tx) {
1284                 preload = len;
1285                 if (preload < 128)
1286                         preload = 128;
1287         }
1288
1289         /* PREPARE RESULT */
1290         nskb = mI_alloc_skb(len + preload, GFP_ATOMIC);
1291         if (!nskb) {
1292                 printk(KERN_ERR
1293                     "FATAL ERROR in mISDN_dsp.o: cannot alloc %d bytes\n",
1294                     len + preload);
1295                 return;
1296         }
1297         hh = mISDN_HEAD_P(nskb);
1298         hh->prim = PH_DATA_REQ;
1299         hh->id = 0;
1300         dsp->last_tx = 1;
1301
1302         /* set pointers, indexes and stuff */
1303         member = dsp;
1304         p = dsp->tx_buff; /* transmit data */
1305         q = dsp->rx_buff; /* received data */
1306         d = skb_put(nskb, preload + len); /* result */
1307         t = dsp->tx_R; /* tx-pointers */
1308         tt = dsp->tx_W;
1309         r = dsp->rx_R; /* rx-pointers */
1310         rr = (r + len) & CMX_BUFF_MASK;
1311
1312         /* preload with silence, if required */
1313         if (preload) {
1314                 memset(d, dsp_silence, preload);
1315                 d += preload;
1316         }
1317
1318         /* PROCESS TONES/TX-DATA ONLY */
1319         if (dsp->tone.tone && dsp->tone.software) {
1320                 /* -> copy tone */
1321                 dsp_tone_copy(dsp, d, len);
1322                 dsp->tx_R = 0; /* clear tx buffer */
1323                 dsp->tx_W = 0;
1324                 goto send_packet;
1325         }
1326         /* if we have tx-data but do not use mixing */
1327         if (!dsp->tx_mix && t != tt) {
1328                 /* -> send tx-data and continue when not enough */
1329 #ifdef CMX_TX_DEBUG
1330         sprintf(debugbuf, "TX sending (%04x-%04x)%p: ", t, tt, p);
1331 #endif
1332                 while (r != rr && t != tt) {
1333 #ifdef CMX_TX_DEBUG
1334                         if (strlen(debugbuf) < 48)
1335                             sprintf(debugbuf+strlen(debugbuf), " %02x", p[t]);
1336 #endif
1337                         *d++ = p[t]; /* write tx_buff */
1338                         t = (t+1) & CMX_BUFF_MASK;
1339                         r = (r+1) & CMX_BUFF_MASK;
1340                 }
1341                 if (r == rr) {
1342                         dsp->tx_R = t;
1343 #ifdef CMX_TX_DEBUG
1344         printk(KERN_DEBUG "%s\n", debugbuf);
1345 #endif
1346                         goto send_packet;
1347                 }
1348         }
1349 #ifdef CMX_TX_DEBUG
1350         printk(KERN_DEBUG "%s\n", debugbuf);
1351 #endif
1352
1353         /* PROCESS DATA (one member / no conf) */
1354         if (!conf || members <= 1) {
1355                 /* -> if echo is NOT enabled */
1356                 if (!dsp->echo) {
1357                         /* -> send tx-data if available or use 0-volume */
1358                         while (r != rr && t != tt) {
1359                                 *d++ = p[t]; /* write tx_buff */
1360                                 t = (t+1) & CMX_BUFF_MASK;
1361                                 r = (r+1) & CMX_BUFF_MASK;
1362                         }
1363                         if (r != rr)
1364                                 memset(d, dsp_silence, (rr-r)&CMX_BUFF_MASK);
1365                 /* -> if echo is enabled */
1366                 } else {
1367                         /*
1368                          * -> mix tx-data with echo if available,
1369                          * or use echo only
1370                          */
1371                         while (r != rr && t != tt) {
1372                                 *d++ = dsp_audio_mix_law[(p[t]<<8)|q[r]];
1373                                 t = (t+1) & CMX_BUFF_MASK;
1374                                 r = (r+1) & CMX_BUFF_MASK;
1375                         }
1376                         while (r != rr) {
1377                                 *d++ = q[r]; /* echo */
1378                                 r = (r+1) & CMX_BUFF_MASK;
1379                         }
1380                 }
1381                 dsp->tx_R = t;
1382                 goto send_packet;
1383         }
1384         /* PROCESS DATA (two members) */
1385 #ifdef CMX_CONF_DEBUG
1386         if (0) {
1387 #else
1388         if (members == 2) {
1389 #endif
1390                 /* "other" becomes other party */
1391                 other = (list_entry(conf->mlist.next,
1392                     struct dsp_conf_member, list))->dsp;
1393                 if (other == member)
1394                         other = (list_entry(conf->mlist.prev,
1395                             struct dsp_conf_member, list))->dsp;
1396                 o_q = other->rx_buff; /* received data */
1397                 o_rr = (other->rx_R + len) & CMX_BUFF_MASK;
1398                         /* end of rx-pointer */
1399                 o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
1400                         /* start rx-pointer at current read position*/
1401                 /* -> if echo is NOT enabled */
1402                 if (!dsp->echo) {
1403                         /*
1404                          * -> copy other member's rx-data,
1405                          * if tx-data is available, mix
1406                          */
1407                         while (o_r != o_rr && t != tt) {
1408                                 *d++ = dsp_audio_mix_law[(p[t]<<8)|o_q[o_r]];
1409                                 t = (t+1) & CMX_BUFF_MASK;
1410                                 o_r = (o_r+1) & CMX_BUFF_MASK;
1411                         }
1412                         while (o_r != o_rr) {
1413                                 *d++ = o_q[o_r];
1414                                 o_r = (o_r+1) & CMX_BUFF_MASK;
1415                         }
1416                 /* -> if echo is enabled */
1417                 } else {
1418                         /*
1419                          * -> mix other member's rx-data with echo,
1420                          * if tx-data is available, mix
1421                          */
1422                         while (r != rr && t != tt) {
1423                                 sample = dsp_audio_law_to_s32[p[t]] +
1424                                     dsp_audio_law_to_s32[q[r]] +
1425                                     dsp_audio_law_to_s32[o_q[o_r]];
1426                                 if (sample < -32768)
1427                                         sample = -32768;
1428                                 else if (sample > 32767)
1429                                         sample = 32767;
1430                                 *d++ = dsp_audio_s16_to_law[sample & 0xffff];
1431                                     /* tx-data + rx_data + echo */
1432                                 t = (t+1) & CMX_BUFF_MASK;
1433                                 r = (r+1) & CMX_BUFF_MASK;
1434                                 o_r = (o_r+1) & CMX_BUFF_MASK;
1435                         }
1436                         while (r != rr) {
1437                                 *d++ = dsp_audio_mix_law[(q[r]<<8)|o_q[o_r]];
1438                                 r = (r+1) & CMX_BUFF_MASK;
1439                                 o_r = (o_r+1) & CMX_BUFF_MASK;
1440                         }
1441                 }
1442                 dsp->tx_R = t;
1443                 goto send_packet;
1444         }
1445 #ifdef DSP_NEVER_DEFINED
1446         }
1447 #endif
1448         /* PROCESS DATA (three or more members) */
1449         /* -> if echo is NOT enabled */
1450         if (!dsp->echo) {
1451                 /*
1452                  * -> substract rx-data from conf-data,
1453                  * if tx-data is available, mix
1454                  */
1455                 while (r != rr && t != tt) {
1456                         sample = dsp_audio_law_to_s32[p[t]] + *c++ -
1457                             dsp_audio_law_to_s32[q[r]];
1458                         if (sample < -32768)
1459                                 sample = -32768;
1460                         else if (sample > 32767)
1461                                 sample = 32767;
1462                         *d++ = dsp_audio_s16_to_law[sample & 0xffff];
1463                             /* conf-rx+tx */
1464                         r = (r+1) & CMX_BUFF_MASK;
1465                         t = (t+1) & CMX_BUFF_MASK;
1466                 }
1467                 while (r != rr) {
1468                         sample = *c++ - dsp_audio_law_to_s32[q[r]];
1469                         if (sample < -32768)
1470                                 sample = -32768;
1471                         else if (sample > 32767)
1472                                 sample = 32767;
1473                         *d++ = dsp_audio_s16_to_law[sample & 0xffff];
1474                             /* conf-rx */
1475                         r = (r+1) & CMX_BUFF_MASK;
1476                 }
1477         /* -> if echo is enabled */
1478         } else {
1479                 /*
1480                  * -> encode conf-data, if tx-data
1481                  * is available, mix
1482                  */
1483                 while (r != rr && t != tt) {
1484                         sample = dsp_audio_law_to_s32[p[t]] + *c++;
1485                         if (sample < -32768)
1486                                 sample = -32768;
1487                         else if (sample > 32767)
1488                                 sample = 32767;
1489                         *d++ = dsp_audio_s16_to_law[sample & 0xffff];
1490                             /* conf(echo)+tx */
1491                         t = (t+1) & CMX_BUFF_MASK;
1492                         r = (r+1) & CMX_BUFF_MASK;
1493                 }
1494                 while (r != rr) {
1495                         sample = *c++;
1496                         if (sample < -32768)
1497                                 sample = -32768;
1498                         else if (sample > 32767)
1499                                 sample = 32767;
1500                         *d++ = dsp_audio_s16_to_law[sample & 0xffff];
1501                             /* conf(echo) */
1502                         r = (r+1) & CMX_BUFF_MASK;
1503                 }
1504         }
1505         dsp->tx_R = t;
1506         goto send_packet;
1507
1508 send_packet:
1509         /*
1510          * send tx-data if enabled - don't filter,
1511          * becuase we want what we send, not what we filtered
1512          */
1513         if (dsp->tx_data) {
1514                 /* PREPARE RESULT */
1515                 txskb = mI_alloc_skb(len, GFP_ATOMIC);
1516                 if (!txskb) {
1517                         printk(KERN_ERR
1518                             "FATAL ERROR in mISDN_dsp.o: "
1519                             "cannot alloc %d bytes\n", len);
1520                 } else {
1521                         thh = mISDN_HEAD_P(txskb);
1522                         thh->prim = DL_DATA_REQ;
1523                         thh->id = 0;
1524                         memcpy(skb_put(txskb, len), nskb->data+preload, len);
1525                         /* queue (trigger later) */
1526                         skb_queue_tail(&dsp->sendq, txskb);
1527                 }
1528         }
1529         /* adjust volume */
1530         if (dsp->tx_volume)
1531                 dsp_change_volume(nskb, dsp->tx_volume);
1532         /* pipeline */
1533         if (dsp->pipeline.inuse)
1534                 dsp_pipeline_process_tx(&dsp->pipeline, nskb->data, nskb->len);
1535         /* crypt */
1536         if (dsp->bf_enable)
1537                 dsp_bf_encrypt(dsp, nskb->data, nskb->len);
1538         /* queue and trigger */
1539         skb_queue_tail(&dsp->sendq, nskb);
1540         schedule_work(&dsp->workq);
1541 }
1542
1543 static u32      samplecount;
1544 struct timer_list dsp_spl_tl;
1545 u32     dsp_spl_jiffies; /* calculate the next time to fire */
1546 #ifdef UNUSED
1547 static u32      dsp_start_jiffies; /* jiffies at the time, the calculation begins */
1548 #endif /* UNUSED */
1549 static struct timeval dsp_start_tv; /* time at start of calculation */
1550
1551 void
1552 dsp_cmx_send(void *arg)
1553 {
1554         struct dsp_conf *conf;
1555         struct dsp_conf_member *member;
1556         struct dsp *dsp;
1557         int mustmix, members;
1558         s32 mixbuffer[MAX_POLL+100], *c;
1559         u8 *p, *q;
1560         int r, rr;
1561         int jittercheck = 0, delay, i;
1562         u_long flags;
1563         struct timeval tv;
1564         u32 elapsed;
1565         s16 length;
1566
1567         /* lock */
1568         spin_lock_irqsave(&dsp_lock, flags);
1569
1570         if (!dsp_start_tv.tv_sec) {
1571                 do_gettimeofday(&dsp_start_tv);
1572                 length = dsp_poll;
1573         } else {
1574                 do_gettimeofday(&tv);
1575                 elapsed = ((tv.tv_sec - dsp_start_tv.tv_sec) * 8000)
1576                     + ((s32)(tv.tv_usec / 125) - (dsp_start_tv.tv_usec / 125));
1577                 dsp_start_tv.tv_sec = tv.tv_sec;
1578                 dsp_start_tv.tv_usec = tv.tv_usec;
1579                 length = elapsed;
1580         }
1581         if (length > MAX_POLL + 100)
1582                 length = MAX_POLL + 100;
1583 /* printk(KERN_DEBUG "len=%d dsp_count=0x%x.%04x dsp_poll_diff=0x%x.%04x\n",
1584  length, dsp_count >> 16, dsp_count & 0xffff, dsp_poll_diff >> 16,
1585  dsp_poll_diff & 0xffff);
1586  */
1587
1588         /*
1589          * check if jitter needs to be checked
1590          * (this is about every second = 8192 samples)
1591          */
1592         samplecount += length;
1593         if ((samplecount & 8191) < length)
1594                 jittercheck = 1;
1595
1596         /* loop all members that do not require conference mixing */
1597         list_for_each_entry(dsp, &dsp_ilist, list) {
1598                 if (dsp->hdlc)
1599                         continue;
1600                 conf = dsp->conf;
1601                 mustmix = 0;
1602                 members = 0;
1603                 if (conf) {
1604                         members = count_list_member(&conf->mlist);
1605 #ifdef CMX_CONF_DEBUG
1606                         if (conf->software && members > 1)
1607 #else
1608                         if (conf->software && members > 2)
1609 #endif
1610                                 mustmix = 1;
1611                 }
1612
1613                 /* transmission required */
1614                 if (!mustmix) {
1615                         dsp_cmx_send_member(dsp, length, mixbuffer, members);
1616
1617                         /*
1618                          * unused mixbuffer is given to prevent a
1619                          * potential null-pointer-bug
1620                          */
1621                 }
1622         }
1623
1624         /* loop all members that require conference mixing */
1625         list_for_each_entry(conf, &conf_ilist, list) {
1626                 /* count members and check hardware */
1627                 members = count_list_member(&conf->mlist);
1628 #ifdef CMX_CONF_DEBUG
1629                 if (conf->software && members > 1) {
1630 #else
1631                 if (conf->software && members > 2) {
1632 #endif
1633                         /* check for hdlc conf */
1634                         member = list_entry(conf->mlist.next,
1635                                 struct dsp_conf_member, list);
1636                         if (member->dsp->hdlc)
1637                                 continue;
1638                         /* mix all data */
1639                         memset(mixbuffer, 0, length*sizeof(s32));
1640                         list_for_each_entry(member, &conf->mlist, list) {
1641                                 dsp = member->dsp;
1642                                 /* get range of data to mix */
1643                                 c = mixbuffer;
1644                                 q = dsp->rx_buff;
1645                                 r = dsp->rx_R;
1646                                 rr = (r + length) & CMX_BUFF_MASK;
1647                                 /* add member's data */
1648                                 while (r != rr) {
1649                                         *c++ += dsp_audio_law_to_s32[q[r]];
1650                                         r = (r+1) & CMX_BUFF_MASK;
1651                                 }
1652                         }
1653
1654                         /* process each member */
1655                         list_for_each_entry(member, &conf->mlist, list) {
1656                                 /* transmission */
1657                                 dsp_cmx_send_member(member->dsp, length,
1658                                     mixbuffer, members);
1659                         }
1660                 }
1661         }
1662
1663         /* delete rx-data, increment buffers, change pointers */
1664         list_for_each_entry(dsp, &dsp_ilist, list) {
1665                 if (dsp->hdlc)
1666                         continue;
1667                 p = dsp->rx_buff;
1668                 q = dsp->tx_buff;
1669                 r = dsp->rx_R;
1670                 /* move receive pointer when receiving */
1671                 if (!dsp->rx_is_off) {
1672                         rr = (r + length) & CMX_BUFF_MASK;
1673                         /* delete rx-data */
1674                         while (r != rr) {
1675                                 p[r] = dsp_silence;
1676                                 r = (r+1) & CMX_BUFF_MASK;
1677                         }
1678                         /* increment rx-buffer pointer */
1679                         dsp->rx_R = r; /* write incremented read pointer */
1680                 }
1681
1682                 /* check current rx_delay */
1683                 delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK;
1684                 if (delay >= CMX_BUFF_HALF)
1685                         delay = 0; /* will be the delay before next write */
1686                 /* check for lower delay */
1687                 if (delay < dsp->rx_delay[0])
1688                         dsp->rx_delay[0] = delay;
1689                 /* check current tx_delay */
1690                 delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK;
1691                 if (delay >= CMX_BUFF_HALF)
1692                         delay = 0; /* will be the delay before next write */
1693                 /* check for lower delay */
1694                 if (delay < dsp->tx_delay[0])
1695                         dsp->tx_delay[0] = delay;
1696                 if (jittercheck) {
1697                         /* find the lowest of all rx_delays */
1698                         delay = dsp->rx_delay[0];
1699                         i = 1;
1700                         while (i < MAX_SECONDS_JITTER_CHECK) {
1701                                 if (delay > dsp->rx_delay[i])
1702                                         delay = dsp->rx_delay[i];
1703                                 i++;
1704                         }
1705                         /*
1706                          * remove rx_delay only if we have delay AND we
1707                          * have not preset cmx_delay
1708                          */
1709                         if (delay && !dsp->cmx_delay) {
1710                                 if (dsp_debug & DEBUG_DSP_CMX)
1711                                         printk(KERN_DEBUG
1712                                             "%s lowest rx_delay of %d bytes for"
1713                                             " dsp %s are now removed.\n",
1714                                             __func__, delay,
1715                                             dsp->name);
1716                                 r = dsp->rx_R;
1717                                 rr = (r + delay) & CMX_BUFF_MASK;
1718                                 /* delete rx-data */
1719                                 while (r != rr) {
1720                                         p[r] = dsp_silence;
1721                                         r = (r+1) & CMX_BUFF_MASK;
1722                                 }
1723                                 /* increment rx-buffer pointer */
1724                                 dsp->rx_R = r;
1725                                     /* write incremented read pointer */
1726                         }
1727                         /* find the lowest of all tx_delays */
1728                         delay = dsp->tx_delay[0];
1729                         i = 1;
1730                         while (i < MAX_SECONDS_JITTER_CHECK) {
1731                                 if (delay > dsp->tx_delay[i])
1732                                         delay = dsp->tx_delay[i];
1733                                 i++;
1734                         }
1735                         /*
1736                          * remove delay only if we have delay AND we
1737                          * have enabled tx_dejitter
1738                          */
1739                         if (delay && dsp->tx_dejitter) {
1740                                 if (dsp_debug & DEBUG_DSP_CMX)
1741                                         printk(KERN_DEBUG
1742                                             "%s lowest tx_delay of %d bytes for"
1743                                             " dsp %s are now removed.\n",
1744                                             __func__, delay,
1745                                             dsp->name);
1746                                 r = dsp->tx_R;
1747                                 rr = (r + delay) & CMX_BUFF_MASK;
1748                                 /* delete tx-data */
1749                                 while (r != rr) {
1750                                         q[r] = dsp_silence;
1751                                         r = (r+1) & CMX_BUFF_MASK;
1752                                 }
1753                                 /* increment rx-buffer pointer */
1754                                 dsp->tx_R = r;
1755                                     /* write incremented read pointer */
1756                         }
1757                         /* scroll up delays */
1758                         i = MAX_SECONDS_JITTER_CHECK - 1;
1759                         while (i) {
1760                                 dsp->rx_delay[i] = dsp->rx_delay[i-1];
1761                                 dsp->tx_delay[i] = dsp->tx_delay[i-1];
1762                                 i--;
1763                         }
1764                         dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
1765                         dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
1766                 }
1767         }
1768
1769         /* if next event would be in the past ... */
1770         if ((s32)(dsp_spl_jiffies+dsp_tics-jiffies) <= 0)
1771                 dsp_spl_jiffies = jiffies + 1;
1772         else
1773                 dsp_spl_jiffies += dsp_tics;
1774
1775         dsp_spl_tl.expires = dsp_spl_jiffies;
1776         add_timer(&dsp_spl_tl);
1777
1778         /* unlock */
1779         spin_unlock_irqrestore(&dsp_lock, flags);
1780 }
1781
1782 /*
1783  * audio data is transmitted from upper layer to the dsp
1784  */
1785 void
1786 dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb)
1787 {
1788         u_int w, ww;
1789         u8 *d, *p;
1790         int space; /* todo: , l = skb->len; */
1791 #ifdef CMX_TX_DEBUG
1792         char debugbuf[256] = "";
1793 #endif
1794
1795         /* check if there is enough space, and then copy */
1796         w = dsp->tx_W;
1797         ww = dsp->tx_R;
1798         p = dsp->tx_buff;
1799         d = skb->data;
1800         space = ww-w;
1801         if (space <= 0)
1802                 space += CMX_BUFF_SIZE;
1803         /* write-pointer should not overrun nor reach read pointer */
1804         if (space-1 < skb->len)
1805                 /* write to the space we have left */
1806                 ww = (ww - 1) & CMX_BUFF_MASK;
1807         else
1808                 /* write until all byte are copied */
1809                 ww = (w + skb->len) & CMX_BUFF_MASK;
1810         dsp->tx_W = ww;
1811
1812         /* show current buffer */
1813 #ifdef CMX_DEBUG
1814         printk(KERN_DEBUG
1815             "cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n",
1816             (u_long)dsp, (ww-w)&CMX_BUFF_MASK, w, ww, dsp->name);
1817 #endif
1818
1819         /* copy transmit data to tx-buffer */
1820 #ifdef CMX_TX_DEBUG
1821         sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p);
1822 #endif
1823         while (w != ww) {
1824 #ifdef CMX_TX_DEBUG
1825                 if (strlen(debugbuf) < 48)
1826                         sprintf(debugbuf+strlen(debugbuf), " %02x", *d);
1827 #endif
1828                 p[w] = *d++;
1829                 w = (w+1) & CMX_BUFF_MASK;
1830         }
1831 #ifdef CMX_TX_DEBUG
1832         printk(KERN_DEBUG "%s\n", debugbuf);
1833 #endif
1834
1835 }
1836
1837 /*
1838  * hdlc data is received from card and sent to all members.
1839  */
1840 void
1841 dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
1842 {
1843         struct sk_buff *nskb = NULL;
1844         struct dsp_conf_member *member;
1845         struct mISDNhead *hh;
1846
1847         /* not if not active */
1848         if (!dsp->b_active)
1849                 return;
1850
1851         /* check if we have sompen */
1852         if (skb->len < 1)
1853                 return;
1854
1855         /* no conf */
1856         if (!dsp->conf) {
1857                 /* in case of hardware (echo) */
1858                 if (dsp->pcm_slot_tx >= 0)
1859                         return;
1860                 if (dsp->echo)
1861                         nskb = skb_clone(skb, GFP_ATOMIC);
1862                         if (nskb) {
1863                                 hh = mISDN_HEAD_P(nskb);
1864                                 hh->prim = PH_DATA_REQ;
1865                                 hh->id = 0;
1866                                 skb_queue_tail(&dsp->sendq, nskb);
1867                                 schedule_work(&dsp->workq);
1868                         }
1869                 return;
1870         }
1871         /* in case of hardware conference */
1872         if (dsp->conf->hardware)
1873                 return;
1874         list_for_each_entry(member, &dsp->conf->mlist, list) {
1875                 if (dsp->echo || member->dsp != dsp) {
1876                         nskb = skb_clone(skb, GFP_ATOMIC);
1877                         if (nskb) {
1878                                 hh = mISDN_HEAD_P(nskb);
1879                                 hh->prim = PH_DATA_REQ;
1880                                 hh->id = 0;
1881                                 skb_queue_tail(&member->dsp->sendq, nskb);
1882                                 schedule_work(&member->dsp->workq);
1883                         }
1884                 }
1885         }
1886 }
1887
1888