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.
This commit is contained in:
Maxime Henrion 2003-04-06 23:09:57 +00:00
parent 270086ec64
commit ec6b76b760
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=113187

View File

@ -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;
/*