PERFORCE change 142779 for review

Julian Elischer julian at FreeBSD.org
Tue Jun 3 00:57:55 UTC 2008


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

Change 142779 by julian at julian_trafmon1 on 2008/06/03 00:57:28

	IFC at 142777

Affected files ...

.. //depot/projects/vimage/src/sys/compat/linux/linux_stats.c#8 integrate
.. //depot/projects/vimage/src/sys/compat/linux/linux_util.c#4 integrate
.. //depot/projects/vimage/src/sys/dev/fe/if_fe.c#3 integrate
.. //depot/projects/vimage/src/sys/dev/fe/if_fe_pccard.c#2 integrate
.. //depot/projects/vimage/src/sys/dev/fe/if_fevar.h#2 integrate
.. //depot/projects/vimage/src/sys/dev/ie/if_ie.c#3 integrate
.. //depot/projects/vimage/src/sys/dev/ie/if_ie_isa.c#3 integrate
.. //depot/projects/vimage/src/sys/dev/ie/if_ievar.h#3 integrate
.. //depot/projects/vimage/src/sys/dev/xe/if_xe.c#3 integrate
.. //depot/projects/vimage/src/sys/dev/xe/if_xe_pccard.c#2 integrate
.. //depot/projects/vimage/src/sys/dev/xe/if_xevar.h#2 integrate
.. //depot/projects/vimage/src/sys/netinet/ip_carp.c#7 integrate
.. //depot/projects/vimage/src/sys/netinet/tcp_subr.c#41 integrate
.. //depot/projects/vimage/src/sys/netinet/tcp_timer.c#16 integrate
.. //depot/projects/vimage/src/sys/nlm/nlm_prot_impl.c#3 integrate

Differences ...

==== //depot/projects/vimage/src/sys/compat/linux/linux_stats.c#8 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/compat/linux/linux_stats.c,v 1.91 2008/04/08 09:45:47 kib Exp $");
+__FBSDID("$FreeBSD: src/sys/compat/linux/linux_stats.c,v 1.92 2008/06/02 08:40:06 ed Exp $");
 
 #include "opt_compat.h"
 #include "opt_mac.h"
@@ -178,19 +178,8 @@
 #endif
 
 	error = kern_stat(td, path, UIO_SYSSPACE, &buf);
-	if (!error) {
-		if (strlen(path) > strlen("/dev/pts/") &&
-		    !strncmp(path, "/dev/pts/", strlen("/dev/pts/")) &&
-		    path[9] >= '0' && path[9] <= '9') {
-			/*
-			 * Linux checks major and minors of the slave device
-			 * to make sure it's a pty device, so let's make him
-			 * believe it is.
-			 */
-			buf.st_rdev = (136 << 8);
-		} else
-			translate_path_major_minor(td, path, &buf);
-	}
+	if (!error)
+		translate_path_major_minor(td, path, &buf);
 	LFREEPATH(path);
 	if (error)
 		return (error);
@@ -528,19 +517,8 @@
 #endif
 
 	error = kern_stat(td, filename, UIO_SYSSPACE, &buf);
-	if (!error) {
-		if (strlen(filename) > strlen("/dev/pts/") &&
-		    !strncmp(filename, "/dev/pts/", strlen("/dev/pts/")) &&
-		    filename[9] >= '0' && filename[9] <= '9') {
-			/*
-			 * Linux checks major and minors of the slave device
-			 * to make sure it's a pty deivce, so let's make him
-			 * believe it is.
-			 */
-			buf.st_rdev = (136 << 8);
-		} else
-			translate_path_major_minor(td, filename, &buf);
-	}
+	if (!error)
+		translate_path_major_minor(td, filename, &buf);
 	LFREEPATH(filename);
 	if (error)
 		return (error);

==== //depot/projects/vimage/src/sys/compat/linux/linux_util.c#4 (text+ko) ====

@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/compat/linux/linux_util.c,v 1.34 2008/04/08 09:45:47 kib Exp $");
+__FBSDID("$FreeBSD: src/sys/compat/linux/linux_util.c,v 1.35 2008/06/02 08:40:06 ed Exp $");
 
 #include "opt_compat.h"
 
