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