Пример #1
0
static int
w6692_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
{
	struct bchannel *bch = container_of(ch, struct bchannel, ch);
	struct w6692_ch	*bc = container_of(bch, struct w6692_ch, bch);
	struct w6692_hw *card = bch->hw;
	int ret = -EINVAL;
	struct mISDNhead *hh = mISDN_HEAD_P(skb);
	u32 id;
	u_long flags;

	switch (hh->prim) {
	case PH_DATA_REQ:
		spin_lock_irqsave(&card->lock, flags);
		ret = bchannel_senddata(bch, skb);
		if (ret > 0) { 
			id = hh->id; 
			ret = 0;
			W6692_fill_Bfifo(bc);
			spin_unlock_irqrestore(&card->lock, flags);
			if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
				queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
		} else
			spin_unlock_irqrestore(&card->lock, flags);
		return ret;
	case PH_ACTIVATE_REQ:
		spin_lock_irqsave(&card->lock, flags);
		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
			ret = w6692_mode(bc, ch->protocol);
		else
			ret = 0;
		spin_unlock_irqrestore(&card->lock, flags);
		if (!ret)
			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
				NULL, GFP_KERNEL);
		break;
	case PH_DEACTIVATE_REQ:
		spin_lock_irqsave(&card->lock, flags);
		mISDN_clear_bchannel(bch);
		w6692_mode(bc, ISDN_P_NONE);
		spin_unlock_irqrestore(&card->lock, flags);
		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
			NULL, GFP_KERNEL);
		ret = 0;
		break;
	default:
		pr_info("%s: %s unknown prim(%x,%x)\n",
			card->name, __func__, hh->prim, hh->id);
		ret = -EINVAL;
	}
	if (!ret)
		dev_kfree_skb(skb);
	return ret;
}
Пример #2
0
static int
hfcusb_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
{
	struct bchannel		*bch = container_of(ch, struct bchannel, ch);
	struct hfcsusb		*hw = bch->hw;
	int			ret = -EINVAL;
	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
	u_long			flags;

	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);

	switch (hh->prim) {
	case PH_DATA_REQ:
		spin_lock_irqsave(&hw->lock, flags);
		ret = bchannel_senddata(bch, skb);
		spin_unlock_irqrestore(&hw->lock, flags);
		if (debug & DBG_HFC_CALL_TRACE)
			printk(KERN_DEBUG "%s: %s PH_DATA_REQ ret(%i)\n",
				hw->name, __func__, ret);
		if (ret > 0) {
			
			queue_ch_frame(ch, PH_DATA_CNF, hh->id, NULL);
			ret = 0;
		}
		return ret;
	case PH_ACTIVATE_REQ:
		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) {
			hfcsusb_start_endpoint(hw, bch->nr);
			ret = hfcsusb_setup_bch(bch, ch->protocol);
		} else
			ret = 0;
		if (!ret)
			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
				0, NULL, GFP_KERNEL);
		break;
	case PH_DEACTIVATE_REQ:
		deactivate_bchannel(bch);
		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY,
			0, NULL, GFP_KERNEL);
		ret = 0;
		break;
	}
	if (!ret)
		dev_kfree_skb(skb);
	return ret;
}
Пример #3
0
static int
w6692_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
{
	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
	struct w6692_hw		*card = container_of(dch, struct w6692_hw, dch);
	int			ret = -EINVAL;
	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
	u32			id;
	u_long			flags;

	switch (hh->prim) {
	case PH_DATA_REQ:
		spin_lock_irqsave(&card->lock, flags);
		ret = dchannel_senddata(dch, skb);
		if (ret > 0) { 
			id = hh->id; 
			W6692_fill_Dfifo(card);
			ret = 0;
			spin_unlock_irqrestore(&card->lock, flags);
			queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
		} else
			spin_unlock_irqrestore(&card->lock, flags);
		return ret;
	case PH_ACTIVATE_REQ:
		ret = l1_event(dch->l1, hh->prim);
		break;
	case PH_DEACTIVATE_REQ:
		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
		ret = l1_event(dch->l1, hh->prim);
		break;
	}

	if (!ret)
		dev_kfree_skb(skb);
	return ret;
}
Пример #4
0
static int
hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
{
	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
	struct hfcsusb		*hw = dch->hw;
	int			ret = -EINVAL;
	u_long			flags;

	switch (hh->prim) {
	case PH_DATA_REQ:
		if (debug & DBG_HFC_CALL_TRACE)
			printk(KERN_DEBUG "%s: %s: PH_DATA_REQ\n",
			       hw->name, __func__);

		spin_lock_irqsave(&hw->lock, flags);
		ret = dchannel_senddata(dch, skb);
		spin_unlock_irqrestore(&hw->lock, flags);
		if (ret > 0) {
			ret = 0;
			queue_ch_frame(ch, PH_DATA_CNF, hh->id, NULL);
		}
		break;

	case PH_ACTIVATE_REQ:
		if (debug & DBG_HFC_CALL_TRACE)
			printk(KERN_DEBUG "%s: %s: PH_ACTIVATE_REQ %s\n",
			       hw->name, __func__,
			       (hw->protocol == ISDN_P_NT_S0) ? "NT" : "TE");

		if (hw->protocol == ISDN_P_NT_S0) {
			ret = 0;
			if (test_bit(FLG_ACTIVE, &dch->Flags)) {
				_queue_data(&dch->dev.D,
					    PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
					    NULL, GFP_ATOMIC);
			} else {
				hfcsusb_ph_command(hw,
						   HFC_L1_ACTIVATE_NT);
				test_and_set_bit(FLG_L2_ACTIVATED,
						 &dch->Flags);
			}
		} else {
			hfcsusb_ph_command(hw, HFC_L1_ACTIVATE_TE);
			ret = l1_event(dch->l1, hh->prim);
		}
		break;

	case PH_DEACTIVATE_REQ:
		if (debug & DBG_HFC_CALL_TRACE)
			printk(KERN_DEBUG "%s: %s: PH_DEACTIVATE_REQ\n",
			       hw->name, __func__);
		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);

		if (hw->protocol == ISDN_P_NT_S0) {
			hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT);
			spin_lock_irqsave(&hw->lock, flags);
			skb_queue_purge(&dch->squeue);
			if (dch->tx_skb) {
				dev_kfree_skb(dch->tx_skb);
				dch->tx_skb = NULL;
			}
			dch->tx_idx = 0;
			if (dch->rx_skb) {
				dev_kfree_skb(dch->rx_skb);
				dch->rx_skb = NULL;
			}
			test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
			spin_unlock_irqrestore(&hw->lock, flags);
#ifdef FIXME
			if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
				dchannel_sched_event(&hc->dch, D_CLEARBUSY);
#endif
			ret = 0;
		} else
			ret = l1_event(dch->l1, hh->prim);
		break;
	case MPH_INFORMATION_REQ:
		hfcsusb_ph_info(hw);
		ret = 0;
		break;
	}

	return ret;
}
Пример #5
0
static int
isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
{
	struct bchannel *bch = container_of(ch, struct bchannel, ch);
	struct isar_ch *ich = container_of(bch, struct isar_ch, bch);
	int ret = -EINVAL;
	struct mISDNhead *hh = mISDN_HEAD_P(skb);
	u32 id, *val;
	u_long flags;

	switch (hh->prim) {
	case PH_DATA_REQ:
		spin_lock_irqsave(ich->is->hwlock, flags);
		ret = bchannel_senddata(bch, skb);
		if (ret > 0) { /* direct TX */
			id = hh->id; /* skb can be freed */
			ret = 0;
			isar_fill_fifo(ich);
			spin_unlock_irqrestore(ich->is->hwlock, flags);
			if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
				queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
		} else
			spin_unlock_irqrestore(ich->is->hwlock, flags);
		return ret;
	case PH_ACTIVATE_REQ:
		spin_lock_irqsave(ich->is->hwlock, flags);
		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
			ret = modeisar(ich, ch->protocol);
		else
			ret = 0;
		spin_unlock_irqrestore(ich->is->hwlock, flags);
		if (!ret)
			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
				NULL, GFP_KERNEL);
		break;
	case PH_DEACTIVATE_REQ:
		spin_lock_irqsave(ich->is->hwlock, flags);
		mISDN_clear_bchannel(bch);
		modeisar(ich, ISDN_P_NONE);
		spin_unlock_irqrestore(ich->is->hwlock, flags);
		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
			NULL, GFP_KERNEL);
		ret = 0;
		break;
	case PH_CONTROL_REQ:
		val = (u32 *)skb->data;
		pr_debug("%s: PH_CONTROL | REQUEST %x/%x\n", ich->is->name,
			hh->id, *val);
		if ((hh->id == 0) && ((*val & ~DTMF_TONE_MASK) ==
		    DTMF_TONE_VAL)) {
			if (bch->state == ISDN_P_B_L2DTMF) {
				char tt = *val & DTMF_TONE_MASK;

				if (tt == '*')
					tt = 0x1e;
				else if (tt == '#')
					tt = 0x1f;
				else if (tt > '9')
					tt -= 7;
				tt &= 0x1f;
				spin_lock_irqsave(ich->is->hwlock, flags);
				isar_pump_cmd(ich, PCTRL_CMD_TDTMF, tt);
				spin_unlock_irqrestore(ich->is->hwlock, flags);
			} else {
				pr_info("%s: DTMF send wrong protocol %x\n",
					__func__, bch->state);
				return -EINVAL;
			}
		} else if ((hh->id == HW_MOD_FRM) || (hh->id == HW_MOD_FRH) ||
		    (hh->id == HW_MOD_FTM) || (hh->id == HW_MOD_FTH)) {
			for (id = 0; id < FAXMODCNT; id++)
				if (faxmodulation[id] == *val)
					break;
			if ((FAXMODCNT > id) &&
			    test_bit(FLG_INITIALIZED, &bch->Flags)) {
				pr_debug("%s: isar: new mod\n", ich->is->name);
				isar_pump_cmd(ich, hh->id, *val);
				ret = 0;
			} else {
				pr_info("%s: wrong modulation\n",
					ich->is->name);
				ret = -EINVAL;
			}
		} else if (hh->id == HW_MOD_LASTDATA)
			test_and_set_bit(FLG_DLEETX, &bch->Flags);
		else {
			pr_info("%s: unknown PH_CONTROL_REQ %x\n",
				ich->is->name, hh->id);
			ret = -EINVAL;
		}
	default:
		pr_info("%s: %s unknown prim(%x,%x)\n",
			ich->is->name, __func__, hh->prim, hh->id);
		ret = -EINVAL;
	}
	if (!ret)
		dev_kfree_skb(skb);
	return ret;
}