PERFORCE change 82227 for review

John Baldwin jhb at FreeBSD.org
Thu Aug 18 20:27:05 GMT 2005


http://perforce.freebsd.org/chv.cgi?CH=82227

Change 82227 by jhb at jhb_slimer on 2005/08/18 20:26:37

	IFC @82226.

Affected files ...

.. //depot/projects/smpng/sys/dev/re/if_re.c#25 integrate
.. //depot/projects/smpng/sys/net/bridgestp.c#4 integrate
.. //depot/projects/smpng/sys/net/if.c#72 integrate
.. //depot/projects/smpng/sys/net/if_bridge.c#7 integrate
.. //depot/projects/smpng/sys/pci/if_dc.c#68 integrate
.. //depot/projects/smpng/sys/pci/if_sf.c#37 integrate
.. //depot/projects/smpng/sys/pci/if_sfreg.h#9 integrate
.. //depot/projects/smpng/sys/pci/if_xl.c#61 integrate
.. //depot/projects/smpng/sys/pci/if_xlreg.h#18 integrate

Differences ...

==== //depot/projects/smpng/sys/dev/re/if_re.c#25 (text+ko) ====

@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/re/if_re.c,v 1.50 2005/08/18 14:29:01 sobomax Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/re/if_re.c,v 1.51 2005/08/18 18:36:39 sobomax Exp $");
 
 /*
  * RealTek 8139C+/8169/8169S/8110S PCI NIC driver

==== //depot/projects/smpng/sys/net/bridgestp.c#4 (text+ko) ====

@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/net/bridgestp.c,v 1.5 2005/08/15 02:54:29 thompsa Exp $");
+__FBSDID("$FreeBSD: src/sys/net/bridgestp.c,v 1.6 2005/08/18 20:17:00 thompsa Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1092,7 +1092,7 @@
 	struct bridge_softc *sc = arg;
 	struct bridge_iflist *bif;
 
-	BRIDGE_LOCK(sc);
+	BRIDGE_LOCK_ASSERT(sc);
 
 #if 0
 	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
@@ -1141,8 +1141,6 @@
 
 	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
 		callout_reset(&sc->sc_bstpcallout, hz, bstp_tick, sc);
-
-	BRIDGE_UNLOCK(sc);
 }
 
 void

==== //depot/projects/smpng/sys/net/if.c#72 (text+ko) ====

@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)if.c	8.5 (Berkeley) 1/9/95
- * $FreeBSD: src/sys/net/if.c,v 1.243 2005/08/16 17:02:35 brooks Exp $
+ * $FreeBSD: src/sys/net/if.c,v 1.244 2005/08/18 18:36:39 brooks Exp $
  */
 
 #include "opt_compat.h"
@@ -104,7 +104,6 @@
 static void	if_grow(void);
 static void	if_init(void *);
 static void	if_check(void *);
-static int	if_findindex(struct ifnet *);
 static void	if_qflush(struct ifaltq *);
 static void	if_route(struct ifnet *, int flag, int fam);
 static int	if_setflag(struct ifnet *, int, int, int *, int);
@@ -329,57 +328,6 @@
 	if_slowtimo(0);
 }
 