@@ -130,6 +130,22 @@
 
 	if (node == NULL || major == NULL || minor == NULL)
 		return 1;
+
+	if (strlen(node) > strlen("pts/") &&
+	    strncmp(node, "pts/", strlen("pts/")) == 0) {
+		unsigned long devno;
+
+		/*
+		 * Linux checks major and minors of the slave device
+		 * to make sure it's a pty device, so let's make him
+		 * believe it is.
+		 */
+		devno = strtoul(node + strlen("pts/"), NULL, 10);
+		*major = 136 + (devno / 256);
+		*minor = devno % 256;
+		return 0;
+	}
+
 	TAILQ_FOREACH(de, &devices, list) {
 		if (strcmp(node, de->entry.bsd_device_name) == 0) {
 			*major = de->entry.linux_major;

==== //depot/projects/vimage/src/sys/dev/fe/if_fe.c#3 (text+ko) ====

@@ -21,7 +21,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/fe/if_fe.c,v 1.98 2007/02/23 12:18:41 piso Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/fe/if_fe.c,v 1.99 2008/06/02 19:58:48 jhb Exp $");
 
 /*
  *
@@ -71,6 +71,7 @@
  */
 
 #include <sys/param.h>
+#include <sys/kernel.h>
 #include <sys/systm.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
@@ -135,10 +136,12 @@
 
 /* Standard driver entry points.  These can be static.  */
 static void		fe_init		(void *);
+static void		fe_init_locked	(struct fe_softc *);
 static driver_intr_t	fe_intr;
 static int		fe_ioctl	(struct ifnet *, u_long, caddr_t);
 static void		fe_start	(struct ifnet *);
-static void		fe_watchdog	(struct ifnet *);
+static void		fe_start_locked	(struct ifnet *);
+static void		fe_watchdog	(void *);
 static int		fe_medchange	(struct ifnet *);
 static void		fe_medstat	(struct ifnet *, struct ifmediareq *);
 
@@ -737,16 +740,13 @@
 	ifp = sc->ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL) {
 		device_printf(dev, "can not ifalloc\n");
+		fe_release_resource(dev);
 		return (ENOSPC);
 	}
 
-	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
-			       NULL, fe_intr, sc, &sc->irq_handle);
-	if (error) {
-		if_free(ifp);
-		fe_release_resource(dev);
-		return ENXIO;
-	}
+	mtx_init(&sc->lock, device_get_nameunit(dev), MTX_NETWORK_LOCK,
+	    MTX_DEF);
+	callout_init_mtx(&sc->timer, &sc->lock, 0);
 
 	/*
 	 * Initialize ifnet structure
@@ -755,7 +755,6 @@
 	if_initname(sc->ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_start    = fe_start;
 	ifp->if_ioctl    = fe_ioctl;
-	ifp->if_watchdog = fe_watchdog;
 	ifp->if_init     = fe_init;
 	ifp->if_linkmib  = &sc->mibdata;
 	ifp->if_linkmiblen = sizeof (sc->mibdata);
@@ -767,8 +766,7 @@
 	/*
 	 * Set fixed interface flags.
 	 */
- 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
-	    IFF_NEEDSGIANT;
+ 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 
 #if 1
 	/*
@@ -830,9 +828,21 @@
 #endif
 
 	/* Attach and stop the interface. */
+	FE_LOCK(sc);
+	fe_stop(sc);
+	FE_UNLOCK(sc);
 	ether_ifattach(sc->ifp, sc->enaddr);
-	fe_stop(sc);
-  
+
+	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
+			       NULL, fe_intr, sc, &sc->irq_handle);
+	if (error) {
+		ether_ifdetach(ifp);
+		mtx_destroy(&sc->lock);
+		if_free(ifp);
+		fe_release_resource(dev);
+		return ENXIO;
+	}
+
   	/* Print additional info when attached.  */
  	device_printf(dev, "type %s%s\n", sc->typestr,
 		      (sc->proto_dlcr4 & FE_D4_DSC) ? ", full duplex" : "");
