Skip to content

Commit

Permalink
mISDN: Allow to set a minimum length for transparent data
Browse files Browse the repository at this point in the history
If the FIFO of the card is small, many short messages are queued up to
the upper layers and the userspace. This change allows the applications
to set a minimum datalen they want from the drivers.
Create a common control function to avoid code duplication in each
driver.

Signed-off-by: Karsten Keil <kkeil@linux-pingi.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
kkeil authored and davem330 committed May 16, 2012
1 parent 7206e65 commit 034005a
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 132 deletions.
35 changes: 13 additions & 22 deletions drivers/isdn/hardware/mISDN/avmfritz.c
Original file line number Diff line number Diff line change
Expand Up @@ -536,12 +536,12 @@ HDLC_irq(struct bchannel *bch, u32 stat)
hdlc_empty_fifo(bch, len);
if (!bch->rx_skb)
goto handle_tx;
if (test_bit(FLG_TRANSPARENT, &bch->Flags) ||
(stat & HDLC_STAT_RME)) {
if (((stat & HDLC_STAT_CRCVFRRAB) ==
HDLC_STAT_CRCVFR) ||
test_bit(FLG_TRANSPARENT, &bch->Flags)) {
recv_Bchannel(bch, 0);
if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
recv_Bchannel(bch, 0, false);
} else if (stat & HDLC_STAT_RME) {
if ((stat & HDLC_STAT_CRCVFRRAB) ==
HDLC_STAT_CRCVFR) {
recv_Bchannel(bch, 0, false);
} else {
pr_warning("%s: got invalid frame\n",
fc->name);
Expand Down Expand Up @@ -809,21 +809,7 @@ init_card(struct fritzcard *fc)
static int
channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
{
int ret = 0;
struct fritzcard *fc = bch->hw;

switch (cq->op) {
case MISDN_CTRL_GETOP:
cq->op = 0;
break;
/* Nothing implemented yet */
case MISDN_CTRL_FILL_EMPTY:
default:
pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op);
ret = -EINVAL;
break;
}
return ret;
return mISDN_ctrl_bchannel(bch, cq);
}

static int
Expand Down Expand Up @@ -1019,6 +1005,7 @@ static int __devinit
setup_instance(struct fritzcard *card)
{
int i, err;
unsigned short minsize;
u_long flags;

snprintf(card->name, MISDN_MAX_IDLEN - 1, "AVM.%d", AVM_cnt + 1);
Expand All @@ -1038,7 +1025,11 @@ setup_instance(struct fritzcard *card)
for (i = 0; i < 2; i++) {
card->bch[i].nr = i + 1;
set_channelmap(i + 1, card->isac.dch.dev.channelmap);
mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM);
if (AVM_FRITZ_PCIV2 == card->type)
minsize = HDLC_FIFO_SIZE_V2;
else
minsize = HDLC_FIFO_SIZE_V1;
mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, minsize);
card->bch[i].hw = card;
card->bch[i].ch.send = avm_l2l1B;
card->bch[i].ch.ctrl = avm_bctrl;
Expand Down
17 changes: 8 additions & 9 deletions drivers/isdn/hardware/mISDN/hfcmulti.c
Original file line number Diff line number Diff line change
Expand Up @@ -2352,7 +2352,7 @@ hfcmulti_rx(struct hfc_multi *hc, int ch)
if (dch)
recv_Dchannel(dch);
else
recv_Bchannel(bch, MISDN_ID_ANY);
recv_Bchannel(bch, MISDN_ID_ANY, false);
*sp = skb;
again++;
goto next_frame;
Expand All @@ -2367,7 +2367,7 @@ hfcmulti_rx(struct hfc_multi *hc, int ch)
"(z1=%04x, z2=%04x) TRANS\n",
__func__, hc->id + 1, ch, Zsize, z1, z2);
/* only bch is transparent */
recv_Bchannel(bch, hc->chan[ch].Zfill);
recv_Bchannel(bch, hc->chan[ch].Zfill, false);
}
}

Expand Down Expand Up @@ -3574,8 +3574,9 @@ 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_FILL_EMPTY;
ret = mISDN_ctrl_bchannel(bch, cq);
cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP |
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;
Expand Down Expand Up @@ -3683,9 +3684,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
ret = -EINVAL;
break;
default:
printk(KERN_WARNING "%s: unknown Op %x\n",
__func__, cq->op);
ret = -EINVAL;
ret = mISDN_ctrl_bchannel(bch, cq);
break;
}
return ret;
Expand Down Expand Up @@ -4855,7 +4854,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
bch->nr = ch;
bch->slot = ch;
bch->debug = debug;
mISDN_initbchannel(bch, MAX_DATA_MEM);
mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1);
bch->hw = hc;
bch->ch.send = handle_bmsg;
bch->ch.ctrl = hfcm_bctrl;
Expand Down Expand Up @@ -4928,7 +4927,7 @@ init_multi_port(struct hfc_multi *hc, int pt)
bch->nr = ch + 1;
bch->slot = i + ch;
bch->debug = debug;
mISDN_initbchannel(bch, MAX_DATA_MEM);
mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1);
bch->hw = hc;
bch->ch.send = handle_bmsg;
bch->ch.ctrl = hfcm_bctrl;
Expand Down
12 changes: 6 additions & 6 deletions drivers/isdn/hardware/mISDN/hfcpci.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
}
bz->za[new_f2].z2 = cpu_to_le16(new_z2);
bz->f2 = new_f2; /* next buffer */
recv_Bchannel(bch, MISDN_ID_ANY);
recv_Bchannel(bch, MISDN_ID_ANY, false);
}
}

