aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 6d74951a179..4aa6a8b41f5 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 5783d22a18f..fd9241ab180 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 ff5ec3cbeb7..3fc2e9d9534 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 cd8302af40e..80c356e5dbe 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 6c3fed6b8d4..ded94806933 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 c884511e2d4..fc8ea41ae6a 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 1dc21d80341..1d504ba954f 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 e794dfb8750..9384b92dfc6 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 8f2d60da04e..74c903cd7a0 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