static void isac_xpr_irq(struct isac_hw *isac) { if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) del_timer(&isac->dch.timer); if (isac->dch.tx_skb && isac->dch.tx_idx < isac->dch.tx_skb->len) { isac_fill_fifo(isac); } else { if (isac->dch.tx_skb) dev_kfree_skb(isac->dch.tx_skb); if (get_next_dframe(&isac->dch)) isac_fill_fifo(isac); } }
static void isac_retransmit(struct isac_hw *isac) { if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) del_timer(&isac->dch.timer); if (test_bit(FLG_TX_BUSY, &isac->dch.Flags)) { /* Restart frame */ isac->dch.tx_idx = 0; isac_fill_fifo(isac); } else if (isac->dch.tx_skb) { /* should not happen */ pr_info("%s: tx_skb exist but not busy\n", isac->name); test_and_set_bit(FLG_TX_BUSY, &isac->dch.Flags); isac->dch.tx_idx = 0; isac_fill_fifo(isac); } else { pr_info("%s: ISAC XDU no TX_BUSY\n", isac->name); if (get_next_dframe(&isac->dch)) isac_fill_fifo(isac); } }
void isac_interrupt(struct IsdnCardState *cs, u_char val) { u_char exval, v1; struct sk_buff *skb; unsigned int count; if (cs->debug & L1_DEB_ISAC) debugl1(cs, "ISAC interrupt %x", val); if (val & 0x80) { /* RME */ exval = cs->readisac(cs, ISAC_RSTA); if ((exval & 0x70) != 0x20) { if (exval & 0x40) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "ISAC RDO"); #ifdef ERROR_STATISTIC cs->err_rx++; #endif } if (!(exval & 0x20)) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "ISAC CRC error"); #ifdef ERROR_STATISTIC cs->err_crc++; #endif } cs->writeisac(cs, ISAC_CMDR, 0x80); } else { count = cs->readisac(cs, ISAC_RBCL) & 0x1f; if (count == 0) count = 32; isac_empty_fifo(cs, count); if ((count = cs->rcvidx) > 0) { cs->rcvidx = 0; if (!(skb = alloc_skb(count, GFP_ATOMIC))) printk(KERN_WARNING "HiSax: D receive out of memory\n"); else { memcpy(skb_put(skb, count), cs->rcvbuf, count); skb_queue_tail(&cs->rq, skb); } } } cs->rcvidx = 0; schedule_event(cs, D_RCVBUFREADY); } if (val & 0x40) { /* RPF */ isac_empty_fifo(cs, 32); } if (val & 0x20) { /* RSC */ /* never */ if (cs->debug & L1_DEB_WARN) debugl1(cs, "ISAC RSC interrupt"); } if (val & 0x10) { /* XPR */ if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) del_timer(&cs->dbusytimer); if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) schedule_event(cs, D_CLEARBUSY); if (cs->tx_skb) { if (cs->tx_skb->len) { isac_fill_fifo(cs); goto afterXPR; } else { dev_kfree_skb_irq(cs->tx_skb); cs->tx_cnt = 0; cs->tx_skb = NULL; } } if ((cs->tx_skb = skb_dequeue(&cs->sq))) { cs->tx_cnt = 0; isac_fill_fifo(cs); } else schedule_event(cs, D_XMTBUFREADY); } afterXPR: if (val & 0x04) { /* CISQ */ exval = cs->readisac(cs, ISAC_CIR0); if (cs->debug & L1_DEB_ISAC) debugl1(cs, "ISAC CIR0 %02X", exval ); if (exval & 2) { cs->dc.isac.ph_state = (exval >> 2) & 0xf; if (cs->debug & L1_DEB_ISAC) debugl1(cs, "ph_state change %x", cs->dc.isac.ph_state); schedule_event(cs, D_L1STATECHANGE); }
static inline void isac_interrupt(struct IsdnCardState *sp, u_char val) { u_char exval; struct sk_buff *skb; unsigned int count; char tmp[32]; if (sp->debug & L1_DEB_ISAC) { sprintf(tmp, "ISAC interrupt %x", val); debugl1(sp, tmp); } if (val & 0x80) { /* RME */ exval = IsacReadReg(sp->isac, ISAC_RSTA); if ((exval & 0x70) != 0x20) { if (exval & 0x40) if (sp->debug & L1_DEB_WARN) debugl1(sp, "ISAC RDO"); if (!(exval & 0x20)) if (sp->debug & L1_DEB_WARN) debugl1(sp, "ISAC CRC error"); IsacWriteReg(sp->isac, ISAC_CMDR, 0x80); } else { count = IsacReadReg(sp->isac, ISAC_RBCL) & 0x1f; if (count == 0) count = 32; isac_empty_fifo(sp, count); if ((count = sp->rcvidx) > 0) { sp->rcvidx = 0; if (!(skb = alloc_skb(count, GFP_ATOMIC))) printk(KERN_WARNING "IX1: D receive out of memory\n"); else { SET_SKB_FREE(skb); memcpy(skb_put(skb, count), sp->rcvbuf, count); skb_queue_tail(&sp->rq, skb); } } } sp->rcvidx = 0; isac_sched_event(sp, ISAC_RCVBUFREADY); } if (val & 0x40) { /* RPF */ isac_empty_fifo(sp, 32); } if (val & 0x20) { /* RSC */ /* never */ if (sp->debug & L1_DEB_WARN) debugl1(sp, "ISAC RSC interrupt"); } if (val & 0x10) { /* XPR */ if (sp->tx_skb) if (sp->tx_skb->len) { isac_fill_fifo(sp); goto afterXPR; } else { dev_kfree_skb(sp->tx_skb, FREE_WRITE); sp->tx_cnt = 0; sp->tx_skb = NULL; } if ((sp->tx_skb = skb_dequeue(&sp->sq))) { sp->tx_cnt = 0; isac_fill_fifo(sp); } else isac_sched_event(sp, ISAC_XMTBUFREADY); } afterXPR: if (val & 0x04) { /* CISQ */ sp->ph_state = (IsacReadReg(sp->isac, ISAC_CIX0) >> 2) & 0xf; if (sp->debug & L1_DEB_ISAC) { sprintf(tmp, "l1state %d", sp->ph_state); debugl1(sp, tmp); } isac_new_ph(sp); }