]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
mISDN: Add feature via MISDN_CTRL_FILL_EMPTY to fill fifo if empty
authorAndreas Eversberg <andreas@eversberg.eu>
Sat, 2 Aug 2008 20:51:52 +0000 (22:51 +0200)
committerKarsten Keil <kkeil@suse.de>
Fri, 9 Jan 2009 21:44:22 +0000 (22:44 +0100)
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>
drivers/isdn/hardware/mISDN/hfc_multi.h
drivers/isdn/hardware/mISDN/hfc_pci.h
drivers/isdn/hardware/mISDN/hfcmulti.c
drivers/isdn/hardware/mISDN/hfcpci.c
drivers/isdn/mISDN/dsp.h
drivers/isdn/mISDN/dsp_cmx.c
drivers/isdn/mISDN/dsp_core.c
include/linux/mISDNhw.h
include/linux/mISDNif.h

index 6d74951a17976940e8dd95374fc02c22f41c7279..4aa6a8b41f507290b957a4aad4ef342afa6f1564 100644 (file)
@@ -9,6 +9,7 @@
 #define        DEBUG_HFCMULTI_MODE     0x00100000
 #define        DEBUG_HFCMULTI_MSG      0x00200000
 #define        DEBUG_HFCMULTI_STATE    0x00400000
+#define        DEBUG_HFCMULTI_FILL     0x00800000
 #define        DEBUG_HFCMULTI_SYNC     0x01000000
 #define        DEBUG_HFCMULTI_DTMF     0x02000000
 #define        DEBUG_HFCMULTI_LOCK     0x80000000
@@ -166,6 +167,8 @@ struct hfc_multi {
 
        u_long          chip;   /* chip configuration */
        int             masterclk; /* port that provides master clock -1=off */
+       unsigned char   silence;/* silence byte */
+       unsigned char   silence_data[128];/* silence block */
        int             dtmf;   /* flag that dtmf is currently in process */
        int             Flen;   /* F-buffer size */
        int             Zlen;   /* Z-buffer size (must be int for calculation)*/
index 5783d22a18fe0f4d5201b5bca21a28ae8be43944..fd9241ab18025a99b572ff8e2fa75d45f0313ce6 100644 (file)
@@ -27,6 +27,7 @@
  */
 #define HFCPCI_BTRANS_THRESHOLD 128
 #define HFCPCI_BTRANS_MAX      256
+#define HFCPCI_FILLEMPTY       64
 #define HFCPCI_BTRANS_THRESMASK 0x00
 
 /* defines for PCI config */
index ff5ec3cbeb775a6db7b38714795abd122fee661d..3fc2e9d953413f11ede05c82979ca57de2c10bc6 100644 (file)
@@ -180,7 +180,6 @@ static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30  };
 #define        CLKDEL_TE       0x0f    /* CLKDEL in TE mode */
 #define        CLKDEL_NT       0x6c    /* CLKDEL in NT mode
                                   (0x60 MUST be included!) */
-static u_char silence =        0xff;   /* silence by LAW */
 
 #define        DIP_4S  0x1             /* DIP Switches for Beronet 1S/2S/4S cards */
 #define        DIP_8S  0x2             /* DIP Switches for Beronet 8S+ cards */
@@ -1975,6 +1974,17 @@ next_frame:
                return; /* no data */
        }
 
+       /* "fill fifo if empty" feature */
+       if (bch && test_bit(FLG_FILLEMPTY, &bch->Flags)
+               && !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) {
+               if (debug & DEBUG_HFCMULTI_FILL)
+                       printk(KERN_DEBUG "%s: buffer empty, so we have "
+                               "underrun\n", __func__);
+               /* fill buffer, to prevent future underrun */
+               hc->write_fifo(hc, hc->silence_data, poll >> 1);
+               Zspace -= (poll >> 1);
+       }
+
        /* if audio data and connected slot */
        if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending)
                && slot_tx >= 0) {
@@ -2011,7 +2021,6 @@ next_frame:
                        __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,
                        temp ? "HDLC":"TRANS");
 
-
        /* Have to prep the audio data */
        hc->write_fifo(hc, d, ii - i);
        *idxp = ii;
@@ -2050,7 +2059,7 @@ next_frame:
         * no more data at all. this prevents sending an undefined value.
         */
        if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))