-/* XXX: should be locked. */
-static int
-if_findindex(struct ifnet *ifp)
-{
-	int i, unit;
-	char eaddr[18], devname[32];
-	const char *name, *p;
-
-	switch (ifp->if_type) {
-	case IFT_ETHER:			/* these types use struct arpcom */
-	case IFT_FDDI:
-	case IFT_XETHER:
-	case IFT_ISO88025:
-	case IFT_L2VLAN:
-	case IFT_BRIDGE:
-		snprintf(eaddr, 18, "%6D", IFP2ENADDR(ifp), ":");
-		break;
-	default:
-		eaddr[0] = '\0';
-		break;
-	}
-	strlcpy(devname, ifp->if_xname, sizeof(devname));
-	name = net_cdevsw.d_name;
-	i = 0;
-	while ((resource_find_dev(&i, name, &unit, NULL, NULL)) == 0) {
-		if (resource_string_value(name, unit, "ether", &p) == 0)
-			if (strcmp(p, eaddr) == 0)
-				goto found;
-		if (resource_string_value(name, unit, "dev", &p) == 0)
-			if (strcmp(p, devname) == 0)
-				goto found;
-	}
-	unit = 0;
-found:
-	if (unit != 0) {
-		if (ifaddr_byindex(unit) == NULL)
-			return (unit);
-		printf("%s%d in use, cannot hardwire it to %s.\n",
-		    name, unit, devname);
-	}
-	for (unit = 1; ; unit++) {
-		if (unit <= if_index && ifaddr_byindex(unit) != NULL)
-			continue;
-		if (resource_string_value(name, unit, "ether", &p) == 0 ||
-		    resource_string_value(name, unit, "dev", &p) == 0)
-			continue;
-		break;
-	}
-	return (unit);
-}
-
 /*
  * Allocate a struct ifnet and in index for an interface.
  */
@@ -390,13 +338,25 @@
 
 	ifp = malloc(sizeof(struct ifnet), M_IFNET, M_WAITOK|M_ZERO);
 
-	/* XXX: This should fail if if_index is too big */
-	ifp->if_index = if_findindex(ifp);
+	/*
+	 * Try to find an empty slot below if_index.  If we fail, take
+	 * the next slot.
+	 *
+	 * XXX: should be locked!
+	 */
+	for (ifp->if_index = 1; ifp->if_index <= if_index; ifp->if_index++) {
+		if (ifnet_byindex(ifp->if_index) == NULL)
+			break;
+	}
+	/* Catch if_index overflow. */
+	if (ifp->if_index < 1) {
+		free(ifp, M_IFNET);
+		return (NULL);
+	}
 	if (ifp->if_index > if_index)
 		if_index = ifp->if_index;
 	if (if_index >= if_indexlim)
 		if_grow();
-
 	ifnet_byindex(ifp->if_index) = ifp;
 
 	ifp->if_type = type;
@@ -436,7 +396,7 @@
 	ifnet_byindex(ifp->if_index) = NULL;
 
 	/* XXX: should be locked with if_findindex() */
-	while (if_index > 0 && ifaddr_byindex(if_index) == NULL)
+	while (if_index > 0 && ifnet_byindex(if_index) == NULL)
 		if_index--;
 
 	if (if_com_free[type] != NULL)

==== //depot/projects/smpng/sys/net/if_bridge.c#7 (text+ko) ====

@@ -80,7 +80,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/net/if_bridge.c,v 1.17 2005/08/15 02:50:13 thompsa Exp $");
+__FBSDID("$FreeBSD: src/sys/net/if_bridge.c,v 1.18 2005/08/18 20:17:00 thompsa Exp $");
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
@@ -439,8 +439,8 @@
 	/* Initialize our routing table. */
 	bridge_rtable_init(sc);
 
-	callout_init(&sc->sc_brcallout, 0);
-	callout_init(&sc->sc_bstpcallout, 0);
+	callout_init_mtx(&sc->sc_brcallout, &sc->sc_mtx, 0);
+	callout_init_mtx(&sc->sc_bstpcallout, &sc->sc_mtx, 0);
 
 	LIST_INIT(&sc->sc_iflist);
 
@@ -498,6 +498,9 @@
 
 	BRIDGE_UNLOCK(sc);
 
+	callout_drain(&sc->sc_brcallout);
+	callout_drain(&sc->sc_bstpcallout);
+
 	mtx_lock(&bridge_list_mtx);
 	LIST_REMOVE(sc, sc_list);
 	mtx_unlock(&bridge_list_mtx);
@@ -1212,10 +1215,10 @@
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 		return;
 
+	BRIDGE_LOCK(sc);
 	callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz,
 	    bridge_timer, sc);
 
-	BRIDGE_LOCK(sc);
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	bstp_initialization(sc);
 	BRIDGE_UNLOCK(sc);
