diff options
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfc_multi.h | 3 | ||||
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfc_pci.h | 1 | ||||
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfcmulti.c | 45 | ||||
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfcpci.c | 41 | ||||
-rw-r--r-- | drivers/isdn/mISDN/dsp.h | 1 | ||||
-rw-r--r-- | drivers/isdn/mISDN/dsp_cmx.c | 56 | ||||
-rw-r--r-- | drivers/isdn/mISDN/dsp_core.c | 37 | ||||
-rw-r--r-- | include/linux/mISDNhw.h | 25 | ||||
-rw-r--r-- | include/linux/mISDNif.h | 1 |
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!) */ |
183 | static 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 | |||
754 | next_t_frame: | 784 | next_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) | |||
1481 | static int | 1511 | static int |
1482 | channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) | 1512 | channel_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 */ | ||
255 | static void | ||
256 | dsp_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 | |||
252 | static int | 280 | static int |
253 | dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) | 281 | dsp_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 |