PERFORCE change 82227 for review
John Baldwin
jhb at FreeBSD.org
Thu Aug 18 20:27:05 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=82227
Change 82227 by jhb at jhb_slimer on 2005/08/18 20:26:37
IFC @82226.
Affected files ...
.. //depot/projects/smpng/sys/dev/re/if_re.c#25 integrate
.. //depot/projects/smpng/sys/net/bridgestp.c#4 integrate
.. //depot/projects/smpng/sys/net/if.c#72 integrate
.. //depot/projects/smpng/sys/net/if_bridge.c#7 integrate
.. //depot/projects/smpng/sys/pci/if_dc.c#68 integrate
.. //depot/projects/smpng/sys/pci/if_sf.c#37 integrate
.. //depot/projects/smpng/sys/pci/if_sfreg.h#9 integrate
.. //depot/projects/smpng/sys/pci/if_xl.c#61 integrate
.. //depot/projects/smpng/sys/pci/if_xlreg.h#18 integrate
Differences ...
==== //depot/projects/smpng/sys/dev/re/if_re.c#25 (text+ko) ====
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/re/if_re.c,v 1.50 2005/08/18 14:29:01 sobomax Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/re/if_re.c,v 1.51 2005/08/18 18:36:39 sobomax Exp $");
/*
* RealTek 8139C+/8169/8169S/8110S PCI NIC driver
==== //depot/projects/smpng/sys/net/bridgestp.c#4 (text+ko) ====
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/net/bridgestp.c,v 1.5 2005/08/15 02:54:29 thompsa Exp $");
+__FBSDID("$FreeBSD: src/sys/net/bridgestp.c,v 1.6 2005/08/18 20:17:00 thompsa Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1092,7 +1092,7 @@
struct bridge_softc *sc = arg;
struct bridge_iflist *bif;
- BRIDGE_LOCK(sc);
+ BRIDGE_LOCK_ASSERT(sc);
#if 0
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
@@ -1141,8 +1141,6 @@
if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
callout_reset(&sc->sc_bstpcallout, hz, bstp_tick, sc);
-
- BRIDGE_UNLOCK(sc);
}
void
==== //depot/projects/smpng/sys/net/if.c#72 (text+ko) ====
@@ -27,7 +27,7 @@
* SUCH DAMAGE.
*
* @(#)if.c 8.5 (Berkeley) 1/9/95
- * $FreeBSD: src/sys/net/if.c,v 1.243 2005/08/16 17:02:35 brooks Exp $
+ * $FreeBSD: src/sys/net/if.c,v 1.244 2005/08/18 18:36:39 brooks Exp $
*/
#include "opt_compat.h"
@@ -104,7 +104,6 @@
static void if_grow(void);
static void if_init(void *);
static void if_check(void *);
-static int if_findindex(struct ifnet *);
static void if_qflush(struct ifaltq *);
static void if_route(struct ifnet *, int flag, int fam);
static int if_setflag(struct ifnet *, int, int, int *, int);
@@ -329,57 +328,6 @@
if_slowtimo(0);
}
-/* XXX: should be locked. */
-static int
-if_findindex(struct ifnet *ifp)
-{
- int i, unit;
- char eaddr[18], devname[32];
- const char *name, *p;
-
- switch (ifp->if_type) {
- case IFT_ETHER: /* these types use struct arpcom */
- case IFT_FDDI:
- case IFT_XETHER:
- case IFT_ISO88025:
- case IFT_L2VLAN:
- case IFT_BRIDGE:
- snprintf(eaddr, 18, "%6D", IFP2ENADDR(ifp), ":");
- break;
- default:
- eaddr[0] = '\0';
- break;
- }
- strlcpy(devname, ifp->if_xname, sizeof(devname));
- name = net_cdevsw.d_name;
- i = 0;
- while ((resource_find_dev(&i, name, &unit, NULL, NULL)) == 0) {
- if (resource_string_value(name, unit, "ether", &p) == 0)
- if (strcmp(p, eaddr) == 0)
- goto found;
- if (resource_string_value(name, unit, "dev", &p) == 0)
- if (strcmp(p, devname) == 0)
- goto found;
- }
- unit = 0;
-found:
- if (unit != 0) {
- if (ifaddr_byindex(unit) == NULL)
- return (unit);
- printf("%s%d in use, cannot hardwire it to %s.\n",
- name, unit, devname);
- }
- for (unit = 1; ; unit++) {
- if (unit <= if_index && ifaddr_byindex(unit) != NULL)
- continue;
- if (resource_string_value(name, unit, "ether", &p) == 0 ||
- resource_string_value(name, unit, "dev", &p) == 0)
- continue;
- break;
- }
- return (unit);
-}
-
/*
* Allocate a struct ifnet and in index for an interface.
*/
@@ -390,13 +338,25 @@
ifp = malloc(sizeof(struct ifnet), M_IFNET, M_WAITOK|M_ZERO);
- /* XXX: This should fail if if_index is too big */
- ifp->if_index = if_findindex(ifp);
+ /*
+ * Try to find an empty slot below if_index. If we fail, take
+ * the next slot.
+ *
+ * XXX: should be locked!
+ */
+ for (ifp->if_index = 1; ifp->if_index <= if_index; ifp->if_index++) {
+ if (ifnet_byindex(ifp->if_index) == NULL)
+ break;
+ }
+ /* Catch if_index overflow. */
+ if (ifp->if_index < 1) {
+ free(ifp, M_IFNET);
+ return (NULL);
+ }
if (ifp->if_index > if_index)
if_index = ifp->if_index;
if (if_index >= if_indexlim)
if_grow();
-
ifnet_byindex(ifp->if_index) = ifp;
ifp->if_type = type;
@@ -436,7 +396,7 @@
ifnet_byindex(ifp->if_index) = NULL;
/* XXX: should be locked with if_findindex() */
- while (if_index > 0 && ifaddr_byindex(if_index) == NULL)
+ while (if_index > 0 && ifnet_byindex(if_index) == NULL)
if_index--;
if (if_com_free[type] != NULL)
==== //depot/projects/smpng/sys/net/if_bridge.c#7 (text+ko) ====
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/net/if_bridge.c,v 1.17 2005/08/15 02:50:13 thompsa Exp $");
+__FBSDID("$FreeBSD: src/sys/net/if_bridge.c,v 1.18 2005/08/18 20:17:00 thompsa Exp $");
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -439,8 +439,8 @@
/* Initialize our routing table. */
bridge_rtable_init(sc);
- callout_init(&sc->sc_brcallout, 0);
- callout_init(&sc->sc_bstpcallout, 0);
+ callout_init_mtx(&sc->sc_brcallout, &sc->sc_mtx, 0);
+ callout_init_mtx(&sc->sc_bstpcallout, &sc->sc_mtx, 0);
LIST_INIT(&sc->sc_iflist);
@@ -498,6 +498,9 @@
BRIDGE_UNLOCK(sc);
+ callout_drain(&sc->sc_brcallout);
+ callout_drain(&sc->sc_bstpcallout);
+
mtx_lock(&bridge_list_mtx);
LIST_REMOVE(sc, sc_list);
mtx_unlock(&bridge_list_mtx);
@@ -1212,10 +1215,10 @@
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
return;
+ BRIDGE_LOCK(sc);
callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz,
bridge_timer, sc);
- BRIDGE_LOCK(sc);
ifp->if_drv_flags |= IFF_DRV_RUNNING;
bstp_initialization(sc);
BRIDGE_UNLOCK(sc);
@@ -1988,9 +1991,9 @@
{
struct bridge_softc *sc = arg;
- BRIDGE_LOCK(sc);
+ BRIDGE_LOCK_ASSERT(sc);
+
bridge_rtage(sc);
- BRIDGE_UNLOCK(sc);
if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
callout_reset(&sc->sc_brcallout,
==== //depot/projects/smpng/sys/pci/if_dc.c#68 (text+ko) ====
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/pci/if_dc.c,v 1.163 2005/08/10 20:33:46 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/pci/if_dc.c,v 1.164 2005/08/18 19:10:07 jhb Exp $");
/*
* DEC "tulip" clone ethernet driver. Supports the DEC/Intel 21143
@@ -235,8 +235,10 @@
static void dc_tx_underrun(struct dc_softc *);
static void dc_intr(void *);
static void dc_start(struct ifnet *);
+static void dc_start_locked(struct ifnet *);
static int dc_ioctl(struct ifnet *, u_long, caddr_t);
static void dc_init(void *);
+static void dc_init_locked(struct dc_softc *);
static void dc_stop(struct dc_softc *);
static void dc_watchdog(struct ifnet *);
static void dc_shutdown(device_t);
@@ -343,8 +345,6 @@
#define SIO_SET(x) DC_SETBIT(sc, DC_SIO, (x))
#define SIO_CLR(x) DC_CLRBIT(sc, DC_SIO, (x))
-#define IS_MPSAFE 0
-
static void
dc_delay(struct dc_softc *sc)
{
@@ -670,8 +670,6 @@
{
int i, ack;
- DC_LOCK(sc);
-
/*
* Set up frame for RX.
*/
@@ -724,8 +722,6 @@
dc_mii_writebit(sc, 0);
dc_mii_writebit(sc, 0);
- DC_UNLOCK(sc);
-
if (ack)
return (1);
return (0);
@@ -738,7 +734,6 @@
dc_mii_writereg(struct dc_softc *sc, struct dc_mii_frame *frame)
{
- DC_LOCK(sc);
/*
* Set up frame for TX.
*/
@@ -763,8 +758,6 @@
dc_mii_writebit(sc, 0);
dc_mii_writebit(sc, 0);
- DC_UNLOCK(sc);
-
return (0);
}
@@ -1844,7 +1837,7 @@
sc = device_get_softc(dev);
mtx_init(&sc->dc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
+ MTX_DEF);
/*
* Map control/status registers.
@@ -2194,8 +2187,6 @@
/* XXX: bleah, MTU gets overwritten in ether_ifattach() */
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- if (!IS_MPSAFE)
- ifp->if_flags |= IFF_NEEDSGIANT;
ifp->if_ioctl = dc_ioctl;
ifp->if_start = dc_start;
ifp->if_watchdog = dc_watchdog;
@@ -2276,7 +2267,7 @@
#endif
ifp->if_capenable = ifp->if_capabilities;
- callout_init(&sc->dc_stat_ch, IS_MPSAFE ? CALLOUT_MPSAFE : 0);
+ callout_init_mtx(&sc->dc_stat_ch, &sc->dc_mtx, 0);
#ifdef SRM_MEDIA
sc->dc_srm_media = 0;
@@ -2310,8 +2301,7 @@
ether_ifattach(ifp, eaddr);
/* Hook interrupt last to avoid having to lock softc */
- error = bus_setup_intr(dev, sc->dc_irq, INTR_TYPE_NET |
- (IS_MPSAFE ? INTR_MPSAFE : 0),
+ error = bus_setup_intr(dev, sc->dc_irq, INTR_TYPE_NET | INTR_MPSAFE,
dc_intr, sc, &sc->dc_intrhand);
if (error) {
@@ -2344,13 +2334,15 @@
sc = device_get_softc(dev);
KASSERT(mtx_initialized(&sc->dc_mtx), ("dc mutex not initialized"));
- DC_LOCK(sc);
ifp = sc->dc_ifp;
/* These should only be active if attach succeeded */
if (device_is_attached(dev)) {
+ DC_LOCK(sc);
dc_stop(sc);
+ DC_UNLOCK(sc);
+ callout_drain(&sc->dc_stat_ch);
ether_ifdetach(ifp);
if_free(ifp);
}
@@ -2390,7 +2382,6 @@
}
free(sc->dc_srom, M_DEVBUF);
- DC_UNLOCK(sc);
mtx_destroy(&sc->dc_mtx);
return (0);
@@ -2751,7 +2742,7 @@
DC_INC(i, DC_RX_LIST_CNT);
continue;
} else {
- dc_init(sc);
+ dc_init_locked(sc);
return;
}
}
@@ -2879,7 +2870,7 @@
if (txstat & DC_TXSTAT_LATECOLL)
ifp->if_collisions++;
if (!(txstat & DC_TXSTAT_UNDERRUN)) {
- dc_init(sc);
+ dc_init_locked(sc);
return;
}
}
@@ -2918,7 +2909,7 @@
u_int32_t r;
sc = xsc;
- DC_LOCK(sc);
+ DC_LOCK_ASSERT(sc);
ifp = sc->dc_ifp;
mii = device_get_softc(sc->dc_miibus);
@@ -2972,15 +2963,13 @@
IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
sc->dc_link++;
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- dc_start(ifp);
+ dc_start_locked(ifp);
}
if (sc->dc_flags & DC_21143_NWAY && !sc->dc_link)
callout_reset(&sc->dc_stat_ch, hz/10, dc_tick, sc);
else
callout_reset(&sc->dc_stat_ch, hz, dc_tick, sc);
-
- DC_UNLOCK(sc);
}
/*
@@ -2994,7 +2983,7 @@
int i;
if (DC_IS_DAVICOM(sc))
- dc_init(sc);
+ dc_init_locked(sc);
if (DC_IS_INTEL(sc)) {
/*
@@ -3013,7 +3002,7 @@
if (i == DC_TIMEOUT) {
if_printf(sc->dc_ifp,
"failed to force tx to idle state\n");
- dc_init(sc);
+ dc_init_locked(sc);
}
}
@@ -3055,7 +3044,7 @@
dc_txeof(sc);
if (!IFQ_IS_EMPTY(&ifp->if_snd) &&
!(ifp->if_drv_flags & IFF_DRV_OACTIVE))
- dc_start(ifp);
+ dc_start_locked(ifp);
if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */
u_int32_t status;
@@ -3088,7 +3077,7 @@
if (status & DC_ISR_BUS_ERR) {
if_printf(ifp, "dc_poll: bus error\n");
dc_reset(sc);
- dc_init(sc);
+ dc_init_locked(sc);
}
}
DC_UNLOCK(sc);
@@ -3175,7 +3164,7 @@
if (status & DC_ISR_BUS_ERR) {
dc_reset(sc);
- dc_init(sc);
+ dc_init_locked(sc);
}
}
@@ -3183,7 +3172,7 @@
CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- dc_start(ifp);
+ dc_start_locked(ifp);
#ifdef DEVICE_POLLING
done:
@@ -3312,23 +3301,30 @@
dc_start(struct ifnet *ifp)
{
struct dc_softc *sc;
+
+ sc = ifp->if_softc;
+ DC_LOCK(sc);
+ dc_start_locked(ifp);
+ DC_UNLOCK(sc);
+}
+
+static void
+dc_start_locked(struct ifnet *ifp)
+{
+ struct dc_softc *sc;
struct mbuf *m_head = NULL, *m;
unsigned int queued = 0;
int idx;
sc = ifp->if_softc;
- DC_LOCK(sc);
+ DC_LOCK_ASSERT(sc);
- if (!sc->dc_link && ifp->if_snd.ifq_len < 10) {
- DC_UNLOCK(sc);
+ if (!sc->dc_link && ifp->if_snd.ifq_len < 10)
return;
- }
- if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
- DC_UNLOCK(sc);
+ if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
return;
- }
idx = sc->dc_cdata.dc_tx_first = sc->dc_cdata.dc_tx_prod;
@@ -3380,18 +3376,37 @@
*/
ifp->if_timer = 5;
}
-
- DC_UNLOCK(sc);
}
static void
dc_init(void *xsc)
{
struct dc_softc *sc = xsc;
+
+ DC_LOCK(sc);
+ dc_init_locked(sc);
+#ifdef SRM_MEDIA
+ if(sc->dc_srm_media) {
+ struct ifreq ifr;
+ struct mii_data *mii;
+
+ ifr.ifr_media = sc->dc_srm_media;
+ sc->dc_srm_media = 0;
+ DC_UNLOCK(sc);
+ mii = device_get_softc(sc->dc_miibus);
+ ifmedia_ioctl(sc->dc_ifp, &ifr, &mii->mii_media, SIOCSIFMEDIA);
+ } else
+#endif
+ DC_UNLOCK(sc);
+}
+
+static void
+dc_init_locked(struct dc_softc *sc)
+{
struct ifnet *ifp = sc->dc_ifp;
struct mii_data *mii;
- DC_LOCK(sc);
+ DC_LOCK_ASSERT(sc);
mii = device_get_softc(sc->dc_miibus);
@@ -3487,7 +3502,6 @@
if_printf(ifp,
"initialization failed: no memory for rx buffers\n");
dc_stop(sc);
- DC_UNLOCK(sc);
return;
}
@@ -3559,17 +3573,6 @@
else
callout_reset(&sc->dc_stat_ch, hz, dc_tick, sc);
}
-
-#ifdef SRM_MEDIA
- if(sc->dc_srm_media) {
- struct ifreq ifr;
-
- ifr.ifr_media = sc->dc_srm_media;
- ifmedia_ioctl(ifp, &ifr, &mii->mii_media, SIOCSIFMEDIA);
- sc->dc_srm_media = 0;
- }
-#endif
- DC_UNLOCK(sc);
}
/*
@@ -3584,6 +3587,7 @@
sc = ifp->if_softc;
mii = device_get_softc(sc->dc_miibus);
+ DC_LOCK(sc);
mii_mediachg(mii);
ifm = &mii->mii_media;
@@ -3592,6 +3596,7 @@
dc_setcfg(sc, ifm->ifm_media);
else
sc->dc_link = 0;
+ DC_UNLOCK(sc);
return (0);
}
@@ -3608,6 +3613,7 @@
sc = ifp->if_softc;
mii = device_get_softc(sc->dc_miibus);
+ DC_LOCK(sc);
mii_pollstat(mii);
ifm = &mii->mii_media;
if (DC_IS_DAVICOM(sc)) {
@@ -3619,6 +3625,7 @@
}
ifmr->ifm_active = mii->mii_media_active;
ifmr->ifm_status = mii->mii_media_status;
+ DC_UNLOCK(sc);
}
static int
@@ -3629,10 +3636,9 @@
struct mii_data *mii;
int error = 0;
- DC_LOCK(sc);
-
switch (command) {
case SIOCSIFFLAGS:
+ DC_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
int need_setfilt = (ifp->if_flags ^ sc->dc_if_flags) &
(IFF_PROMISC | IFF_ALLMULTI);
@@ -3642,18 +3648,21 @@
dc_setfilt(sc);
} else {
sc->dc_txthresh = 0;
- dc_init(sc);
+ dc_init_locked(sc);
}
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
dc_stop(sc);
}
sc->dc_if_flags = ifp->if_flags;
+ DC_UNLOCK(sc);
error = 0;
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
+ DC_LOCK(sc);
dc_setfilt(sc);
+ DC_UNLOCK(sc);
error = 0;
break;
case SIOCGIFMEDIA:
@@ -3661,21 +3670,23 @@
mii = device_get_softc(sc->dc_miibus);
error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
#ifdef SRM_MEDIA
+ DC_LOCK(sc);
if (sc->dc_srm_media)
sc->dc_srm_media = 0;
+ DC_UNLOCK(sc);
#endif
break;
case SIOCSIFCAP:
+ DC_LOCK(sc);
ifp->if_capenable &= ~IFCAP_POLLING;
ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING;
+ DC_UNLOCK(sc);
break;
default:
error = ether_ioctl(ifp, command, data);
break;
}
- DC_UNLOCK(sc);
-
return (error);
}
@@ -3693,10 +3704,10 @@
dc_stop(sc);
dc_reset(sc);
- dc_init(sc);
+ dc_init_locked(sc);
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- dc_start(ifp);
+ dc_start_locked(ifp);
DC_UNLOCK(sc);
}
@@ -3714,7 +3725,7 @@
int i;
u_int32_t ctl;
- DC_LOCK(sc);
+ DC_LOCK_ASSERT(sc);
ifp = sc->dc_ifp;
ifp->if_timer = 0;
@@ -3762,8 +3773,6 @@
}
}
bzero(&ld->dc_tx_list, sizeof(ld->dc_tx_list));
-
- DC_UNLOCK(sc);
}
/*
@@ -3775,15 +3784,13 @@
dc_suspend(device_t dev)
{
struct dc_softc *sc;
- int s;
-
- s = splimp();
sc = device_get_softc(dev);
+ DC_LOCK(sc);
dc_stop(sc);
sc->suspended = 1;
+ DC_UNLOCK(sc);
- splx(s);
return (0);
}
@@ -3797,20 +3804,18 @@
{
struct dc_softc *sc;
struct ifnet *ifp;
- int s;
- s = splimp();
-
sc = device_get_softc(dev);
ifp = sc->dc_ifp;
/* reinitialize interface if necessary */
+ DC_LOCK(sc);
if (ifp->if_flags & IFF_UP)
- dc_init(sc);
+ dc_init_locked(sc);
sc->suspended = 0;
+ DC_UNLOCK(sc);
- splx(s);
return (0);
}
@@ -3825,5 +3830,7 @@
sc = device_get_softc(dev);
+ DC_LOCK(sc);
dc_stop(sc);
+ DC_UNLOCK(sc);
}
==== //depot/projects/smpng/sys/pci/if_sf.c#37 (text+ko) ====
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/pci/if_sf.c,v 1.85 2005/08/10 20:24:39 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/pci/if_sf.c,v 1.86 2005/08/18 17:09:16 jhb Exp $");
/*
* Adaptec AIC-6915 "Starfire" PCI fast ethernet driver for FreeBSD.
@@ -137,12 +137,15 @@
static int sf_encap(struct sf_softc *, struct sf_tx_bufdesc_type0 *,
struct mbuf *);
static void sf_start(struct ifnet *);
+static void sf_start_locked(struct ifnet *);
static int sf_ioctl(struct ifnet *, u_long, caddr_t);
static void sf_init(void *);
+static void sf_init_locked(struct sf_softc *);
static void sf_stop(struct sf_softc *);
static void sf_watchdog(struct ifnet *);
static void sf_shutdown(device_t);
static int sf_ifmedia_upd(struct ifnet *);
+static void sf_ifmedia_upd_locked(struct ifnet *);
static void sf_ifmedia_sts(struct ifnet *, struct ifmediareq *);
static void sf_reset(struct sf_softc *);
static int sf_init_rx_ring(struct sf_softc *);
@@ -462,10 +465,25 @@
struct ifnet *ifp;
{
struct sf_softc *sc;
+
+ sc = ifp->if_softc;
+ SF_LOCK(sc);
+ sf_ifmedia_upd_locked(ifp);
+ SF_UNLOCK(sc);
+
+ return(0);
+}
+
+static void
+sf_ifmedia_upd_locked(ifp)
+ struct ifnet *ifp;
+{
+ struct sf_softc *sc;
struct mii_data *mii;
sc = ifp->if_softc;
mii = device_get_softc(sc->sf_miibus);
+ SF_LOCK_ASSERT(sc);
sc->sf_link = 0;
if (mii->mii_instance) {
struct mii_softc *miisc;
@@ -473,8 +491,6 @@
mii_phy_reset(miisc);
}
mii_mediachg(mii);
-
- return(0);
}
/*
@@ -489,11 +505,13 @@
struct mii_data *mii;
sc = ifp->if_softc;
+ SF_LOCK(sc);
mii = device_get_softc(sc->sf_miibus);
mii_pollstat(mii);
ifmr->ifm_active = mii->mii_media_active;
ifmr->ifm_status = mii->mii_media_status;
+ SF_UNLOCK(sc);
}
static int
@@ -507,10 +525,9 @@
struct mii_data *mii;
int error = 0;
- SF_LOCK(sc);
-
switch(command) {
case SIOCSIFFLAGS:
+ SF_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
ifp->if_flags & IFF_PROMISC &&
@@ -521,17 +538,20 @@
sc->sf_if_flags & IFF_PROMISC) {
SF_CLRBIT(sc, SF_RXFILT, SF_RXFILT_PROMISC);
} else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- sf_init(sc);
+ sf_init_locked(sc);
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
sf_stop(sc);
}
sc->sf_if_flags = ifp->if_flags;
+ SF_UNLOCK(sc);
error = 0;
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
+ SF_LOCK(sc);
sf_setmulti(sc);
+ SF_UNLOCK(sc);
error = 0;
break;
case SIOCGIFMEDIA:
@@ -540,16 +560,16 @@
error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
break;
case SIOCSIFCAP:
+ SF_LOCK(sc);
ifp->if_capenable &= ~IFCAP_POLLING;
ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING;
+ SF_UNLOCK(sc);
break;
default:
error = ether_ioctl(ifp, command, data);
break;
}
- SF_UNLOCK(sc);
-
return(error);
}
@@ -649,7 +669,7 @@
sc = device_get_softc(dev);
mtx_init(&sc->sf_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
+ MTX_DEF);
/*
* Map control/status registers.
*/
@@ -678,7 +698,8 @@
goto fail;
}
- callout_handle_init(&sc->sf_stat_ch);
+ callout_init_mtx(&sc->sf_stat_callout, &sc->sf_mtx, 0);
+
/* Reset the adapter. */
sf_reset(sc);
@@ -719,8 +740,7 @@
ifp->if_softc = sc;
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = sf_ioctl;
ifp->if_start = sf_start;
ifp->if_watchdog = sf_watchdog;
@@ -740,7 +760,7 @@
ether_ifattach(ifp, eaddr);
/* Hook interrupt last to avoid having to lock softc */
- error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET,
+ error = bus_setup_intr(dev, sc->sf_irq, INTR_TYPE_NET | INTR_MPSAFE,
sf_intr, sc, &sc->sf_intrhand);
if (error) {
@@ -773,12 +793,14 @@
sc = device_get_softc(dev);
KASSERT(mtx_initialized(&sc->sf_mtx), ("sf mutex not initialized"));
- SF_LOCK(sc);
ifp = sc->sf_ifp;
/* These should only be active if attach succeeded */
if (device_is_attached(dev)) {
+ SF_LOCK(sc);
sf_stop(sc);
+ SF_UNLOCK(sc);
+ callout_drain(&sc->sf_stat_callout);
ether_ifdetach(ifp);
if_free(ifp);
}
@@ -796,7 +818,6 @@
if (sc->sf_ldata)
contigfree(sc->sf_ldata, sizeof(struct sf_list_data), M_DEVBUF);
- SF_UNLOCK(sc);
mtx_destroy(&sc->sf_mtx);
return(0);
@@ -984,6 +1005,7 @@
ifp = sc->sf_ifp;
+ SF_LOCK_ASSERT(sc);
txcons = csr_read_4(sc, SF_CQ_CONSIDX);
cmpprodidx = SF_IDX_HI(csr_read_4(sc, SF_CQ_PRODIDX));
cmpconsidx = SF_IDX_HI(txcons);
@@ -1072,7 +1094,7 @@
sf_rxeof(sc);
sf_txeof(sc);
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- sf_start(ifp);
+ sf_start_locked(ifp);
if (cmd == POLL_AND_CHECK_STATUS) {
u_int32_t status;
@@ -1086,11 +1108,10 @@
if (status & SF_ISR_ABNORMALINTR) {
if (status & SF_ISR_STATSOFLOW) {
- untimeout(sf_stats_update, sc,
- sc->sf_stat_ch);
+ callout_stop(&sc->sf_stat_callout);
sf_stats_update(sc);
} else
- sf_init(sc);
+ sf_init_locked(sc);
}
}
}
@@ -1151,11 +1172,10 @@
if (status & SF_ISR_ABNORMALINTR) {
if (status & SF_ISR_STATSOFLOW) {
- untimeout(sf_stats_update, sc,
- sc->sf_stat_ch);
+ callout_stop(&sc->sf_stat_callout);
sf_stats_update(sc);
} else
- sf_init(sc);
+ sf_init_locked(sc);
}
}
@@ -1163,7 +1183,7 @@
csr_write_4(sc, SF_IMR, SF_INTRS);
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- sf_start(ifp);
+ sf_start_locked(ifp);
#ifdef DEVICE_POLLING
done_locked:
@@ -1176,12 +1196,22 @@
void *xsc;
{
struct sf_softc *sc;
+
+ sc = xsc;
+ SF_LOCK(sc);
+ sf_init_locked(sc);
+ SF_UNLOCK(sc);
+}
+
+static void
+sf_init_locked(sc)
+ struct sf_softc *sc;
+{
struct ifnet *ifp;
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list