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