@@ -1988,9 +1991,9 @@
 {
 	struct bridge_softc *sc = arg;
 
-	BRIDGE_LOCK(sc);
+	BRIDGE_LOCK_ASSERT(sc);
+
 	bridge_rtage(sc);
-	BRIDGE_UNLOCK(sc);
 
 	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
 		callout_reset(&sc->sc_brcallout,

==== //depot/projects/smpng/sys/pci/if_dc.c#68 (text+ko) ====

@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/pci/if_dc.c,v 1.163 2005/08/10 20:33:46 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/pci/if_dc.c,v 1.164 2005/08/18 19:10:07 jhb Exp $");
 
 /*
  * DEC "tulip" clone ethernet driver. Supports the DEC/Intel 21143
@@ -235,8 +235,10 @@
 static void dc_tx_underrun(struct dc_softc *);
 static void dc_intr(void *);
 static void dc_start(struct ifnet *);
+static void dc_start_locked(struct ifnet *);
 static int dc_ioctl(struct ifnet *, u_long, caddr_t);
 static void dc_init(void *);
+static void dc_init_locked(struct dc_softc *);
 static void dc_stop(struct dc_softc *);
 static void dc_watchdog(struct ifnet *);
 static void dc_shutdown(device_t);
@@ -343,8 +345,6 @@
 #define SIO_SET(x)	DC_SETBIT(sc, DC_SIO, (x))
 #define SIO_CLR(x)	DC_CLRBIT(sc, DC_SIO, (x))
 
-#define IS_MPSAFE 	0
-
 static void
 dc_delay(struct dc_softc *sc)
 {
@@ -670,8 +670,6 @@
 {
 	int i, ack;
 
-	DC_LOCK(sc);
-
 	/*
 	 * Set up frame for RX.
 	 */
@@ -724,8 +722,6 @@
 	dc_mii_writebit(sc, 0);
 	dc_mii_writebit(sc, 0);
 
-	DC_UNLOCK(sc);
-
 	if (ack)
 		return (1);
 	return (0);
@@ -738,7 +734,6 @@
 dc_mii_writereg(struct dc_softc *sc, struct dc_mii_frame *frame)
 {
 
-	DC_LOCK(sc);
 	/*
 	 * Set up frame for TX.
 	 */
@@ -763,8 +758,6 @@
 	dc_mii_writebit(sc, 0);
 	dc_mii_writebit(sc, 0);
 
-	DC_UNLOCK(sc);
-
 	return (0);
 }
 
@@ -1844,7 +1837,7 @@
 	sc = device_get_softc(dev);
 
 	mtx_init(&sc->dc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
-	    MTX_DEF | MTX_RECURSE);
+	    MTX_DEF);
 
 	/*
 	 * Map control/status registers.
@@ -2194,8 +2187,6 @@
 	/* XXX: bleah, MTU gets overwritten in ether_ifattach() */
 	ifp->if_mtu = ETHERMTU;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
-	if (!IS_MPSAFE)
-		ifp->if_flags |= IFF_NEEDSGIANT;
 	ifp->if_ioctl = dc_ioctl;
 	ifp->if_start = dc_start;
 	ifp->if_watchdog = dc_watchdog;
@@ -2276,7 +2267,7 @@
 #endif
 	ifp->if_capenable = ifp->if_capabilities;
 
-	callout_init(&sc->dc_stat_ch, IS_MPSAFE ? CALLOUT_MPSAFE : 0);
+	callout_init_mtx(&sc->dc_stat_ch, &sc->dc_mtx, 0);
 
 #ifdef SRM_MEDIA
 	sc->dc_srm_media = 0;
@@ -2310,8 +2301,7 @@
 	ether_ifattach(ifp, eaddr);
 
 	/* Hook interrupt last to avoid having to lock softc */
-	error = bus_setup_intr(dev, sc->dc_irq, INTR_TYPE_NET |
-	    (IS_MPSAFE ? INTR_MPSAFE : 0),
+	error = bus_setup_intr(dev, sc->dc_irq, INTR_TYPE_NET | INTR_MPSAFE,
 	    dc_intr, sc, &sc->dc_intrhand);
 
 	if (error) {
@@ -2344,13 +2334,15 @@
 
 	sc = device_get_softc(dev);
 	KASSERT(mtx_initialized(&sc->dc_mtx), ("dc mutex not initialized"));
-	DC_LOCK(sc);
 
 	ifp = sc->dc_ifp;
 
 	/* These should only be active if attach succeeded */
 	if (device_is_attached(dev)) {
+		DC_LOCK(sc);
 		dc_stop(sc);
+		DC_UNLOCK(sc);
+		callout_drain(&sc->dc_stat_ch);
 		ether_ifdetach(ifp);
 		if_free(ifp);
 	}
@@ -2390,7 +2382,6 @@
 	}
 	free(sc->dc_srom, M_DEVBUF);
 
-	DC_UNLOCK(sc);
 	mtx_destroy(&sc->dc_mtx);
 
 	return (0);
@@ -2751,7 +2742,7 @@
 					DC_INC(i, DC_RX_LIST_CNT);
 					continue;
 				} else {
-					dc_init(sc);
+					dc_init_locked(sc);
 					return;
 				}
 			}
