PR/31455: Robert Elz: ex (905[BC]) cards can hang in -current kernels

- fix bus_space_read_1 -> bus_space_read_2 since revision 1.27 changed
  the bit defines to assume 2 byte reads.
- Increment oerrors in case of collisions
- Clamp success counter to 100, instead of letting rotate freely.
This commit is contained in:
christos 2005-10-04 17:37:26 +00:00
parent c1a47858e9
commit a9c3ad6f5c
1 changed files with 10 additions and 6 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: elinkxl.c,v 1.83 2005/05/31 01:48:22 christos Exp $ */ /* $NetBSD: elinkxl.c,v 1.84 2005/10/04 17:37:26 christos Exp $ */
/*- /*-
* Copyright (c) 1998 The NetBSD Foundation, Inc. * Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: elinkxl.c,v 1.83 2005/05/31 01:48:22 christos Exp $"); __KERNEL_RCSID(0, "$NetBSD: elinkxl.c,v 1.84 2005/10/04 17:37:26 christos Exp $");
#include "bpfilter.h" #include "bpfilter.h"
#include "rnd.h" #include "rnd.h"
@ -789,9 +789,12 @@ ex_txstat(sc)
/* /*
* We need to read+write TX_STATUS until we get a 0 status * We need to read+write TX_STATUS until we get a 0 status
* in order to turn off the interrupt flag. * in order to turn off the interrupt flag.
* ELINK_TXSTATUS is in the upper byte of 2 with ELINK_TIMER
* XXX: Big Endian? Can we assume that TXSTATUS will be the
* upper byte?
*/ */
while ((i = bus_space_read_1(iot, ioh, ELINK_TXSTATUS)) & TXS_COMPLETE) { while ((i = bus_space_read_2(iot, ioh, ELINK_TXSTATUS)) & TXS_COMPLETE) {
bus_space_write_1(iot, ioh, ELINK_TXSTATUS, 0x0); bus_space_write_2(iot, ioh, ELINK_TXSTATUS, 0x0);
if (i & TXS_JABBER) { if (i & TXS_JABBER) {
++sc->sc_ethercom.ec_if.if_oerrors; ++sc->sc_ethercom.ec_if.if_oerrors;
@ -813,11 +816,12 @@ ex_txstat(sc)
ex_init(ifp); ex_init(ifp);
/* TODO: be more subtle here */ /* TODO: be more subtle here */
} else if (i & TXS_MAX_COLLISION) { } else if (i & TXS_MAX_COLLISION) {
++sc->sc_ethercom.ec_if.if_oerrors;
++sc->sc_ethercom.ec_if.if_collisions; ++sc->sc_ethercom.ec_if.if_collisions;
bus_space_write_2(iot, ioh, ELINK_COMMAND, TX_ENABLE); bus_space_write_2(iot, ioh, ELINK_COMMAND, TX_ENABLE);
sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE; sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE;
} else } else if (sc->tx_succ_ok < 100)
sc->tx_succ_ok = (sc->tx_succ_ok+1) & 127; sc->tx_succ_ok++;
} }
} }