@@ -942,7 +952,7 @@
 	/* Put the interface into known initial state.  */
 	fe_stop(sc);
 	if (sc->ifp->if_flags & IFF_UP)
-		fe_init(sc);
+		fe_init_locked(sc);
 }
 
 /*
@@ -954,9 +964,8 @@
 void
 fe_stop (struct fe_softc *sc)
 {
-	int s;
 
-	s = splimp();
+	FE_ASSERT_LOCKED(sc);
 
 	/* Disable interrupts.  */
 	fe_outb(sc, FE_DLCR2, 0x00);
@@ -978,7 +987,7 @@
 
 	/* Reset transmitter variables and interface flags.  */
 	sc->ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING);
-	sc->ifp->if_timer = 0;
+	callout_stop(&sc->timer);
 	sc->txb_free = sc->txb_size;
 	sc->txb_count = 0;
 	sc->txb_sched = 0;
@@ -989,8 +998,6 @@
 	/* Call a device-specific hook.  */
 	if (sc->stop)
 		sc->stop(sc);
-
-	(void) splx(s);
 }
 
 /*
@@ -998,16 +1005,18 @@
  * generate an interrupt after a transmit has been started on it.
  */
 static void
-fe_watchdog ( struct ifnet *ifp )
+fe_watchdog (void *arg)
 {
-	struct fe_softc *sc = ifp->if_softc;
+	struct fe_softc *sc = arg;
+
+	FE_ASSERT_LOCKED(sc);
 
 	/* A "debug" message.  */
-	if_printf(ifp, "transmission timeout (%d+%d)%s\n",
+	if_printf(sc->ifp, "transmission timeout (%d+%d)%s\n",
 	       sc->txb_sched, sc->txb_count,
-	       (ifp->if_flags & IFF_UP) ? "" : " when down");
+	       (sc->ifp->if_flags & IFF_UP) ? "" : " when down");
 	if (sc->ifp->if_opackets == 0 && sc->ifp->if_ipackets == 0)
-		if_printf(ifp, "wrong IRQ setting in config?\n");
+		if_printf(sc->ifp, "wrong IRQ setting in config?\n");
 	fe_reset(sc);
 }
 
@@ -1018,10 +1027,17 @@
 fe_init (void * xsc)
 {
 	struct fe_softc *sc = xsc;
-	int s;
+
+	FE_LOCK(sc);
+	fe_init_locked(sc);
+	FE_UNLOCK(sc);
+}
+
+static void
+fe_init_locked (struct fe_softc *sc)
+{
 
 	/* Start initializing 86960.  */
-	s = splimp();
 
 	/* Call a hook before we start initializing the chip.  */
 	if (sc->init)
@@ -1128,10 +1144,8 @@
            the interface keeping it idle.  The upper layer will soon
            start the interface anyway, and there are no significant
            delay.  */
-	fe_start(sc->ifp);
+	fe_start_locked(sc->ifp);
 #endif
-
-	(void) splx(s);
 }
 
 /*
@@ -1145,7 +1159,7 @@
 	 * We use longer timeout for multiple packet transmission.
 	 * I'm not sure this timer value is appropriate.  FIXME.
 	 */
-	sc->ifp->if_timer = 1 + sc->txb_count;
+	callout_reset(&sc->timer, (1 + sc->txb_count) * hz, fe_watchdog, sc);
 
 	/* Update txb variables.  */
 	sc->txb_sched = sc->txb_count;
