Commit 18c91913 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN/HiSax: Share D-Channel XDU interrupt handling

The FIFO based cards can share the data underrun handling.
parent dd429079
...@@ -255,23 +255,11 @@ icc_interrupt(struct IsdnCardState *cs, u_char val) ...@@ -255,23 +255,11 @@ icc_interrupt(struct IsdnCardState *cs, u_char val)
printk(KERN_WARNING "HiSax: ICC XMR\n"); printk(KERN_WARNING "HiSax: ICC XMR\n");
} }
if (exval & 0x40) { /* XDU */ if (exval & 0x40) { /* XDU */
debugl1(cs, "ICC XDU");
printk(KERN_WARNING "HiSax: ICC XDU\n");
#ifdef ERROR_STATISTIC
cs->err_tx++;
#endif
if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
del_timer(&cs->dbusytimer); del_timer(&cs->dbusytimer);
if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
sched_d_event(cs, D_CLEARBUSY); sched_d_event(cs, D_CLEARBUSY);
if (cs->tx_skb) { /* Restart frame */ xmit_xdu_d(cs, NULL);
skb_push(cs->tx_skb, cs->tx_cnt);
cs->tx_cnt = 0;
icc_fill_fifo(cs);
} else {
printk(KERN_WARNING "HiSax: ICC XDU no skb\n");
debugl1(cs, "ICC XDU no skb");
}
} }
if (exval & 0x04) { /* MOS */ if (exval & 0x04) { /* MOS */
v1 = cs->readisac(cs, ICC_MOSR); v1 = cs->readisac(cs, ICC_MOSR);
......
...@@ -421,16 +421,8 @@ dch_int(struct IsdnCardState *cs) ...@@ -421,16 +421,8 @@ dch_int(struct IsdnCardState *cs)
} }
if (istad &0x0C) { // XDU or XMR if (istad &0x0C) { // XDU or XMR
if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_int(): XDU"); xmit_xdu_d(cs, NULL);
if (cs->tx_skb) { }
skb_push(cs->tx_skb, cs->tx_cnt); // retransmit
cs->tx_cnt = 0;
dch_fill_fifo(cs);
} else {
printk(KERN_WARNING "HiSax: ISAC XDU no skb\n");
debugl1(cs, "ISAC XDU no skb");
}
}
} }
//---------------------------------------------------------- //----------------------------------------------------------
......
...@@ -249,23 +249,11 @@ isac_interrupt(struct IsdnCardState *cs, u_char val) ...@@ -249,23 +249,11 @@ isac_interrupt(struct IsdnCardState *cs, u_char val)
printk(KERN_WARNING "HiSax: ISAC XMR\n"); printk(KERN_WARNING "HiSax: ISAC XMR\n");
} }
if (exval & 0x40) { /* XDU */ if (exval & 0x40) { /* XDU */
debugl1(cs, "ISAC XDU");
printk(KERN_WARNING "HiSax: ISAC XDU\n");
#ifdef ERROR_STATISTIC
cs->err_tx++;
#endif
if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
del_timer(&cs->dbusytimer); del_timer(&cs->dbusytimer);
if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
sched_d_event(cs, D_CLEARBUSY); sched_d_event(cs, D_CLEARBUSY);
if (cs->tx_skb) { /* Restart frame */ xmit_xdu_d(cs, NULL);
skb_push(cs->tx_skb, cs->tx_cnt);
cs->tx_cnt = 0;
isac_fill_fifo(cs);
} else {
printk(KERN_WARNING "HiSax: ISAC XDU no skb\n");
debugl1(cs, "ISAC XDU no skb");
}
} }
if (exval & 0x04) { /* MOS */ if (exval & 0x04) { /* MOS */
v1 = cs->readisac(cs, ISAC_MOSR); v1 = cs->readisac(cs, ISAC_MOSR);
......
...@@ -166,6 +166,21 @@ xmit_restart_b(struct BCState *bcs) ...@@ -166,6 +166,21 @@ xmit_restart_b(struct BCState *bcs)
bcs->count = 0; bcs->count = 0;
} }
/* called with the card lock held */
static inline void
xmit_restart_d(struct IsdnCardState *cs)
{
#ifdef ERROR_STATISTIC
cs->err_tx++;
#endif
if (!cs->tx_skb) {
WARN_ON(1);
return;
}
skb_push(cs->tx_skb, cs->tx_cnt);
cs->tx_cnt = 0;
}
/* Useful for HSCX/ISAC work-alike's */ /* Useful for HSCX/ISAC work-alike's */
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
...@@ -227,6 +242,20 @@ xmit_xdu_b(struct BCState *bcs, void (*reset_xmit)(struct BCState *bcs)) ...@@ -227,6 +242,20 @@ xmit_xdu_b(struct BCState *bcs, void (*reset_xmit)(struct BCState *bcs))
} }
} }
/* XDU - transmit data underrun */
/* called with the card lock held */
static inline void
xmit_xdu_d(struct IsdnCardState *cs, void (*reset_xmit)(struct IsdnCardState *cs))
{
printk(KERN_WARNING "HiSax: D XDU\n");
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "D XDU");
xmit_restart_d(cs);
if (reset_xmit)
reset_xmit(cs);
}
static inline unsigned char * static inline unsigned char *
xmit_fill_fifo_b(struct BCState *bcs, int fifo_size, int *count, int *more) xmit_fill_fifo_b(struct BCState *bcs, int fifo_size, int *count, int *more)
{ {
......
...@@ -366,21 +366,11 @@ W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs) ...@@ -366,21 +366,11 @@ W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs)
if (cs->debug & L1_DEB_WARN) if (cs->debug & L1_DEB_WARN)
debugl1(cs, "W6692 D_EXIR %02x", exval); debugl1(cs, "W6692 D_EXIR %02x", exval);
if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) { /* Transmit underrun/collision */ if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) { /* Transmit underrun/collision */
debugl1(cs, "W6692 D-chan underrun/collision");
printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL\n");
if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
del_timer(&cs->dbusytimer); del_timer(&cs->dbusytimer);
if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
sched_d_event(cs, D_CLEARBUSY); sched_d_event(cs, D_CLEARBUSY);
if (cs->tx_skb) { /* Restart frame */ xmit_xdu_d(cs, NULL);
skb_push(cs->tx_skb, cs->tx_cnt);
cs->tx_cnt = 0;
W6692_fill_fifo(cs);
} else {
printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL no skb\n");
debugl1(cs, "W6692 XDUN/XCOL no skb");
cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST);
}
} }
if (exval & W_D_EXI_RDOV) { /* RDOV */ if (exval & W_D_EXI_RDOV) { /* RDOV */
debugl1(cs, "W6692 D-channel RDOV"); debugl1(cs, "W6692 D-channel RDOV");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment