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