Expand Down Expand Up @@ -599,7 +599,7 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz,
ptr1 = bdata; /* start of buffer */
memcpy(ptr, ptr1, fcnt_rx); /* rest */
}
recv_Bchannel(bch, fcnt_tx); /* bch, id */
recv_Bchannel(bch, fcnt_tx, false); /* bch, id, !force */
}
*z2r = cpu_to_le16(new_z2); /* new position */
}
Expand Down Expand Up @@ -1535,7 +1535,8 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)

switch (cq->op) {
case MISDN_CTRL_GETOP:
cq->op = MISDN_CTRL_FILL_EMPTY;
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);
Expand All @@ -1544,8 +1545,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
"off=%d)\n", __func__, bch->nr, !!cq->p1);
break;
default:
printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op);
ret = -EINVAL;
ret = mISDN_ctrl_bchannel(bch, cq);
break;
}
return ret;
Expand Down Expand Up @@ -2116,7 +2116,7 @@ setup_card(struct hfc_pci *card)
card->bch[i].nr = i + 1;
set_channelmap(i + 1, card->dch.dev.channelmap);
card->bch[i].debug = debug;
mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM);
mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, poll >> 1);
card->bch[i].hw = card;
card->bch[i].ch.send = hfcpci_l2l1B;
card->bch[i].ch.ctrl = hfc_bctrl;
Expand Down
14 changes: 7 additions & 7 deletions drivers/isdn/hardware/mISDN/hfcsusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,8 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)

switch (cq->op) {
case MISDN_CTRL_GETOP:
cq->op = MISDN_CTRL_FILL_EMPTY;
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);
Expand All @@ -819,8 +820,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
"off=%d)\n", __func__, bch->nr, !!cq->p1);
break;
default:
printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op);
ret = -EINVAL;
ret = mISDN_ctrl_bchannel(bch, cq);
break;
}
return ret;
Expand Down Expand Up @@ -931,7 +931,8 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
if (fifo->dch)
recv_Dchannel(fifo->dch);
if (fifo->bch)
recv_Bchannel(fifo->bch, MISDN_ID_ANY);
recv_Bchannel(fifo->bch, MISDN_ID_ANY,
0);
if (fifo->ech)
recv_Echannel(fifo->ech,
&hw->dch);
Expand All @@ -952,8 +953,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
}
} else {
/* deliver transparent data to layer2 */
if (rx_skb->len >= poll)
recv_Bchannel(fifo->bch, MISDN_ID_ANY);
recv_Bchannel(fifo->bch, MISDN_ID_ANY, false);
}
spin_unlock(&hw->lock);
}
Expand Down Expand Up @@ -1861,7 +1861,7 @@ setup_instance(struct hfcsusb *hw, struct device *parent)
hw->bch[i].nr = i + 1;
set_channelmap(i + 1, hw->dch.dev.channelmap);
hw->bch[i].debug = debug;
mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM);
mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM, poll >> 1);
hw->bch[i].hw = hw;
hw->bch[i].ch.send = hfcusb_l2l1B;
hw->bch[i].ch.ctrl = hfc_bctrl;
Expand Down
27 changes: 6 additions & 21 deletions drivers/isdn/hardware/mISDN/mISDNipac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,7 @@ ipac_rme(struct hscx_hw *hx)
skb_trim(hx->bch.rx_skb, 0);
} else {
skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1);
recv_Bchannel(&hx->bch, 0);
recv_Bchannel(&hx->bch, 0, false);
}
}

Expand Down Expand Up @@ -1114,11 +1114,8 @@ ipac_irq(struct hscx_hw *hx, u8 ista)

if (istab & IPACX_B_RPF) {
hscx_empty_fifo(hx, hx->fifo_size);
if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) {
/* receive transparent audio data */
if (hx->bch.rx_skb)
recv_Bchannel(&hx->bch, 0);
}
if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags))
recv_Bchannel(&hx->bch, 0, false);
}

