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