@@ -2879,7 +2870,7 @@
 			if (txstat & DC_TXSTAT_LATECOLL)
 				ifp->if_collisions++;
 			if (!(txstat & DC_TXSTAT_UNDERRUN)) {
-				dc_init(sc);
+				dc_init_locked(sc);
 				return;
 			}
 		}
@@ -2918,7 +2909,7 @@
 	u_int32_t r;
 
 	sc = xsc;
-	DC_LOCK(sc);
+	DC_LOCK_ASSERT(sc);
 	ifp = sc->dc_ifp;
 	mii = device_get_softc(sc->dc_miibus);
 
@@ -2972,15 +2963,13 @@
 	    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
 		sc->dc_link++;
 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-			dc_start(ifp);
+			dc_start_locked(ifp);
 	}
 
 	if (sc->dc_flags & DC_21143_NWAY && !sc->dc_link)
 		callout_reset(&sc->dc_stat_ch, hz/10, dc_tick, sc);
 	else
 		callout_reset(&sc->dc_stat_ch, hz, dc_tick, sc);
-
-	DC_UNLOCK(sc);
 }
 
 /*
@@ -2994,7 +2983,7 @@
 	int i;
 
 	if (DC_IS_DAVICOM(sc))
-		dc_init(sc);
+		dc_init_locked(sc);
 
 	if (DC_IS_INTEL(sc)) {
 		/*
@@ -3013,7 +3002,7 @@
 		if (i == DC_TIMEOUT) {
 			if_printf(sc->dc_ifp,
 			    "failed to force tx to idle state\n");
-			dc_init(sc);
+			dc_init_locked(sc);
 		}
 	}
 
@@ -3055,7 +3044,7 @@
 	dc_txeof(sc);
 	if (!IFQ_IS_EMPTY(&ifp->if_snd) &&
 	    !(ifp->if_drv_flags & IFF_DRV_OACTIVE))
-		dc_start(ifp);
+		dc_start_locked(ifp);
 
 	if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */
 		u_int32_t	status;
@@ -3088,7 +3077,7 @@
 		if (status & DC_ISR_BUS_ERR) {
 			if_printf(ifp, "dc_poll: bus error\n");
 			dc_reset(sc);
-			dc_init(sc);
+			dc_init_locked(sc);
 		}
 	}
 	DC_UNLOCK(sc);
@@ -3175,7 +3164,7 @@
 
 		if (status & DC_ISR_BUS_ERR) {
 			dc_reset(sc);
-			dc_init(sc);
+			dc_init_locked(sc);
 		}
 	}
 
@@ -3183,7 +3172,7 @@
 	CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
 
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		dc_start(ifp);
+		dc_start_locked(ifp);
 
 #ifdef DEVICE_POLLING
 done:
@@ -3312,23 +3301,30 @@
 dc_start(struct ifnet *ifp)
 {
 	struct dc_softc *sc;
+
+	sc = ifp->if_softc;
+	DC_LOCK(sc);
+	dc_start_locked(ifp);
+	DC_UNLOCK(sc);
+}
+
+static void
+dc_start_locked(struct ifnet *ifp)
+{
+	struct dc_softc *sc;
 	struct mbuf *m_head = NULL, *m;
 	unsigned int queued = 0;
 	int idx;
 
 	sc = ifp->if_softc;
 
-	DC_LOCK(sc);
+	DC_LOCK_ASSERT(sc);
 
-	if (!sc->dc_link && ifp->if_snd.ifq_len < 10) {
-		DC_UNLOCK(sc);
+	if (!sc->dc_link && ifp->if_snd.ifq_len < 10)
 		return;
-	}
 
-	if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
-		DC_UNLOCK(sc);
+	if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
 		return;
-	}
 
 	idx = sc->dc_cdata.dc_tx_first = sc->dc_cdata.dc_tx_prod;
 
@@ -3380,18 +3376,37 @@
 		 */
 		ifp->if_timer = 5;
 	}
-
-	DC_UNLOCK(sc);
 }
 
 static void
 dc_init(void *xsc)
 {
 	struct dc_softc *sc = xsc;
+
+	DC_LOCK(sc);
+	dc_init_locked(sc);
+#ifdef SRM_MEDIA
+	if(sc->dc_srm_media) {
+		struct ifreq ifr;
+		struct mii_data *mii;
+
+		ifr.ifr_media = sc->dc_srm_media;
+		sc->dc_srm_media = 0;
+		DC_UNLOCK(sc);
+		mii = device_get_softc(sc->dc_miibus);
+		ifmedia_ioctl(sc->dc_ifp, &ifr, &mii->mii_media, SIOCSIFMEDIA);
+	} else
+#endif
+		DC_UNLOCK(sc);
+}
+
+static void
+dc_init_locked(struct dc_softc *sc)
+{
 	struct ifnet *ifp = sc->dc_ifp;
 	struct mii_data *mii;
 
-	DC_LOCK(sc);
+	DC_LOCK_ASSERT(sc);
 
 	mii = device_get_softc(sc->dc_miibus);
 
@@ -3487,7 +3502,6 @@
 		if_printf(ifp,
 		    "initialization failed: no memory for rx buffers\n");
 		dc_stop(sc);
-		DC_UNLOCK(sc);
 		return;
 	}
 
@@ -3559,17 +3573,6 @@
 		else
 			callout_reset(&sc->dc_stat_ch, hz, dc_tick, sc);
 	}