-               HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence);
+               HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
 }
 
 
@@ -2932,7 +2941,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
                        HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
                        HFC_wait(hc);
                        /* tx silence */
-                       HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence);
+                       HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
                        HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
                            ((ch % 4) * 4)) << 1);
                        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,
                        HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
                        HFC_wait(hc);
                        /* tx silence */
-                       HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence);
+                       HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
                        /* enable RX fifo */
                        HFC_outb(hc, R_FIFO, (ch<<1)|1);
                        HFC_wait(hc);
@@ -3439,7 +3448,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
        switch (cq->op) {
        case MISDN_CTRL_GETOP:
                cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP
-                       | MISDN_CTRL_RX_OFF;
+                       | MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY;
                break;
        case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
                hc->chan[bch->slot].rx_off = !!cq->p1;
@@ -3454,6 +3463,12 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
                        printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n",
                            __func__, bch->nr, hc->chan[bch->slot].rx_off);
                break;
+       case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */
+               test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
+               if (debug & DEBUG_HFCMULTI_MSG)
+                       printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "
+                               "off=%d)\n", __func__, bch->nr, !!cq->p1);
+               break;
        case MISDN_CTRL_HW_FEATURES: /* fill features structure */
                if (debug & DEBUG_HFCMULTI_MSG)
                        printk(KERN_DEBUG "%s: HW_FEATURE request\n",
@@ -3970,6 +3985,7 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
        }
        if (test_and_set_bit(FLG_OPEN, &bch->Flags))
                return -EBUSY; /* b-channel can be only open once */
+       test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
        bch->ch.protocol = rq->protocol;
        hc->chan[ch].rx_off = 0;
        rq->ch = &bch->ch;
@@ -4806,6 +4822,7 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
        struct hfc_multi        *hc;
        u_long          flags;
        u_char          dips = 0, pmj = 0; /* dip settings, port mode Jumpers */
+       int             i;
 
        if (HFC_cnt >= MAX_CARDS) {
                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)
        hc->id = HFC_cnt;
        hc->pcm = pcm[HFC_cnt];
        hc->io_mode = iomode[HFC_cnt];
-       if (dslot[HFC_cnt] < 0) {
+       if (dslot[HFC_cnt] < 0 && hc->type == 1) {
                hc->dslot = 0;
                printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
                        "31 B-channels\n");
-       } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32) {
+       } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32 && hc->type == 1) {
                hc->dslot = dslot[HFC_cnt];
                printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
                        "time slot %d\n", dslot[HFC_cnt]);
@@ -4854,9 +4871,17 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
        hc->masterclk = -1;
        if (type[HFC_cnt] & 0x100) {
                test_and_set_bit(HFC_CHIP_ULAW, &hc->chip);
-               silence = 0xff; /* ulaw silence */
+               hc->silence = 0xff; /* ulaw silence */
        } else
-               silence = 0x2a; /* alaw silence */
+               hc->silence = 0x2a; /* alaw silence */
+       if ((poll >> 1) > sizeof(hc->silence_data)) {
+               printk(KERN_ERR "HFCMULTI error: silence_data too small, "
+                       "please fix\n");
+               return -EINVAL;
+       }
+       for (i = 0; i < (poll >> 1); i++)
+               hc->silence_data[i] = hc->silence;
+
        if (!(type[HFC_cnt] & 0x200))
                test_and_set_bit(HFC_CHIP_DTMF, &hc->chip);
 
index cd8302af40ebace556b7dc5dc89b1465c0ac3dd3..80c356e5dbe1813259074ba69516f4ef6d76c856 100644 (file)
@@ -751,6 +751,36 @@ hfcpci_fill_fifo(struct bchannel *bch)
                            /* fcnt contains available bytes in fifo */
                fcnt = B_FIFO_SIZE - fcnt;
                    /* remaining bytes to send (bytes in fifo) */
