1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156#include <linux/delay.h>
157#include <linux/mISDNif.h>
158#include <linux/mISDNdsp.h>
159#include <linux/module.h>
160#include <linux/vmalloc.h>
161#include "core.h"
162#include "dsp.h"
163
164static const char *mISDN_dsp_revision = "2.0";
165
166static int debug;
167static int options;
168static int poll;
169static int dtmfthreshold = 100;
170
171MODULE_AUTHOR("Andreas Eversberg");
172module_param(debug, uint, S_IRUGO | S_IWUSR);
173module_param(options, uint, S_IRUGO | S_IWUSR);
174module_param(poll, uint, S_IRUGO | S_IWUSR);
175module_param(dtmfthreshold, uint, S_IRUGO | S_IWUSR);
176MODULE_LICENSE("GPL");
177
178
179
180spinlock_t dsp_lock;
181struct list_head dsp_ilist;
182struct list_head conf_ilist;
183int dsp_debug;
184int dsp_options;
185int dsp_poll, dsp_tics;
186
187
188static void
189dsp_rx_off_member(struct dsp *dsp)
190{
191 struct mISDN_ctrl_req cq;
192 int rx_off = 1;
193
194 memset(&cq, 0, sizeof(cq));
195
196 if (!dsp->features_rx_off)
197 return;
198
199
200 if (!dsp->rx_disabled)
201 rx_off = 0;
202
203 else if (dsp->dtmf.software)
204 rx_off = 0;
205
206 else if (dsp->echo.software)
207 rx_off = 0;
208
209 else if (dsp->conf && dsp->conf->software)
210 rx_off = 0;
211
212
213
214 if (rx_off == dsp->rx_is_off)
215 return;
216
217 if (!dsp->ch.peer) {
218 if (dsp_debug & DEBUG_DSP_CORE)
219 printk(KERN_DEBUG "%s: no peer, no rx_off\n",
220 __func__);
221 return;
222 }
223 cq.op = MISDN_CTRL_RX_OFF;
224 cq.p1 = rx_off;
225 if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
226 printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n",
227 __func__);
228 return;
229 }
230 dsp->rx_is_off = rx_off;
231 if (dsp_debug & DEBUG_DSP_CORE)
232 printk(KERN_DEBUG "%s: %s set rx_off = %d\n",
233 __func__, dsp->name, rx_off);
234}
235static void
236dsp_rx_off(struct dsp *dsp)
237{
238 struct dsp_conf_member *member;
239
240 if (dsp_options & DSP_OPT_NOHARDWARE)
241 return;
242
243
244 if (!dsp->conf) {
245 dsp_rx_off_member(dsp);
246 return;
247 }
248
249 list_for_each_entry(member, &dsp->conf->mlist, list) {
250 dsp_rx_off_member(member->dsp);
251 }
252}
253
254
255static void
256dsp_fill_empty(struct dsp *dsp)
257{
258 struct mISDN_ctrl_req cq;
259
260 memset(&cq, 0, sizeof(cq));
261
262 if (!dsp->ch.peer) {
263 if (dsp_debug & DEBUG_DSP_CORE)
264 printk(KERN_DEBUG "%s: no peer, no fill_empty\n",
265 __func__);
266 return;
267 }
268 cq.op = MISDN_CTRL_FILL_EMPTY;
269 cq.p1 = 1;
270 if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
271 printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
272 __func__);
273 return;
274 }
275 if (dsp_debug & DEBUG_DSP_CORE)
276 printk(KERN_DEBUG "%s: %s set fill_empty = 1\n",
277 __func__, dsp->name);
278}
279
280static int
281dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
282{
283 struct sk_buff *nskb;
284 int ret = 0;
285 int cont;
286 u8 *data;
287 int len;
288
289 if (skb->len < sizeof(int))
290 printk(KERN_ERR "%s: PH_CONTROL message too short\n", __func__);
291 cont = *((int *)skb->data);
292 len = skb->len - sizeof(int);
293 data = skb->data + sizeof(int);
294
295 switch (cont) {
296 case DTMF_TONE_START:
297 if (dsp->hdlc) {
298 ret = -EINVAL;
299 break;
300 }
301 if (dsp_debug & DEBUG_DSP_CORE)
302 printk(KERN_DEBUG "%s: start dtmf\n", __func__);
303 if (len == sizeof(int)) {
304 if (dsp_debug & DEBUG_DSP_CORE)
305 printk(KERN_NOTICE "changing DTMF Threshold "
306 "to %d\n", *((int *)data));
307 dsp->dtmf.treshold = (*(int *)data) * 10000;
308 }
309 dsp->dtmf.enable = 1;
310
311 dsp_dtmf_goertzel_init(dsp);
312
313
314 dsp_dtmf_hardware(dsp);
315 dsp_rx_off(dsp);
316 break;
317 case DTMF_TONE_STOP:
318 if (dsp_debug & DEBUG_DSP_CORE)
319 printk(KERN_DEBUG "%s: stop dtmf\n", __func__);
320 dsp->dtmf.enable = 0;
321 dsp->dtmf.hardware = 0;
322 dsp->dtmf.software = 0;
323 break;
324 case DSP_CONF_JOIN:
325 if (len < sizeof(int)) {
326 ret = -EINVAL;
327 break;
328 }
329 if (*((u32 *)data) == 0)
330 goto conf_split;
331 if (dsp_debug & DEBUG_DSP_CORE)
332 printk(KERN_DEBUG "%s: join conference %d\n",
333 __func__, *((u32 *)data));
334 ret = dsp_cmx_conf(dsp, *((u32 *)data));
335
336 dsp_rx_off(dsp);
337 if (dsp_debug & DEBUG_DSP_CMX)
338 dsp_cmx_debug(dsp);
339 break;
340 case DSP_CONF_SPLIT:
341conf_split:
342 if (dsp_debug & DEBUG_DSP_CORE)
343 printk(KERN_DEBUG "%s: release conference\n", __func__);
344 ret = dsp_cmx_conf(dsp, 0);
345
346 if (dsp_debug & DEBUG_DSP_CMX)
347 dsp_cmx_debug(dsp);
348 dsp_rx_off(dsp);
349 break;
350 case DSP_TONE_PATT_ON:
351 if (dsp->hdlc) {
352 ret = -EINVAL;
353 break;
354 }
355 if (len < sizeof(int)) {
356 ret = -EINVAL;
357 break;
358 }
359 if (dsp_debug & DEBUG_DSP_CORE)
360 printk(KERN_DEBUG "%s: turn tone 0x%x on\n",
361 __func__, *((int *)skb->data));
362 ret = dsp_tone(dsp, *((int *)data));
363 if (!ret) {
364 dsp_cmx_hardware(dsp->conf, dsp);
365 dsp_rx_off(dsp);
366 }
367 if (!dsp->tone.tone)
368 goto tone_off;
369 break;
370 case DSP_TONE_PATT_OFF:
371 if (dsp->hdlc) {
372 ret = -EINVAL;
373 break;
374 }
375 if (dsp_debug & DEBUG_DSP_CORE)
376 printk(KERN_DEBUG "%s: turn tone off\n", __func__);
377 dsp_tone(dsp, 0);
378 dsp_cmx_hardware(dsp->conf, dsp);
379 dsp_rx_off(dsp);
380
381tone_off:
382 dsp->rx_W = 0;
383 dsp->rx_R = 0;
384 break;
385 case DSP_VOL_CHANGE_TX:
386 if (dsp->hdlc) {
387 ret = -EINVAL;
388 break;
389 }
390 if (len < sizeof(int)) {
391 ret = -EINVAL;
392 break;
393 }
394 dsp->tx_volume = *((int *)data);
395 if (dsp_debug & DEBUG_DSP_CORE)
396 printk(KERN_DEBUG "%s: change tx vol to %d\n",
397 __func__, dsp->tx_volume);
398 dsp_cmx_hardware(dsp->conf, dsp);
399 dsp_dtmf_hardware(dsp);
400 dsp_rx_off(dsp);
401 break;
402 case DSP_VOL_CHANGE_RX:
403 if (dsp->hdlc) {
404 ret = -EINVAL;
405 break;
406 }
407 if (len < sizeof(int)) {
408 ret = -EINVAL;
409 break;
410 }
411 dsp->rx_volume = *((int *)data);
412 if (dsp_debug & DEBUG_DSP_CORE)
413 printk(KERN_DEBUG "%s: change rx vol to %d\n",
414 __func__, dsp->tx_volume);
415 dsp_cmx_hardware(dsp->conf, dsp);
416 dsp_dtmf_hardware(dsp);
417 dsp_rx_off(dsp);
418 break;
419 case DSP_ECHO_ON:
420 dsp->echo.software = 1;
421 if (dsp_debug & DEBUG_DSP_CORE)
422 printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__);
423 dsp_cmx_hardware(dsp->conf, dsp);
424 dsp_rx_off(dsp);
425 if (dsp_debug & DEBUG_DSP_CMX)
426 dsp_cmx_debug(dsp);
427 break;
428 case DSP_ECHO_OFF:
429 dsp->echo.software = 0;
430 dsp->echo.hardware = 0;
431 if (dsp_debug & DEBUG_DSP_CORE)
432 printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__);
433 dsp_cmx_hardware(dsp->conf, dsp);
434 dsp_rx_off(dsp);
435 if (dsp_debug & DEBUG_DSP_CMX)
436 dsp_cmx_debug(dsp);
437 break;
438 case DSP_RECEIVE_ON:
439 if (dsp_debug & DEBUG_DSP_CORE)
440 printk(KERN_DEBUG "%s: enable receive to user "
441 "space\n", __func__);
442 dsp->rx_disabled = 0;
443 dsp_rx_off(dsp);
444 break;
445 case DSP_RECEIVE_OFF:
446 if (dsp_debug & DEBUG_DSP_CORE)
447 printk(KERN_DEBUG "%s: disable receive to "
448 "user space\n", __func__);
449 dsp->rx_disabled = 1;
450 dsp_rx_off(dsp);
451 break;
452 case DSP_MIX_ON:
453 if (dsp->hdlc) {
454 ret = -EINVAL;
455 break;
456 }
457 if (dsp_debug & DEBUG_DSP_CORE)
458 printk(KERN_DEBUG "%s: enable mixing of "
459 "tx-data with conf mebers\n", __func__);
460 dsp->tx_mix = 1;
461 dsp_cmx_hardware(dsp->conf, dsp);
462 dsp_rx_off(dsp);
463 if (dsp_debug & DEBUG_DSP_CMX)
464 dsp_cmx_debug(dsp);
465 break;
466 case DSP_MIX_OFF:
467 if (dsp->hdlc) {
468 ret = -EINVAL;
469 break;
470 }
471 if (dsp_debug & DEBUG_DSP_CORE)
472 printk(KERN_DEBUG "%s: disable mixing of "
473 "tx-data with conf mebers\n", __func__);
474 dsp->tx_mix = 0;
475 dsp_cmx_hardware(dsp->conf, dsp);
476 dsp_rx_off(dsp);
477 if (dsp_debug & DEBUG_DSP_CMX)
478 dsp_cmx_debug(dsp);
479 break;
480 case DSP_TXDATA_ON:
481 dsp->tx_data = 1;
482 if (dsp_debug & DEBUG_DSP_CORE)
483 printk(KERN_DEBUG "%s: enable tx-data\n", __func__);
484 dsp_cmx_hardware(dsp->conf, dsp);
485 dsp_rx_off(dsp);
486 if (dsp_debug & DEBUG_DSP_CMX)
487 dsp_cmx_debug(dsp);
488 break;
489 case DSP_TXDATA_OFF:
490 dsp->tx_data = 0;
491 if (dsp_debug & DEBUG_DSP_CORE)
492 printk(KERN_DEBUG "%s: disable tx-data\n", __func__);
493 dsp_cmx_hardware(dsp->conf, dsp);
494 dsp_rx_off(dsp);
495 if (dsp_debug & DEBUG_DSP_CMX)
496 dsp_cmx_debug(dsp);
497 break;
498 case DSP_DELAY:
499
500 if (dsp->hdlc) {
501 ret = -EINVAL;
502 break;
503 }
504 if (len < sizeof(int)) {
505 ret = -EINVAL;
506 break;
507 }
508 dsp->cmx_delay = (*((int *)data)) << 3;
509
510 if (dsp->cmx_delay >= (CMX_BUFF_HALF>>1))
511
512
513 dsp->cmx_delay = (CMX_BUFF_HALF>>1) - 1;
514 if (dsp_debug & DEBUG_DSP_CORE)
515 printk(KERN_DEBUG "%s: use delay algorithm to "
516 "compensate jitter (%d samples)\n",
517 __func__, dsp->cmx_delay);
518 break;
519 case DSP_JITTER:
520
521 if (dsp->hdlc) {
522 ret = -EINVAL;
523 break;
524 }
525 dsp->cmx_delay = 0;
526 if (dsp_debug & DEBUG_DSP_CORE)
527 printk(KERN_DEBUG "%s: use jitter algorithm to "
528 "compensate jitter\n", __func__);
529 break;
530 case DSP_TX_DEJITTER:
531 if (dsp->hdlc) {
532 ret = -EINVAL;
533 break;
534 }
535 dsp->tx_dejitter = 1;
536 if (dsp_debug & DEBUG_DSP_CORE)
537 printk(KERN_DEBUG "%s: use dejitter on TX "
538 "buffer\n", __func__);
539 break;
540 case DSP_TX_DEJ_OFF:
541 if (dsp->hdlc) {
542 ret = -EINVAL;
543 break;
544 }
545 dsp->tx_dejitter = 0;
546 if (dsp_debug & DEBUG_DSP_CORE)
547 printk(KERN_DEBUG "%s: use TX buffer without "
548 "dejittering\n", __func__);
549 break;
550 case DSP_PIPELINE_CFG:
551 if (dsp->hdlc) {
552 ret = -EINVAL;
553 break;
554 }
555 if (len > 0 && ((char *)data)[len - 1]) {
556 printk(KERN_DEBUG "%s: pipeline config string "
557 "is not NULL terminated!\n", __func__);
558 ret = -EINVAL;
559 } else {
560 dsp->pipeline.inuse = 1;
561 dsp_cmx_hardware(dsp->conf, dsp);
562 ret = dsp_pipeline_build(&dsp->pipeline,
563 len > 0 ? data : NULL);
564 dsp_cmx_hardware(dsp->conf, dsp);
565 dsp_rx_off(dsp);
566 }
567 break;
568 case DSP_BF_ENABLE_KEY:
569 if (dsp->hdlc) {
570 ret = -EINVAL;
571 break;
572 }
573 if (len < 4 || len > 56) {
574 ret = -EINVAL;
575 break;
576 }
577 if (dsp_debug & DEBUG_DSP_CORE)
578 printk(KERN_DEBUG "%s: turn blowfish on (key "
579 "not shown)\n", __func__);
580 ret = dsp_bf_init(dsp, (u8 *)data, len);
581
582 if (!ret)
583 cont = DSP_BF_ACCEPT;
584 else
585 cont = DSP_BF_REJECT;
586
587 nskb = _alloc_mISDN_skb(PH_CONTROL_IND, MISDN_ID_ANY,
588 sizeof(int), &cont, GFP_ATOMIC);
589 if (nskb) {
590 if (dsp->up) {
591 if (dsp->up->send(dsp->up, nskb))
592 dev_kfree_skb(nskb);
593 } else
594 dev_kfree_skb(nskb);
595 }
596 if (!ret) {
597 dsp_cmx_hardware(dsp->conf, dsp);
598 dsp_dtmf_hardware(dsp);
599 dsp_rx_off(dsp);
600 }
601 break;
602 case DSP_BF_DISABLE:
603 if (dsp->hdlc) {
604 ret = -EINVAL;
605 break;
606 }
607 if (dsp_debug & DEBUG_DSP_CORE)
608 printk(KERN_DEBUG "%s: turn blowfish off\n", __func__);
609 dsp_bf_cleanup(dsp);
610 dsp_cmx_hardware(dsp->conf, dsp);
611 dsp_dtmf_hardware(dsp);
612 dsp_rx_off(dsp);
613 break;
614 default:
615 if (dsp_debug & DEBUG_DSP_CORE)
616 printk(KERN_DEBUG "%s: ctrl req %x unhandled\n",
617 __func__, cont);
618 ret = -EINVAL;
619 }
620 return ret;
621}
622
623static void
624get_features(struct mISDNchannel *ch)
625{
626 struct dsp *dsp = container_of(ch, struct dsp, ch);
627 struct mISDN_ctrl_req cq;
628
629 if (!ch->peer) {
630 if (dsp_debug & DEBUG_DSP_CORE)
631 printk(KERN_DEBUG "%s: no peer, no features\n",
632 __func__);
633 return;
634 }
635 memset(&cq, 0, sizeof(cq));
636 cq.op = MISDN_CTRL_GETOP;
637 if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq) < 0) {
638 printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
639 __func__);
640 return;
641 }
642 if (cq.op & MISDN_CTRL_RX_OFF)
643 dsp->features_rx_off = 1;
644 if (cq.op & MISDN_CTRL_FILL_EMPTY)
645 dsp->features_fill_empty = 1;
646 if (dsp_options & DSP_OPT_NOHARDWARE)
647 return;
648 if ((cq.op & MISDN_CTRL_HW_FEATURES_OP)) {
649 cq.op = MISDN_CTRL_HW_FEATURES;
650 *((u_long *)&cq.p1) = (u_long)&dsp->features;
651 if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq)) {
652 printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n",
653 __func__);
654 }
655 } else
656 if (dsp_debug & DEBUG_DSP_CORE)
657 printk(KERN_DEBUG "%s: features not supported for %s\n",
658 __func__, dsp->name);
659}
660
661static int
662dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
663{
664 struct dsp *dsp = container_of(ch, struct dsp, ch);
665 struct mISDNhead *hh;
666 int ret = 0;
667 u8 *digits = NULL;
668 u_long flags;
669
670 hh = mISDN_HEAD_P(skb);
671 switch (hh->prim) {
672
673 case (PH_DATA_CNF):
674 dsp->data_pending = 0;
675
676 if (dsp->hdlc) {
677 spin_lock_irqsave(&dsp_lock, flags);
678 if (dsp->b_active)
679 schedule_work(&dsp->workq);
680 spin_unlock_irqrestore(&dsp_lock, flags);
681 }
682 break;
683 case (PH_DATA_IND):
684 case (DL_DATA_IND):
685 if (skb->len < 1) {
686 ret = -EINVAL;
687 break;
688 }
689 if (dsp->rx_is_off) {
690 if (dsp_debug & DEBUG_DSP_CORE)
691 printk(KERN_DEBUG "%s: rx-data during rx_off"
692 " for %s\n",
693 __func__, dsp->name);
694 }
695 if (dsp->hdlc) {
696
697 spin_lock_irqsave(&dsp_lock, flags);
698 dsp_cmx_hdlc(dsp, skb);
699 spin_unlock_irqrestore(&dsp_lock, flags);
700 if (dsp->rx_disabled) {
701
702 break;
703 }
704 hh->prim = DL_DATA_IND;
705 if (dsp->up)
706 return dsp->up->send(dsp->up, skb);
707 break;
708 }
709
710 spin_lock_irqsave(&dsp_lock, flags);
711
712
713 if (dsp->bf_enable)
714 dsp_bf_decrypt(dsp, skb->data, skb->len);
715
716 if (dsp->pipeline.inuse)
717 dsp_pipeline_process_rx(&dsp->pipeline, skb->data,
718 skb->len, hh->id);
719
720 if (dsp->rx_volume)
721 dsp_change_volume(skb, dsp->rx_volume);
722
723 if (dsp->dtmf.software) {
724 digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
725 skb->len, (dsp_options&DSP_OPT_ULAW) ? 1 : 0);
726 }
727
728 if (dsp->conf && dsp->conf->software) {
729
730 dsp_cmx_receive(dsp, skb);
731 }
732
733 spin_unlock_irqrestore(&dsp_lock, flags);
734
735
736 if (digits) {
737 while (*digits) {
738 int k;
739 struct sk_buff *nskb;
740 if (dsp_debug & DEBUG_DSP_DTMF)
741 printk(KERN_DEBUG "%s: digit"
742 "(%c) to layer %s\n",
743 __func__, *digits, dsp->name);
744 k = *digits | DTMF_TONE_VAL;
745 nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
746 MISDN_ID_ANY, sizeof(int), &k,
747 GFP_ATOMIC);
748 if (nskb) {
749 if (dsp->up) {
750 if (dsp->up->send(
751 dsp->up, nskb))
752 dev_kfree_skb(nskb);
753 } else
754 dev_kfree_skb(nskb);
755 }
756 digits++;
757 }
758 }
759 if (dsp->rx_disabled) {
760
761 break;
762 }
763 hh->prim = DL_DATA_IND;
764 if (dsp->up)
765 return dsp->up->send(dsp->up, skb);
766 break;
767 case (PH_CONTROL_IND):
768 if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
769 printk(KERN_DEBUG "%s: PH_CONTROL INDICATION "
770 "received: %x (len %d) %s\n", __func__,
771 hh->id, skb->len, dsp->name);
772 switch (hh->id) {
773 case (DTMF_HFC_COEF):
774 if (!dsp->dtmf.hardware) {
775 if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
776 printk(KERN_DEBUG "%s: ignoring DTMF "
777 "coefficients from HFC\n",
778 __func__);
779 break;
780 }
781 digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
782 skb->len, 2);
783 while (*digits) {
784 int k;
785 struct sk_buff *nskb;
786 if (dsp_debug & DEBUG_DSP_DTMF)
787 printk(KERN_DEBUG "%s: digit"
788 "(%c) to layer %s\n",
789 __func__, *digits, dsp->name);
790 k = *digits | DTMF_TONE_VAL;
791 nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
792 MISDN_ID_ANY, sizeof(int), &k,
793 GFP_ATOMIC);
794 if (nskb) {
795 if (dsp->up) {
796 if (dsp->up->send(
797 dsp->up, nskb))
798 dev_kfree_skb(nskb);
799 } else
800 dev_kfree_skb(nskb);
801 }
802 digits++;
803 }
804 break;
805 case (HFC_VOL_CHANGE_TX):
806 if (skb->len != sizeof(int)) {
807 ret = -EINVAL;
808 break;
809 }
810 spin_lock_irqsave(&dsp_lock, flags);
811 dsp->tx_volume = *((int *)skb->data);
812 if (dsp_debug & DEBUG_DSP_CORE)
813 printk(KERN_DEBUG "%s: change tx volume to "
814 "%d\n", __func__, dsp->tx_volume);
815 dsp_cmx_hardware(dsp->conf, dsp);
816 dsp_dtmf_hardware(dsp);
817 dsp_rx_off(dsp);
818 spin_unlock_irqrestore(&dsp_lock, flags);
819 break;
820 default:
821 if (dsp_debug & DEBUG_DSP_CORE)
822 printk(KERN_DEBUG "%s: ctrl ind %x unhandled "
823 "%s\n", __func__, hh->id, dsp->name);
824 ret = -EINVAL;
825 }
826 break;
827 case (PH_ACTIVATE_IND):
828 case (PH_ACTIVATE_CNF):
829 if (dsp_debug & DEBUG_DSP_CORE)
830 printk(KERN_DEBUG "%s: b_channel is now active %s\n",
831 __func__, dsp->name);
832
833 spin_lock_irqsave(&dsp_lock, flags);
834 dsp->b_active = 1;
835 dsp->data_pending = 0;
836 dsp->rx_init = 1;
837
838 dsp->rx_W = 0;
839 dsp->rx_R = 0;
840 memset(dsp->rx_buff, 0, sizeof(dsp->rx_buff));
841 dsp_cmx_hardware(dsp->conf, dsp);
842 dsp_dtmf_hardware(dsp);
843 dsp_rx_off(dsp);
844 spin_unlock_irqrestore(&dsp_lock, flags);
845 if (dsp_debug & DEBUG_DSP_CORE)
846 printk(KERN_DEBUG "%s: done with activation, sending "
847 "confirm to user space. %s\n", __func__,
848 dsp->name);
849
850 hh->prim = DL_ESTABLISH_CNF;
851 if (dsp->up)
852 return dsp->up->send(dsp->up, skb);
853 break;
854 case (PH_DEACTIVATE_IND):
855 case (PH_DEACTIVATE_CNF):
856 if (dsp_debug & DEBUG_DSP_CORE)
857 printk(KERN_DEBUG "%s: b_channel is now inactive %s\n",
858 __func__, dsp->name);
859
860 spin_lock_irqsave(&dsp_lock, flags);
861 dsp->b_active = 0;
862 dsp->data_pending = 0;
863 dsp_cmx_hardware(dsp->conf, dsp);
864 dsp_rx_off(dsp);
865 spin_unlock_irqrestore(&dsp_lock, flags);
866 hh->prim = DL_RELEASE_CNF;
867 if (dsp->up)
868 return dsp->up->send(dsp->up, skb);
869 break;
870
871 case (DL_DATA_REQ):
872 case (PH_DATA_REQ):
873 if (skb->len < 1) {
874 ret = -EINVAL;
875 break;
876 }
877 if (dsp->hdlc) {
878
879 if (!dsp->b_active) {
880 ret = -EIO;
881 break;
882 }
883 hh->prim = PH_DATA_REQ;
884 spin_lock_irqsave(&dsp_lock, flags);
885 skb_queue_tail(&dsp->sendq, skb);
886 schedule_work(&dsp->workq);
887 spin_unlock_irqrestore(&dsp_lock, flags);
888 return 0;
889 }
890
891 if (!dsp->tone.tone) {
892 spin_lock_irqsave(&dsp_lock, flags);
893 dsp_cmx_transmit(dsp, skb);
894 spin_unlock_irqrestore(&dsp_lock, flags);
895 }
896 break;
897 case (PH_CONTROL_REQ):
898 spin_lock_irqsave(&dsp_lock, flags);
899 ret = dsp_control_req(dsp, hh, skb);
900 spin_unlock_irqrestore(&dsp_lock, flags);
901 break;
902 case (DL_ESTABLISH_REQ):
903 case (PH_ACTIVATE_REQ):
904 if (dsp_debug & DEBUG_DSP_CORE)
905 printk(KERN_DEBUG "%s: activating b_channel %s\n",
906 __func__, dsp->name);
907 if (dsp->dtmf.hardware || dsp->dtmf.software)
908 dsp_dtmf_goertzel_init(dsp);
909 get_features(ch);
910
911 if (dsp->features_fill_empty)
912 dsp_fill_empty(dsp);
913
914 hh->prim = PH_ACTIVATE_REQ;
915 if (ch->peer)
916 return ch->recv(ch->peer, skb);
917 break;
918 case (DL_RELEASE_REQ):
919 case (PH_DEACTIVATE_REQ):
920 if (dsp_debug & DEBUG_DSP_CORE)
921 printk(KERN_DEBUG "%s: releasing b_channel %s\n",
922 __func__, dsp->name);
923 spin_lock_irqsave(&dsp_lock, flags);
924 dsp->tone.tone = 0;
925 dsp->tone.hardware = 0;
926 dsp->tone.software = 0;
927 if (timer_pending(&dsp->tone.tl))
928 del_timer(&dsp->tone.tl);
929 if (dsp->conf)
930 dsp_cmx_conf(dsp, 0);
931
932 skb_queue_purge(&dsp->sendq);
933 spin_unlock_irqrestore(&dsp_lock, flags);
934 hh->prim = PH_DEACTIVATE_REQ;
935 if (ch->peer)
936 return ch->recv(ch->peer, skb);
937 break;
938 default:
939 if (dsp_debug & DEBUG_DSP_CORE)
940 printk(KERN_DEBUG "%s: msg %x unhandled %s\n",
941 __func__, hh->prim, dsp->name);
942 ret = -EINVAL;
943 }
944 if (!ret)
945 dev_kfree_skb(skb);
946 return ret;
947}
948
949static int
950dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
951{
952 struct dsp *dsp = container_of(ch, struct dsp, ch);
953 u_long flags;
954 int err = 0;
955
956 if (debug & DEBUG_DSP_CTRL)
957 printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
958
959 switch (cmd) {
960 case OPEN_CHANNEL:
961 break;
962 case CLOSE_CHANNEL:
963 if (dsp->ch.peer)
964 dsp->ch.peer->ctrl(dsp->ch.peer, CLOSE_CHANNEL, NULL);
965
966
967
968
969 spin_lock_irqsave(&dsp_lock, flags);
970 dsp->b_active = 0;
971 spin_unlock_irqrestore(&dsp_lock, flags);
972
973 cancel_work_sync(&dsp->workq);
974 spin_lock_irqsave(&dsp_lock, flags);
975 if (timer_pending(&dsp->tone.tl))
976 del_timer(&dsp->tone.tl);
977 skb_queue_purge(&dsp->sendq);
978 if (dsp_debug & DEBUG_DSP_CTRL)
979 printk(KERN_DEBUG "%s: releasing member %s\n",
980 __func__, dsp->name);
981 dsp->b_active = 0;
982 dsp_cmx_conf(dsp, 0);
983
984 dsp_pipeline_destroy(&dsp->pipeline);
985
986 if (dsp_debug & DEBUG_DSP_CTRL)
987 printk(KERN_DEBUG "%s: remove & destroy object %s\n",
988 __func__, dsp->name);
989 list_del(&dsp->list);
990 spin_unlock_irqrestore(&dsp_lock, flags);
991
992 if (dsp_debug & DEBUG_DSP_CTRL)
993 printk(KERN_DEBUG "%s: dsp instance released\n",
994 __func__);
995 vfree(dsp);
996 module_put(THIS_MODULE);
997 break;
998 }
999 return err;
1000}
1001
1002static void
1003dsp_send_bh(struct work_struct *work)
1004{
1005 struct dsp *dsp = container_of(work, struct dsp, workq);
1006 struct sk_buff *skb;
1007 struct mISDNhead *hh;
1008
1009 if (dsp->hdlc && dsp->data_pending)
1010 return;
1011
1012
1013 while ((skb = skb_dequeue(&dsp->sendq))) {
1014
1015 if (dsp->data_pending) {
1016 if (dsp_debug & DEBUG_DSP_CORE)
1017 printk(KERN_DEBUG "%s: fifo full %s, this is "
1018 "no bug!\n", __func__, dsp->name);
1019
1020 dev_kfree_skb(skb);
1021 continue;
1022 }
1023 hh = mISDN_HEAD_P(skb);
1024 if (hh->prim == DL_DATA_REQ) {
1025
1026 if (dsp->up) {
1027 if (dsp->up->send(dsp->up, skb))
1028 dev_kfree_skb(skb);
1029 } else
1030 dev_kfree_skb(skb);
1031 } else {
1032
1033 if (dsp->ch.peer) {
1034 dsp->data_pending = 1;
1035 if (dsp->ch.recv(dsp->ch.peer, skb)) {
1036 dev_kfree_skb(skb);
1037 dsp->data_pending = 0;
1038 }
1039 } else
1040 dev_kfree_skb(skb);
1041 }
1042 }
1043}
1044
1045static int
1046dspcreate(struct channel_req *crq)
1047{
1048 struct dsp *ndsp;
1049 u_long flags;
1050
1051 if (crq->protocol != ISDN_P_B_L2DSP
1052 && crq->protocol != ISDN_P_B_L2DSPHDLC)
1053 return -EPROTONOSUPPORT;
1054 ndsp = vmalloc(sizeof(struct dsp));
1055 if (!ndsp) {
1056 printk(KERN_ERR "%s: vmalloc struct dsp failed\n", __func__);
1057 return -ENOMEM;
1058 }
1059 memset(ndsp, 0, sizeof(struct dsp));
1060 if (dsp_debug & DEBUG_DSP_CTRL)
1061 printk(KERN_DEBUG "%s: creating new dsp instance\n", __func__);
1062
1063
1064 INIT_WORK(&ndsp->workq, (void *)dsp_send_bh);
1065 skb_queue_head_init(&ndsp->sendq);
1066 ndsp->ch.send = dsp_function;
1067 ndsp->ch.ctrl = dsp_ctrl;
1068 ndsp->up = crq->ch;
1069 crq->ch = &ndsp->ch;
1070 if (crq->protocol == ISDN_P_B_L2DSP) {
1071 crq->protocol = ISDN_P_B_RAW;
1072 ndsp->hdlc = 0;
1073 } else {
1074 crq->protocol = ISDN_P_B_HDLC;
1075 ndsp->hdlc = 1;
1076 }
1077 if (!try_module_get(THIS_MODULE))
1078 printk(KERN_WARNING "%s:cannot get module\n",
1079 __func__);
1080
1081 sprintf(ndsp->name, "DSP_C%x(0x%p)",
1082 ndsp->up->st->dev->id + 1, ndsp);
1083
1084 ndsp->features.hfc_id = -1;
1085 ndsp->features.pcm_id = -1;
1086 ndsp->pcm_slot_rx = -1;
1087 ndsp->pcm_slot_tx = -1;
1088 ndsp->pcm_bank_rx = -1;
1089 ndsp->pcm_bank_tx = -1;
1090 ndsp->hfc_conf = -1;
1091
1092 ndsp->tone.tl.function = (void *)dsp_tone_timeout;
1093 ndsp->tone.tl.data = (long) ndsp;
1094 init_timer(&ndsp->tone.tl);
1095
1096 if (dtmfthreshold < 20 || dtmfthreshold > 500)
1097 dtmfthreshold = 200;
1098 ndsp->dtmf.treshold = dtmfthreshold*10000;
1099
1100
1101 spin_lock_irqsave(&dsp_lock, flags);
1102 dsp_pipeline_init(&ndsp->pipeline);
1103 list_add_tail(&ndsp->list, &dsp_ilist);
1104 spin_unlock_irqrestore(&dsp_lock, flags);
1105
1106 return 0;
1107}
1108
1109
1110static struct Bprotocol DSP = {
1111 .Bprotocols = (1 << (ISDN_P_B_L2DSP & ISDN_P_B_MASK))
1112 | (1 << (ISDN_P_B_L2DSPHDLC & ISDN_P_B_MASK)),
1113 .name = "dsp",
1114 .create = dspcreate
1115};
1116
1117static int dsp_init(void)
1118{
1119 int err;
1120 int tics;
1121
1122 printk(KERN_INFO "DSP modul %s\n", mISDN_dsp_revision);
1123
1124 dsp_options = options;
1125 dsp_debug = debug;
1126
1127
1128 dsp_poll = poll;
1129 if (dsp_poll) {
1130 if (dsp_poll > MAX_POLL) {
1131 printk(KERN_ERR "%s: Wrong poll value (%d), use %d "
1132 "maximum.\n", __func__, poll, MAX_POLL);
1133 err = -EINVAL;
1134 return err;
1135 }
1136 if (dsp_poll < 8) {
1137 printk(KERN_ERR "%s: Wrong poll value (%d), use 8 "
1138 "minimum.\n", __func__, dsp_poll);
1139 err = -EINVAL;
1140 return err;
1141 }
1142 dsp_tics = poll * HZ / 8000;
1143 if (dsp_tics * 8000 != poll * HZ) {
1144 printk(KERN_INFO "mISDN_dsp: Cannot clock every %d "
1145 "samples (0,125 ms). It is not a multiple of "
1146 "%d HZ.\n", poll, HZ);
1147 err = -EINVAL;
1148 return err;
1149 }
1150 } else {
1151 poll = 8;
1152 while (poll <= MAX_POLL) {
1153 tics = (poll * HZ) / 8000;
1154 if (tics * 8000 == poll * HZ) {
1155 dsp_tics = tics;
1156 dsp_poll = poll;
1157 if (poll >= 64)
1158 break;
1159 }
1160 poll++;
1161 }
1162 }
1163 if (dsp_poll == 0) {
1164 printk(KERN_INFO "mISDN_dsp: There is no multiple of kernel "
1165 "clock that equals exactly the duration of 8-256 "
1166 "samples. (Choose kernel clock speed like 100, 250, "
1167 "300, 1000)\n");
1168 err = -EINVAL;
1169 return err;
1170 }
1171 printk(KERN_INFO "mISDN_dsp: DSP clocks every %d samples. This equals "
1172 "%d jiffies.\n", dsp_poll, dsp_tics);
1173
1174 spin_lock_init(&dsp_lock);
1175 INIT_LIST_HEAD(&dsp_ilist);
1176 INIT_LIST_HEAD(&conf_ilist);
1177
1178
1179 dsp_audio_generate_law_tables();
1180 dsp_silence = (dsp_options&DSP_OPT_ULAW) ? 0xff : 0x2a;
1181 dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW) ?
1182 dsp_audio_ulaw_to_s32 : dsp_audio_alaw_to_s32;
1183 dsp_audio_generate_s2law_table();
1184 dsp_audio_generate_seven();
1185 dsp_audio_generate_mix_table();
1186 if (dsp_options & DSP_OPT_ULAW)
1187 dsp_audio_generate_ulaw_samples();
1188 dsp_audio_generate_volume_changes();
1189
1190 err = dsp_pipeline_module_init();
1191 if (err) {
1192 printk(KERN_ERR "mISDN_dsp: Can't initialize pipeline, "
1193 "error(%d)\n", err);
1194 return err;
1195 }
1196
1197 err = mISDN_register_Bprotocol(&DSP);
1198 if (err) {
1199 printk(KERN_ERR "Can't register %s error(%d)\n", DSP.name, err);
1200 return err;
1201 }
1202
1203
1204 dsp_spl_tl.function = (void *)dsp_cmx_send;
1205 dsp_spl_tl.data = 0;
1206 init_timer(&dsp_spl_tl);
1207 dsp_spl_tl.expires = jiffies + dsp_tics;
1208 dsp_spl_jiffies = dsp_spl_tl.expires;
1209 add_timer(&dsp_spl_tl);
1210
1211 return 0;
1212}
1213
1214
1215static void dsp_cleanup(void)
1216{
1217 mISDN_unregister_Bprotocol(&DSP);
1218
1219 if (timer_pending(&dsp_spl_tl))
1220 del_timer(&dsp_spl_tl);
1221
1222 if (!list_empty(&dsp_ilist)) {
1223 printk(KERN_ERR "mISDN_dsp: Audio DSP object inst list not "
1224 "empty.\n");
1225 }
1226 if (!list_empty(&conf_ilist)) {
1227 printk(KERN_ERR "mISDN_dsp: Conference list not empty. Not "
1228 "all memory freed.\n");
1229 }
1230
1231 dsp_pipeline_module_exit();
1232}
1233
1234module_init(dsp_init);
1235module_exit(dsp_cleanup);
1236
1237