-
-#ifdef SRM_MEDIA
-	if(sc->dc_srm_media) {
-		struct ifreq ifr;
-
-		ifr.ifr_media = sc->dc_srm_media;
-		ifmedia_ioctl(ifp, &ifr, &mii->mii_media, SIOCSIFMEDIA);
-		sc->dc_srm_media = 0;
-	}
-#endif
-	DC_UNLOCK(sc);
 }
 
 /*
@@ -3584,6 +3587,7 @@
 
 	sc = ifp->if_softc;
 	mii = device_get_softc(sc->dc_miibus);
+	DC_LOCK(sc);
 	mii_mediachg(mii);
 	ifm = &mii->mii_media;
 
@@ -3592,6 +3596,7 @@
 		dc_setcfg(sc, ifm->ifm_media);
 	else
 		sc->dc_link = 0;
+	DC_UNLOCK(sc);
 
 	return (0);
 }
@@ -3608,6 +3613,7 @@
 
 	sc = ifp->if_softc;
 	mii = device_get_softc(sc->dc_miibus);
+	DC_LOCK(sc);
 	mii_pollstat(mii);
 	ifm = &mii->mii_media;
 	if (DC_IS_DAVICOM(sc)) {
@@ -3619,6 +3625,7 @@
 	}
 	ifmr->ifm_active = mii->mii_media_active;
 	ifmr->ifm_status = mii->mii_media_status;
+	DC_UNLOCK(sc);
 }
 
 static int
@@ -3629,10 +3636,9 @@
 	struct mii_data *mii;
 	int error = 0;
 
-	DC_LOCK(sc);
-
 	switch (command) {
 	case SIOCSIFFLAGS:
+		DC_LOCK(sc);
 		if (ifp->if_flags & IFF_UP) {
 			int need_setfilt = (ifp->if_flags ^ sc->dc_if_flags) &
 				(IFF_PROMISC | IFF_ALLMULTI);
@@ -3642,18 +3648,21 @@
 					dc_setfilt(sc);
 			} else {
 				sc->dc_txthresh = 0;
-				dc_init(sc);
+				dc_init_locked(sc);
 			}
 		} else {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 				dc_stop(sc);
 		}
 		sc->dc_if_flags = ifp->if_flags;
+		DC_UNLOCK(sc);
 		error = 0;
 		break;
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
+		DC_LOCK(sc);
 		dc_setfilt(sc);
+		DC_UNLOCK(sc);
 		error = 0;
 		break;
 	case SIOCGIFMEDIA:
@@ -3661,21 +3670,23 @@
 		mii = device_get_softc(sc->dc_miibus);
 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 #ifdef SRM_MEDIA
+		DC_LOCK(sc);
 		if (sc->dc_srm_media)
 			sc->dc_srm_media = 0;
+		DC_UNLOCK(sc);
 #endif
 		break;
 	case SIOCSIFCAP:
+		DC_LOCK(sc);
 		ifp->if_capenable &= ~IFCAP_POLLING;
 		ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING;
+		DC_UNLOCK(sc);
 		break;
 	default:
 		error = ether_ioctl(ifp, command, data);
 		break;
 	}
 
-	DC_UNLOCK(sc);
-
 	return (error);
 }
 
@@ -3693,10 +3704,10 @@
 
 	dc_stop(sc);
 	dc_reset(sc);
-	dc_init(sc);
+	dc_init_locked(sc);
 
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		dc_start(ifp);
+		dc_start_locked(ifp);
 
 	DC_UNLOCK(sc);
 }
@@ -3714,7 +3725,7 @@
 	int i;
 	u_int32_t ctl;
 
-	DC_LOCK(sc);
+	DC_LOCK_ASSERT(sc);
 
 	ifp = sc->dc_ifp;
 	ifp->if_timer = 0;
@@ -3762,8 +3773,6 @@
 		}
 	}
 	bzero(&ld->dc_tx_list, sizeof(ld->dc_tx_list));
-
-	DC_UNLOCK(sc);
 }
 
 /*
@@ -3775,15 +3784,13 @@
 dc_suspend(device_t dev)
 {
 	struct dc_softc *sc;
-	int s;
-
-	s = splimp();
 
 	sc = device_get_softc(dev);
+	DC_LOCK(sc);
 	dc_stop(sc);
 	sc->suspended = 1;
+	DC_UNLOCK(sc);
 
-	splx(s);
 	return (0);
 }
 
@@ -3797,20 +3804,18 @@
 {
 	struct dc_softc *sc;
 	struct ifnet *ifp;
-	int s;
 
-	s = splimp();
-
 	sc = device_get_softc(dev);
 	ifp = sc->dc_ifp;
 
 	/* reinitialize interface if necessary */
+	DC_LOCK(sc);
 	if (ifp->if_flags & IFF_UP)
-		dc_init(sc);
+		dc_init_locked(sc);
 
 	sc->suspended = 0;
+	DC_UNLOCK(sc);
 
-	splx(s);
 	return (0);
 }
 
@@ -3825,5 +3830,7 @@
 
 	sc = device_get_softc(dev);
 
+	DC_LOCK(sc);
 	dc_stop(sc);
+	DC_UNLOCK(sc);
 }

==== //depot/projects/smpng/sys/pci/if_sf.c#37 (text+ko) ====