if (istab & IPACX_B_RFO) {
Expand Down Expand Up @@ -1377,20 +1374,7 @@ hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
static int
channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
{
int ret = 0;

switch (cq->op) {
case MISDN_CTRL_GETOP:
cq->op = 0;
break;
/* Nothing implemented yet */
case MISDN_CTRL_FILL_EMPTY:
default:
pr_info("%s: unknown Op %x\n", __func__, cq->op);
ret = -EINVAL;
break;
}
return ret;
return mISDN_ctrl_bchannel(bch, cq);
}

static int
Expand Down Expand Up @@ -1608,7 +1592,8 @@ mISDNipac_init(struct ipac_hw *ipac, void *hw)
set_channelmap(i + 1, ipac->isac.dch.dev.channelmap);
list_add(&ipac->hscx[i].bch.ch.list,
&ipac->isac.dch.dev.bchannels);
mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM);
mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM,
ipac->hscx[i].fifo_size);
ipac->hscx[i].bch.ch.nr = i + 1;
ipac->hscx[i].bch.ch.send = &hscx_l2l1;
ipac->hscx[i].bch.ch.ctrl = hscx_bctrl;
Expand Down
25 changes: 6 additions & 19 deletions drivers/isdn/hardware/mISDN/mISDNisar.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ isar_rcv_frame(struct isar_ch *ch)
break;
}
rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
recv_Bchannel(&ch->bch, 0);
recv_Bchannel(&ch->bch, 0, false);
break;
case ISDN_P_B_HDLC:
maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb);
Expand Down Expand Up @@ -481,7 +481,7 @@ isar_rcv_frame(struct isar_ch *ch)
break;
}
skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
recv_Bchannel(&ch->bch, 0);
recv_Bchannel(&ch->bch, 0, false);
}
break;
case ISDN_P_B_T30_FAX:
Expand Down Expand Up @@ -517,7 +517,7 @@ isar_rcv_frame(struct isar_ch *ch)
ch->state = STFAX_ESCAPE;
/* set_skb_flag(skb, DF_NOMOREDATA); */
}
recv_Bchannel(&ch->bch, 0);
recv_Bchannel(&ch->bch, 0, false);
if (ch->is->cmsb & SART_NMD)
deliver_status(ch, HW_MOD_NOCARR);
break;
Expand Down Expand Up @@ -557,7 +557,7 @@ isar_rcv_frame(struct isar_ch *ch)
break;
}
skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
recv_Bchannel(&ch->bch, 0);
recv_Bchannel(&ch->bch, 0, false);
}
if (ch->is->cmsb & SART_NMD) { /* ABORT */
pr_debug("%s: isar_rcv_frame: no more data\n",
Expand Down Expand Up @@ -1554,20 +1554,7 @@ isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
static int
channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
{
int ret = 0;

switch (cq->op) {
case MISDN_CTRL_GETOP:
cq->op = 0;
break;
/* Nothing implemented yet */
case MISDN_CTRL_FILL_EMPTY:
default:
pr_info("%s: unknown Op %x\n", __func__, cq->op);
ret = -EINVAL;
break;
}
return ret;
return mISDN_ctrl_bchannel(bch, cq);
}

static int
Expand Down Expand Up @@ -1665,7 +1652,7 @@ mISDNisar_init(struct isar_hw *isar, void *hw)
isar->hw = hw;
for (i = 0; i < 2; i++) {
isar->ch[i].bch.nr = i + 1;
mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM);
mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM, 32);
isar->ch[i].bch.ch.nr = i + 1;
isar->ch[i].bch.ch.send = &isar_l2l1;
isar->ch[i].bch.ch.ctrl = isar_bctrl;
Expand Down
23 changes: 5 additions & 18 deletions drivers/isdn/hardware/mISDN/netjet.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ read_dma(struct tiger_ch *bc, u32 idx, int cnt)
}

if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) {
recv_Bchannel(&bc->bch, 0);
recv_Bchannel(&bc->bch, 0, false);
return;
}

Expand All @@ -426,7 +426,7 @@ read_dma(struct tiger_ch *bc, u32 idx, int cnt)
DUMP_PREFIX_OFFSET, p,
stat);
}
recv_Bchannel(&bc->bch, 0);
recv_Bchannel(&bc->bch, 0, false);
stat = bchannel_get_rxbuf(&bc->bch, bc->bch.maxlen);
if (stat < 0) {
pr_warning("%s.B%d: No memory for %d bytes\n",
Expand Down Expand Up @@ -758,21 +758,7 @@ nj_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
static int
channel_bctrl(struct tiger_ch *bc, struct mISDN_ctrl_req *cq)
{
int ret = 0;
struct tiger_hw *card = bc->bch.hw;

switch (cq->op) {
case MISDN_CTRL_GETOP:
cq->op = 0;
break;
/* Nothing implemented yet */
case MISDN_CTRL_FILL_EMPTY:
default:
pr_info("%s: %s unknown Op %x\n", card->name, __func__, cq->op);
ret = -EINVAL;
break;
}
return ret;
return mISDN_ctrl_bchannel(&bc->bch, cq);
}

static int
Expand Down Expand Up @@ -1006,7 +992,8 @@ setup_instance(struct tiger_hw *card)
for (i = 0; i < 2; i++) {
card->bc[i].bch.nr = i + 1;
set_channelmap(i + 1, card->isac.dch.dev.channelmap);
mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM);
mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM,
NJ_DMA_RXSIZE >> 1);
card->bc[i].bch.hw = card;
card->bc[i].bch.ch.send = nj_l2l1B;
card->bc[i].bch.ch.ctrl = nj_bctrl;
Expand Down
Loading

0 comments on commit 034005a

Please sign in to comment.