Add locking to make able to run without the Giant lock being held. This

is enabling as all entries are still called with Giant being held.
Maintaining compatability with NetBSD makes what should be very simple
kinda ugly.

Reviewed by:	Jason Evans
This commit is contained in:
cp 2000-09-17 13:26:25 +00:00
parent 7f027602a7
commit 21a8969396
4 changed files with 102 additions and 34 deletions

View File

@ -84,6 +84,7 @@
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <machine/mutex.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
@ -521,13 +522,16 @@ fxp_attach(device_t dev)
int error = 0;
struct fxp_softc *sc = device_get_softc(dev);
struct ifnet *ifp;
int s;
FXP_SPLVAR(s)
u_long val;
int rid;
#if !defined(__NetBSD__)
mtx_init(&sc->sc_mtx, "fxp", MTX_DEF);
#endif
callout_handle_init(&sc->stat_ch);
s = splimp();
FXP_LOCK(sc, s);
/*
* Enable bus mastering.
@ -605,11 +609,12 @@ fxp_attach(device_t dev)
*/
ifp->if_snd.ifq_maxlen = FXP_NTXCB - 1;
splx(s);
FXP_UNLOCK(sc, s);
return 0;
fail:
splx(s);
FXP_UNLOCK(sc, s);
mtx_destroy(&sc->sc_mtx);
return error;
}
@ -620,9 +625,9 @@ static int
fxp_detach(device_t dev)
{
struct fxp_softc *sc = device_get_softc(dev);
int s;
FXP_SPLVAR(s)
s = splimp();
FXP_LOCK(sc, s);
/*
* Close down routes etc.
@ -659,7 +664,7 @@ fxp_detach(device_t dev)
free(sc->fxp_stats, M_DEVBUF);
free(sc->mcsp, M_DEVBUF);
splx(s);
FXP_UNLOCK(sc, s);
return 0;
}
@ -959,13 +964,18 @@ fxp_start(ifp)
struct fxp_softc *sc = ifp->if_softc;
struct fxp_cb_tx *txp;
#if !defined(__NetBSD__)
FXP_LOCK(sc, s);
#endif
/*
* See if we need to suspend xmit until the multicast filter
* has been reprogrammed (which can only be done at the head
* of the command chain).
*/
if (sc->need_mcsetup)
if (sc->need_mcsetup) {
FXP_UNLOCK(sc, s);
return;
}
txp = NULL;
@ -1093,6 +1103,9 @@ fxp_start(ifp)
fxp_scb_wait(sc);
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_RESUME);
}
#if !defined(__NetBSD__)
FXP_UNLOCK(sc, s);
#endif
}
/*
@ -1107,6 +1120,9 @@ fxp_intr(arg)
u_int8_t statack;
#if defined(__NetBSD__)
int claimed = 0;
#else
FXP_LOCK(sc, s);
#endif
while ((statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK)) != 0) {
@ -1215,6 +1231,8 @@ fxp_intr(arg)
}
#if defined(__NetBSD__)
return (claimed);
#else
FXP_UNLOCK(sc, s);
#endif
}
@ -1237,7 +1255,7 @@ fxp_stats_update(arg)
struct ifnet *ifp = &sc->sc_if;
struct fxp_stats *sp = sc->fxp_stats;
struct fxp_cb_tx *txp;
int s;
FXP_SPLVAR(s)
ifp->if_opackets += sp->tx_good;
ifp->if_collisions += sp->tx_total_collisions;
@ -1264,7 +1282,7 @@ fxp_stats_update(arg)
if (tx_threshold < 192)
tx_threshold += 64;
}
s = splimp();
FXP_LOCK(sc, s);
/*
* Release any xmit buffers that have completed DMA. This isn't
* strictly necessary to do here, but it's advantagous for mbufs
@ -1322,7 +1340,7 @@ fxp_stats_update(arg)
sp->rx_rnr_errors = 0;
sp->rx_overrun_errors = 0;
}
splx(s);
FXP_UNLOCK(sc, s);
/*
* Schedule another timeout one second from now.
*/
@ -1341,6 +1359,10 @@ fxp_stop(sc)
struct fxp_cb_tx *txp;
int i;
#if !defined(__NetBSD__)
FXP_LOCK(sc, s);
#endif
/*
* Cancel stats updater.
*/
@ -1386,6 +1408,9 @@ fxp_stop(sc)
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
ifp->if_timer = 0;
#if !defined(__NetBSD__)
FXP_UNLOCK(sc, s);
#endif
}
/*
@ -1415,9 +1440,10 @@ fxp_init(xsc)
struct fxp_cb_config *cbp;
struct fxp_cb_ias *cb_ias;
struct fxp_cb_tx *txp;
int i, s, prm;
int i, prm;
FXP_SPLVAR(s)
s = splimp();
FXP_LOCK(sc, s);
/*
* Cancel any pending I/O
*/
@ -1564,7 +1590,7 @@ fxp_init(xsc)
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
splx(s);
FXP_UNLOCK(sc, s);
/*
* Start stats updater.
@ -1857,9 +1883,10 @@ fxp_ioctl(ifp, command, data)
{
struct fxp_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *)data;
int s, error = 0;
FXP_SPLVAR(s)
int error = 0;
s = splimp();
FXP_LOCK(sc, s);
switch (command) {
@ -1936,7 +1963,7 @@ fxp_ioctl(ifp, command, data)
default:
error = EINVAL;
}
(void) splx(s);
FXP_UNLOCK(sc, s);
return (error);
}

View File

@ -48,6 +48,7 @@ struct fxp_softc {
struct resource *mem; /* resource descriptor for registers */
struct resource *irq; /* resource descriptor for interrupt */
void *ih; /* interrupt handler cookie */
struct mtx sc_mtx;
#endif /* __NetBSD__ */
bus_space_tag_t sc_st; /* bus space tag */
bus_space_handle_t sc_sh; /* bus space handle */
@ -92,6 +93,9 @@ struct fxp_softc {
#define FXP_INTR_TYPE int
#define FXP_IOCTLCMD_TYPE u_long
#define FXP_BPFTAP_ARG(ifp) (ifp)->if_bpf
#define FXP_SPLVAR(x) int x;
#define FXP_LOCK(sc, x) x = splimp()
#define FXP_UNLOCK(sc, x) splx(x)
#else /* __FreeBSD__ */
#define sc_if arpcom.ac_if
#define FXP_FORMAT "fxp%d"
@ -99,4 +103,7 @@ struct fxp_softc {
#define FXP_INTR_TYPE void
#define FXP_IOCTLCMD_TYPE u_long
#define FXP_BPFTAP_ARG(ifp) ifp
#define FXP_SPLVAR(s)
#define FXP_LOCK(_sc, x) mtx_enter(&(_sc)->sc_mtx, MTX_DEF)
#define FXP_UNLOCK(_sc, x) mtx_exit(&(_sc)->sc_mtx, MTX_DEF)
#endif /* __NetBSD__ */

View File

@ -84,6 +84,7 @@
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <machine/mutex.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
@ -521,13 +522,16 @@ fxp_attach(device_t dev)
int error = 0;
struct fxp_softc *sc = device_get_softc(dev);
struct ifnet *ifp;
int s;
FXP_SPLVAR(s)
u_long val;
int rid;
#if !defined(__NetBSD__)
mtx_init(&sc->sc_mtx, "fxp", MTX_DEF);
#endif
callout_handle_init(&sc->stat_ch);
s = splimp();
FXP_LOCK(sc, s);
/*
* Enable bus mastering.
@ -605,11 +609,12 @@ fxp_attach(device_t dev)
*/
ifp->if_snd.ifq_maxlen = FXP_NTXCB - 1;
splx(s);
FXP_UNLOCK(sc, s);
return 0;
fail:
splx(s);
FXP_UNLOCK(sc, s);
mtx_destroy(&sc->sc_mtx);
return error;
}
@ -620,9 +625,9 @@ static int
fxp_detach(device_t dev)
{
struct fxp_softc *sc = device_get_softc(dev);
int s;
FXP_SPLVAR(s)
s = splimp();
FXP_LOCK(sc, s);
/*
* Close down routes etc.
@ -659,7 +664,7 @@ fxp_detach(device_t dev)
free(sc->fxp_stats, M_DEVBUF);
free(sc->mcsp, M_DEVBUF);
splx(s);
FXP_UNLOCK(sc, s);
return 0;
}
@ -959,13 +964,18 @@ fxp_start(ifp)
struct fxp_softc *sc = ifp->if_softc;
struct fxp_cb_tx *txp;
#if !defined(__NetBSD__)
FXP_LOCK(sc, s);
#endif
/*
* See if we need to suspend xmit until the multicast filter
* has been reprogrammed (which can only be done at the head
* of the command chain).
*/
if (sc->need_mcsetup)
if (sc->need_mcsetup) {
FXP_UNLOCK(sc, s);
return;
}
txp = NULL;
@ -1093,6 +1103,9 @@ fxp_start(ifp)
fxp_scb_wait(sc);
CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_RESUME);
}
#if !defined(__NetBSD__)
FXP_UNLOCK(sc, s);
#endif
}
/*
@ -1107,6 +1120,9 @@ fxp_intr(arg)
u_int8_t statack;
#if defined(__NetBSD__)
int claimed = 0;
#else
FXP_LOCK(sc, s);
#endif
while ((statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK)) != 0) {
@ -1215,6 +1231,8 @@ fxp_intr(arg)
}
#if defined(__NetBSD__)
return (claimed);
#else
FXP_UNLOCK(sc, s);
#endif
}
@ -1237,7 +1255,7 @@ fxp_stats_update(arg)
struct ifnet *ifp = &sc->sc_if;
struct fxp_stats *sp = sc->fxp_stats;
struct fxp_cb_tx *txp;
int s;
FXP_SPLVAR(s)
ifp->if_opackets += sp->tx_good;
ifp->if_collisions += sp->tx_total_collisions;
@ -1264,7 +1282,7 @@ fxp_stats_update(arg)
if (tx_threshold < 192)
tx_threshold += 64;
}
s = splimp();
FXP_LOCK(sc, s);
/*
* Release any xmit buffers that have completed DMA. This isn't
* strictly necessary to do here, but it's advantagous for mbufs
@ -1322,7 +1340,7 @@ fxp_stats_update(arg)
sp->rx_rnr_errors = 0;
sp->rx_overrun_errors = 0;
}
splx(s);
FXP_UNLOCK(sc, s);
/*
* Schedule another timeout one second from now.
*/
@ -1341,6 +1359,10 @@ fxp_stop(sc)
struct fxp_cb_tx *txp;
int i;
#if !defined(__NetBSD__)
FXP_LOCK(sc, s);
#endif
/*
* Cancel stats updater.
*/
@ -1386,6 +1408,9 @@ fxp_stop(sc)
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
ifp->if_timer = 0;
#if !defined(__NetBSD__)
FXP_UNLOCK(sc, s);
#endif
}
/*
@ -1415,9 +1440,10 @@ fxp_init(xsc)
struct fxp_cb_config *cbp;
struct fxp_cb_ias *cb_ias;
struct fxp_cb_tx *txp;
int i, s, prm;
int i, prm;
FXP_SPLVAR(s)
s = splimp();
FXP_LOCK(sc, s);
/*
* Cancel any pending I/O
*/
@ -1564,7 +1590,7 @@ fxp_init(xsc)
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
splx(s);
FXP_UNLOCK(sc, s);
/*
* Start stats updater.
@ -1857,9 +1883,10 @@ fxp_ioctl(ifp, command, data)
{
struct fxp_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *)data;
int s, error = 0;
FXP_SPLVAR(s)
int error = 0;
s = splimp();
FXP_LOCK(sc, s);
switch (command) {
@ -1936,7 +1963,7 @@ fxp_ioctl(ifp, command, data)
default:
error = EINVAL;
}
(void) splx(s);
FXP_UNLOCK(sc, s);
return (error);
}

View File

@ -48,6 +48,7 @@ struct fxp_softc {
struct resource *mem; /* resource descriptor for registers */
struct resource *irq; /* resource descriptor for interrupt */
void *ih; /* interrupt handler cookie */
struct mtx sc_mtx;
#endif /* __NetBSD__ */
bus_space_tag_t sc_st; /* bus space tag */
bus_space_handle_t sc_sh; /* bus space handle */
@ -92,6 +93,9 @@ struct fxp_softc {
#define FXP_INTR_TYPE int
#define FXP_IOCTLCMD_TYPE u_long
#define FXP_BPFTAP_ARG(ifp) (ifp)->if_bpf
#define FXP_SPLVAR(x) int x;
#define FXP_LOCK(sc, x) x = splimp()
#define FXP_UNLOCK(sc, x) splx(x)
#else /* __FreeBSD__ */
#define sc_if arpcom.ac_if
#define FXP_FORMAT "fxp%d"
@ -99,4 +103,7 @@ struct fxp_softc {
#define FXP_INTR_TYPE void
#define FXP_IOCTLCMD_TYPE u_long
#define FXP_BPFTAP_ARG(ifp) ifp
#define FXP_SPLVAR(s)
#define FXP_LOCK(_sc, x) mtx_enter(&(_sc)->sc_mtx, MTX_DEF)
#define FXP_UNLOCK(_sc, x) mtx_exit(&(_sc)->sc_mtx, MTX_DEF)
#endif /* __NetBSD__ */