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