@@ -1159,17 +1173,24 @@
 
 /*
  * Start output on interface.
- * We make two assumptions here:
- *  1) that the current priority is set to splimp _before_ this code
- *     is called *and* is returned to the appropriate priority after
- *     return
- *  2) that the IFF_DRV_OACTIVE flag is checked before this code is called
+ * We make one assumption here:
+ *  1) that the IFF_DRV_OACTIVE flag is checked before this code is called
  *     (i.e. that the output part of the interface is idle)
  */
 static void
 fe_start (struct ifnet *ifp)
 {
 	struct fe_softc *sc = ifp->if_softc;
+
+	FE_LOCK(sc);
+	fe_start_locked(ifp);
+	FE_UNLOCK(sc);
+}
+
+static void
+fe_start_locked (struct ifnet *ifp)
+{
+	struct fe_softc *sc = ifp->if_softc;
 	struct mbuf *m;
 
 #ifdef DIAGNOSTIC
@@ -1534,7 +1555,7 @@
 		 * Reset output active flag and watchdog timer.
 		 */
 		sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-		sc->ifp->if_timer = 0;
+		callout_stop(&sc->timer);
 
 		/*
 		 * If more data is ready to transmit in the buffer, start
@@ -1685,6 +1706,8 @@
 	u_char tstat, rstat;
 	int loop_count = FE_MAX_LOOP;
 
+	FE_LOCK(sc);
+
 	/* Loop until there are no more new interrupt conditions.  */
 	while (loop_count-- > 0) {
 		/*
@@ -1692,8 +1715,10 @@
 		 */
 		tstat = fe_inb(sc, FE_DLCR0) & FE_TMASK;
 		rstat = fe_inb(sc, FE_DLCR1) & FE_RMASK;
-		if (tstat == 0 && rstat == 0)
+		if (tstat == 0 && rstat == 0) {
+			FE_UNLOCK(sc);
 			return;
+		}
 
 		/*
 		 * Reset the conditions we are acknowledging.
@@ -1741,8 +1766,9 @@
 		 * interrupt when the transmission buffer is full.
 		 */
 		if ((sc->ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0)
-			fe_start(sc->ifp);
+			fe_start_locked(sc->ifp);
 	}
+	FE_UNLOCK(sc);
 
 	if_printf(sc->ifp, "too many loops\n");
 }
@@ -1756,9 +1782,7 @@
 {
 	struct fe_softc *sc = ifp->if_softc;
 	struct ifreq *ifr = (struct ifreq *)data;
-	int s, error = 0;
-
-	s = splimp();
+	int error = 0;
 
 	switch (command) {
 
@@ -1767,9 +1791,10 @@
 		 * Switch interface state between "running" and
 		 * "stopped", reflecting the UP flag.
 		 */
+		FE_LOCK(sc);
 		if (sc->ifp->if_flags & IFF_UP) {
 			if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
-				fe_init(sc);
+				fe_init_locked(sc);
 		} else {
 			if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
 				fe_stop(sc);
@@ -1780,6 +1805,7 @@
 		 * so reprogram the multicast filter and/or receive mode.
 		 */
 		fe_setmode(sc);
+		FE_UNLOCK(sc);
 
 		/* Done.  */
 		break;
@@ -1790,7 +1816,9 @@
 		 * Multicast list has changed; set the hardware filter
 		 * accordingly.
 		 */
+		FE_LOCK(sc);
 		fe_setmode(sc);
+		FE_UNLOCK(sc);
 		break;
 
 	  case SIOCSIFMEDIA:
@@ -1805,7 +1833,6 @@
 		break;
 	}
 
-	(void) splx(s);
 	return (error);
 }
 
@@ -1821,6 +1848,8 @@
 	struct ether_header *eh;
 	struct mbuf *m;
 
+	FE_ASSERT_LOCKED(sc);
+
 	/*
 	 * NFS wants the data be aligned to the word (4 byte)
 	 * boundary.  Ethernet header has 14 bytes.  There is a
@@ -1890,7 +1919,9 @@
 	}
 
 	/* Feed the packet to upper layer.  */
+	FE_UNLOCK(sc);
 	(*ifp->if_input)(ifp, m);
+	FE_LOCK(sc);
 	return 0;
 }
 
@@ -2164,7 +2195,7 @@
 /*
  * Load a new multicast address filter into MARs.
  *
- * The caller must have splimp'ed before fe_loadmar.
+ * The caller must have acquired the softc lock before fe_loadmar.
  * This function starts the DLC upon return.  So it can be called only
  * when the chip is working, i.e., from the driver's point of view, when
  * a device is RUNNING.  (I mistook the point in previous versions.)
@@ -2223,9 +2254,11 @@
 	   until the transmission buffer being empty?  Changing the
 	   media when we are sending a frame will cause two garbages
 	   on wires, one on old media and another on new.  FIXME */
+	FE_LOCK(sc);
 	if (sc->ifp->if_flags & IFF_UP) {
 		if (sc->msel) sc->msel(sc);
 	}
+	FE_UNLOCK(sc);
 
 	return 0;
 }