@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/pci/if_sf.c,v 1.85 2005/08/10 20:24:39 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/pci/if_sf.c,v 1.86 2005/08/18 17:09:16 jhb Exp $");
 
 /*
  * Adaptec AIC-6915 "Starfire" PCI fast ethernet driver for FreeBSD.
@@ -137,12 +137,15 @@
 static int sf_encap(struct sf_softc *, struct sf_tx_bufdesc_type0 *,
 		struct mbuf *);
 static void sf_start(struct ifnet *);
+static void sf_start_locked(struct ifnet *);
 static int sf_ioctl(struct ifnet *, u_long, caddr_t);
 static void sf_init(void *);
+static void sf_init_locked(struct sf_softc *);
 static void sf_stop(struct sf_softc *);
 static void sf_watchdog(struct ifnet *);
 static void sf_shutdown(device_t);
 static int sf_ifmedia_upd(struct ifnet *);
+static void sf_ifmedia_upd_locked(struct ifnet *);
 static void sf_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 static void sf_reset(struct sf_softc *);
 static int sf_init_rx_ring(struct sf_softc *);
@@ -462,10 +465,25 @@
 	struct ifnet		*ifp;
 {
 	struct sf_softc		*sc;
+
+	sc = ifp->if_softc;
+	SF_LOCK(sc);
+	sf_ifmedia_upd_locked(ifp);
+	SF_UNLOCK(sc);
+
+	return(0);
+}
+
+static void
+sf_ifmedia_upd_locked(ifp)
+	struct ifnet		*ifp;
+{
+	struct sf_softc		*sc;
 	struct mii_data		*mii;
 
 	sc = ifp->if_softc;
 	mii = device_get_softc(sc->sf_miibus);
+	SF_LOCK_ASSERT(sc);
 	sc->sf_link = 0;
 	if (mii->mii_instance) {
 		struct mii_softc        *miisc;
@@ -473,8 +491,6 @@
 			mii_phy_reset(miisc);
 	}
 	mii_mediachg(mii);
-
-	return(0);
 }
 
 /*
@@ -489,11 +505,13 @@
 	struct mii_data		*mii;
 
 	sc = ifp->if_softc;
+	SF_LOCK(sc);
 	mii = device_get_softc(sc->sf_miibus);
 
 	mii_pollstat(mii);
 	ifmr->ifm_active = mii->mii_media_active;
 	ifmr->ifm_status = mii->mii_media_status;
+	SF_UNLOCK(sc);
 }
 
 static int
@@ -507,10 +525,9 @@
 	struct mii_data		*mii;
 	int			error = 0;
 
-	SF_LOCK(sc);
-
 	switch(command) {
 	case SIOCSIFFLAGS:
+		SF_LOCK(sc);
 		if (ifp->if_flags & IFF_UP) {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
 			    ifp->if_flags & IFF_PROMISC &&
@@ -521,17 +538,20 @@
 			    sc->sf_if_flags & IFF_PROMISC) {
 				SF_CLRBIT(sc, SF_RXFILT, SF_RXFILT_PROMISC);
 			} else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
-				sf_init(sc);
+				sf_init_locked(sc);
 		} else {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 				sf_stop(sc);
 		}
 		sc->sf_if_flags = ifp->if_flags;
+		SF_UNLOCK(sc);
 		error = 0;
 		break;
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
+		SF_LOCK(sc);
 		sf_setmulti(sc);
+		SF_UNLOCK(sc);
 		error = 0;
 		break;
 	case SIOCGIFMEDIA:
@@ -540,16 +560,16 @@
 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 		break;
 	case SIOCSIFCAP:
+		SF_LOCK(sc);
 		ifp->if_capenable &= ~IFCAP_POLLING;
 		ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING;
+		SF_UNLOCK(sc);
 		break;
 	default:
 		error = ether_ioctl(ifp, command, data);
 		break;
 	}
 
-	SF_UNLOCK(sc);
-
 	return(error);
 }
 
@@ -649,7 +669,7 @@
 	sc = device_get_softc(dev);
 
 	mtx_init(&sc->sf_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
-	    MTX_DEF | MTX_RECURSE);
+	    MTX_DEF);
 	/*
 	 * Map control/status registers.
 	 */
