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; }
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; }