Commit 6d1ee48f authored by Karsten Keil's avatar Karsten Keil Committed by David S. Miller

mISDN: Implement MISDN_CTRL_FILL_EMPTY for more drivers

MISDN_CTRL_FILL_EMPTY is a meachanism to send a fixed value (normally silence)
as long no data from upper layers is available. It can be used when recording
voice messages or with unidirectional protocols.
Signed-off-by: default avatarKarsten Keil <kkeil@linux-pingi.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 034005a0
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include "ipac.h" #include "ipac.h"
#define AVMFRITZ_REV "2.2" #define AVMFRITZ_REV "2.3"
static int AVM_cnt; static int AVM_cnt;
static int debug; static int debug;
...@@ -442,19 +442,26 @@ hdlc_fill_fifo(struct bchannel *bch) ...@@ -442,19 +442,26 @@ hdlc_fill_fifo(struct bchannel *bch)
{ {
struct fritzcard *fc = bch->hw; struct fritzcard *fc = bch->hw;
struct hdlc_hw *hdlc; struct hdlc_hw *hdlc;
int count, fs, cnt = 0; int count, fs, cnt = 0, idx, fillempty = 0;
u8 *p; u8 *p;
u32 *ptr, val, addr; u32 *ptr, val, addr;
hdlc = &fc->hdlc[(bch->nr - 1) & 1]; idx = (bch->nr - 1) & 1;
if (!bch->tx_skb) hdlc = &fc->hdlc[idx];
return;
count = bch->tx_skb->len - bch->tx_idx;
if (count <= 0)
return;
fs = (fc->type == AVM_FRITZ_PCIV2) ? fs = (fc->type == AVM_FRITZ_PCIV2) ?
HDLC_FIFO_SIZE_V2 : HDLC_FIFO_SIZE_V1; HDLC_FIFO_SIZE_V2 : HDLC_FIFO_SIZE_V1;
p = bch->tx_skb->data + bch->tx_idx; if (!bch->tx_skb) {
if (!test_bit(FLG_TX_EMPTY, &bch->Flags))
return;
count = fs;
p = bch->fill;
fillempty = 1;
} else {
count = bch->tx_skb->len - bch->tx_idx;
if (count <= 0)
return;
p = bch->tx_skb->data + bch->tx_idx;
}
hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XME; hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XME;
if (count > fs) { if (count > fs) {
count = fs; count = fs;
...@@ -462,10 +469,14 @@ hdlc_fill_fifo(struct bchannel *bch) ...@@ -462,10 +469,14 @@ hdlc_fill_fifo(struct bchannel *bch)
if (test_bit(FLG_HDLC, &bch->Flags)) if (test_bit(FLG_HDLC, &bch->Flags))
hdlc->ctrl.sr.cmd |= HDLC_CMD_XME; hdlc->ctrl.sr.cmd |= HDLC_CMD_XME;
} }
pr_debug("%s: %s %d/%d/%d", fc->name, __func__, count,
bch->tx_idx, bch->tx_skb->len);
ptr = (u32 *)p; ptr = (u32 *)p;
bch->tx_idx += count; if (fillempty) {
pr_debug("%s.B%d: %d/%d/%d", fc->name, bch->nr, count,
bch->tx_idx, bch->tx_skb->len);
bch->tx_idx += count;
} else {
pr_debug("%s.B%d: fillempty %d\n", fc->name, bch->nr, count);
}
hdlc->ctrl.sr.xml = ((count == fs) ? 0 : count); hdlc->ctrl.sr.xml = ((count == fs) ? 0 : count);
if (fc->type == AVM_FRITZ_PCIV2) { if (fc->type == AVM_FRITZ_PCIV2) {
__write_ctrl_pciv2(fc, hdlc, bch->nr); __write_ctrl_pciv2(fc, hdlc, bch->nr);
...@@ -475,13 +486,21 @@ hdlc_fill_fifo(struct bchannel *bch) ...@@ -475,13 +486,21 @@ hdlc_fill_fifo(struct bchannel *bch)
__write_ctrl_pci(fc, hdlc, bch->nr); __write_ctrl_pci(fc, hdlc, bch->nr);
addr = fc->addr + CHIP_WINDOW; addr = fc->addr + CHIP_WINDOW;
} }
while (cnt < count) { if (fillempty) {
val = get_unaligned(ptr); while (cnt < count) {
outl(cpu_to_le32(val), addr); /* all bytes the same - no worry about endian */
ptr++; outl(*ptr, addr);
cnt += 4; cnt += 4;
}
} else {
while (cnt < count) {
val = get_unaligned(ptr);
outl(cpu_to_le32(val), addr);
ptr++;
cnt += 4;
}
} }
if (debug & DEBUG_HW_BFIFO) { if ((debug & DEBUG_HW_BFIFO) && !fillempty) {
snprintf(fc->log, LOG_SIZE, "B%1d-send %s %d ", snprintf(fc->log, LOG_SIZE, "B%1d-send %s %d ",
bch->nr, fc->name, count); bch->nr, fc->name, count);
print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count); print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
...@@ -496,8 +515,12 @@ HDLC_irq_xpr(struct bchannel *bch) ...@@ -496,8 +515,12 @@ HDLC_irq_xpr(struct bchannel *bch)
} else { } else {
if (bch->tx_skb) if (bch->tx_skb)
dev_kfree_skb(bch->tx_skb); dev_kfree_skb(bch->tx_skb);
if (get_next_bframe(bch)) if (get_next_bframe(bch)) {
hdlc_fill_fifo(bch); hdlc_fill_fifo(bch);
test_and_clear_bit(FLG_TX_EMPTY, &bch->Flags);
} else if (test_bit(FLG_TX_EMPTY, &bch->Flags)) {
hdlc_fill_fifo(bch);
}
} }
} }
...@@ -561,6 +584,8 @@ HDLC_irq(struct bchannel *bch, u32 stat) ...@@ -561,6 +584,8 @@ HDLC_irq(struct bchannel *bch, u32 stat)
if (bch->tx_skb && bch->tx_skb->len) { if (bch->tx_skb && bch->tx_skb->len) {
if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
bch->tx_idx = 0; bch->tx_idx = 0;
} else if (test_bit(FLG_FILLEMPTY, &bch->Flags)) {
test_and_set_bit(FLG_TX_EMPTY, &bch->Flags);
} }
hdlc->ctrl.sr.xml = 0; hdlc->ctrl.sr.xml = 0;
hdlc->ctrl.sr.cmd |= HDLC_CMD_XRS; hdlc->ctrl.sr.cmd |= HDLC_CMD_XRS;
...@@ -882,7 +907,6 @@ open_bchannel(struct fritzcard *fc, struct channel_req *rq) ...@@ -882,7 +907,6 @@ open_bchannel(struct fritzcard *fc, struct channel_req *rq)
bch = &fc->bch[rq->adr.channel - 1]; bch = &fc->bch[rq->adr.channel - 1];
if (test_and_set_bit(FLG_OPEN, &bch->Flags)) if (test_and_set_bit(FLG_OPEN, &bch->Flags))
return -EBUSY; /* b-channel can be only open once */ return -EBUSY; /* b-channel can be only open once */
test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
bch->ch.protocol = rq->protocol; bch->ch.protocol = rq->protocol;
rq->ch = &bch->ch; rq->ch = &bch->ch;
return 0; return 0;
......
...@@ -3576,7 +3576,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) ...@@ -3576,7 +3576,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
case MISDN_CTRL_GETOP: case MISDN_CTRL_GETOP:
ret = mISDN_ctrl_bchannel(bch, cq); ret = mISDN_ctrl_bchannel(bch, cq);
cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP | cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP |
MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY; MISDN_CTRL_RX_OFF;
break; break;
case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */ case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
hc->chan[bch->slot].rx_off = !!cq->p1; hc->chan[bch->slot].rx_off = !!cq->p1;
...@@ -3591,11 +3591,10 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) ...@@ -3591,11 +3591,10 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n", printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n",
__func__, bch->nr, hc->chan[bch->slot].rx_off); __func__, bch->nr, hc->chan[bch->slot].rx_off);
break; break;
case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */ case MISDN_CTRL_FILL_EMPTY:
test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); ret = mISDN_ctrl_bchannel(bch, cq);
if (debug & DEBUG_HFCMULTI_MSG) hc->silence = bch->fill[0];
printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d " memset(hc->silence_data, hc->silence, sizeof(hc->silence_data));
"off=%d)\n", __func__, bch->nr, !!cq->p1);
break; break;
case MISDN_CTRL_HW_FEATURES: /* fill features structure */ case MISDN_CTRL_HW_FEATURES: /* fill features structure */
if (debug & DEBUG_HFCMULTI_MSG) if (debug & DEBUG_HFCMULTI_MSG)
...@@ -4118,7 +4117,6 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch, ...@@ -4118,7 +4117,6 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
} }
if (test_and_set_bit(FLG_OPEN, &bch->Flags)) if (test_and_set_bit(FLG_OPEN, &bch->Flags))
return -EBUSY; /* b-channel can be only open once */ return -EBUSY; /* b-channel can be only open once */
test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
bch->ch.protocol = rq->protocol; bch->ch.protocol = rq->protocol;
hc->chan[ch].rx_off = 0; hc->chan[ch].rx_off = 0;
rq->ch = &bch->ch; rq->ch = &bch->ch;
......
...@@ -565,11 +565,6 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz, ...@@ -565,11 +565,6 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz,
if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL))
new_z2 -= B_FIFO_SIZE; /* buffer wrap */ new_z2 -= B_FIFO_SIZE; /* buffer wrap */
if (fcnt_rx > MAX_DATA_SIZE) { /* flush, if oversized */
*z2r = cpu_to_le16(new_z2); /* new position */
return;
}
fcnt_tx = le16_to_cpu(*z2t) - le16_to_cpu(*z1t); fcnt_tx = le16_to_cpu(*z2t) - le16_to_cpu(*z1t);
if (fcnt_tx <= 0) if (fcnt_tx <= 0)
fcnt_tx += B_FIFO_SIZE; fcnt_tx += B_FIFO_SIZE;
...@@ -761,9 +756,14 @@ hfcpci_fill_fifo(struct bchannel *bch) ...@@ -761,9 +756,14 @@ hfcpci_fill_fifo(struct bchannel *bch)
if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO)) if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO))
printk(KERN_DEBUG "%s\n", __func__); printk(KERN_DEBUG "%s\n", __func__);
if ((!bch->tx_skb) || bch->tx_skb->len <= 0) if ((!bch->tx_skb) || bch->tx_skb->len == 0) {
return; if (!test_bit(FLG_FILLEMPTY, &bch->Flags) &&
count = bch->tx_skb->len - bch->tx_idx; !test_bit(FLG_TRANSPARENT, &bch->Flags))
return;
count = HFCPCI_FILLEMPTY;
} else {
count = bch->tx_skb->len - bch->tx_idx;
}
if ((bch->nr & 2) && (!hc->hw.bswapped)) { if ((bch->nr & 2) && (!hc->hw.bswapped)) {
bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2; bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2;
bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b2; bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b2;
...@@ -782,16 +782,10 @@ hfcpci_fill_fifo(struct bchannel *bch) ...@@ -782,16 +782,10 @@ hfcpci_fill_fifo(struct bchannel *bch)
fcnt = le16_to_cpu(*z2t) - le16_to_cpu(*z1t); fcnt = le16_to_cpu(*z2t) - le16_to_cpu(*z1t);
if (fcnt <= 0) if (fcnt <= 0)
fcnt += B_FIFO_SIZE; fcnt += B_FIFO_SIZE;
/* fcnt contains available bytes in fifo */ if (test_bit(FLG_FILLEMPTY, &bch->Flags)) {
fcnt = B_FIFO_SIZE - fcnt; /* fcnt contains available bytes in fifo */
/* remaining bytes to send (bytes in fifo) */ if (count > fcnt)
count = fcnt;
/* "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_z1 = le16_to_cpu(*z1t) + count;
/* new buffer Position */ /* new buffer Position */
if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
...@@ -803,17 +797,20 @@ hfcpci_fill_fifo(struct bchannel *bch) ...@@ -803,17 +797,20 @@ hfcpci_fill_fifo(struct bchannel *bch)
printk(KERN_DEBUG "hfcpci_FFt fillempty " printk(KERN_DEBUG "hfcpci_FFt fillempty "
"fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n", "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n",
fcnt, maxlen, new_z1, dst); fcnt, maxlen, new_z1, dst);
fcnt += count;
if (maxlen > count) if (maxlen > count)
maxlen = count; /* limit size */ maxlen = count; /* limit size */
memset(dst, 0x2a, maxlen); /* first copy */ memset(dst, bch->fill[0], maxlen); /* first copy */
count -= maxlen; /* remaining bytes */ count -= maxlen; /* remaining bytes */
if (count) { if (count) {
dst = bdata; /* start of buffer */ dst = bdata; /* start of buffer */
memset(dst, 0x2a, count); memset(dst, bch->fill[0], count);
} }
*z1t = cpu_to_le16(new_z1); /* now send data */ *z1t = cpu_to_le16(new_z1); /* now send data */
return;
} }
/* fcnt contains available bytes in fifo */
fcnt = B_FIFO_SIZE - fcnt;
/* remaining bytes to send (bytes in fifo) */
next_t_frame: next_t_frame:
count = bch->tx_skb->len - bch->tx_idx; count = bch->tx_skb->len - bch->tx_idx;
...@@ -1531,24 +1528,7 @@ deactivate_bchannel(struct bchannel *bch) ...@@ -1531,24 +1528,7 @@ deactivate_bchannel(struct bchannel *bch)
static int static int
channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
{ {
int ret = 0; return mISDN_ctrl_bchannel(bch, cq);
switch (cq->op) {
case MISDN_CTRL_GETOP:
ret = mISDN_ctrl_bchannel(bch, cq);
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:
ret = mISDN_ctrl_bchannel(bch, cq);
break;
}
return ret;
} }
static int static int
hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
...@@ -1964,7 +1944,6 @@ open_bchannel(struct hfc_pci *hc, struct channel_req *rq) ...@@ -1964,7 +1944,6 @@ open_bchannel(struct hfc_pci *hc, struct channel_req *rq)
bch = &hc->bch[rq->adr.channel - 1]; bch = &hc->bch[rq->adr.channel - 1];
if (test_and_set_bit(FLG_OPEN, &bch->Flags)) if (test_and_set_bit(FLG_OPEN, &bch->Flags))
return -EBUSY; /* b-channel can be only open once */ return -EBUSY; /* b-channel can be only open once */
test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
bch->ch.protocol = rq->protocol; bch->ch.protocol = rq->protocol;
rq->ch = &bch->ch; /* TODO: E-channel */ rq->ch = &bch->ch; /* TODO: E-channel */
if (!try_module_get(THIS_MODULE)) if (!try_module_get(THIS_MODULE))
......
...@@ -491,7 +491,6 @@ open_bchannel(struct hfcsusb *hw, struct channel_req *rq) ...@@ -491,7 +491,6 @@ open_bchannel(struct hfcsusb *hw, struct channel_req *rq)
bch = &hw->bch[rq->adr.channel - 1]; bch = &hw->bch[rq->adr.channel - 1];
if (test_and_set_bit(FLG_OPEN, &bch->Flags)) if (test_and_set_bit(FLG_OPEN, &bch->Flags))
return -EBUSY; /* b-channel can be only open once */ return -EBUSY; /* b-channel can be only open once */
test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
bch->ch.protocol = rq->protocol; bch->ch.protocol = rq->protocol;
rq->ch = &bch->ch; rq->ch = &bch->ch;
...@@ -806,24 +805,7 @@ hfcsusb_ph_command(struct hfcsusb *hw, u_char command) ...@@ -806,24 +805,7 @@ hfcsusb_ph_command(struct hfcsusb *hw, u_char command)
static int static int
channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
{ {
int ret = 0; return mISDN_ctrl_bchannel(bch, cq);
switch (cq->op) {
case MISDN_CTRL_GETOP:
ret = mISDN_ctrl_bchannel(bch, cq);
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:
ret = mISDN_ctrl_bchannel(bch, cq);
break;
}
return ret;
} }
/* collect data from incoming interrupt or isochron USB data */ /* collect data from incoming interrupt or isochron USB data */
...@@ -1183,8 +1165,8 @@ tx_iso_complete(struct urb *urb) ...@@ -1183,8 +1165,8 @@ tx_iso_complete(struct urb *urb)
int k, tx_offset, num_isoc_packets, sink, remain, current_len, int k, tx_offset, num_isoc_packets, sink, remain, current_len,
errcode, hdlc, i; errcode, hdlc, i;
int *tx_idx; int *tx_idx;
int frame_complete, fifon, status; int frame_complete, fifon, status, fillempty = 0;
__u8 threshbit; __u8 threshbit, *p;
spin_lock(&hw->lock); spin_lock(&hw->lock);
if (fifo->stop_gracefull) { if (fifo->stop_gracefull) {
...@@ -1202,6 +1184,9 @@ tx_iso_complete(struct urb *urb) ...@@ -1202,6 +1184,9 @@ tx_iso_complete(struct urb *urb)
tx_skb = fifo->bch->tx_skb; tx_skb = fifo->bch->tx_skb;
tx_idx = &fifo->bch->tx_idx; tx_idx = &fifo->bch->tx_idx;
hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags); hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags);
if (!tx_skb && !hdlc &&
test_bit(FLG_FILLEMPTY, &fifo->bch->Flags))
fillempty = 1;
} else { } else {
printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n", printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n",
hw->name, __func__); hw->name, __func__);
...@@ -1260,6 +1245,8 @@ tx_iso_complete(struct urb *urb) ...@@ -1260,6 +1245,8 @@ tx_iso_complete(struct urb *urb)
/* Generate next ISO Packets */ /* Generate next ISO Packets */
if (tx_skb) if (tx_skb)
remain = tx_skb->len - *tx_idx; remain = tx_skb->len - *tx_idx;
else if (fillempty)
remain = 15; /* > not complete */
else else
remain = 0; remain = 0;
...@@ -1290,15 +1277,20 @@ tx_iso_complete(struct urb *urb) ...@@ -1290,15 +1277,20 @@ tx_iso_complete(struct urb *urb)
} }
/* copy tx data to iso-urb buffer */ /* copy tx data to iso-urb buffer */
memcpy(context_iso_urb->buffer + tx_offset + 1, p = context_iso_urb->buffer + tx_offset + 1;
(tx_skb->data + *tx_idx), current_len); if (fillempty) {
*tx_idx += current_len; memset(p, fifo->bch->fill[0],
current_len);
} else {
memcpy(p, (tx_skb->data + *tx_idx),
current_len);
*tx_idx += current_len;
}
urb->iso_frame_desc[k].offset = tx_offset; urb->iso_frame_desc[k].offset = tx_offset;
urb->iso_frame_desc[k].length = current_len + 1; urb->iso_frame_desc[k].length = current_len + 1;
/* USB data log for every D ISO out */ /* USB data log for every D ISO out */
if ((fifon == HFCUSB_D_RX) && if ((fifon == HFCUSB_D_RX) && !fillempty &&
(debug & DBG_HFC_USB_VERBOSE)) { (debug & DBG_HFC_USB_VERBOSE)) {
printk(KERN_DEBUG printk(KERN_DEBUG
"%s: %s (%d/%d) offs(%d) len(%d) ", "%s: %s (%d/%d) offs(%d) len(%d) ",
......
...@@ -969,22 +969,28 @@ hscx_fill_fifo(struct hscx_hw *hscx) ...@@ -969,22 +969,28 @@ hscx_fill_fifo(struct hscx_hw *hscx)
int count, more; int count, more;
u8 *p; u8 *p;
if (!hscx->bch.tx_skb) if (!hscx->bch.tx_skb) {
return; if (!test_bit(FLG_TX_EMPTY, &hscx->bch.Flags))
count = hscx->bch.tx_skb->len - hscx->bch.tx_idx; return;
if (count <= 0)
return;
p = hscx->bch.tx_skb->data + hscx->bch.tx_idx;
more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0;
if (count > hscx->fifo_size) {
count = hscx->fifo_size; count = hscx->fifo_size;
more = 1; more = 1;
} p = hscx->log;
pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr, count, memset(p, hscx->bch.fill[0], count);
hscx->bch.tx_idx, hscx->bch.tx_skb->len); } else {
hscx->bch.tx_idx += count; count = hscx->bch.tx_skb->len - hscx->bch.tx_idx;
if (count <= 0)
return;
p = hscx->bch.tx_skb->data + hscx->bch.tx_idx;
more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0;
if (count > hscx->fifo_size) {
count = hscx->fifo_size;
more = 1;
}
pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr,
count, hscx->bch.tx_idx, hscx->bch.tx_skb->len);
hscx->bch.tx_idx += count;
}
if (hscx->ip->type & IPAC_TYPE_IPACX) if (hscx->ip->type & IPAC_TYPE_IPACX)
hscx->ip->write_fifo(hscx->ip->hw, hscx->ip->write_fifo(hscx->ip->hw,
hscx->off + IPACX_XFIFOB, p, count); hscx->off + IPACX_XFIFOB, p, count);
...@@ -995,7 +1001,7 @@ hscx_fill_fifo(struct hscx_hw *hscx) ...@@ -995,7 +1001,7 @@ hscx_fill_fifo(struct hscx_hw *hscx)
} }
hscx_cmdr(hscx, more ? 0x08 : 0x0a); hscx_cmdr(hscx, more ? 0x08 : 0x0a);
if (hscx->bch.debug & DEBUG_HW_BFIFO) { if (hscx->bch.tx_skb && (hscx->bch.debug & DEBUG_HW_BFIFO)) {
snprintf(hscx->log, 64, "B%1d-send %s %d ", snprintf(hscx->log, 64, "B%1d-send %s %d ",
hscx->bch.nr, hscx->ip->name, count); hscx->bch.nr, hscx->ip->name, count);
print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count); print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
...@@ -1010,8 +1016,12 @@ hscx_xpr(struct hscx_hw *hx) ...@@ -1010,8 +1016,12 @@ hscx_xpr(struct hscx_hw *hx)
} else { } else {
if (hx->bch.tx_skb) if (hx->bch.tx_skb)
dev_kfree_skb(hx->bch.tx_skb); dev_kfree_skb(hx->bch.tx_skb);
if (get_next_bframe(&hx->bch)) if (get_next_bframe(&hx->bch)) {
hscx_fill_fifo(hx); hscx_fill_fifo(hx);
test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags);
} else if (test_bit(FLG_TX_EMPTY, &hx->bch.Flags)) {
hscx_fill_fifo(hx);
}
} }
} }
...@@ -1128,7 +1138,9 @@ ipac_irq(struct hscx_hw *hx, u8 ista) ...@@ -1128,7 +1138,9 @@ ipac_irq(struct hscx_hw *hx, u8 ista)
if (istab & IPACX_B_XDU) { if (istab & IPACX_B_XDU) {
if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) { if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) {
hscx_fill_fifo(hx); if (test_bit(FLG_FILLEMPTY, &hx->bch.Flags))
test_and_set_bit(FLG_TX_EMPTY, &hx->bch.Flags);
hscx_xpr(hx);
return; return;
} }
pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name, pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name,
......
...@@ -585,16 +585,25 @@ isar_fill_fifo(struct isar_ch *ch) ...@@ -585,16 +585,25 @@ isar_fill_fifo(struct isar_ch *ch)
u8 msb; u8 msb;
u8 *ptr; u8 *ptr;
pr_debug("%s: ch%d tx_skb %p tx_idx %d\n", pr_debug("%s: ch%d tx_skb %d tx_idx %d\n", ch->is->name, ch->bch.nr,
ch->is->name, ch->bch.nr, ch->bch.tx_skb, ch->bch.tx_idx); ch->bch.tx_skb ? ch->bch.tx_skb->len : -1, ch->bch.tx_idx);
if (!ch->bch.tx_skb) if (!(ch->is->bstat &
(ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
return;
if (!ch->bch.tx_skb) {
if (!test_bit(FLG_TX_EMPTY, &ch->bch.Flags) ||
(ch->bch.state != ISDN_P_B_RAW))
return;
count = ch->mml;
/* use the card buffer */
memset(ch->is->buf, ch->bch.fill[0], count);
send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
0, count, ch->is->buf);
return; return;
}
count = ch->bch.tx_skb->len - ch->bch.tx_idx; count = ch->bch.tx_skb->len - ch->bch.tx_idx;
if (count <= 0) if (count <= 0)
return; return;
if (!(ch->is->bstat &
(ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
return;
if (count > ch->mml) { if (count > ch->mml) {
msb = 0; msb = 0;
count = ch->mml; count = ch->mml;
...@@ -673,9 +682,9 @@ sel_bch_isar(struct isar_hw *isar, u8 dpath) ...@@ -673,9 +682,9 @@ sel_bch_isar(struct isar_hw *isar, u8 dpath)
static void static void
send_next(struct isar_ch *ch) send_next(struct isar_ch *ch)
{ {
pr_debug("%s: %s ch%d tx_skb %p tx_idx %d\n", pr_debug("%s: %s ch%d tx_skb %d tx_idx %d\n", ch->is->name, __func__,
ch->is->name, __func__, ch->bch.nr, ch->bch.nr, ch->bch.tx_skb ? ch->bch.tx_skb->len : -1,
ch->bch.tx_skb, ch->bch.tx_idx); ch->bch.tx_idx);
if (ch->bch.state == ISDN_P_B_T30_FAX) { if (ch->bch.state == ISDN_P_B_T30_FAX) {
if (ch->cmd == PCTRL_CMD_FTH) { if (ch->cmd == PCTRL_CMD_FTH) {
if (test_bit(FLG_LASTDATA, &ch->bch.Flags)) { if (test_bit(FLG_LASTDATA, &ch->bch.Flags)) {
...@@ -693,6 +702,9 @@ send_next(struct isar_ch *ch) ...@@ -693,6 +702,9 @@ send_next(struct isar_ch *ch)
dev_kfree_skb(ch->bch.tx_skb); dev_kfree_skb(ch->bch.tx_skb);
if (get_next_bframe(&ch->bch)) { if (get_next_bframe(&ch->bch)) {
isar_fill_fifo(ch); isar_fill_fifo(ch);
test_and_clear_bit(FLG_TX_EMPTY, &ch->bch.Flags);
} else if (test_bit(FLG_TX_EMPTY, &ch->bch.Flags)) {
isar_fill_fifo(ch);
} else { } else {
if (test_and_clear_bit(FLG_DLEETX, &ch->bch.Flags)) { if (test_and_clear_bit(FLG_DLEETX, &ch->bch.Flags)) {
if (test_and_clear_bit(FLG_LASTDATA, if (test_and_clear_bit(FLG_LASTDATA,
...@@ -707,6 +719,8 @@ send_next(struct isar_ch *ch) ...@@ -707,6 +719,8 @@ send_next(struct isar_ch *ch)
} else { } else {
deliver_status(ch, HW_MOD_CONNECT); deliver_status(ch, HW_MOD_CONNECT);
} }
} else if (test_bit(FLG_FILLEMPTY, &ch->bch.Flags)) {
test_and_set_bit(FLG_TX_EMPTY, &ch->bch.Flags);
} }
} }
} }
...@@ -1638,7 +1652,6 @@ isar_open(struct isar_hw *isar, struct channel_req *rq) ...@@ -1638,7 +1652,6 @@ isar_open(struct isar_hw *isar, struct channel_req *rq)
bch = &isar->ch[rq->adr.channel - 1].bch; bch = &isar->ch[rq->adr.channel - 1].bch;
if (test_and_set_bit(FLG_OPEN, &bch->Flags)) if (test_and_set_bit(FLG_OPEN, &bch->Flags))
return -EBUSY; /* b-channel can be only open once */ return -EBUSY; /* b-channel can be only open once */
test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
bch->ch.protocol = rq->protocol; bch->ch.protocol = rq->protocol;
rq->ch = &bch->ch; rq->ch = &bch->ch;
return 0; return 0;
......
...@@ -533,22 +533,31 @@ static void ...@@ -533,22 +533,31 @@ static void
fill_dma(struct tiger_ch *bc) fill_dma(struct tiger_ch *bc)
{ {
struct tiger_hw *card = bc->bch.hw; struct tiger_hw *card = bc->bch.hw;
int count, i; int count, i, fillempty = 0;
u32 m, v; u32 m, v, n = 0;
u8 *p; u8 *p;
if (bc->free == 0) if (bc->free == 0)
return; return;
count = bc->bch.tx_skb->len - bc->bch.tx_idx; if (!bc->bch.tx_skb) {
if (count <= 0) if (!test_bit(FLG_TX_EMPTY, &bc->bch.Flags))
return; return;
pr_debug("%s: %s B%1d %d/%d/%d/%d state %x idx %d/%d\n", card->name, fillempty = 1;
__func__, bc->bch.nr, count, bc->free, bc->bch.tx_idx, count = card->send.size >> 1;
bc->bch.tx_skb->len, bc->txstate, bc->idx, card->send.idx); p = bc->bch.fill;
} else {
count = bc->bch.tx_skb->len - bc->bch.tx_idx;
if (count <= 0)
return;
pr_debug("%s: %s B%1d %d/%d/%d/%d state %x idx %d/%d\n",
card->name, __func__, bc->bch.nr, count, bc->free,
bc->bch.tx_idx, bc->bch.tx_skb->len, bc->txstate,
bc->idx, card->send.idx);
p = bc->bch.tx_skb->data + bc->bch.tx_idx;
}
if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN)) if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN))
resync(bc, card); resync(bc, card);
p = bc->bch.tx_skb->data + bc->bch.tx_idx; if (test_bit(FLG_HDLC, &bc->bch.Flags) && !fillempty) {
if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
count = isdnhdlc_encode(&bc->hsend, p, count, &i, count = isdnhdlc_encode(&bc->hsend, p, count, &i,
bc->hsbuf, bc->free); bc->hsbuf, bc->free);
pr_debug("%s: B%1d hdlc encoded %d in %d\n", card->name, pr_debug("%s: B%1d hdlc encoded %d in %d\n", card->name,
...@@ -559,17 +568,33 @@ fill_dma(struct tiger_ch *bc) ...@@ -559,17 +568,33 @@ fill_dma(struct tiger_ch *bc)
} else { } else {
if (count > bc->free) if (count > bc->free)
count = bc->free; count = bc->free;
bc->bch.tx_idx += count; if (!fillempty)
bc->bch.tx_idx += count;
bc->free -= count; bc->free -= count;
} }
m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff; m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff;
for (i = 0; i < count; i++) { if (fillempty) {
if (bc->idx >= card->send.size) n = p[0];
bc->idx = 0; if (!(bc->bch.nr & 1))
v = card->send.start[bc->idx]; n <<= 8;
v &= m; for (i = 0; i < count; i++) {
v |= (bc->bch.nr & 1) ? (u32)(p[i]) : ((u32)(p[i])) << 8; if (bc->idx >= card->send.size)
card->send.start[bc->idx++] = v; bc->idx = 0;
v = card->send.start[bc->idx];
v &= m;
v |= n;
card->send.start[bc->idx++] = v;
}
} else {
for (i = 0; i < count; i++) {
if (bc->idx >= card->send.size)
bc->idx = 0;
v = card->send.start[bc->idx];
v &= m;
n = p[i];
v |= (bc->bch.nr & 1) ? n : n << 8;
card->send.start[bc->idx++] = v;
}
} }
if (debug & DEBUG_HW_BFIFO) { if (debug & DEBUG_HW_BFIFO) {
snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ", snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ",
...@@ -584,17 +609,26 @@ fill_dma(struct tiger_ch *bc) ...@@ -584,17 +609,26 @@ fill_dma(struct tiger_ch *bc)
static int static int
bc_next_frame(struct tiger_ch *bc) bc_next_frame(struct tiger_ch *bc)
{ {
int ret = 1;
if (bc->bch.tx_skb && bc->bch.tx_idx < bc->bch.tx_skb->len) { if (bc->bch.tx_skb && bc->bch.tx_idx < bc->bch.tx_skb->len) {
fill_dma(bc); fill_dma(bc);
} else { } else {
if (bc->bch.tx_skb) if (bc->bch.tx_skb)
dev_kfree_skb(bc->bch.tx_skb); dev_kfree_skb(bc->bch.tx_skb);
if (get_next_bframe(&bc->bch)) if (get_next_bframe(&bc->bch)) {
fill_dma(bc); fill_dma(bc);
else test_and_clear_bit(FLG_TX_EMPTY, &bc->bch.Flags);
return 0; } else if (test_bit(FLG_TX_EMPTY, &bc->bch.Flags)) {
fill_dma(bc);
} else if (test_bit(FLG_FILLEMPTY, &bc->bch.Flags)) {
test_and_set_bit(FLG_TX_EMPTY, &bc->bch.Flags);
ret = 0;
} else {
ret = 0;
}
} }
return 1; return ret;
} }
static void static void
......
...@@ -498,16 +498,22 @@ static void ...@@ -498,16 +498,22 @@ static void
W6692_fill_Bfifo(struct w6692_ch *wch) W6692_fill_Bfifo(struct w6692_ch *wch)
{ {
struct w6692_hw *card = wch->bch.hw; struct w6692_hw *card = wch->bch.hw;
int count; int count, fillempty = 0;
u8 *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS; u8 *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS;
pr_debug("%s: fill Bfifo\n", card->name); pr_debug("%s: fill Bfifo\n", card->name);
if (!wch->bch.tx_skb) if (!wch->bch.tx_skb) {
return; if (!test_bit(FLG_TX_EMPTY, &wch->bch.Flags))
count = wch->bch.tx_skb->len - wch->bch.tx_idx; return;
if (count <= 0) ptr = wch->bch.fill;
return; count = W_B_FIFO_THRESH;
ptr = wch->bch.tx_skb->data + wch->bch.tx_idx; fillempty = 1;
} else {
count = wch->bch.tx_skb->len - wch->bch.tx_idx;
if (count <= 0)
return;
ptr = wch->bch.tx_skb->data + wch->bch.tx_idx;
}
if (count > W_B_FIFO_THRESH) if (count > W_B_FIFO_THRESH)
count = W_B_FIFO_THRESH; count = W_B_FIFO_THRESH;
else if (test_bit(FLG_HDLC, &wch->bch.Flags)) else if (test_bit(FLG_HDLC, &wch->bch.Flags))
...@@ -516,9 +522,16 @@ W6692_fill_Bfifo(struct w6692_ch *wch) ...@@ -516,9 +522,16 @@ W6692_fill_Bfifo(struct w6692_ch *wch)
pr_debug("%s: fill Bfifo%d/%d\n", card->name, pr_debug("%s: fill Bfifo%d/%d\n", card->name,
count, wch->bch.tx_idx); count, wch->bch.tx_idx);
wch->bch.tx_idx += count; wch->bch.tx_idx += count;
outsb(wch->addr + W_B_XFIFO, ptr, count); if (fillempty) {
while (count > 0) {
outsb(wch->addr + W_B_XFIFO, ptr, MISDN_BCH_FILL_SIZE);
count -= MISDN_BCH_FILL_SIZE;
}
} else {
outsb(wch->addr + W_B_XFIFO, ptr, count);
}
WriteW6692B(wch, W_B_CMDR, cmd); WriteW6692B(wch, W_B_CMDR, cmd);
if (debug & DEBUG_HW_DFIFO) { if ((debug & DEBUG_HW_BFIFO) && !fillempty) {
snprintf(card->log, 63, "B%1d-send %s %d ", snprintf(card->log, 63, "B%1d-send %s %d ",
wch->bch.nr, card->name, count); wch->bch.nr, card->name, count);
print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count); print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
...@@ -637,8 +650,12 @@ send_next(struct w6692_ch *wch) ...@@ -637,8 +650,12 @@ send_next(struct w6692_ch *wch)
} else { } else {
if (wch->bch.tx_skb) if (wch->bch.tx_skb)
dev_kfree_skb(wch->bch.tx_skb); dev_kfree_skb(wch->bch.tx_skb);
if (get_next_bframe(&wch->bch)) if (get_next_bframe(&wch->bch)) {
W6692_fill_Bfifo(wch);
test_and_clear_bit(FLG_TX_EMPTY, &wch->bch.Flags);
} else if (test_bit(FLG_TX_EMPTY, &wch->bch.Flags)) {
W6692_fill_Bfifo(wch); W6692_fill_Bfifo(wch);
}
} }
} }
...@@ -727,8 +744,8 @@ W6692B_interrupt(struct w6692_hw *card, int ch) ...@@ -727,8 +744,8 @@ W6692B_interrupt(struct w6692_hw *card, int ch)
wch->bch.nr, star); wch->bch.nr, star);
} }
if (star & W_B_STAR_XDOW) { if (star & W_B_STAR_XDOW) {
pr_debug("%s: B%d XDOW proto=%x\n", card->name, pr_warning("%s: B%d XDOW proto=%x\n", card->name,
wch->bch.nr, wch->bch.state); wch->bch.nr, wch->bch.state);
#ifdef ERROR_STATISTIC #ifdef ERROR_STATISTIC
wch->bch.err_xdu++; wch->bch.err_xdu++;
#endif #endif
...@@ -741,20 +758,21 @@ W6692B_interrupt(struct w6692_hw *card, int ch) ...@@ -741,20 +758,21 @@ W6692B_interrupt(struct w6692_hw *card, int ch)
} }
} }
send_next(wch); send_next(wch);
if (stat & W_B_EXI_XDUN) if (star & W_B_STAR_XDOW)
return; /* handle XDOW only once */ return; /* handle XDOW only once */
} }
if (stat & W_B_EXI_XDUN) { if (stat & W_B_EXI_XDUN) {
pr_debug("%s: B%d XDUN proto=%x\n", card->name, pr_warning("%s: B%d XDUN proto=%x\n", card->name,
wch->bch.nr, wch->bch.state); wch->bch.nr, wch->bch.state);
#ifdef ERROR_STATISTIC #ifdef ERROR_STATISTIC
wch->bch.err_xdu++; wch->bch.err_xdu++;
#endif #endif
WriteW6692B(wch, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT); /* resend - no XRST needed */
/* resend */
if (wch->bch.tx_skb) { if (wch->bch.tx_skb) {
if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags)) if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
wch->bch.tx_idx = 0; wch->bch.tx_idx = 0;
} else if (test_bit(FLG_FILLEMPTY, &wch->bch.Flags)) {
test_and_set_bit(FLG_TX_EMPTY, &wch->bch.Flags);
} }
send_next(wch); send_next(wch);
} }
...@@ -993,7 +1011,6 @@ open_bchannel(struct w6692_hw *card, struct channel_req *rq) ...@@ -993,7 +1011,6 @@ open_bchannel(struct w6692_hw *card, struct channel_req *rq)
bch = &card->bc[rq->adr.channel - 1].bch; bch = &card->bc[rq->adr.channel - 1].bch;
if (test_and_set_bit(FLG_OPEN, &bch->Flags)) if (test_and_set_bit(FLG_OPEN, &bch->Flags))
return -EBUSY; /* b-channel can be only open once */ return -EBUSY; /* b-channel can be only open once */
test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
bch->ch.protocol = rq->protocol; bch->ch.protocol = rq->protocol;
rq->ch = &bch->ch; rq->ch = &bch->ch;
return 0; return 0;
......
...@@ -268,6 +268,7 @@ dsp_fill_empty(struct dsp *dsp) ...@@ -268,6 +268,7 @@ dsp_fill_empty(struct dsp *dsp)
} }
cq.op = MISDN_CTRL_FILL_EMPTY; cq.op = MISDN_CTRL_FILL_EMPTY;
cq.p1 = 1; cq.p1 = 1;
cq.p2 = dsp_silence;
if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) { if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n", printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
__func__); __func__);
......
...@@ -140,6 +140,8 @@ mISDN_clear_bchannel(struct bchannel *ch) ...@@ -140,6 +140,8 @@ mISDN_clear_bchannel(struct bchannel *ch)
test_and_clear_bit(FLG_TX_BUSY, &ch->Flags); test_and_clear_bit(FLG_TX_BUSY, &ch->Flags);
test_and_clear_bit(FLG_TX_NEXT, &ch->Flags); test_and_clear_bit(FLG_TX_NEXT, &ch->Flags);
test_and_clear_bit(FLG_ACTIVE, &ch->Flags); test_and_clear_bit(FLG_ACTIVE, &ch->Flags);
test_and_clear_bit(FLG_FILLEMPTY, &ch->Flags);
test_and_clear_bit(FLG_TX_EMPTY, &ch->Flags);
ch->minlen = ch->init_minlen; ch->minlen = ch->init_minlen;
ch->next_minlen = ch->init_minlen; ch->next_minlen = ch->init_minlen;
ch->maxlen = ch->init_maxlen; ch->maxlen = ch->init_maxlen;
...@@ -165,7 +167,15 @@ mISDN_ctrl_bchannel(struct bchannel *bch, struct mISDN_ctrl_req *cq) ...@@ -165,7 +167,15 @@ mISDN_ctrl_bchannel(struct bchannel *bch, struct mISDN_ctrl_req *cq)
switch (cq->op) { switch (cq->op) {
case MISDN_CTRL_GETOP: case MISDN_CTRL_GETOP:
cq->op = MISDN_CTRL_RX_BUFFER; cq->op = MISDN_CTRL_RX_BUFFER | MISDN_CTRL_FILL_EMPTY;
break;
case MISDN_CTRL_FILL_EMPTY:
if (cq->p1) {
memset(bch->fill, cq->p2 & 0xff, MISDN_BCH_FILL_SIZE);
test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
} else {
test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
}
break; break;
case MISDN_CTRL_RX_BUFFER: case MISDN_CTRL_RX_BUFFER:
if (cq->p2 > MISDN_CTRL_RX_SIZE_IGNORE) if (cq->p2 > MISDN_CTRL_RX_SIZE_IGNORE)
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
#define FLG_LL_OK 24 #define FLG_LL_OK 24
#define FLG_LL_CONN 25 #define FLG_LL_CONN 25
#define FLG_DTMFSEND 26 #define FLG_DTMFSEND 26
#define FLG_TX_EMPTY 27
/* workq events */ /* workq events */
#define FLG_RECVQUEUE 30 #define FLG_RECVQUEUE 30
#define FLG_PHCHANGE 31 #define FLG_PHCHANGE 31
...@@ -142,6 +142,7 @@ extern int create_l1(struct dchannel *, dchannel_l1callback *); ...@@ -142,6 +142,7 @@ extern int create_l1(struct dchannel *, dchannel_l1callback *);
struct layer1; struct layer1;
extern int l1_event(struct layer1 *, u_int); extern int l1_event(struct layer1 *, u_int);
#define MISDN_BCH_FILL_SIZE 4
struct bchannel { struct bchannel {
struct mISDNchannel ch; struct mISDNchannel ch;
...@@ -153,6 +154,7 @@ struct bchannel { ...@@ -153,6 +154,7 @@ struct bchannel {
int slot; /* multiport card channel slot */ int slot; /* multiport card channel slot */
struct timer_list timer; struct timer_list timer;
/* receive data */ /* receive data */
u8 fill[MISDN_BCH_FILL_SIZE];
struct sk_buff *rx_skb; struct sk_buff *rx_skb;
unsigned short maxlen; unsigned short maxlen;
unsigned short init_maxlen; /* initial value */ unsigned short init_maxlen; /* initial value */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment