Commit dd429079 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN/HiSax: Consolidate D-Channel XPR interrupt handling

More code which can be nicely shared...
parent 4cfa7f10
......@@ -1049,28 +1049,8 @@ hfcpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
receive_dmsg(cs);
}
if (val & 0x04) { /* dframe transmitted */
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))
sched_d_event(cs, D_CLEARBUSY);
if (cs->tx_skb) {
if (cs->tx_skb->len) {
if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
hfcpci_fill_dfifo(cs);
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
} else {
debugl1(cs, "hfcpci_fill_dfifo irq blocked");
}
goto afterXPR;
} else {
dev_kfree_skb_irq(cs->tx_skb);
cs->tx_cnt = 0;
cs->tx_skb = NULL;
}
}
xmit_ready_d(cs);
xmit_xpr_d(cs);
}
afterXPR:
if (cs->hw.hfcpci.int_s1 && count--) {
val = cs->hw.hfcpci.int_s1;
cs->hw.hfcpci.int_s1 = 0;
......
......@@ -849,28 +849,8 @@ hfcsx_interrupt(int intno, void *dev_id, struct pt_regs *regs)
receive_dmsg(cs);
}
if (val & 0x04) { /* dframe transmitted */
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))
sched_d_event(cs, D_CLEARBUSY);
if (cs->tx_skb) {
if (cs->tx_skb->len) {
if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
hfcsx_fill_dfifo(cs);
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
} else {
debugl1(cs, "hfcsx_fill_dfifo irq blocked");
}
goto afterXPR;
} else {
dev_kfree_skb_irq(cs->tx_skb);
cs->tx_cnt = 0;
cs->tx_skb = NULL;
}
}
xmit_ready_d(cs);
xmit_xpr_d(cs);
}
afterXPR:
if (cs->hw.hfcsx.int_s1 && count--) {
val = cs->hw.hfcsx.int_s1;
cs->hw.hfcsx.int_s1 = 0;
......
......@@ -223,23 +223,8 @@ icc_interrupt(struct IsdnCardState *cs, u_char val)
debugl1(cs, "ICC 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))
sched_d_event(cs, D_CLEARBUSY);
if (cs->tx_skb) {
if (cs->tx_skb->len) {
icc_fill_fifo(cs);
goto afterXPR;
} else {
dev_kfree_skb_irq(cs->tx_skb);
cs->tx_cnt = 0;
cs->tx_skb = NULL;
}
}
xmit_ready_d(cs);
xmit_xpr_d(cs);
}
afterXPR:
if (val & 0x04) { /* CISQ */
exval = cs->readisac(cs, ICC_CIR0);
if (cs->debug & L1_DEB_ISAC)
......
......@@ -416,25 +416,9 @@ dch_int(struct IsdnCardState *cs)
cs->writeisac(cs, IPACX_CMDRD, 0x40); //RRES
}
if (istad &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))
sched_d_event(cs, D_CLEARBUSY);
if (cs->tx_skb) {
if (cs->tx_skb->len) {
dch_fill_fifo(cs);
goto afterXPR;
}
else {
dev_kfree_skb_irq(cs->tx_skb);
cs->tx_skb = NULL;
cs->tx_cnt = 0;
}
}
xmit_ready(cs);
}
afterXPR:
if (istad &0x10) { // XPR
xmit_xpr_d(cs);
}
if (istad &0x0C) { // XDU or XMR
if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_int(): XDU");
......
......@@ -217,23 +217,8 @@ isac_interrupt(struct IsdnCardState *cs, u_char val)
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))
sched_d_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;
}
}
xmit_ready_d(cs);
xmit_xpr_d(cs);
}
afterXPR:
if (val & 0x04) { /* CISQ */
exval = cs->readisac(cs, ISAC_CIR0);
if (cs->debug & L1_DEB_ISAC)
......
......@@ -58,6 +58,14 @@ xmit_complete_b(struct BCState *bcs)
bcs->tx_skb = NULL;
}
/* called with the card lock held */
static inline void
xmit_complete_d(struct IsdnCardState *cs)
{
dev_kfree_skb_irq(cs->tx_skb);
cs->tx_skb = NULL;
}
/* called with the card lock held */
static inline void
xmit_ready_b(struct BCState *bcs)
......@@ -158,7 +166,7 @@ xmit_restart_b(struct BCState *bcs)
bcs->count = 0;
}
/* Useful for HSCX work-alike's */
/* Useful for HSCX/ISAC work-alike's */
/* ---------------------------------------------------------------------- */
/* XPR - transmit pool ready */
......@@ -179,6 +187,28 @@ xmit_xpr_b(struct BCState *bcs)
xmit_ready_b(bcs);
}
/* XPR - transmit pool ready */
/* called with the card lock held */
static inline void
xmit_xpr_d(struct IsdnCardState *cs)
{
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))
sched_d_event(cs, D_CLEARBUSY);
/* current frame? */
if (cs->tx_skb) {
/* last frame not done yet? */
if (cs->tx_skb->len) {
cs->DC_Send_Data(cs);
return;
}
xmit_complete_d(cs);
cs->tx_cnt = 0;
}
xmit_ready_d(cs);
}
/* XDU - transmit data underrun */
/* called with the card lock held */
static inline void
......
......@@ -355,23 +355,8 @@ W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs)
W6692_empty_fifo(cs, W_D_FIFO_THRESH);
}
if (val & W_INT_D_XFR) { /* XFR */
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))
sched_d_event(cs, D_CLEARBUSY);
if (cs->tx_skb) {
if (cs->tx_skb->len) {
W6692_fill_fifo(cs);
goto afterXFR;
} else {
dev_kfree_skb_irq(cs->tx_skb);
cs->tx_cnt = 0;
cs->tx_skb = NULL;
}
}
xmit_ready_d(cs);
xmit_xpr_d(cs);
}
afterXFR:
if (val & (W_INT_XINT0 | W_INT_XINT1)) { /* XINT0/1 - never */
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "W6692 spurious XINT!");
......
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