+
+               /* "fill fifo if empty" feature */
+               if (test_bit(FLG_FILLEMPTY, &bch->Flags) && !fcnt) {
+                       /* printk(KERN_DEBUG "%s: buffer empty, so we have "
+                               "underrun\n", __func__); */
+                       /* fill buffer, to prevent future underrun */
+                       count = HFCPCI_FILLEMPTY;
+                       new_z1 = le16_to_cpu(*z1t) + count;
+                          /* new buffer Position */
+                       if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
+                               new_z1 -= B_FIFO_SIZE;  /* buffer wrap */
+                       dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL);
+                       maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t);
+                           /* end of fifo */
+                       if (bch->debug & DEBUG_HW_BFIFO)
+                               printk(KERN_DEBUG "hfcpci_FFt fillempty "
+                                   "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n",
+                                   fcnt, maxlen, new_z1, dst);
+                       fcnt += count;
+                       if (maxlen > count)
+                               maxlen = count;         /* limit size */
+                       memset(dst, 0x2a, maxlen);      /* first copy */
+                       count -= maxlen;                /* remaining bytes */
+                       if (count) {
+                               dst = bdata;            /* start of buffer */
+                               memset(dst, 0x2a, count);
+                       }
+                       *z1t = cpu_to_le16(new_z1);     /* now send data */
+               }
+
 next_t_frame:
                count = bch->tx_skb->len - bch->tx_idx;
                /* maximum fill shall be HFCPCI_BTRANS_MAX */
@@ -1481,11 +1511,17 @@ deactivate_bchannel(struct bchannel *bch)
 static int
 channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 {
-       int                     ret = 0;
+       int     ret = 0;
 
        switch (cq->op) {
        case MISDN_CTRL_GETOP:
-               cq->op = 0;
+               cq->op = MISDN_CTRL_FILL_EMPTY;
+               break;
+       case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */
+               test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
+               if (debug & DEBUG_HW_OPEN)
+                       printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "
+                               "off=%d)\n", __func__, bch->nr, !!cq->p1);
                break;
        default:
                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)
        bch = &hc->bch[rq->adr.channel - 1];
        if (test_and_set_bit(FLG_OPEN, &bch->Flags))
                return -EBUSY; /* b-channel can be only open once */
+       test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
        bch->ch.protocol = rq->protocol;
        rq->ch = &bch->ch; /* TODO: E-channel */
        if (!try_module_get(THIS_MODULE))
index 6c3fed6b8d4f830a7aca4843ce833a2a1d0250ca..ded9480693350659ce876d6b9cb3cf4d2d8c24db 100644 (file)
@@ -198,6 +198,7 @@ struct dsp {
        /* hardware stuff */
        struct dsp_features features;
        int             features_rx_off; /* set if rx_off is featured */
+       int             features_fill_empty; /* set if fill_empty is featured */
        int             pcm_slot_rx; /* current PCM slot (or -1) */
        int             pcm_bank_rx;
        int             pcm_slot_tx;
index c884511e2d49038a465ab9e550a8e04739463de0..fc8ea41ae6a238afbeff4faafdec58bffc72e1ca 100644 (file)
@@ -1168,11 +1168,18 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
                dsp->rx_init = 0;
                if (dsp->features.unordered) {
                        dsp->rx_R = (hh->id & CMX_BUFF_MASK);
-                       dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
-                               & CMX_BUFF_MASK;
+                       if (dsp->cmx_delay)
+                               dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
+                                       & CMX_BUFF_MASK;
+                       else
+                               dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
+                                       & CMX_BUFF_MASK;
                } else {
                        dsp->rx_R = 0;
-                       dsp->rx_W = dsp->cmx_delay;
+                       if (dsp->cmx_delay)
+                               dsp->rx_W = dsp->cmx_delay;
+                       else
+                               dsp->rx_W = dsp_poll >> 1;
                }
        }
        /* if frame contains time code, write directly */
@@ -1190,14 +1197,20 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
                            "cmx_receive(dsp=%lx): UNDERRUN (or overrun the "
                            "maximum delay), adjusting read pointer! "
                            "(inst %s)\n", (u_long)dsp, dsp->name);
-               /* flush buffer */
+               /* flush rx buffer and set delay to dsp_poll / 2 */
                if (dsp->features.unordered) {
                        dsp->rx_R = (hh->id & CMX_BUFF_MASK);
-                       dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
-                               & CMX_BUFF_MASK;
+                       if (dsp->cmx_delay)
+                               dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
+                                       & CMX_BUFF_MASK;
+                               dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
+                                       & CMX_BUFF_MASK;
                } else {
                        dsp->rx_R = 0;
-                       dsp->rx_W = dsp->cmx_delay;
+                       if (dsp->cmx_delay)
+                               dsp->rx_W = dsp->cmx_delay;
+                       else
+                               dsp->rx_W = dsp_poll >> 1;
                }
                memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
        }
