diff options
author | mux <mux@FreeBSD.org> | 2003-04-06 23:09:57 +0000 |
---|---|---|
committer | mux <mux@FreeBSD.org> | 2003-04-06 23:09:57 +0000 |
commit | f11ab00778097668bfe1184c9f66e961a84e5df6 (patch) | |
tree | 628fd6c495198c8b34c9af68220993d8b3136694 | |
parent | 32862f82ea93f1c7f99b1d617f0fb03f5f9d93c1 (diff) | |
download | FreeBSD-src-f11ab00778097668bfe1184c9f66e961a84e5df6.zip FreeBSD-src-f11ab00778097668bfe1184c9f66e961a84e5df6.tar.gz |
Because alpha can't access memory in 16-bit granularity,
we're using an atomic operation to clear the suspend flag
in fxp_start(). Since other architectures may need the
same thing, we want to do it all the time and not only
in the __alpha__ case. However, we don't want to use
atomic operations on 16-bit integers, because those may
not be available on any architecture. We're thus faking
a 32-bit atomic operation here. This patch also deals
with endianness here.
-rw-r--r-- | sys/dev/fxp/if_fxp.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c index 5e035db..77204c3 100644 --- a/sys/dev/fxp/if_fxp.c +++ b/sys/dev/fxp/if_fxp.c @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include <net/ethernet.h> #include <net/if_arp.h> +#include <machine/atomic.h> #include <machine/clock.h> /* for DELAY */ #include <net/if_types.h> @@ -1207,7 +1208,7 @@ static void fxp_start(struct ifnet *ifp) { struct fxp_softc *sc = ifp->if_softc; - struct fxp_tx *txp; + struct fxp_tx *txp, *last; struct mbuf *mb_head; int error; @@ -1377,18 +1378,21 @@ fxp_start(struct ifnet *ifp) * Advance the end of list forward. */ -#ifdef __alpha__ /* * On platforms which can't access memory in 16-bit * granularities, we must prevent the card from DMA'ing * up the status while we update the command field. * This could cause us to overwrite the completion status. + * + * This is a bit tricky, because we want to avoid using + * atomic operations on 16bits values, since they may not + * be available on any architecture or may be very + * inefficient. */ - atomic_clear_short(&sc->fxp_desc.tx_last->tx_cb->cb_command, - FXP_CB_COMMAND_S); -#else - sc->fxp_desc.tx_last->tx_cb->cb_command &= ~FXP_CB_COMMAND_S; -#endif /*__alpha__*/ + last = sc->fxp_desc.tx_last; + atomic_clear_32((u_int32_t *)&last->tx_cb->cb_status, + htobe32(bswap16(FXP_CB_COMMAND_S))); + sc->fxp_desc.tx_last = txp; /* |