PERFORCE change 39273 for review
Sam Leffler
sam at FreeBSD.org
Mon Oct 6 13:58:33 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=39273
Change 39273 by sam at sam_ebb on 2003/10/06 13:58:23
add simple locking
Affected files ...
.. //depot/projects/netperf/sys/dev/bge/if_bge.c#10 edit
.. //depot/projects/netperf/sys/dev/bge/if_bgereg.h#5 edit
Differences ...
==== //depot/projects/netperf/sys/dev/bge/if_bge.c#10 (text+ko) ====
@@ -184,6 +184,7 @@
static void bge_txeof (struct bge_softc *);
static void bge_rxeof (struct bge_softc *);
+static void bge_tick_locked (struct bge_softc *);
static void bge_tick (void *);
static void bge_stats_update (struct bge_softc *);
static void bge_stats_update_regs
@@ -192,8 +193,10 @@
u_int32_t *);
static void bge_intr (void *);
+static void bge_start_locked (struct ifnet *);
static void bge_start (struct ifnet *);
static int bge_ioctl (struct ifnet *, u_long, caddr_t);
+static void bge_init_locked (struct bge_softc *);
static void bge_init (void *);
static void bge_stop (struct bge_softc *);
static void bge_watchdog (struct ifnet *);
@@ -1154,6 +1157,8 @@
u_int32_t hashes[4] = { 0, 0, 0, 0 };
int h, i;
+ BGE_LOCK_ASSERT(sc);
+
ifp = &sc->arpcom.ac_if;
if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
@@ -2225,15 +2230,12 @@
bge_attach(dev)
device_t dev;
{
- int s;
struct ifnet *ifp;
struct bge_softc *sc;
u_int32_t hwcfg = 0;
u_int32_t mac_addr = 0;
int unit, error = 0, rid;
- s = splimp();
-
sc = device_get_softc(dev);
unit = device_get_unit(dev);
sc->bge_dev = dev;
@@ -2270,16 +2272,9 @@
goto fail;
}
- error = bus_setup_intr(dev, sc->bge_irq, INTR_TYPE_NET,
- bge_intr, sc, &sc->bge_intrhand);
+ sc->bge_unit = unit;
- if (error) {
- bge_release_resources(sc);
- printf("bge%d: couldn't set up irq\n", unit);
- goto fail;
- }
-
- sc->bge_unit = unit;
+ BGE_LOCK_INIT(sc, device_get_nameunit(dev));
/* Try to reset the chip. */
bge_reset(sc);
@@ -2449,11 +2444,20 @@
* Call MI attach routine.
*/
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
- callout_handle_init(&sc->bge_stat_ch);
+ callout_init(&sc->bge_stat_ch, CALLOUT_MPSAFE);
+
+ /*
+ * Hookup IRQ last.
+ */
+ error = bus_setup_intr(dev, sc->bge_irq, INTR_TYPE_NET | INTR_MPSAFE,
+ bge_intr, sc, &sc->bge_intrhand);
+
+ if (error) {
+ bge_release_resources(sc);
+ printf("bge%d: couldn't set up irq\n", unit);
+ }
fail:
- splx(s);
-
return(error);
}
@@ -2463,16 +2467,16 @@
{
struct bge_softc *sc;
struct ifnet *ifp;
- int s;
-
- s = splimp();
sc = device_get_softc(dev);
ifp = &sc->arpcom.ac_if;
- ether_ifdetach(ifp);
+ BGE_LOCK(sc);
bge_stop(sc);
bge_reset(sc);
+ BGE_UNLOCK(sc);
+
+ ether_ifdetach(ifp);
if (sc->bge_tbi) {
ifmedia_removeall(&sc->bge_ifmedia);
@@ -2485,8 +2489,6 @@
if (sc->bge_asicrev != BGE_ASICREV_BCM5705)
bge_free_jumbo_mem(sc);
- splx(s);
-
return(0);
}
@@ -2516,6 +2518,9 @@
bge_dma_free(sc);
+ if (mtx_initialized(&sc->bge_mtx)) /* XXX */
+ BGE_LOCK_DESTROY(sc);
+
return;
}
@@ -2620,6 +2625,8 @@
struct ifnet *ifp;
int stdcnt = 0, jumbocnt = 0;
+ BGE_LOCK_ASSERT(sc);
+
ifp = &sc->arpcom.ac_if;
bus_dmamap_sync(sc->bge_cdata.bge_rx_return_ring_tag,
@@ -2732,7 +2739,9 @@
if (have_tag)
VLAN_INPUT_TAG(ifp, m, vlan_tag, continue);
+ BGE_UNLOCK(sc);
(*ifp->if_input)(ifp, m);
+ BGE_LOCK(sc);
}
bus_dmamap_sync(sc->bge_cdata.bge_rx_return_ring_tag,
@@ -2762,6 +2771,8 @@
struct bge_tx_bd *cur_tx = NULL;
struct ifnet *ifp;
+ BGE_LOCK_ASSERT(sc);
+
ifp = &sc->arpcom.ac_if;
/*
@@ -2805,6 +2816,8 @@
sc = xsc;
ifp = &sc->arpcom.ac_if;
+ BGE_LOCK(sc);
+
bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTWRITE);
@@ -2837,8 +2850,8 @@
status = CSR_READ_4(sc, BGE_MAC_STS);
if (status & BGE_MACSTAT_MI_INTERRUPT) {
sc->bge_link = 0;
- untimeout(bge_tick, sc, sc->bge_stat_ch);
- bge_tick(sc);
+ callout_stop(&sc->bge_stat_ch);
+ bge_tick_locked(sc);
/* Clear the interrupt */
CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,
BGE_EVTENB_MI_INTERRUPT);
@@ -2864,8 +2877,8 @@
if (!(status & (BGE_MACSTAT_PORT_DECODE_ERROR|
BGE_MACSTAT_MI_COMPLETE))) {
sc->bge_link = 0;
- untimeout(bge_tick, sc, sc->bge_stat_ch);
- bge_tick(sc);
+ callout_stop(&sc->bge_stat_ch);
+ bge_tick_locked(sc);
}
/* Clear the interrupt */
CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED|
@@ -2894,35 +2907,32 @@
CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL)
- bge_start(ifp);
+ bge_start_locked(ifp);
+
+ BGE_UNLOCK(sc);
return;
}
static void
-bge_tick(xsc)
- void *xsc;
+bge_tick_locked(sc)
+ struct bge_softc *sc;
{
- struct bge_softc *sc;
struct mii_data *mii = NULL;
struct ifmedia *ifm = NULL;
struct ifnet *ifp;
- int s;
- sc = xsc;
ifp = &sc->arpcom.ac_if;
- s = splimp();
+ BGE_LOCK_ASSERT(sc);
if (sc->bge_asicrev == BGE_ASICREV_BCM5705)
bge_stats_update_regs(sc);
else
bge_stats_update(sc);
- sc->bge_stat_ch = timeout(bge_tick, sc, hz);
- if (sc->bge_link) {
- splx(s);
+ callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc);
+ if (sc->bge_link)
return;
- }
if (sc->bge_tbi) {
ifm = &sc->bge_ifmedia;
@@ -2932,9 +2942,8 @@
CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF);
printf("bge%d: gigabit link up\n", sc->bge_unit);
if (ifp->if_snd.ifq_head != NULL)
- bge_start(ifp);
+ bge_start_locked(ifp);
}
- splx(s);
return;
}
@@ -2949,12 +2958,23 @@
printf("bge%d: gigabit link up\n",
sc->bge_unit);
if (ifp->if_snd.ifq_head != NULL)
- bge_start(ifp);
+ bge_start_locked(ifp);
}
- splx(s);
+ return;
+}
+
+static void
+bge_tick(xsc)
+ void *xsc;
+{
+ struct bge_softc *sc;
+
+ sc = xsc;
- return;
+ BGE_LOCK(sc);
+ bge_tick_locked(sc);
+ BGE_UNLOCK(sc);
}
static void
@@ -3093,7 +3113,7 @@
* to the mbuf data regions directly in the transmit descriptors.
*/
static void
-bge_start(ifp)
+bge_start_locked(ifp)
struct ifnet *ifp;
{
struct bge_softc *sc;
@@ -3162,23 +3182,35 @@
return;
}
+/*
+ * Main transmit routine. To avoid having to do mbuf copies, we put pointers
+ * to the mbuf data regions directly in the transmit descriptors.
+ */
static void
-bge_init(xsc)
- void *xsc;
+bge_start(ifp)
+ struct ifnet *ifp;
+{
+ struct bge_softc *sc;
+
+ sc = ifp->if_softc;
+ BGE_LOCK(sc);
+ bge_start_locked(ifp);
+ BGE_UNLOCK(sc);
+}
+
+static void
+bge_init_locked(sc)
+ struct bge_softc *sc;
{
- struct bge_softc *sc = xsc;
struct ifnet *ifp;
u_int16_t *m;
- int s;
- s = splimp();
+ BGE_LOCK_ASSERT(sc);
ifp = &sc->arpcom.ac_if;
- if (ifp->if_flags & IFF_RUNNING) {
- splx(s);
+ if (ifp->if_flags & IFF_RUNNING)
return;
- }
/* Cancel pending I/O and flush buffers. */
bge_stop(sc);
@@ -3191,7 +3223,6 @@
*/
if (bge_blockinit(sc)) {
printf("bge%d: initialization failure\n", sc->bge_unit);
- splx(s);
return;
}
@@ -3266,9 +3297,20 @@
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
- splx(s);
+ callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc);
+
+ return;
+}
+
+static void
+bge_init(xsc)
+ void *xsc;
+{
+ struct bge_softc *sc = xsc;
- sc->bge_stat_ch = timeout(bge_tick, sc, hz);
+ BGE_LOCK(sc);
+ bge_init_locked(sc);
+ BGE_UNLOCK(sc);
return;
}
@@ -3365,11 +3407,9 @@
{
struct bge_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *) data;
- int s, mask, error = 0;
+ int mask, error = 0;
struct mii_data *mii;
- s = splimp();
-
switch(command) {
case SIOCSIFMTU:
/* Disallow jumbo frames on 5705. */
@@ -3383,6 +3423,7 @@
}
break;
case SIOCSIFFLAGS:
+ BGE_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
/*
* If only the state of the PROMISC flag changed,
@@ -3403,19 +3444,22 @@
BGE_CLRBIT(sc, BGE_RX_MODE,
BGE_RXMODE_RX_PROMISC);
} else
- bge_init(sc);
+ bge_init_locked(sc);
} else {
if (ifp->if_flags & IFF_RUNNING) {
bge_stop(sc);
}
}
sc->bge_if_flags = ifp->if_flags;
+ BGE_UNLOCK(sc);
error = 0;
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
if (ifp->if_flags & IFF_RUNNING) {
+ BGE_LOCK(sc);
bge_setmulti(sc);
+ BGE_UNLOCK(sc);
error = 0;
}
break;
@@ -3445,8 +3489,6 @@
break;
}
- (void)splx(s);
-
return(error);
}
@@ -3481,12 +3523,14 @@
struct mii_data *mii = NULL;
int mtmp, itmp;
+ BGE_LOCK_ASSERT(sc);
+
ifp = &sc->arpcom.ac_if;
if (!sc->bge_tbi)
mii = device_get_softc(sc->bge_miibus);
- untimeout(bge_tick, sc, sc->bge_stat_ch);
+ callout_stop(&sc->bge_stat_ch);
/*
* Disable all of the receiver blocks
@@ -3583,8 +3627,10 @@
sc = device_get_softc(dev);
+ BGE_LOCK(sc);
bge_stop(sc);
bge_reset(sc);
+ BGE_UNLOCK(sc);
return;
}
==== //depot/projects/netperf/sys/dev/bge/if_bgereg.h#5 (text+ko) ====
@@ -2258,6 +2258,7 @@
struct bge_softc {
struct arpcom arpcom; /* interface info */
device_t bge_dev;
+ struct mtx bge_mtx;
device_t bge_miibus;
bus_space_handle_t bge_bhandle;
vm_offset_t bge_vhandle;
@@ -2293,7 +2294,14 @@
int bge_if_flags;
int bge_txcnt;
int bge_link;
- struct callout_handle bge_stat_ch;
+ struct callout bge_stat_ch;
char *bge_vpd_prodname;
char *bge_vpd_readonly;
};
+
+#define BGE_LOCK_INIT(_sc, _name) \
+ mtx_init(&(_sc)->bge_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF)
+#define BGE_LOCK(_sc) mtx_lock(&(_sc)->bge_mtx)
+#define BGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->bge_mtx, MA_OWNED)
+#define BGE_UNLOCK(_sc) mtx_unlock(&(_sc)->bge_mtx)
+#define BGE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->bge_mtx)
More information about the p4-projects
mailing list