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