aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
authorAndreas Eversberg <andreas@eversberg.eu>2009-05-22 07:04:48 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-25 03:51:33 -0400
commitb5df5a5c3bf0f809d854ad7156ce26b709b533c0 (patch)
tree5655ba6abfb945b00bb5eae5c9bdb58d6f21180c /drivers/isdn
parente73f6b2260daf02793071e5ce06ea87df762920a (diff)
mISDN: Fix DTMF locking bug issue
DTMF digits were sent up to socket in locked state. Receive audio stream was not enabled in certain condition. Signed-off-by: Andreas Eversberg <andreas@eversberg.eu> Signed-off-by: Karsten Keil <keil@b1-systems.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c4
-rw-r--r--drivers/isdn/mISDN/dsp.h2
-rw-r--r--drivers/isdn/mISDN/dsp_core.c37
3 files changed, 23 insertions, 20 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index fc76f401a4d3..bc0d3efeb567 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -1817,8 +1817,8 @@ hfcmulti_dtmf(struct hfc_multi *hc)
1817 coeff[(co<<1)|1] = mantissa; 1817 coeff[(co<<1)|1] = mantissa;
1818 } 1818 }
1819 if (debug & DEBUG_HFCMULTI_DTMF) 1819 if (debug & DEBUG_HFCMULTI_DTMF)
1820 printk("%s: DTMF ready %08x %08x %08x %08x " 1820 printk(" DTMF ready %08x %08x %08x %08x "
1821 "%08x %08x %08x %08x\n", __func__, 1821 "%08x %08x %08x %08x\n",
1822 coeff[0], coeff[1], coeff[2], coeff[3], 1822 coeff[0], coeff[1], coeff[2], coeff[3],
1823 coeff[4], coeff[5], coeff[6], coeff[7]); 1823 coeff[4], coeff[5], coeff[6], coeff[7]);
1824 hc->chan[ch].coeff_count++; 1824 hc->chan[ch].coeff_count++;
diff --git a/drivers/isdn/mISDN/dsp.h b/drivers/isdn/mISDN/dsp.h
index 4a1c444d73ac..41c6cfdca8c8 100644
--- a/drivers/isdn/mISDN/dsp.h
+++ b/drivers/isdn/mISDN/dsp.h
@@ -124,7 +124,7 @@ struct dsp_dtmf {
124 /* buffers one full dtmf frame */ 124 /* buffers one full dtmf frame */
125 u8 lastwhat, lastdigit; 125 u8 lastwhat, lastdigit;
126 int count; 126 int count;
127 u8 digits[16]; /* just the dtmf result */ 127 u8 digits[16]; /* dtmf result */
128}; 128};
129 129
130 130
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c
index 621ea9bc7c25..6b4939854306 100644
--- a/drivers/isdn/mISDN/dsp_core.c
+++ b/drivers/isdn/mISDN/dsp_core.c
@@ -311,6 +311,7 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
311 311
312 /* check dtmf hardware */ 312 /* check dtmf hardware */
313 dsp_dtmf_hardware(dsp); 313 dsp_dtmf_hardware(dsp);
314 dsp_rx_off(dsp);
314 break; 315 break;
315 case DTMF_TONE_STOP: /* turn off DTMF */ 316 case DTMF_TONE_STOP: /* turn off DTMF */
316 if (dsp_debug & DEBUG_DSP_CORE) 317 if (dsp_debug & DEBUG_DSP_CORE)
@@ -657,11 +658,10 @@ get_features(struct mISDNchannel *ch)
657static int 658static int
658dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) 659dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
659{ 660{
660 struct dsp *dsp = container_of(ch, struct dsp, ch); 661 struct dsp *dsp = container_of(ch, struct dsp, ch);
661 struct mISDNhead *hh; 662 struct mISDNhead *hh;
662 int ret = 0; 663 int ret = 0;
663 u8 *digits; 664 u8 *digits = NULL;
664 int cont;
665 u_long flags; 665 u_long flags;
666 666
667 hh = mISDN_HEAD_P(skb); 667 hh = mISDN_HEAD_P(skb);
@@ -716,40 +716,43 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
716 /* change volume if requested */ 716 /* change volume if requested */
717 if (dsp->rx_volume) 717 if (dsp->rx_volume)
718 dsp_change_volume(skb, dsp->rx_volume); 718 dsp_change_volume(skb, dsp->rx_volume);
719
720 /* check if dtmf soft decoding is turned on */ 719 /* check if dtmf soft decoding is turned on */
721 if (dsp->dtmf.software) { 720 if (dsp->dtmf.software) {
722 digits = dsp_dtmf_goertzel_decode(dsp, skb->data, 721 digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
723 skb->len, (dsp_options&DSP_OPT_ULAW)?1:0); 722 skb->len, (dsp_options&DSP_OPT_ULAW)?1:0);
723 }
724 /* we need to process receive data if software */
725 if (dsp->pcm_slot_tx < 0 && dsp->pcm_slot_rx < 0) {
726 /* process data from card at cmx */
727 dsp_cmx_receive(dsp, skb);
728 }
729
730 spin_unlock_irqrestore(&dsp_lock, flags);
731
732 /* send dtmf result, if any */
733 if (digits) {
724 while (*digits) { 734 while (*digits) {
735 int k;
725 struct sk_buff *nskb; 736 struct sk_buff *nskb;
726 if (dsp_debug & DEBUG_DSP_DTMF) 737 if (dsp_debug & DEBUG_DSP_DTMF)
727 printk(KERN_DEBUG "%s: digit" 738 printk(KERN_DEBUG "%s: digit"
728 "(%c) to layer %s\n", 739 "(%c) to layer %s\n",
729 __func__, *digits, dsp->name); 740 __func__, *digits, dsp->name);
730 cont = DTMF_TONE_VAL | *digits; 741 k = *digits | DTMF_TONE_VAL;
731 nskb = _alloc_mISDN_skb(PH_CONTROL_IND, 742 nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
732 MISDN_ID_ANY, sizeof(int), &cont, 743 MISDN_ID_ANY, sizeof(int), &k,
733 GFP_ATOMIC); 744 GFP_ATOMIC);
734 if (nskb) { 745 if (nskb) {
735 if (dsp->up) { 746 if (dsp->up) {
736 if (dsp->up->send( 747 if (dsp->up->send(
737 dsp->up, nskb)) 748 dsp->up, nskb))
738 dev_kfree_skb(nskb); 749 dev_kfree_skb(nskb);
739 } else 750 } else
740 dev_kfree_skb(nskb); 751 dev_kfree_skb(nskb);
741 } 752 }
742 digits++; 753 digits++;
743 } 754 }
744 } 755 }
745 /* we need to process receive data if software */
746 if (dsp->pcm_slot_tx < 0 && dsp->pcm_slot_rx < 0) {
747 /* process data from card at cmx */
748 dsp_cmx_receive(dsp, skb);
749 }
750
751 spin_unlock_irqrestore(&dsp_lock, flags);
752
753 if (dsp->rx_disabled) { 756 if (dsp->rx_disabled) {
754 /* if receive is not allowed */ 757 /* if receive is not allowed */
755 break; 758 break;
@@ -789,7 +792,7 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
789 if (dsp->up) { 792 if (dsp->up) {
790 if (dsp->up->send( 793 if (dsp->up->send(
791 dsp->up, nskb)) 794 dsp->up, nskb))
792 dev_kfree_skb(nskb); 795 dev_kfree_skb(nskb);
793 } else 796 } else
794 dev_kfree_skb(nskb); 797 dev_kfree_skb(nskb);
795 } 798 }