Exemplo n.º 1
0
static int
open_dchannel(struct hfcsusb *hw, struct mISDNchannel *ch,
	      struct channel_req *rq)
{
	int err = 0;

	if (debug & DEBUG_HW_OPEN)
		printk(KERN_DEBUG "%s: %s: dev(%d) open addr(%i) from %p\n",
		       hw->name, __func__, hw->dch.dev.id, rq->adr.channel,
		       __builtin_return_address(0));
	if (rq->protocol == ISDN_P_NONE)
		return -EINVAL;

	test_and_clear_bit(FLG_ACTIVE, &hw->dch.Flags);
	test_and_clear_bit(FLG_ACTIVE, &hw->ech.Flags);
	hfcsusb_start_endpoint(hw, HFC_CHAN_D);

	
	if (rq->adr.channel == 1) {
		if (hw->fifos[HFCUSB_PCM_RX].pipe) {
			hfcsusb_start_endpoint(hw, HFC_CHAN_E);
			set_bit(FLG_ACTIVE, &hw->ech.Flags);
			_queue_data(&hw->ech.dev.D, PH_ACTIVATE_IND,
				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
		} else
			return -EINVAL;
	}

	if (!hw->initdone) {
		hw->protocol = rq->protocol;
		if (rq->protocol == ISDN_P_TE_S0) {
			err = create_l1(&hw->dch, hfc_l1callback);
			if (err)
				return err;
		}
		setPortMode(hw);
		ch->protocol = rq->protocol;
		hw->initdone = 1;
	} else {
		if (rq->protocol != ch->protocol)
			return -EPROTONOSUPPORT;
	}

	if (((ch->protocol == ISDN_P_NT_S0) && (hw->dch.state == 3)) ||
	    ((ch->protocol == ISDN_P_TE_S0) && (hw->dch.state == 7)))
		_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
			    0, NULL, GFP_KERNEL);
	rq->ch = ch;
	if (!try_module_get(THIS_MODULE))
		printk(KERN_WARNING "%s: %s: cannot get module\n",
		       hw->name, __func__);
	return 0;
}
Exemplo n.º 2
0
static int
setup_instance(struct w6692_hw *card)
{
	int		i, err;
	u_long		flags;

	snprintf(card->name, MISDN_MAX_IDLEN - 1, "w6692.%d", w6692_cnt + 1);
	write_lock_irqsave(&card_lock, flags);
	list_add_tail(&card->list, &Cards);
	write_unlock_irqrestore(&card_lock, flags);
	card->fmask = (1 << w6692_cnt);
	_set_debug(card);
	spin_lock_init(&card->lock);
	mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, W6692_ph_bh);
	card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
	card->dch.dev.D.send = w6692_l2l1D;
	card->dch.dev.D.ctrl = w6692_dctrl;
	card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
	card->dch.hw = card;
	card->dch.dev.nrbchan = 2;
	for (i = 0; i < 2; i++) {
		mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM);
		card->bc[i].bch.hw = card;
		card->bc[i].bch.nr = i + 1;
		card->bc[i].bch.ch.nr = i + 1;
		card->bc[i].bch.ch.send = w6692_l2l1B;
		card->bc[i].bch.ch.ctrl = w6692_bctrl;
		set_channelmap(i + 1, card->dch.dev.channelmap);
		list_add(&card->bc[i].bch.ch.list, &card->dch.dev.bchannels);
	}
	err = setup_w6692(card);
	if (err)
		goto error_setup;
	err = mISDN_register_device(&card->dch.dev, &card->pdev->dev,
		card->name);
	if (err)
		goto error_reg;
	err = init_card(card);
	if (err)
		goto error_init;
	err = create_l1(&card->dch, w6692_l1callback);
	if (!err) {
		w6692_cnt++;
		pr_notice("W6692 %d cards installed\n", w6692_cnt);
		return 0;
	}

	free_irq(card->irq, card);
error_init:
	mISDN_unregister_device(&card->dch.dev);
error_reg:
	release_region(card->addr, 256);
error_setup:
	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);
	kfree(card);
	return err;
}