==== //depot/projects/vimage/src/sys/dev/fe/if_fe_pccard.c#2 (text+ko) ====

@@ -22,7 +22,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/fe/if_fe_pccard.c,v 1.32 2005/11/19 23:26:57 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/fe/if_fe_pccard.c,v 1.33 2008/06/02 19:58:48 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -175,11 +175,15 @@
 	struct fe_softc *sc = device_get_softc(dev);
 	struct ifnet *ifp = sc->ifp;
 
+	FE_LOCK(sc);
 	fe_stop(sc);
+	FE_UNLOCK(sc);
+	callout_drain(&sc->timer);
 	ether_ifdetach(ifp);
 	bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
 	if_free(ifp);
 	fe_release_resource(dev);
+	mtx_destroy(&sc->lock);
 
 	return 0;
 }

==== //depot/projects/vimage/src/sys/dev/fe/if_fevar.h#2 (text+ko) ====

@@ -19,7 +19,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/fe/if_fevar.h,v 1.6 2005/06/10 16:49:08 brooks Exp $
+ * $FreeBSD: src/sys/dev/fe/if_fevar.h,v 1.7 2008/06/02 19:58:48 jhb Exp $
  */
 
 /* How many registers does an fe-supported adapter have at maximum?  */
@@ -117,6 +117,8 @@
 	int defmedia;		/* default media  */
 	void (* msel)(struct fe_softc *); /* media selector.  */
 
+	struct mtx		lock;
+	struct callout		timer;
 };
 
 struct fe_simple_probe_struct {
@@ -125,6 +127,9 @@
 	u_char bits;	/* Values to be compared against.  */
 };
 
+#define	FE_LOCK(sc)		mtx_lock(&(sc)->lock)
+#define	FE_UNLOCK(sc)		mtx_unlock(&(sc)->lock)
+#define	FE_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->lock, MA_OWNED)
 
 extern	devclass_t fe_devclass;
 

==== //depot/projects/vimage/src/sys/dev/ie/if_ie.c#3 (text+ko) ====

@@ -51,7 +51,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ie/if_ie.c,v 1.108 2008/05/30 16:22:30 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ie/if_ie.c,v 1.109 2008/06/02 19:17:40 jhb Exp $");
 
 /*
  * Intel 82586 Ethernet chip
@@ -161,9 +161,11 @@
 struct ie_softc;
 
 static void	ieinit			(void *);
+static void	ieinit_locked		(struct ie_softc *);
 static void	ie_stop			(struct ie_softc *);
 static int	ieioctl			(struct ifnet *, u_long, caddr_t);
 static void	iestart			(struct ifnet *);
+static void	iestart_locked		(struct ifnet *);
 
 static __inline void
 		ee16_interrupt_enable	(struct ie_softc *);
@@ -179,7 +181,6 @@
 static void	ie_readframe		(struct ie_softc *, int);
 static void	ie_drop_packet_buffer	(struct ie_softc *);
 static void	find_ie_mem_size	(struct ie_softc *);
-static void	chan_attn_timeout	(void *);
 static int	command_and_wait	(struct ie_softc *,
 					 int, void volatile *, int);
 static void	run_tdr			(struct ie_softc *,
@@ -263,7 +264,7 @@
 	struct ie_softc *       sc;
 	struct ifnet *          ifp;
 	size_t                  allocsize;
-	int                     factor;
+	int                     error, factor;
 
 	sc = device_get_softc(dev);
 	ifp = sc->ifp = if_alloc(IFT_ETHER);
@@ -273,6 +274,8 @@
 	}
 
 	sc->dev = dev;
+	mtx_init(&sc->lock, device_get_nameunit(dev), MTX_NETWORK_LOCK,
+	    MTX_DEF);
 
 	/*
 	 * based on the amount of memory we have, allocate our tx and rx
@@ -294,7 +297,7 @@
 								     M_DEVBUF,
 								   M_NOWAIT);
 	if (sc->rframes == NULL) {
-		if_free(ifp);
+		mtx_destroy(&sc->lock);
 		return (ENXIO);
 	}
 	sc->rbuffs =
@@ -313,8 +316,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_start = iestart;
 	ifp->if_ioctl = ieioctl;
 	ifp->if_init = ieinit;
@@ -325,6 +327,15 @@
 				      sc, SHUTDOWN_PRI_DEFAULT);
 
 	ether_ifattach(ifp, sc->enaddr);
+
+	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
+				NULL, ie_intr, sc, &sc->irq_ih);
+	if (error) {
+		device_printf(dev, "Unable to register interrupt handler\n"); 
+		mtx_destroy(&sc->lock);
+		return (error);
+	}
+
 	return (0);
 }
 
@@ -345,6 +356,8 @@
 	struct ie_softc *sc = (struct ie_softc *)xsc;
 	u_short status;
 
+	IE_LOCK(sc);
+
 	/* Clear the interrupt latch on the 3C507. */
 	if (sc->hard_type == IE_3C507
 	 && (inb(PORT(sc) + IE507_CTRL) & EL_CTRL_INTL))
