Пример #1
0
int
bchannel_senddata(struct bchannel *ch, struct sk_buff *skb)
{

	/* check oversize */
	if (skb->len <= 0) {
		printk(KERN_WARNING "%s: skb too small\n", __func__);
		return -EINVAL;
	}
	if (skb->len > ch->maxlen) {
		printk(KERN_WARNING "%s: skb too large(%d/%d)\n",
		       __func__, skb->len, ch->maxlen);
		return -EINVAL;
	}
	/* HW lock must be obtained */
	/* check for pending next_skb */
	if (ch->next_skb) {
		printk(KERN_WARNING
		       "%s: next_skb exist ERROR (skb->len=%d next_skb->len=%d)\n",
		       __func__, skb->len, ch->next_skb->len);
		return -EBUSY;
	}
	if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) {
		test_and_set_bit(FLG_TX_NEXT, &ch->Flags);
		ch->next_skb = skb;
		return 0;
	} else {
		/* write to fifo */
		ch->tx_skb = skb;
		ch->tx_idx = 0;
		confirm_Bsend(ch);
		return 1;
	}
}
Пример #2
0
static void
send_next(struct w6692_ch *wch)
{
	if (wch->bch.tx_skb && wch->bch.tx_idx < wch->bch.tx_skb->len)
		W6692_fill_Bfifo(wch);
	else {
		if (wch->bch.tx_skb) {
			
			if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
				confirm_Bsend(&wch->bch);
			dev_kfree_skb(wch->bch.tx_skb);
		}
		if (get_next_bframe(&wch->bch))
			W6692_fill_Bfifo(wch);
	}
}
Пример #3
0
static void
send_next(struct isar_ch *ch)
{
	pr_debug("%s: %s ch%d tx_skb %p tx_idx %d\n",
		ch->is->name, __func__, ch->bch.nr,
		ch->bch.tx_skb, ch->bch.tx_idx);
	if (ch->bch.state == ISDN_P_B_T30_FAX) {
		if (ch->cmd == PCTRL_CMD_FTH) {
			if (test_bit(FLG_LASTDATA, &ch->bch.Flags)) {
				pr_debug("set NMD_DATA\n");
				test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags);
			}
		} else if (ch->cmd == PCTRL_CMD_FTM) {
			if (test_bit(FLG_DLEETX, &ch->bch.Flags)) {
				test_and_set_bit(FLG_LASTDATA, &ch->bch.Flags);
				test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags);
			}
		}
	}
	if (ch->bch.tx_skb) {
		/* send confirm, on trans, free on hdlc. */
		if (test_bit(FLG_TRANSPARENT, &ch->bch.Flags))
			confirm_Bsend(&ch->bch);
		dev_kfree_skb(ch->bch.tx_skb);
	}
	if (get_next_bframe(&ch->bch))
		isar_fill_fifo(ch);
	else {
		if (test_and_clear_bit(FLG_DLEETX, &ch->bch.Flags)) {
			if (test_and_clear_bit(FLG_LASTDATA,
			    &ch->bch.Flags)) {
				if (test_and_clear_bit(FLG_NMD_DATA,
				    &ch->bch.Flags)) {
					u8 zd = 0;
					send_mbox(ch->is, SET_DPS(ch->dpath) |
						ISAR_HIS_SDATA, 0x01, 1, &zd);
				}
				test_and_set_bit(FLG_LL_OK, &ch->bch.Flags);
			} else {
				deliver_status(ch, HW_MOD_CONNECT);
			}
		}
	}
}
Пример #4
0
int
get_next_bframe(struct bchannel *bch)
{
	bch->tx_idx = 0;
	if (test_bit(FLG_TX_NEXT, &bch->Flags)) {
		bch->tx_skb = bch->next_skb;
		if (bch->tx_skb) {
			bch->next_skb = NULL;
			test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
			if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
				confirm_Bsend(bch); /* not for transparent */
			return 1;
		} else {
			test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
			printk(KERN_WARNING "B TX_NEXT without skb\n");
		}
	}
	bch->tx_skb = NULL;
	test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
	return 0;
}
Пример #5
0
int
get_next_bframe(struct bchannel *bch)
{
	bch->tx_idx = 0;
	if (test_bit(FLG_TX_NEXT, &bch->Flags)) {
		bch->tx_skb = bch->next_skb;
		if (bch->tx_skb) {
			bch->next_skb = NULL;
			test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
			/* confirm imediately to allow next data */
			confirm_Bsend(bch);
			return 1;
		} else {
			test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
			printk(KERN_WARNING "B TX_NEXT without skb\n");
		}
	}
	bch->tx_skb = NULL;
	test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
	return 0;
}