summaryrefslogtreecommitdiffstats
path: root/sys/dev/bm
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2008-07-03 21:51:30 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2008-07-03 21:51:30 +0000
commit0d5154a8e550f94aa78901356041f6acc9bbcd57 (patch)
tree96451623e9b6bcebc0e009627598def725c2f3ea /sys/dev/bm
parent8404071f2967d768d2b01ca51f39a96f822e5eb0 (diff)
downloadFreeBSD-src-0d5154a8e550f94aa78901356041f6acc9bbcd57.zip
FreeBSD-src-0d5154a8e550f94aa78901356041f6acc9bbcd57.tar.gz
Fix some locking and logic bugs pointed out by jhb. These fix driver detach and speed up data transfer by nearly a factor of 2.
Approved by: marcel (mentor)
Diffstat (limited to 'sys/dev/bm')
-rw-r--r--sys/dev/bm/if_bm.c52
-rw-r--r--sys/dev/bm/if_bmreg.h12
-rw-r--r--sys/dev/bm/if_bmvar.h2
3 files changed, 26 insertions, 40 deletions
diff --git a/sys/dev/bm/if_bm.c b/sys/dev/bm/if_bm.c
index 332884d..eee01e0 100644
--- a/sys/dev/bm/if_bm.c
+++ b/sys/dev/bm/if_bm.c
@@ -101,7 +101,6 @@ static int bm_add_rxbuf_dma (struct bm_softc *sc, int i);
static void bm_enable_interrupts (struct bm_softc *sc);
static void bm_disable_interrupts (struct bm_softc *sc);
static void bm_tick (void *xsc);
-static int bm_watchdog (struct bm_softc *sc);
static int bm_ifmedia_upd (struct ifnet *);
static void bm_ifmedia_sts (struct ifnet *, struct ifmediareq *);
@@ -240,8 +239,6 @@ bm_mii_readreg(struct bm_softc *sc, struct bm_mii_frame *frame)
{
int i, ack, bit;
- BM_LOCK(sc);
-
/*
* Set up frame for RX.
*/
@@ -284,8 +281,6 @@ bm_mii_readreg(struct bm_softc *sc, struct bm_mii_frame *frame)
bm_mii_writebit(sc, 0);
bm_mii_writebit(sc, 0);
- BM_UNLOCK(sc);
-
return ((ack) ? 1 : 0);
}
@@ -295,8 +290,6 @@ bm_mii_readreg(struct bm_softc *sc, struct bm_mii_frame *frame)
static int
bm_mii_writereg(struct bm_softc *sc, struct bm_mii_frame *frame)
{
- BM_LOCK(sc);
-
/*
* Set up frame for tx
*/
@@ -321,8 +314,6 @@ bm_mii_writereg(struct bm_softc *sc, struct bm_mii_frame *frame)
*/
bm_mii_writebit(sc, 0);
- BM_UNLOCK(sc);
-
return (0);
}
@@ -464,7 +455,7 @@ bm_attach(device_t dev)
error = 0;
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
+ MTX_DEF);
callout_init_mtx(&sc->sc_tick_ch, &sc->sc_mtx, 0);
/* Check for an improved version of Paddington */
@@ -484,9 +475,6 @@ bm_attach(device_t dev)
return (ENXIO);
}
- sc->sc_btag = rman_get_bustag(sc->sc_memr);
- sc->sc_bhandle = rman_get_bushandle(sc->sc_memr);
-
sc->sc_txdmarid = BM_TXDMA_REGISTERS;
sc->sc_rxdmarid = BM_RXDMA_REGISTERS;
@@ -627,8 +615,6 @@ bm_attach(device_t dev)
/* Attach the interface. */
ether_ifattach(ifp, sc->sc_enaddr);
-
- ifp->if_data.ifi_hdrlen = sizeof(struct ether_header);
ifp->if_hwassist = 0;
return (0);
@@ -639,10 +625,14 @@ bm_detach(device_t dev)
{
struct bm_softc *sc = device_get_softc(dev);
- callout_drain(&sc->sc_tick_ch);
-
BM_LOCK(sc);
bm_stop(sc);
+ BM_UNLOCK(sc);
+
+ callout_drain(&sc->sc_tick_ch);
+ ether_ifdetach(sc->sc_ifp);
+ bus_teardown_intr(dev, sc->sc_txdmairq, sc->sc_txihtx);
+ bus_teardown_intr(dev, sc->sc_rxdmairq, sc->sc_rxih);
dbdma_free_channel(sc->sc_txdma);
dbdma_free_channel(sc->sc_rxdma);
@@ -653,15 +643,13 @@ bm_detach(device_t dev)
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rxdmarid,
sc->sc_rxdmar);
- bus_teardown_intr(dev, sc->sc_txdmairq, sc->sc_txihtx);
- bus_teardown_intr(dev, sc->sc_rxdmairq, sc->sc_rxih);
bus_release_resource(dev, SYS_RES_IRQ, sc->sc_txdmairqid,
sc->sc_txdmairq);
bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rxdmairqid,
sc->sc_rxdmairq);
- BM_UNLOCK(sc);
mtx_destroy(&sc->sc_mtx);
+ if_free(sc->sc_ifp);
return (0);
}
@@ -669,7 +657,13 @@ bm_detach(device_t dev)
static void
bm_shutdown(device_t dev)
{
- bm_stop(device_get_softc(dev));
+ struct bm_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ BM_LOCK(sc);
+ bm_stop(sc);
+ BM_UNLOCK(sc);
}
static void
@@ -1205,6 +1199,7 @@ bm_stop(struct bm_softc *sc)
/* And we're down */
sc->sc_ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
sc->sc_wdog_timer = 0;
+ callout_stop(&sc->sc_tick_ch);
}
static void
@@ -1370,22 +1365,15 @@ bm_tick(void *arg)
mii_tick(sc->sc_mii);
bm_miibus_statchg(sc->sc_dev);
- if (bm_watchdog(sc) == EJUSTRETURN)
+ if (sc->sc_wdog_timer == 0 || --sc->sc_wdog_timer != 0) {
+ callout_reset(&sc->sc_tick_ch, hz, bm_tick, sc);
return;
+ }
- callout_reset(&sc->sc_tick_ch, hz, bm_tick, sc);
-}
-
-static int
-bm_watchdog(struct bm_softc *sc)
-{
- if (sc->sc_wdog_timer == 0 || --sc->sc_wdog_timer != 0)
- return (0);
-
+ /* Problems */
device_printf(sc->sc_dev, "device timeout\n");
bm_init_locked(sc);
- return (EJUSTRETURN);
}
static int
diff --git a/sys/dev/bm/if_bmreg.h b/sys/dev/bm/if_bmreg.h
index 5507cdd..15ee1fe 100644
--- a/sys/dev/bm/if_bmreg.h
+++ b/sys/dev/bm/if_bmreg.h
@@ -161,16 +161,16 @@
* register space access macros
*/
#define CSR_WRITE_4(sc, reg, val) \
- bus_space_write_4(sc->sc_btag, sc->sc_bhandle, reg, val)
+ bus_write_4(sc->sc_memr, reg, val)
#define CSR_WRITE_2(sc, reg, val) \
- bus_space_write_2(sc->sc_btag, sc->sc_bhandle, reg, val)
+ bus_write_2(sc->sc_memr, reg, val)
#define CSR_WRITE_1(sc, reg, val) \
- bus_space_write_1(sc->sc_btag, sc->sc_bhandle, reg, val)
+ bus_write_1(sc->sc_memr, reg, val)
#define CSR_READ_4(sc, reg) \
- bus_space_read_4(sc->sc_btag, sc->sc_bhandle, reg)
+ bus_read_4(sc->sc_memr, reg)
#define CSR_READ_2(sc, reg) \
- bus_space_read_2(sc->sc_btag, sc->sc_bhandle, reg)
+ bus_read_2(sc->sc_memr, reg)
#define CSR_READ_1(sc, reg) \
- bus_space_read_1(sc->sc_btag, sc->sc_bhandle, reg)
+ bus_read_1(sc->sc_memr, reg)
diff --git a/sys/dev/bm/if_bmvar.h b/sys/dev/bm/if_bmvar.h
index c256f30..7d31489 100644
--- a/sys/dev/bm/if_bmvar.h
+++ b/sys/dev/bm/if_bmvar.h
@@ -87,8 +87,6 @@ struct bm_softc {
device_t sc_dev; /* back ptr to dev */
struct resource *sc_memr; /* macio bus mem resource */
int sc_memrid;
- bus_space_handle_t sc_bhandle;
- bus_space_tag_t sc_btag;
device_t sc_miibus;
struct mii_data *sc_mii;
OpenPOWER on IntegriCloud