@@ -1360,8 +1373,11 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
                                t = (t+1) & CMX_BUFF_MASK;
                                r = (r+1) & CMX_BUFF_MASK;
                        }
-                       if (r != rr)
+                       if (r != rr) {
+                               printk(KERN_DEBUG "%s: buffer empty\n",
+                                       __func__);
                                memset(d, dsp_silence, (rr-r)&CMX_BUFF_MASK);
+                       }
                /* -> if echo is enabled */
                } else {
                        /*
@@ -1704,9 +1720,10 @@ dsp_cmx_send(void *arg)
                        }
                        /*
                         * remove rx_delay only if we have delay AND we
-                        * have not preset cmx_delay
+                        * have not preset cmx_delay AND
+                        * the delay is greater dsp_poll
                         */
-                       if (delay && !dsp->cmx_delay) {
+                       if (delay > dsp_poll && !dsp->cmx_delay) {
                                if (dsp_debug & DEBUG_DSP_CMX)
                                        printk(KERN_DEBUG
                                            "%s lowest rx_delay of %d bytes for"
@@ -1714,7 +1731,8 @@ dsp_cmx_send(void *arg)
                                            __func__, delay,
                                            dsp->name);
                                r = dsp->rx_R;
-                               rr = (r + delay) & CMX_BUFF_MASK;
+                               rr = (r + delay - (dsp_poll >> 1))
+                                       & CMX_BUFF_MASK;
                                /* delete rx-data */
                                while (r != rr) {
                                        p[r] = dsp_silence;
@@ -1736,7 +1754,7 @@ dsp_cmx_send(void *arg)
                         * remove delay only if we have delay AND we
                         * have enabled tx_dejitter
                         */
-                       if (delay && dsp->tx_dejitter) {
+                       if (delay > dsp_poll && dsp->tx_dejitter) {
                                if (dsp_debug & DEBUG_DSP_CMX)
                                        printk(KERN_DEBUG
                                            "%s lowest tx_delay of %d bytes for"
@@ -1744,7 +1762,8 @@ dsp_cmx_send(void *arg)
                                            __func__, delay,
                                            dsp->name);
                                r = dsp->tx_R;
-                               rr = (r + delay) & CMX_BUFF_MASK;
+                               rr = (r + delay - (dsp_poll >> 1))
+                                       & CMX_BUFF_MASK;
                                /* delete tx-data */
                                while (r != rr) {
                                        q[r] = dsp_silence;
@@ -1797,14 +1816,13 @@ dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb)
        ww = dsp->tx_R;
        p = dsp->tx_buff;
        d = skb->data;
-       space = ww-w;
-       if (space <= 0)
-               space += CMX_BUFF_SIZE;
+       space = (ww - w - 1) & CMX_BUFF_MASK;
        /* write-pointer should not overrun nor reach read pointer */
-       if (space-1 < skb->len)
+       if (space < skb->len) {
                /* write to the space we have left */
-               ww = (ww - 1) & CMX_BUFF_MASK;
-       else
+               ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */
+               printk(KERN_DEBUG "%s: buffer overflow\n", __func__);
+       } else
                /* write until all byte are copied */
                ww = (w + skb->len) & CMX_BUFF_MASK;
        dsp->tx_W = ww;
index 1dc21d8034109f7a71b7f015baae329a994535b4..1d504ba954f59e756488782fa460caf728323ab6 100644 (file)
@@ -191,6 +191,8 @@ dsp_rx_off_member(struct dsp *dsp)
        struct mISDN_ctrl_req   cq;
        int rx_off = 1;
 
+       memset(&cq, 0, sizeof(cq));
+
        if (!dsp->features_rx_off)
                return;
 
@@ -249,6 +251,32 @@ dsp_rx_off(struct dsp *dsp)
        }
 }
 
+/* enable "fill empty" feature */
+static void
+dsp_fill_empty(struct dsp *dsp)
+{
+       struct mISDN_ctrl_req   cq;
+
+       memset(&cq, 0, sizeof(cq));
+
+       if (!dsp->ch.peer) {
+               if (dsp_debug & DEBUG_DSP_CORE)
+                       printk(KERN_DEBUG "%s: no peer, no fill_empty\n",
+                               __func__);
+               return;
+       }
+       cq.op = MISDN_CTRL_FILL_EMPTY;
+       cq.p1 = 1;
+       if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
+               printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
+                       __func__);
+               return;
+       }
+       if (dsp_debug & DEBUG_DSP_CORE)
+               printk(KERN_DEBUG "%s: %s set fill_empty = 1\n",
+                       __func__, dsp->name);
+}
+
 static int
 dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
 {
@@ -593,8 +621,6 @@ get_features(struct mISDNchannel *ch)
        struct dsp              *dsp = container_of(ch, struct dsp, ch);
        struct mISDN_ctrl_req   cq;
 
-       if (dsp_options & DSP_OPT_NOHARDWARE)
-               return;
        if (!ch->peer) {
                if (dsp_debug & DEBUG_DSP_CORE)
                        printk(KERN_DEBUG "%s: no peer, no features\n",
@@ -610,6 +636,10 @@ get_features(struct mISDNchannel *ch)
        }
        if (cq.op & MISDN_CTRL_RX_OFF)
                dsp->features_rx_off = 1;
+       if (cq.op & MISDN_CTRL_FILL_EMPTY)
+               dsp->features_fill_empty = 1;
+       if (dsp_options & DSP_OPT_NOHARDWARE)
+               return;
        if ((cq.op & MISDN_CTRL_HW_FEATURES_OP)) {
                cq.op = MISDN_CTRL_HW_FEATURES;
                *((u_long *)&cq.p1) = (u_long)&dsp->features;
@@ -865,6 +895,9 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
                if (dsp->dtmf.hardware || dsp->dtmf.software)
                        dsp_dtmf_goertzel_init(dsp);
                get_features(ch);
+               /* enable fill_empty feature */
+               if (dsp->features_fill_empty)
+                       dsp_fill_empty(dsp);
                /* send ph_activate */
                hh->prim = PH_ACTIVATE_REQ;
                if (ch->peer)
index e794dfb87504666042a1fa8e634ea6657fe06bdf..9384b92dfc65eb176312b081d8af927052716aea 100644 (file)
 #define FLG_L2DATA             14      /* channel use L2 DATA primitivs */
 #define FLG_ORIGIN             15      /* channel is on origin site */
 /* channel specific stuff */
+#define FLG_FILLEMPTY          16      /* fill fifo on first frame (empty) */
 /* arcofi specific */
-#define FLG_ARCOFI_TIMER       16
-#define FLG_ARCOFI_ERROR       17
+#define FLG_ARCOFI_TIMER       17
+#define FLG_ARCOFI_ERROR       18
 /* isar specific */
-#define FLG_INITIALIZED                16
-#define FLG_DLEETX             17
-#define FLG_LASTDLE            18
-#define FLG_FIRST              19
-#define FLG_LASTDATA           20
-#define FLG_NMD_DATA           21
-#define FLG_FTI_RUN            22
-#define FLG_LL_OK              23
-#define FLG_LL_CONN            24
-#define FLG_DTMFSEND           25
+#define FLG_INITIALIZED                17
+#define FLG_DLEETX             18
+#define FLG_LASTDLE            19
+#define FLG_FIRST              20
+#define FLG_LASTDATA           21
+#define FLG_NMD_DATA           22
+#define FLG_FTI_RUN            23
+#define FLG_LL_OK              24
+#define FLG_LL_CONN            25
+#define FLG_DTMFSEND           26
 
 /* workq events */
 #define FLG_RECVQUEUE          30
index 8f2d60da04e757f1e1c5a9bbd26f486916a419da..74c903cd7a0a7728acf59d5353b151c1fb5a1ed1 100644 (file)
@@ -312,6 +312,7 @@ clear_channelmap(u_int nr, u_char *map)
 #define MISDN_CTRL_SETPEER             0x0040
 #define MISDN_CTRL_UNSETPEER           0x0080
 #define MISDN_CTRL_RX_OFF              0x0100
+#define MISDN_CTRL_FILL_EMPTY          0x0200
 #define MISDN_CTRL_HW_FEATURES_OP      0x2000
 #define MISDN_CTRL_HW_FEATURES         0x2001
 #define MISDN_CTRL_HFC_OP              0x4000