@@ -405,7 +418,7 @@
 	/* enable interrupts on the EE16. */
 	if (sc->hard_type == IE_EE16)
 		outb(PORT(sc) + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
-
+	IE_UNLOCK(sc);
 }
 
 /*
@@ -465,7 +478,6 @@
 	int	status;
 	int	i;
 
-	ifp->if_timer = 0;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
 	for (i = 0; i < sc->xmit_count; i++) {
@@ -507,7 +519,7 @@
 	/* Wish I knew why this seems to be necessary... */
 	sc->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;
 
-	iestart(ifp);
+	iestart_locked(ifp);
 	return (0);		/* shouldn't be necessary */
 }
 
@@ -877,7 +889,9 @@
 	/*
 	 * Finally pass this packet up to higher layers.
 	 */
+	IE_UNLOCK(sc);
 	(*ifp->if_input)(ifp, m);
+	IE_LOCK(sc);
 }
 
 static void
@@ -917,6 +931,16 @@
 iestart(struct ifnet *ifp)
 {
 	struct	 ie_softc *sc = ifp->if_softc;
+
+	IE_LOCK(sc);
+	iestart_locked(ifp);
+	IE_UNLOCK(sc);
+}
+
+static void
+iestart_locked(struct ifnet *ifp)
+{
+	struct	 ie_softc *sc = ifp->if_softc;
 	struct	 mbuf *m0, *m;
 	volatile unsigned char *buffer;
 	u_short	 len;
@@ -1000,9 +1024,6 @@
 	volatile struct ie_int_sys_conf_ptr *iscp;
 	volatile struct ie_sys_ctl_block *scb;
 	u_long	realbase;
-	int	s;
-
-	s = splimp();
 
 	realbase = (uintptr_t) sc->iomembot + sc->iosize  - (1 << 24);
 
@@ -1035,7 +1056,6 @@
 	DELAY(100);		/* wait a while... */
 
 	if (iscp->ie_busy) {
-		splx(s);
 		return (0);
 	}
 	/*
@@ -1059,7 +1079,6 @@
 	DELAY(100);
 
 	if (iscp->ie_busy) {
-		splx(s);
 		return (0);
 	}
 	sc->iomem = (caddr_t) (uintptr_t) realbase;
@@ -1071,7 +1090,6 @@
 	 * Acknowledge any interrupts we may have caused...
 	 */
 	ie_ack(sc, IE_ST_WHENCE);
-	splx(s);
 
 	return (1);
 }
