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