Exemple #1
0
static void
release_card(struct w6692_hw *card)
{
	u_long	flags;

	spin_lock_irqsave(&card->lock, flags);
	disable_hwirq(card);
	w6692_mode(&card->bc[0], ISDN_P_NONE);
	w6692_mode(&card->bc[1], ISDN_P_NONE);
	if ((card->fmask & led) || card->subtype == W6692_USR) {
		card->xdata |= 0x04;	
		WriteW6692(card, W_XDATA, card->xdata);
	}
	spin_unlock_irqrestore(&card->lock, flags);
	free_irq(card->irq, card);
	l1_event(card->dch.l1, CLOSE_CHANNEL);
	mISDN_unregister_device(&card->dch.dev);
	release_region(card->addr, 256);
	mISDN_freebchannel(&card->bc[1].bch);
	mISDN_freebchannel(&card->bc[0].bch);
	mISDN_freedchannel(&card->dch);
	write_lock_irqsave(&card_lock, flags);
	list_del(&card->list);
	write_unlock_irqrestore(&card_lock, flags);
	pci_disable_device(card->pdev);
	pci_set_drvdata(card->pdev, NULL);
	kfree(card);
}
Exemple #2
0
static void
W6692_ph_bh(struct dchannel *dch)
{
	struct w6692_hw *card = dch->hw;

	switch (card->state) {
	case W_L1CMD_RST:
		dch->state = 0;
		l1_event(dch->l1, HW_RESET_IND);
		break;
	case W_L1IND_CD:
		dch->state = 3;
		l1_event(dch->l1, HW_DEACT_CNF);
		break;
	case W_L1IND_DRD:
		dch->state = 3;
		l1_event(dch->l1, HW_DEACT_IND);
		break;
	case W_L1IND_CE:
		dch->state = 4;
		l1_event(dch->l1, HW_POWERUP_IND);
		break;
	case W_L1IND_LD:
		if (dch->state <= 5) {
			dch->state = 5;
			l1_event(dch->l1, ANYSIGNAL);
		} else {
			dch->state = 8;
			l1_event(dch->l1, LOSTFRAMING);
		}
		break;
	case W_L1IND_ARD:
		dch->state = 6;
		l1_event(dch->l1, INFO2);
		break;
	case W_L1IND_AI8:
		dch->state = 7;
		l1_event(dch->l1, INFO4_P8);
		break;
	case W_L1IND_AI10:
		dch->state = 7;
		l1_event(dch->l1, INFO4_P10);
		break;
	default:
		pr_debug("%s: TE unknown state %02x dch state %02x\n",
			card->name, card->state, dch->state);
		break;
	}
	pr_debug("%s: TE newstate %02x\n", card->name, dch->state);
}
Exemple #3
0
static void
isac_ph_state_bh(struct dchannel *dch)
{
	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);

	switch (isac->state) {
	case ISAC_IND_RS:
	case ISAC_IND_EI:
		dch->state = 0;
		l1_event(dch->l1, HW_RESET_IND);
		break;
	case ISAC_IND_DID:
		dch->state = 3;
		l1_event(dch->l1, HW_DEACT_CNF);
		break;
	case ISAC_IND_DR:
		dch->state = 3;
		l1_event(dch->l1, HW_DEACT_IND);
		break;
	case ISAC_IND_PU:
		dch->state = 4;
		l1_event(dch->l1, HW_POWERUP_IND);
		break;
	case ISAC_IND_RSY:
		if (dch->state <= 5) {
			dch->state = 5;
			l1_event(dch->l1, ANYSIGNAL);
		} else {
			dch->state = 8;
			l1_event(dch->l1, LOSTFRAMING);
		}
		break;
	case ISAC_IND_ARD:
		dch->state = 6;
		l1_event(dch->l1, INFO2);
		break;
	case ISAC_IND_AI8:
		dch->state = 7;
		l1_event(dch->l1, INFO4_P8);
		break;
	case ISAC_IND_AI10:
		dch->state = 7;
		l1_event(dch->l1, INFO4_P10);
		break;
	}
	pr_debug("%s: TE newstate %x\n", isac->name, dch->state);
}
Exemple #4
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;
}
static void
ph_state_te(struct dchannel *dch)
{
	struct hfcsusb *hw = dch->hw;

	if (debug & DEBUG_HW) {
		if (dch->state <= HFC_MAX_TE_LAYER1_STATE)
			printk(KERN_DEBUG "%s: %s: %s\n", hw->name, __func__,
			       HFC_TE_LAYER1_STATES[dch->state]);
		else
			printk(KERN_DEBUG "%s: %s: TE F%d\n",
			       hw->name, __func__, dch->state);
	}

	switch (dch->state) {
	case 0:
		l1_event(dch->l1, HW_RESET_IND);
		break;
	case 3:
		l1_event(dch->l1, HW_DEACT_IND);
		break;
	case 5:
	case 8:
		l1_event(dch->l1, ANYSIGNAL);
		break;
	case 6:
		l1_event(dch->l1, INFO2);
		break;
	case 7:
		l1_event(dch->l1, INFO4_P8);
		break;
	}
	if (dch->state == 7)
		handle_led(hw, LED_S0_ON);
	else
		handle_led(hw, LED_S0_OFF);
}
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;
}