static void isac_bh(struct work_struct *work) { struct IsdnCardState *cs = container_of(work, struct IsdnCardState, tqueue); struct PStack *stptr; if (!cs) return; if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { if (cs->debug) debugl1(cs, "D-Channel Busy cleared"); stptr = cs->stlist; while (stptr != NULL) { stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL); stptr = stptr->next; } } if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) isac_new_ph(cs); if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) DChannel_proc_rcv(cs); if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) DChannel_proc_xmt(cs); #if ARCOFI_USE if (!test_bit(HW_ARCOFI, &cs->HW_Flags)) return; if (test_and_clear_bit(D_RX_MON1, &cs->event)) arcofi_fsm(cs, ARCOFI_RX_END, NULL); if (test_and_clear_bit(D_TX_MON1, &cs->event)) arcofi_fsm(cs, ARCOFI_TX_END, NULL); #endif }
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); }