diff options
author | Andreas Eversberg <andreas@eversberg.eu> | 2009-05-22 07:04:48 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-25 03:51:33 -0400 |
commit | b5df5a5c3bf0f809d854ad7156ce26b709b533c0 (patch) | |
tree | 5655ba6abfb945b00bb5eae5c9bdb58d6f21180c /drivers/isdn | |
parent | e73f6b2260daf02793071e5ce06ea87df762920a (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.c | 4 | ||||
-rw-r--r-- | drivers/isdn/mISDN/dsp.h | 2 | ||||
-rw-r--r-- | drivers/isdn/mISDN/dsp_core.c | 37 |
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) | |||
657 | static int | 658 | static int |
658 | dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) | 659 | dsp_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 | } |