@@ -1235,11 +1253,9 @@
 iereset(struct ie_softc *sc)
 {
 	struct ifnet *ifp = sc->ifp;
-	int	s = splimp();
 
 	if_printf(ifp, "reset\n");
-	ifp->if_flags &= ~IFF_UP;
-	ieioctl(ifp, SIOCSIFFLAGS, 0);
+	ie_stop(sc);
 
 	/*
 	 * Stop i82586 dead in its tracks.
@@ -1255,23 +1271,13 @@
 		panic("ie disappeared!");
 #endif
 
-	ifp->if_flags |= IFF_UP;
-	ieioctl(ifp, SIOCSIFFLAGS, 0);
+	if (ifp->if_flags & IFF_UP)
+		ieinit_locked(sc);
 
-	splx(s);
 	return;
 }
 
 /*
- * This is called if we time out.
- */
-static void
-chan_attn_timeout(void *rock)
-{
-	*(int *) rock = 1;
-}
-
-/*
  * Send a command to the controller and wait for it to either
  * complete or be accepted, depending on the command.  If the
  * command pointer is null, then pretend that the command is
@@ -1284,38 +1290,30 @@
 command_and_wait(struct ie_softc *sc, int cmd, volatile void *pcmd, int mask)
 {
 	volatile struct ie_cmd_common *cc = pcmd;
-	volatile int timedout = 0;
-	struct	 callout_handle ch;
+	int i;
 
 	sc->scb->ie_command = (u_short) cmd;
 
 	if (IE_ACTION_COMMAND(cmd) && pcmd) {
 		(*sc->ie_chan_attn) (sc);
-
+		
 		/*
-		 * According to the packet driver, the minimum timeout
-		 * should be .369 seconds, which we round up to .37.
-		 */
-		ch = timeout(chan_attn_timeout, (caddr_t)&timedout,
-			     37 * hz / 100);
-		/* ignore cast-qual */
-
-		/*
 		 * Now spin-lock waiting for status.  This is not a very
 		 * nice thing to do, but I haven't figured out how, or
 		 * indeed if, we can put the process waiting for action to
 		 * sleep.  (We may be getting called through some other
 		 * timeout running in the kernel.)
+		 *
+		 * According to the packet driver, the minimum timeout
+		 * should be .369 seconds, which we round up to .37.
 		 */
-		while (1) {
-			if ((cc->ie_cmd_status & mask) || timedout)
-				break;
+		for (i = 0; i < 370; i++) {
+			if (cc->ie_cmd_status & mask)
+				return (0);
+			DELAY(1000);
 		}
 
-		untimeout(chan_attn_timeout, (caddr_t)&timedout, ch);
-		/* ignore cast-qual */
-
-		return (timedout);
+		return (1);
 	} else {
 
 		/*
@@ -1371,14 +1369,11 @@
 static void
 start_receiver(struct ie_softc *sc)
 {
-	int	s = splimp();
 
 	sc->scb->ie_recv_list = MK_16(MEM(sc), sc->rframes[0]);
 	command_and_wait(sc, IE_RU_START, 0, 0);
 
 	ie_ack(sc, IE_ST_WHENCE);
-
-	splx(s);
 }
 
 /*
@@ -1455,7 +1450,6 @@
 
 /*
  * Run the multicast setup command.
- * Call at splimp().
  */
 static int
 mc_setup(struct ie_softc *sc)
@@ -1486,14 +1480,21 @@
  * and adds to it all the other structures we need to operate the adapter.
  * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
  * starting the receiver unit, and clearing interrupts.
- *
- * THIS ROUTINE MUST BE CALLED AT splimp() OR HIGHER.
  */
 static void
 ieinit(xsc)
 	void *xsc;
 {
 	struct ie_softc *sc = xsc;
+
+	IE_LOCK(sc);
+	ieinit_locked(sc);
+	IE_UNLOCK(sc);
+}
+
+static void
+ieinit_locked(struct ie_softc *sc)
+{
 	struct ifnet *ifp = sc->ifp;
 	volatile struct ie_sys_ctl_block *scb = sc->scb;
 	caddr_t ptr;
@@ -1614,17 +1615,18 @@
 static void
 ie_stop(struct ie_softc *sc)
 {
+	struct ifnet *ifp = sc->ifp;
+
+	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 	command_and_wait(sc, IE_RU_DISABLE, 0, 0);
 }
 
 static int
 ieioctl(struct ifnet *ifp, u_long command, caddr_t data)
 {
-	int	s, error = 0;
+	int	error = 0;
 	struct	 ie_softc *sc = ifp->if_softc;
 
-	s = splimp();
-
 	switch (command) {
 	case SIOCSIFFLAGS:
 		/*
@@ -1632,9 +1634,9 @@
 		 * mode, so we must turn on promiscuous mode and do the
 		 * filtering manually.
 		 */
+		IE_LOCK(sc);
 		if ((ifp->if_flags & IFF_UP) == 0 &&
 		    (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 			ie_stop(sc);
 		} else if ((ifp->if_flags & IFF_UP) &&
 			   (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
@@ -1647,6 +1649,7 @@
 			    ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
 			ieinit(sc);
 		}
+		IE_UNLOCK(sc);
 		break;
 
 	case SIOCADDMULTI:
@@ -1655,7 +1658,9 @@
 		 * Update multicast listeners
 		 */
 		/* reset multicast filtering */
+		IE_LOCK(sc);
 		ie_mc_reset(sc);
+		IE_UNLOCK(sc);
 		error = 0;
 		break;
 
@@ -1664,7 +1669,6 @@
 		break;
 	}
 
-	splx(s);
 	return (error);
 }
 
@@ -1685,7 +1689,8 @@
 		/* XXX - this is broken... */
 		if (sc->mcast_count >= MAXMCAST) {
 			sc->ifp->if_flags |= IFF_ALLMULTI;
-			ieioctl(sc->ifp, SIOCSIFFLAGS, (void *) 0);
+			if (sc->ifp->if_flags & IFF_UP)
+				ieinit_locked(sc);
 			goto setflag;
 		}
 		bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
@@ -1769,6 +1774,8 @@
 
 	if (sc->irq_ih)
 		bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
+	if (sc->rframes)
+		free(sc->rframes, M_DEVBUF);
 	if (sc->io_res)
 		bus_release_resource(dev, SYS_RES_IOPORT,
 				     sc->io_rid, sc->io_res);
@@ -1793,13 +1800,15 @@
 	sc = device_get_softc(dev);
 	ifp = sc->ifp;
 
+	IE_LOCK(sc);
 	if (sc->hard_type == IE_EE16)
 		ee16_shutdown(sc, 0);
 
 	ie_stop(sc);
-	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+	IE_UNLOCK(sc);
 	ether_ifdetach(ifp);
 	ie_release_resources(dev);
+	mtx_destroy(&sc->lock);
 
 	return (0);
 }

==== //depot/projects/vimage/src/sys/dev/ie/if_ie_isa.c#3 (text+ko) ====

@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ie/if_ie_isa.c,v 1.7 2007/02/23 12:18:43 piso Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ie/if_ie_isa.c,v 1.8 2008/06/02 19:17:40 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -269,13 +269,6 @@
 		goto bad;
 	}
 
-	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
-				NULL, ie_intr, sc, &sc->irq_ih);
-	if (error) {
-		device_printf(dev, "Unable to register interrupt handler\n"); 
-		goto bad;
-	}
-
 	return (0);
 bad:
 	ie_release_resources(dev);
@@ -560,13 +553,6 @@
 		goto bad;
 	}
 
-	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
-				NULL, ie_intr, sc, &sc->irq_ih);
-	if (error) {
-		device_printf(dev, "Unable to register interrupt handler\n"); 
-		goto bad;
-	}
-
 	return (0);
 bad:
 	ie_release_resources(dev);
@@ -772,13 +758,6 @@
 		goto bad;
 	}
 
-	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
-				NULL, ie_intr, sc, &sc->irq_ih);
-	if (error) {
-		device_printf(dev, "Unable to register interrupt handler\n"); 
-		goto bad;
-	}
-
 	return (0);
 bad:
 	ie_release_resources(dev);

==== //depot/projects/vimage/src/sys/dev/ie/if_ievar.h#3 (text+ko) ====

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


More information about the p4-projects mailing list