@@ -678,7 +698,8 @@
 		goto fail;
 	}
 
-	callout_handle_init(&sc->sf_stat_ch);
+	callout_init_mtx(&sc->sf_stat_callout, &sc->sf_mtx, 0);
+
 	/* Reset the adapter. */
 	sf_reset(sc);
 
@@ -719,8 +740,7 @@
 	ifp->if_softc = sc;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
-	    IFF_NEEDSGIANT;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl = sf_ioctl;
 	ifp->if_start = sf_start;
 	ifp->if_watchdog = sf_watchdog;
@@ -740,7 +760,7 @@
 	ether_ifattach(ifp, eaddr);
 
 	/* Hook interrupt last to avoid having to lock softc */
-	error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET,
+	error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET | INTR_MPSAFE,
 	    sf_intr, sc, &sc->sf_intrhand);
 
 	if (error) {
@@ -773,12 +793,14 @@
 
 	sc = device_get_softc(dev);
 	KASSERT(mtx_initialized(&sc->sf_mtx), ("sf mutex not initialized"));
-	SF_LOCK(sc);
 	ifp = sc->sf_ifp;
 
 	/* These should only be active if attach succeeded */
 	if (device_is_attached(dev)) {
+		SF_LOCK(sc);
 		sf_stop(sc);
+		SF_UNLOCK(sc);
+		callout_drain(&sc->sf_stat_callout);
 		ether_ifdetach(ifp);
 		if_free(ifp);
 	}
@@ -796,7 +818,6 @@
 	if (sc->sf_ldata)
 		contigfree(sc->sf_ldata, sizeof(struct sf_list_data), M_DEVBUF);
 
-	SF_UNLOCK(sc);
 	mtx_destroy(&sc->sf_mtx);
 
 	return(0);
@@ -984,6 +1005,7 @@
 
 	ifp = sc->sf_ifp;
 
+	SF_LOCK_ASSERT(sc);
 	txcons = csr_read_4(sc, SF_CQ_CONSIDX);
 	cmpprodidx = SF_IDX_HI(csr_read_4(sc, SF_CQ_PRODIDX));
 	cmpconsidx = SF_IDX_HI(txcons);
@@ -1072,7 +1094,7 @@
 	sf_rxeof(sc);
 	sf_txeof(sc);
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		sf_start(ifp);
+		sf_start_locked(ifp);
 
 	if (cmd == POLL_AND_CHECK_STATUS) {
 		u_int32_t status;
@@ -1086,11 +1108,10 @@
 
 		if (status & SF_ISR_ABNORMALINTR) {
 			if (status & SF_ISR_STATSOFLOW) {
-				untimeout(sf_stats_update, sc,
-				    sc->sf_stat_ch);
+				callout_stop(&sc->sf_stat_callout);
 				sf_stats_update(sc);
 			} else
-				sf_init(sc);
+				sf_init_locked(sc);
 		}
 	}
 }
@@ -1151,11 +1172,10 @@
 
 		if (status & SF_ISR_ABNORMALINTR) {
 			if (status & SF_ISR_STATSOFLOW) {
-				untimeout(sf_stats_update, sc,
-				    sc->sf_stat_ch);
+				callout_stop(&sc->sf_stat_callout);
 				sf_stats_update(sc);
 			} else
-				sf_init(sc);
+				sf_init_locked(sc);
 		}
 	}
 
@@ -1163,7 +1183,7 @@
 	csr_write_4(sc, SF_IMR, SF_INTRS);
 
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		sf_start(ifp);
+		sf_start_locked(ifp);
 
 #ifdef DEVICE_POLLING
 done_locked:
@@ -1176,12 +1196,22 @@
 	void			*xsc;
 {
 	struct sf_softc		*sc;
+
+	sc = xsc;
+	SF_LOCK(sc);
+	sf_init_locked(sc);
+	SF_UNLOCK(sc);
+}
+
+static void
+sf_init_locked(sc)
+	struct sf_softc		*sc;
+{
 	struct ifnet		*ifp;

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list