diff options
author | chuck <chuck@cvs.openbsd.org> | 1996-11-21 20:51:23 +0000 |
---|---|---|
committer | chuck <chuck@cvs.openbsd.org> | 1996-11-21 20:51:23 +0000 |
commit | dda650ffaea1efeaf645e3480751f5c1c4ef2d5e (patch) | |
tree | 29f9de31c408debe74921c22d3c7432712a58ec5 | |
parent | 547552c51648c82413fc12ebbada84d3d58f90cd (diff) |
midway fixes:
1. fix possible hang in en_txlaunch(). when attempting to extend
the length of an mbuf to avoid a flush we should extend it
by cnt [which is ((need - len) % 4)] rather than 4 - cnt.
also, add an EN_DEBUG printf() when we pad/FLUSH a buffer
to help with debugging/understanding what the driver is up to.
2. use interface packet counters
3. when turning off a recv VCI we recompute the new mode. make sure
we don't include the "in service" bit in the new mode, otherwise
a VCI may appear "hung" if you turn it off while a service
interrupt is pending.
4. when shutting down a VCI that is still receiving data, don't bother
going into "drain mode" if only the hardware in service bit is
set (otherwise the VCI may get "hung" in drain mode).
as a result of this we may get "unexpected rx interrupt" messages
which are not really an error, so put this printf in EN_DEBUG.
5. be sure to zero txspeed[lcv] when enabling a VCI (start at full
speed). (hooks for setting txspeed[] are currently not in
the driver, but we are playing with it locally).
credits:
#1: Detected by: Zdenek Salvet <salvet@horn.ics.muni.cz>, fix by me.
#2: Contributed by: Zdenek Salvet <salvet@horn.ics.muni.cz>
#3,#4,#5: Detected by: Milind M. Buddhikot <milind@dworkin.wustl.edu>,
fixed by me.
-rw-r--r-- | sys/dev/ic/midway.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/sys/dev/ic/midway.c b/sys/dev/ic/midway.c index a8e3ca18d87..48759ff2073 100644 --- a/sys/dev/ic/midway.c +++ b/sys/dev/ic/midway.c @@ -1,5 +1,5 @@ -/* $OpenBSD: midway.c,v 1.16 1996/11/12 22:46:23 niklas Exp $ */ -/* (sync'd to midway.c 1.63) */ +/* $NetBSD: midway.c,v 1.21 1996/11/09 03:43:29 chuck Exp $ */ +/* (sync'd to midway.c 1.64) */ /* * @@ -1039,6 +1039,7 @@ int on; sc->rxslot[slot].rxhand = pi->rxhand; if (sc->rxslot[slot].indma.ifq_head || sc->rxslot[slot].q.ifq_head) panic("en_rxctl: left over mbufs on enable"); + sc->txspeed[vci] = 0; /* full speed to start */ en_loadvc(sc, vci); /* does debug printf for us */ return(0); } @@ -1054,7 +1055,7 @@ int on; return(EINVAL); s = splimp(); /* block out enintr() */ oldmode = EN_READ(sc, MID_VC(vci)); - newmode = MIDV_SETMODE(oldmode, MIDV_TRASH); + newmode = MIDV_SETMODE(oldmode, MIDV_TRASH) & ~MIDV_INSERVICE; EN_WRITE(sc, MID_VC(vci), (newmode | (oldmode & MIDV_INSERVICE))); /* halt in tracks, be careful to preserve inserivce bit */ DELAY(27); @@ -1064,7 +1065,6 @@ int on; /* if stuff is still going on we are going to have to drain it out */ if (sc->rxslot[slot].indma.ifq_head || sc->rxslot[slot].q.ifq_head || - (EN_READ(sc, MID_VC(vci)) & MIDV_INSERVICE) != 0 || (sc->rxslot[slot].oth_flags & ENOTHER_SWSL) != 0) { sc->rxslot[slot].oth_flags |= ENOTHER_DRAIN; } else { @@ -1705,6 +1705,7 @@ again: */ EN_COUNT(sc->launch); + sc->enif.if_opackets++; if ((launch.atm_flags & EN_OBHDR) == 0) { EN_COUNT(sc->lheader); /* store tbd1/tbd2 in network byte order */ @@ -1868,11 +1869,8 @@ struct en_launch *l; if (tmp->m_next == NULL) { cnt = (need - len) % sizeof(u_int32_t); - if (cnt) { - cnt = sizeof(u_int32_t) - cnt; /* # of byte we need to FLUSH */ - if (M_TRAILINGSPACE(tmp) >= cnt) - len += cnt; /* pad for FLUSH */ - } + if (cnt && M_TRAILINGSPACE(tmp) >= cnt) + len += cnt; /* pad for FLUSH */ } /* do we need to do a DMA op to align to word boundary? */ @@ -2022,6 +2020,10 @@ struct en_launch *l; EN_WRAPADD(start, stop, cur, pad); EN_DTQADD(sc, pad, chan, MIDDMA_BYTE, vtophys(l->t->m_data), 0, 0); need -= pad; +#ifdef EN_DEBUG + printf("%s: tx%d: pad/FLUSH dma %d bytes (%d left, cur now 0x%x)\n", + sc->sc_dev.dv_xname, chan, pad, need, cur); +#endif } /* copy data */ @@ -2234,6 +2236,7 @@ void *arg; sc->sc_dev.dv_xname, slot, sc->rxslot[slot].atm_vci, m, EN_DQ_LEN(drq), sc->rxslot[slot].rxhand); #endif + sc->enif.if_ipackets++; atm_input(&sc->enif, &ah, m, sc->rxslot[slot].rxhand); } @@ -2265,8 +2268,10 @@ void *arg; EN_WRAPADD(MID_SLOFF, MID_SLEND, sc->hwslistp, 4);/* advance hw ptr */ slot = sc->rxvc2slot[vci]; if (slot == RX_NONE) { +#ifdef EN_DEBUG printf("%s: unexpected rx interrupt on VCI %d\n", sc->sc_dev.dv_xname, vci); +#endif EN_WRITE(sc, MID_VC(vci), MIDV_TRASH); /* rx off, damn it! */ continue; /* next */ } |