From owner-p4-projects@FreeBSD.ORG Tue Jun 3 00:57:55 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D05701065676; Tue, 3 Jun 2008 00:57:54 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 911391065674 for ; Tue, 3 Jun 2008 00:57:54 +0000 (UTC) (envelope-from julian@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 869758FC1D for ; Tue, 3 Jun 2008 00:57:54 +0000 (UTC) (envelope-from julian@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m530vsTL044269 for ; Tue, 3 Jun 2008 00:57:54 GMT (envelope-from julian@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m530vs79044267 for perforce@freebsd.org; Tue, 3 Jun 2008 00:57:54 GMT (envelope-from julian@freebsd.org) Date: Tue, 3 Jun 2008 00:57:54 GMT Message-Id: <200806030057.m530vs79044267@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to julian@freebsd.org using -f From: Julian Elischer To: Perforce Change Reviews Cc: Subject: PERFORCE change 142779 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Jun 2008 00:57:55 -0000 http://perforce.freebsd.org/chv.cgi?CH=142779 Change 142779 by julian@julian_trafmon1 on 2008/06/03 00:57:28 IFC@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 -__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 -__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 -__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 +#include #include #include #include @@ -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 -__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 #include @@ -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 -__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 -__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 #include @@ -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) <<<