void __init initW6692(struct IsdnCardState *cs, int part) { if (part & 1) { cs->tqueue.routine = (void *) (void *) W6692_bh; cs->setstack_d = setstack_W6692; cs->DC_Close = DC_Close_W6692; cs->dbusytimer.function = (void *) dbusy_timer_handler; cs->dbusytimer.data = (long) cs; init_timer(&cs->dbusytimer); resetW6692(cs); ph_command(cs, W_L1CMD_RST); cs->dc.w6692.ph_state = W_L1CMD_RST; W6692_new_ph(cs); ph_command(cs, W_L1CMD_ECK); cs->bcs[0].BC_SetStack = setstack_w6692; cs->bcs[1].BC_SetStack = setstack_w6692; cs->bcs[0].BC_Close = close_w6692state; cs->bcs[1].BC_Close = close_w6692state; W6692Bmode(cs->bcs, 0, 0); W6692Bmode(cs->bcs + 1, 0, 0); } if (part & 2) { /* Reenable all IRQ */ cs->writeW6692(cs, W_IMASK, 0x18); cs->writeW6692(cs, W_D_EXIM, 0x00); cs->BC_Write_Reg(cs, 0, W_B_EXIM, 0x00); cs->BC_Write_Reg(cs, 1, W_B_EXIM, 0x00); /* Reset D-chan receiver and transmitter */ cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST); } }
static void W6692_bh(struct IsdnCardState *cs) { 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)) W6692_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 (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); */ }
static void handle_statusD(struct w6692_hw *card) { struct dchannel *dch = &card->dch; u8 exval, v1, cir; exval = ReadW6692(card, W_D_EXIR); pr_debug("%s: D_EXIR %02x\n", card->name, exval); if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) { pr_debug("%s: D-channel underrun/collision\n", card->name); #ifdef ERROR_STATISTIC dch->err_tx++; #endif d_retransmit(card); } if (exval & W_D_EXI_RDOV) { pr_debug("%s: D-channel RDOV\n", card->name); WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST); } if (exval & W_D_EXI_TIN2) pr_debug("%s: spurious TIN2 interrupt\n", card->name); if (exval & W_D_EXI_MOC) { v1 = ReadW6692(card, W_MOSR); pr_debug("%s: spurious MOC interrupt MOSR %02x\n", card->name, v1); } if (exval & W_D_EXI_ISC) { cir = ReadW6692(card, W_CIR); pr_debug("%s: ISC CIR %02X\n", card->name, cir); if (cir & W_CIR_ICC) { v1 = cir & W_CIR_COD_MASK; pr_debug("%s: ph_state_change %x -> %x\n", card->name, dch->state, v1); card->state = v1; if (card->fmask & led) { switch (v1) { case W_L1IND_AI8: case W_L1IND_AI10: w6692_led_handler(card, 1); break; default: w6692_led_handler(card, 0); break; } } W6692_new_ph(card); } if (cir & W_CIR_SCC) { v1 = ReadW6692(card, W_SQR); pr_debug("%s: SCC SQR %02X\n", card->name, v1); } } if (exval & W_D_EXI_WEXP) pr_debug("%s: spurious WEXP interrupt!\n", card->name); if (exval & W_D_EXI_TEXP) pr_debug("%s: spurious TEXP interrupt!\n", card->name); }
static void W6692_l1hw(struct PStack *st, int pr, void *arg) { struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; struct sk_buff *skb = arg; int val; switch (pr) { case (PH_DATA | REQUEST): if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); if (cs->tx_skb) { skb_queue_tail(&cs->sq, skb); #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0); #endif } else { cs->tx_skb = skb; cs->tx_cnt = 0; #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0); #endif W6692_fill_fifo(cs); } break; case (PH_PULL | INDICATION): if (cs->tx_skb) { if (cs->debug & L1_DEB_WARN) debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); skb_queue_tail(&cs->sq, skb); break; } if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); cs->tx_skb = skb; cs->tx_cnt = 0; #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); #endif W6692_fill_fifo(cs); break; case (PH_PULL | REQUEST): #ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL"); #endif if (!cs->tx_skb) { test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); } else test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); break; case (HW_RESET | REQUEST): if ((cs->dc.w6692.ph_state == W_L1IND_DRD)) ph_command(cs, W_L1CMD_ECK); else { ph_command(cs, W_L1CMD_RST); cs->dc.w6692.ph_state = W_L1CMD_RST; W6692_new_ph(cs); } break; case (HW_ENABLE | REQUEST): ph_command(cs, W_L1CMD_ECK); break; case (HW_INFO3 | REQUEST): ph_command(cs, W_L1CMD_AR8); break; case (HW_TESTLOOP | REQUEST): val = 0; if (1 & (long) arg) val |= 0x0c; if (2 & (long) arg) val |= 0x3; /* !!! not implemented yet */ break; case (HW_DEACTIVATE | RESPONSE): skb_queue_purge(&cs->rq); skb_queue_purge(&cs->sq); if (cs->tx_skb) { dev_kfree_skb_any(cs->tx_skb); cs->tx_skb = NULL; } 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)) W6692_sched_event(cs, D_CLEARBUSY); break; default: if (cs->debug & L1_DEB_WARN) debugl1(cs, "W6692_l1hw unknown %04x", pr); break; } }