aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <andreas@eversberg.eu>2008-08-02 16:51:52 -0400
committerKarsten Keil <kkeil@suse.de>2009-01-09 16:44:22 -0500
commit8dd2f36f317569665e454268a2677cfba3e848f1 (patch)
tree62f0d30aa090594648ed21cb9a863e4cc2b4f4fd
parent69e656cc16511719a89d83373c48172d3f39bc5f (diff)
mISDN: Add feature via MISDN_CTRL_FILL_EMPTY to fill fifo if empty
This prevents underrun of fifo when filled and in case of an underrun it prevents subsequent underruns due to jitter. Improve dsp, so buffers are kept filled with a certain delay, so moderate jitter will not cause underrun all the time -> the audio quality is highly improved. tones are not interrupted by gaps anymore, except when CPU is stalling or in high load. Signed-off-by: Andreas Eversberg <andreas@eversberg.eu> Signed-off-by: Karsten Keil <kkeil@suse.de>
-rw-r--r--drivers/isdn/hardware/mISDN/hfc_multi.h3
-rw-r--r--drivers/isdn/hardware/mISDN/hfc_pci.h1
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c45
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c41
-rw-r--r--drivers/isdn/mISDN/dsp.h1
-rw-r--r--drivers/isdn/mISDN/dsp_cmx.c56
-rw-r--r--drivers/isdn/mISDN/dsp_core.c37
-rw-r--r--include/linux/mISDNhw.h25
-rw-r--r--include/linux/mISDNif.h1
9 files changed, 165 insertions, 45 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
index 6d74951a1797..4aa6a8b41f50 100644
--- a/drivers/isdn/hardware/mISDN/hfc_multi.h
+++ b/drivers/isdn/hardware/mISDN/hfc_multi.h
@@ -9,6 +9,7 @@
9#define DEBUG_HFCMULTI_MODE 0x00100000 9#define DEBUG_HFCMULTI_MODE 0x00100000
10#define DEBUG_HFCMULTI_MSG 0x00200000 10#define DEBUG_HFCMULTI_MSG 0x00200000
11#define DEBUG_HFCMULTI_STATE 0x00400000 11#define DEBUG_HFCMULTI_STATE 0x00400000
12#define DEBUG_HFCMULTI_FILL 0x00800000
12#define DEBUG_HFCMULTI_SYNC 0x01000000 13#define DEBUG_HFCMULTI_SYNC 0x01000000
13#define DEBUG_HFCMULTI_DTMF 0x02000000 14#define DEBUG_HFCMULTI_DTMF 0x02000000
14#define DEBUG_HFCMULTI_LOCK 0x80000000 15#define DEBUG_HFCMULTI_LOCK 0x80000000
@@ -166,6 +167,8 @@ struct hfc_multi {
166 167
167 u_long chip; /* chip configuration */ 168 u_long chip; /* chip configuration */
168 int masterclk; /* port that provides master clock -1=off */ 169 int masterclk; /* port that provides master clock -1=off */
170 unsigned char silence;/* silence byte */
171 unsigned char silence_data[128];/* silence block */
169 int dtmf; /* flag that dtmf is currently in process */ 172 int dtmf; /* flag that dtmf is currently in process */
170 int Flen; /* F-buffer size */ 173 int Flen; /* F-buffer size */
171 int Zlen; /* Z-buffer size (must be int for calculation)*/ 174 int Zlen; /* Z-buffer size (must be int for calculation)*/
diff --git a/drivers/isdn/hardware/mISDN/hfc_pci.h b/drivers/isdn/hardware/mISDN/hfc_pci.h
index 5783d22a18fe..fd9241ab1802 100644
--- a/drivers/isdn/hardware/mISDN/hfc_pci.h
+++ b/drivers/isdn/hardware/mISDN/hfc_pci.h
@@ -27,6 +27,7 @@
27 */ 27 */
28#define HFCPCI_BTRANS_THRESHOLD 128 28#define HFCPCI_BTRANS_THRESHOLD 128
29#define HFCPCI_BTRANS_MAX 256 29#define HFCPCI_BTRANS_MAX 256
30#define HFCPCI_FILLEMPTY 64
30#define HFCPCI_BTRANS_THRESMASK 0x00 31#define HFCPCI_BTRANS_THRESMASK 0x00
31 32
32/* defines for PCI config */ 33/* defines for PCI config */
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index ff5ec3cbeb77..3fc2e9d95341 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -180,7 +180,6 @@ static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 };
180#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */ 180#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */
181#define CLKDEL_NT 0x6c /* CLKDEL in NT mode 181#define CLKDEL_NT 0x6c /* CLKDEL in NT mode
182 (0x60 MUST be included!) */ 182 (0x60 MUST be included!) */
183static u_char silence = 0xff; /* silence by LAW */
184 183
185#define DIP_4S 0x1 /* DIP Switches for Beronet 1S/2S/4S cards */ 184#define DIP_4S 0x1 /* DIP Switches for Beronet 1S/2S/4S cards */
186#define DIP_8S 0x2 /* DIP Switches for Beronet 8S+ cards */ 185#define DIP_8S 0x2 /* DIP Switches for Beronet 8S+ cards */
@@ -1975,6 +1974,17 @@ next_frame:
1975 return; /* no data */ 1974 return; /* no data */
1976 } 1975 }
1977 1976
1977 /* "fill fifo if empty" feature */
1978 if (bch && test_bit(FLG_FILLEMPTY, &bch->Flags)
1979 && !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) {
1980 if (debug & DEBUG_HFCMULTI_FILL)
1981 printk(KERN_DEBUG "%s: buffer empty, so we have "
1982 "underrun\n", __func__);
1983 /* fill buffer, to prevent future underrun */
1984 hc->write_fifo(hc, hc->silence_data, poll >> 1);
1985 Zspace -= (poll >> 1);
1986 }
1987
1978 /* if audio data and connected slot */ 1988 /* if audio data and connected slot */
1979 if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending) 1989 if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending)
1980 && slot_tx >= 0) { 1990 && slot_tx >= 0) {
@@ -2011,7 +2021,6 @@ next_frame:
2011 __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i, 2021 __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,
2012 temp ? "HDLC":"TRANS"); 2022 temp ? "HDLC":"TRANS");
2013 2023
2014
2015 /* Have to prep the audio data */ 2024 /* Have to prep the audio data */
2016 hc->write_fifo(hc, d, ii - i); 2025 hc->write_fifo(hc, d, ii - i);
2017 *idxp = ii; 2026 *idxp = ii;
@@ -2050,7 +2059,7 @@ next_frame:
2050 * no more data at all. this prevents sending an undefined value. 2059 * no more data at all. this prevents sending an undefined value.
2051 */ 2060 */
2052 if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags)) 2061 if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))
2053 HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence); 2062 HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
2054} 2063}
2055 2064
2056 2065
@@ -2932,7 +2941,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
2932 HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); 2941 HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
2933 HFC_wait(hc); 2942 HFC_wait(hc);
2934 /* tx silence */ 2943 /* tx silence */
2935 HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence); 2944 HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
2936 HFC_outb(hc, R_SLOT, (((ch / 4) * 8) + 2945 HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
2937 ((ch % 4) * 4)) << 1); 2946 ((ch % 4) * 4)) << 1);
2938 HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1)); 2947 HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1));
@@ -2947,7 +2956,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
2947 HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); 2956 HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
2948 HFC_wait(hc); 2957 HFC_wait(hc);
2949 /* tx silence */ 2958 /* tx silence */
2950 HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence); 2959 HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
2951 /* enable RX fifo */ 2960 /* enable RX fifo */
2952 HFC_outb(hc, R_FIFO, (ch<<1)|1); 2961 HFC_outb(hc, R_FIFO, (ch<<1)|1);
2953 HFC_wait(hc); 2962 HFC_wait(hc);
@@ -3439,7 +3448,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
3439 switch (cq->op) { 3448 switch (cq->op) {
3440 case MISDN_CTRL_GETOP: 3449 case MISDN_CTRL_GETOP:
3441 cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP 3450 cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP
3442 | MISDN_CTRL_RX_OFF; 3451 | MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY;
3443 break; 3452 break;
3444 case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */ 3453 case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
3445 hc->chan[bch->slot].rx_off = !!cq->p1; 3454 hc->chan[bch->slot].rx_off = !!cq->p1;
@@ -3454,6 +3463,12 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
3454 printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n", 3463 printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n",
3455 __func__, bch->nr, hc->chan[bch->slot].rx_off); 3464 __func__, bch->nr, hc->chan[bch->slot].rx_off);
3456 break; 3465 break;
3466 case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */
3467 test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
3468 if (debug & DEBUG_HFCMULTI_MSG)
3469 printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "
3470 "off=%d)\n", __func__, bch->nr, !!cq->p1);
3471 break;
3457 case MISDN_CTRL_HW_FEATURES: /* fill features structure */ 3472 case MISDN_CTRL_HW_FEATURES: /* fill features structure */
3458 if (debug & DEBUG_HFCMULTI_MSG) 3473 if (debug & DEBUG_HFCMULTI_MSG)
3459 printk(KERN_DEBUG "%s: HW_FEATURE request\n", 3474 printk(KERN_DEBUG "%s: HW_FEATURE request\n",
@@ -3970,6 +3985,7 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
3970 } 3985 }
3971 if (test_and_set_bit(FLG_OPEN, &bch->Flags)) 3986 if (test_and_set_bit(FLG_OPEN, &bch->Flags))
3972 return -EBUSY; /* b-channel can be only open once */ 3987 return -EBUSY; /* b-channel can be only open once */
3988 test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
3973 bch->ch.protocol = rq->protocol; 3989 bch->ch.protocol = rq->protocol;
3974 hc->chan[ch].rx_off = 0; 3990 hc->chan[ch].rx_off = 0;
3975 rq->ch = &bch->ch; 3991 rq->ch = &bch->ch;
@@ -4806,6 +4822,7 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
4806 struct hfc_multi *hc; 4822 struct hfc_multi *hc;
4807 u_long flags; 4823 u_long flags;
4808 u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */ 4824 u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */
4825 int i;
4809 4826
4810 if (HFC_cnt >= MAX_CARDS) { 4827 if (HFC_cnt >= MAX_CARDS) {
4811 printk(KERN_ERR "too many cards (max=%d).\n", 4828 printk(KERN_ERR "too many cards (max=%d).\n",
@@ -4839,11 +4856,11 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
4839 hc->id = HFC_cnt; 4856 hc->id = HFC_cnt;
4840 hc->pcm = pcm[HFC_cnt]; 4857 hc->pcm = pcm[HFC_cnt];
4841 hc->io_mode = iomode[HFC_cnt]; 4858 hc->io_mode = iomode[HFC_cnt];
4842 if (dslot[HFC_cnt] < 0) { 4859 if (dslot[HFC_cnt] < 0 && hc->type == 1) {
4843 hc->dslot = 0; 4860 hc->dslot = 0;
4844 printk(KERN_INFO "HFC-E1 card has disabled D-channel, but " 4861 printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
4845 "31 B-channels\n"); 4862 "31 B-channels\n");
4846 } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32) { 4863 } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32 && hc->type == 1) {
4847 hc->dslot = dslot[HFC_cnt]; 4864 hc->dslot = dslot[HFC_cnt];
4848 printk(KERN_INFO "HFC-E1 card has alternating D-channel on " 4865 printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
4849 "time slot %d\n", dslot[HFC_cnt]); 4866 "time slot %d\n", dslot[HFC_cnt]);
@@ -4854,9 +4871,17 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
4854 hc->masterclk = -1; 4871 hc->masterclk = -1;
4855 if (type[HFC_cnt] & 0x100) { 4872 if (type[HFC_cnt] & 0x100) {
4856 test_and_set_bit(HFC_CHIP_ULAW, &hc->chip); 4873 test_and_set_bit(HFC_CHIP_ULAW, &hc->chip);
4857 silence = 0xff; /* ulaw silence */ 4874 hc->silence = 0xff; /* ulaw silence */
4858 } else 4875 } else
4859 silence = 0x2a; /* alaw silence */ 4876 hc->silence = 0x2a; /* alaw silence */
4877 if ((poll >> 1) > sizeof(hc->silence_data)) {
4878 printk(KERN_ERR "HFCMULTI error: silence_data too small, "
4879 "please fix\n");
4880 return -EINVAL;
4881 }
4882 for (i = 0; i < (poll >> 1); i++)
4883 hc->silence_data[i] = hc->silence;
4884
4860 if (!(type[HFC_cnt] & 0x200)) 4885 if (!(type[HFC_cnt] & 0x200))
4861 test_and_set_bit(HFC_CHIP_DTMF, &hc->chip); 4886 test_and_set_bit(HFC_CHIP_DTMF, &hc->chip);
4862 4887
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index cd8302af40eb..80c356e5dbe1 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -751,6 +751,36 @@ hfcpci_fill_fifo(struct bchannel *bch)
751 /* fcnt contains available bytes in fifo */ 751 /* fcnt contains available bytes in fifo */
752 fcnt = B_FIFO_SIZE - fcnt; 752 fcnt = B_FIFO_SIZE - fcnt;
753 /* remaining bytes to send (bytes in fifo) */ 753 /* remaining bytes to send (bytes in fifo) */
754
755 /* "fill fifo if empty" feature */
756 if (test_bit(FLG_FILLEMPTY, &bch->Flags) && !fcnt) {
757 /* printk(KERN_DEBUG "%s: buffer empty, so we have "
758 "underrun\n", __func__); */
759 /* fill buffer, to prevent future underrun */
760 count = HFCPCI_FILLEMPTY;
761 new_z1 = le16_to_cpu(*z1t) + count;
762 /* new buffer Position */
763 if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
764 new_z1 -= B_FIFO_SIZE; /* buffer wrap */
765 dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL);
766 maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t);
767 /* end of fifo */
768 if (bch->debug & DEBUG_HW_BFIFO)
769 printk(KERN_DEBUG "hfcpci_FFt fillempty "
770 "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n",
771 fcnt, maxlen, new_z1, dst);
772 fcnt += count;
773 if (maxlen > count)
774 maxlen = count; /* limit size */
775 memset(dst, 0x2a, maxlen); /* first copy */
776 count -= maxlen; /* remaining bytes */
777 if (count) {
778 dst = bdata; /* start of buffer */
779 memset(dst, 0x2a, count);
780 }
781 *z1t = cpu_to_le16(new_z1); /* now send data */
782 }
783
754next_t_frame: 784next_t_frame:
755 count = bch->tx_skb->len - bch->tx_idx; 785 count = bch->tx_skb->len - bch->tx_idx;
756 /* maximum fill shall be HFCPCI_BTRANS_MAX */ 786 /* maximum fill shall be HFCPCI_BTRANS_MAX */
@@ -1481,11 +1511,17 @@ deactivate_bchannel(struct bchannel *bch)
1481static int 1511static int
1482channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) 1512channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1483{ 1513{
1484 int ret = 0; 1514 int ret = 0;
1485 1515
1486 switch (cq->op) { 1516 switch (cq->op) {
1487 case MISDN_CTRL_GETOP: 1517 case MISDN_CTRL_GETOP:
1488 cq->op = 0; 1518 cq->op = MISDN_CTRL_FILL_EMPTY;
1519 break;
1520 case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */
1521 test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
1522 if (debug & DEBUG_HW_OPEN)
1523 printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "
1524 "off=%d)\n", __func__, bch->nr, !!cq->p1);
1489 break; 1525 break;
1490 default: 1526 default:
1491 printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); 1527 printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op);
@@ -1903,6 +1939,7 @@ open_bchannel(struct hfc_pci *hc, struct channel_req *rq)
1903 bch = &hc->bch[rq->adr.channel - 1]; 1939 bch = &hc->bch[rq->adr.channel - 1];
1904 if (test_and_set_bit(FLG_OPEN, &bch->Flags)) 1940 if (test_and_set_bit(FLG_OPEN, &bch->Flags))
1905 return -EBUSY; /* b-channel can be only open once */ 1941 return -EBUSY; /* b-channel can be only open once */
1942 test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
1906 bch->ch.protocol = rq->protocol; 1943 bch->ch.protocol = rq->protocol;
1907 rq->ch = &bch->ch; /* TODO: E-channel */ 1944 rq->ch = &bch->ch; /* TODO: E-channel */
1908 if (!try_module_get(THIS_MODULE)) 1945 if (!try_module_get(THIS_MODULE))
diff --git a/drivers/isdn/mISDN/dsp.h b/drivers/isdn/mISDN/dsp.h
index 6c3fed6b8d4f..ded948069335 100644
--- a/drivers/isdn/mISDN/dsp.h
+++ b/drivers/isdn/mISDN/dsp.h
@@ -198,6 +198,7 @@ struct dsp {
198 /* hardware stuff */ 198 /* hardware stuff */
199 struct dsp_features features; 199 struct dsp_features features;
200 int features_rx_off; /* set if rx_off is featured */ 200 int features_rx_off; /* set if rx_off is featured */
201 int features_fill_empty; /* set if fill_empty is featured */
201 int pcm_slot_rx; /* current PCM slot (or -1) */ 202 int pcm_slot_rx; /* current PCM slot (or -1) */
202 int pcm_bank_rx; 203 int pcm_bank_rx;
203 int pcm_slot_tx; 204 int pcm_slot_tx;
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
index c884511e2d49..fc8ea41ae6a2 100644
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -1168,11 +1168,18 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
1168 dsp->rx_init = 0; 1168 dsp->rx_init = 0;
1169 if (dsp->features.unordered) { 1169 if (dsp->features.unordered) {
1170 dsp->rx_R = (hh->id & CMX_BUFF_MASK); 1170 dsp->rx_R = (hh->id & CMX_BUFF_MASK);
1171 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) 1171 if (dsp->cmx_delay)
1172 & CMX_BUFF_MASK; 1172 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
1173 & CMX_BUFF_MASK;
1174 else
1175 dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
1176 & CMX_BUFF_MASK;
1173 } else { 1177 } else {
1174 dsp->rx_R = 0; 1178 dsp->rx_R = 0;
1175 dsp->rx_W = dsp->cmx_delay; 1179 if (dsp->cmx_delay)
1180 dsp->rx_W = dsp->cmx_delay;
1181 else
1182 dsp->rx_W = dsp_poll >> 1;
1176 } 1183 }
1177 } 1184 }
1178 /* if frame contains time code, write directly */ 1185 /* if frame contains time code, write directly */
@@ -1190,14 +1197,20 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
1190 "cmx_receive(dsp=%lx): UNDERRUN (or overrun the " 1197 "cmx_receive(dsp=%lx): UNDERRUN (or overrun the "
1191 "maximum delay), adjusting read pointer! " 1198 "maximum delay), adjusting read pointer! "
1192 "(inst %s)\n", (u_long)dsp, dsp->name); 1199 "(inst %s)\n", (u_long)dsp, dsp->name);
1193 /* flush buffer */ 1200 /* flush rx buffer and set delay to dsp_poll / 2 */
1194 if (dsp->features.unordered) { 1201 if (dsp->features.unordered) {
1195 dsp->rx_R = (hh->id & CMX_BUFF_MASK); 1202 dsp->rx_R = (hh->id & CMX_BUFF_MASK);
1196 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) 1203 if (dsp->cmx_delay)
1197 & CMX_BUFF_MASK; 1204 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
1205 & CMX_BUFF_MASK;
1206 dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
1207 & CMX_BUFF_MASK;
1198 } else { 1208 } else {
1199 dsp->rx_R = 0; 1209 dsp->rx_R = 0;
1200 dsp->rx_W = dsp->cmx_delay; 1210 if (dsp->cmx_delay)
1211 dsp->rx_W = dsp->cmx_delay;
1212 else
1213 dsp->rx_W = dsp_poll >> 1;
1201 } 1214 }
1202 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff)); 1215 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
1203 } 1216 }
@@ -1360,8 +1373,11 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
1360 t = (t+1) & CMX_BUFF_MASK; 1373 t = (t+1) & CMX_BUFF_MASK;
1361 r = (r+1) & CMX_BUFF_MASK; 1374 r = (r+1) & CMX_BUFF_MASK;
1362 } 1375 }
1363 if (r != rr) 1376 if (r != rr) {
1377 printk(KERN_DEBUG "%s: buffer empty\n",
1378 __func__);
1364 memset(d, dsp_silence, (rr-r)&CMX_BUFF_MASK); 1379 memset(d, dsp_silence, (rr-r)&CMX_BUFF_MASK);
1380 }
1365 /* -> if echo is enabled */ 1381 /* -> if echo is enabled */
1366 } else { 1382 } else {
1367 /* 1383 /*
@@ -1704,9 +1720,10 @@ dsp_cmx_send(void *arg)
1704 } 1720 }
1705 /* 1721 /*
1706 * remove rx_delay only if we have delay AND we 1722 * remove rx_delay only if we have delay AND we
1707 * have not preset cmx_delay 1723 * have not preset cmx_delay AND
1724 * the delay is greater dsp_poll
1708 */ 1725 */
1709 if (delay && !dsp->cmx_delay) { 1726 if (delay > dsp_poll && !dsp->cmx_delay) {
1710 if (dsp_debug & DEBUG_DSP_CMX) 1727 if (dsp_debug & DEBUG_DSP_CMX)
1711 printk(KERN_DEBUG 1728 printk(KERN_DEBUG
1712 "%s lowest rx_delay of %d bytes for" 1729 "%s lowest rx_delay of %d bytes for"
@@ -1714,7 +1731,8 @@ dsp_cmx_send(void *arg)
1714 __func__, delay, 1731 __func__, delay,
1715 dsp->name); 1732 dsp->name);
1716 r = dsp->rx_R; 1733 r = dsp->rx_R;
1717 rr = (r + delay) & CMX_BUFF_MASK; 1734 rr = (r + delay - (dsp_poll >> 1))
1735 & CMX_BUFF_MASK;
1718 /* delete rx-data */ 1736 /* delete rx-data */
1719 while (r != rr) { 1737 while (r != rr) {
1720 p[r] = dsp_silence; 1738 p[r] = dsp_silence;
@@ -1736,7 +1754,7 @@ dsp_cmx_send(void *arg)
1736 * remove delay only if we have delay AND we 1754 * remove delay only if we have delay AND we
1737 * have enabled tx_dejitter 1755 * have enabled tx_dejitter
1738 */ 1756 */
1739 if (delay && dsp->tx_dejitter) { 1757 if (delay > dsp_poll && dsp->tx_dejitter) {
1740 if (dsp_debug & DEBUG_DSP_CMX) 1758 if (dsp_debug & DEBUG_DSP_CMX)
1741 printk(KERN_DEBUG 1759 printk(KERN_DEBUG
1742 "%s lowest tx_delay of %d bytes for" 1760 "%s lowest tx_delay of %d bytes for"
@@ -1744,7 +1762,8 @@ dsp_cmx_send(void *arg)
1744 __func__, delay, 1762 __func__, delay,
1745 dsp->name); 1763 dsp->name);
1746 r = dsp->tx_R; 1764 r = dsp->tx_R;
1747 rr = (r + delay) & CMX_BUFF_MASK; 1765 rr = (r + delay - (dsp_poll >> 1))
1766 & CMX_BUFF_MASK;
1748 /* delete tx-data */ 1767 /* delete tx-data */
1749 while (r != rr) { 1768 while (r != rr) {
1750 q[r] = dsp_silence; 1769 q[r] = dsp_silence;
@@ -1797,14 +1816,13 @@ dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb)
1797 ww = dsp->tx_R; 1816 ww = dsp->tx_R;
1798 p = dsp->tx_buff; 1817 p = dsp->tx_buff;
1799 d = skb->data; 1818 d = skb->data;
1800 space = ww-w; 1819 space = (ww - w - 1) & CMX_BUFF_MASK;
1801 if (space <= 0)
1802 space += CMX_BUFF_SIZE;
1803 /* write-pointer should not overrun nor reach read pointer */ 1820 /* write-pointer should not overrun nor reach read pointer */
1804 if (space-1 < skb->len) 1821 if (space < skb->len) {
1805 /* write to the space we have left */ 1822 /* write to the space we have left */
1806 ww = (ww - 1) & CMX_BUFF_MASK; 1823 ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */
1807 else 1824 printk(KERN_DEBUG "%s: buffer overflow\n", __func__);
1825 } else
1808 /* write until all byte are copied */ 1826 /* write until all byte are copied */
1809 ww = (w + skb->len) & CMX_BUFF_MASK; 1827 ww = (w + skb->len) & CMX_BUFF_MASK;
1810 dsp->tx_W = ww; 1828 dsp->tx_W = ww;
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c
index 1dc21d803410..1d504ba954f5 100644
--- a/drivers/isdn/mISDN/dsp_core.c
+++ b/drivers/isdn/mISDN/dsp_core.c
@@ -191,6 +191,8 @@ dsp_rx_off_member(struct dsp *dsp)
191 struct mISDN_ctrl_req cq; 191 struct mISDN_ctrl_req cq;
192 int rx_off = 1; 192 int rx_off = 1;
193 193
194 memset(&cq, 0, sizeof(cq));
195
194 if (!dsp->features_rx_off) 196 if (!dsp->features_rx_off)
195 return; 197 return;
196 198
@@ -249,6 +251,32 @@ dsp_rx_off(struct dsp *dsp)
249 } 251 }
250} 252}
251 253
254/* enable "fill empty" feature */
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
252static int 280static int
253dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) 281dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
254{ 282{
@@ -593,8 +621,6 @@ get_features(struct mISDNchannel *ch)
593 struct dsp *dsp = container_of(ch, struct dsp, ch); 621 struct dsp *dsp = container_of(ch, struct dsp, ch);
594 struct mISDN_ctrl_req cq; 622 struct mISDN_ctrl_req cq;
595 623
596 if (dsp_options & DSP_OPT_NOHARDWARE)
597 return;
598 if (!ch->peer) { 624 if (!ch->peer) {
599 if (dsp_debug & DEBUG_DSP_CORE) 625 if (dsp_debug & DEBUG_DSP_CORE)
600 printk(KERN_DEBUG "%s: no peer, no features\n", 626 printk(KERN_DEBUG "%s: no peer, no features\n",
@@ -610,6 +636,10 @@ get_features(struct mISDNchannel *ch)
610 } 636 }
611 if (cq.op & MISDN_CTRL_RX_OFF) 637 if (cq.op & MISDN_CTRL_RX_OFF)
612 dsp->features_rx_off = 1; 638 dsp->features_rx_off = 1;
639 if (cq.op & MISDN_CTRL_FILL_EMPTY)
640 dsp->features_fill_empty = 1;
641 if (dsp_options & DSP_OPT_NOHARDWARE)
642 return;
613 if ((cq.op & MISDN_CTRL_HW_FEATURES_OP)) { 643 if ((cq.op & MISDN_CTRL_HW_FEATURES_OP)) {
614 cq.op = MISDN_CTRL_HW_FEATURES; 644 cq.op = MISDN_CTRL_HW_FEATURES;
615 *((u_long *)&cq.p1) = (u_long)&dsp->features; 645 *((u_long *)&cq.p1) = (u_long)&dsp->features;
@@ -865,6 +895,9 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
865 if (dsp->dtmf.hardware || dsp->dtmf.software) 895 if (dsp->dtmf.hardware || dsp->dtmf.software)
866 dsp_dtmf_goertzel_init(dsp); 896 dsp_dtmf_goertzel_init(dsp);
867 get_features(ch); 897 get_features(ch);
898 /* enable fill_empty feature */
899 if (dsp->features_fill_empty)
900 dsp_fill_empty(dsp);
868 /* send ph_activate */ 901 /* send ph_activate */
869 hh->prim = PH_ACTIVATE_REQ; 902 hh->prim = PH_ACTIVATE_REQ;
870 if (ch->peer) 903 if (ch->peer)
diff --git a/include/linux/mISDNhw.h b/include/linux/mISDNhw.h
index e794dfb87504..9384b92dfc65 100644
--- a/include/linux/mISDNhw.h
+++ b/include/linux/mISDNhw.h
@@ -57,20 +57,21 @@
57#define FLG_L2DATA 14 /* channel use L2 DATA primitivs */ 57#define FLG_L2DATA 14 /* channel use L2 DATA primitivs */
58#define FLG_ORIGIN 15 /* channel is on origin site */ 58#define FLG_ORIGIN 15 /* channel is on origin site */
59/* channel specific stuff */ 59/* channel specific stuff */
60#define FLG_FILLEMPTY 16 /* fill fifo on first frame (empty) */
60/* arcofi specific */ 61/* arcofi specific */
61#define FLG_ARCOFI_TIMER 16 62#define FLG_ARCOFI_TIMER 17
62#define FLG_ARCOFI_ERROR 17 63#define FLG_ARCOFI_ERROR 18
63/* isar specific */ 64/* isar specific */
64#define FLG_INITIALIZED 16 65#define FLG_INITIALIZED 17
65#define FLG_DLEETX 17 66#define FLG_DLEETX 18
66#define FLG_LASTDLE 18 67#define FLG_LASTDLE 19
67#define FLG_FIRST 19 68#define FLG_FIRST 20
68#define FLG_LASTDATA 20 69#define FLG_LASTDATA 21
69#define FLG_NMD_DATA 21 70#define FLG_NMD_DATA 22
70#define FLG_FTI_RUN 22 71#define FLG_FTI_RUN 23
71#define FLG_LL_OK 23 72#define FLG_LL_OK 24
72#define FLG_LL_CONN 24 73#define FLG_LL_CONN 25
73#define FLG_DTMFSEND 25 74#define FLG_DTMFSEND 26
74 75
75/* workq events */ 76/* workq events */
76#define FLG_RECVQUEUE 30 77#define FLG_RECVQUEUE 30
diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h
index 8f2d60da04e7..74c903cd7a0a 100644
--- a/include/linux/mISDNif.h
+++ b/include/linux/mISDNif.h
@@ -312,6 +312,7 @@ clear_channelmap(u_int nr, u_char *map)
312#define MISDN_CTRL_SETPEER 0x0040 312#define MISDN_CTRL_SETPEER 0x0040
313#define MISDN_CTRL_UNSETPEER 0x0080 313#define MISDN_CTRL_UNSETPEER 0x0080
314#define MISDN_CTRL_RX_OFF 0x0100 314#define MISDN_CTRL_RX_OFF 0x0100
315#define MISDN_CTRL_FILL_EMPTY 0x0200
315#define MISDN_CTRL_HW_FEATURES_OP 0x2000 316#define MISDN_CTRL_HW_FEATURES_OP 0x2000
316#define MISDN_CTRL_HW_FEATURES 0x2001 317#define MISDN_CTRL_HW_FEATURES 0x2001
317#define MISDN_CTRL_HFC_OP 0x4000 318#define MISDN_CTRL_HFC_OP 0x4000