Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 034005a0 authored by Karsten Keil's avatar Karsten Keil Committed by David S. Miller
Browse files

mISDN: Allow to set a minimum length for transparent data



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: default avatarKarsten Keil <kkeil@linux-pingi.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7206e659
Loading
Loading
Loading
Loading
+13 −22
Original line number Diff line number Diff line
@@ -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);
@@ -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
@@ -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);
@@ -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;
+8 −9
Original line number Diff line number Diff line
@@ -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;
@@ -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);
	}
}

@@ -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;
@@ -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;
@@ -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;
@@ -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;
+6 −6
Original line number Diff line number Diff line
@@ -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);
	}
}

@@ -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 */
}
@@ -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);
@@ -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;
@@ -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;
+7 −7
Original line number Diff line number Diff line
@@ -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);
@@ -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;
@@ -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);
@@ -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);
}
@@ -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;
+6 −21
Original line number Diff line number Diff line
@@ -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);
	}
}

@@ -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) {
@@ -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
@@ -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;
Loading