Date: Thu, 18 Aug 2005 20:27:03 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 82227 for review Message-ID: <200508182027.j7IKR3tT063243@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82227 Change 82227 by jhb@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) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508182027.j7IKR3tT063243>