diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c index 695b019fec29..f7c97a1bf240 100644 --- a/sys/dev/dc/if_dc.c +++ b/sys/dev/dc/if_dc.c @@ -109,6 +109,7 @@ #include #include #include +#include #include #include @@ -555,9 +556,9 @@ static int dc_mii_readreg(sc, frame) struct dc_mii_frame *frame; { - int i, ack, s; + int i, ack; - s = splimp(); + DC_LOCK(sc); /* * Set up frame for RX. @@ -612,7 +613,7 @@ static int dc_mii_readreg(sc, frame) dc_mii_writebit(sc, 0); dc_mii_writebit(sc, 0); - splx(s); + DC_UNLOCK(sc); if (ack) return(1); @@ -627,9 +628,7 @@ static int dc_mii_writereg(sc, frame) struct dc_mii_frame *frame; { - int s; - - s = splimp(); + DC_LOCK(sc); /* * Set up frame for TX. */ @@ -654,7 +653,7 @@ static int dc_mii_writereg(sc, frame) dc_mii_writebit(sc, 0); dc_mii_writebit(sc, 0); - splx(s); + DC_UNLOCK(sc); return(0); } @@ -1626,7 +1625,7 @@ static void dc_parse_21143_srom(sc) static int dc_attach(dev) device_t dev; { - int s, tmp = 0; + int tmp = 0; u_char eaddr[ETHER_ADDR_LEN]; u_int32_t command; struct dc_softc *sc; @@ -1634,8 +1633,6 @@ static int dc_attach(dev) u_int32_t revision; int unit, error = 0, rid, mac_offset; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct dc_softc)); @@ -1701,7 +1698,9 @@ static int dc_attach(dev) printf("dc%d: couldn't set up irq\n", unit); goto fail; } - + + mtx_init(&sc->dc_mtx, "dc", MTX_DEF); + DC_LOCK(sc); /* Need this info to decide on a chip type. */ sc->dc_info = dc_devtype(dev); revision = pci_read_config(dev, DC_PCI_CFRV, 4) & 0x000000FF; @@ -1966,10 +1965,12 @@ static int dc_attach(dev) } #endif + DC_UNLOCK(sc); + return(0); fail: - splx(s); - + DC_UNLOCK(sc); + mtx_destroy(&sc->dc_mtx); return(error); } @@ -1978,12 +1979,12 @@ static int dc_detach(dev) { struct dc_softc *sc; struct ifnet *ifp; - int s; struct dc_mediainfo *m; - s = splimp(); - sc = device_get_softc(dev); + + DC_LOCK(sc); + ifp = &sc->arpcom.ac_if; dc_stop(sc); @@ -2006,7 +2007,8 @@ static int dc_detach(dev) sc->dc_mi = m; } - splx(s); + DC_UNLOCK(sc); + mtx_destroy(&sc->dc_mtx); return(0); } @@ -2457,12 +2459,10 @@ static void dc_tick(xsc) struct dc_softc *sc; struct mii_data *mii; struct ifnet *ifp; - int s; u_int32_t r; - s = splimp(); - sc = xsc; + DC_LOCK(sc); ifp = &sc->arpcom.ac_if; mii = device_get_softc(sc->dc_miibus); @@ -2526,7 +2526,7 @@ static void dc_tick(xsc) else sc->dc_stat_ch = timeout(dc_tick, sc, hz); - splx(s); + DC_UNLOCK(sc); return; } @@ -2539,12 +2539,14 @@ static void dc_intr(arg) u_int32_t status; sc = arg; + DC_LOCK(sc); ifp = &sc->arpcom.ac_if; /* Supress unwanted interrupts */ if (!(ifp->if_flags & IFF_UP)) { if (CSR_READ_4(sc, DC_ISR) & DC_INTRS) dc_stop(sc); + DC_UNLOCK(sc); return; } @@ -2621,6 +2623,8 @@ static void dc_intr(arg) if (ifp->if_snd.ifq_head != NULL) dc_start(ifp); + DC_UNLOCK(sc); + return; } @@ -2737,11 +2741,17 @@ static void dc_start(ifp) sc = ifp->if_softc; - if (!sc->dc_link) - return; + DC_LOCK(sc); - if (ifp->if_flags & IFF_OACTIVE) + if (!sc->dc_link) { + DC_UNLOCK(sc); return; + } + + if (ifp->if_flags & IFF_OACTIVE) { + DC_UNLOCK(sc); + return; + } idx = sc->dc_cdata.dc_tx_prod; @@ -2787,6 +2797,8 @@ static void dc_start(ifp) */ ifp->if_timer = 5; + DC_UNLOCK(sc); + return; } @@ -2796,9 +2808,8 @@ static void dc_init(xsc) struct dc_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; struct mii_data *mii; - int s; - s = splimp(); + DC_LOCK(sc); mii = device_get_softc(sc->dc_miibus); @@ -2876,7 +2887,7 @@ static void dc_init(xsc) printf("dc%d: initialization failed: no " "memory for rx buffers\n", sc->dc_unit); dc_stop(sc); - (void)splx(s); + DC_UNLOCK(sc); return; } @@ -2929,8 +2940,6 @@ static void dc_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); - /* Don't start the ticker if this is a homePNA link. */ if (IFM_SUBTYPE(mii->mii_media.ifm_media) == IFM_homePNA) sc->dc_link = 1; @@ -2950,6 +2959,7 @@ static void dc_init(xsc) sc->dc_srm_media = 0; } #endif + DC_UNLOCK(sc); return; } @@ -3013,9 +3023,9 @@ static int dc_ioctl(ifp, command, data) struct dc_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; - int s, error = 0; + int error = 0; - s = splimp(); + DC_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -3063,7 +3073,7 @@ static int dc_ioctl(ifp, command, data) break; } - (void)splx(s); + DC_UNLOCK(sc); return(error); } @@ -3075,6 +3085,8 @@ static void dc_watchdog(ifp) sc = ifp->if_softc; + DC_LOCK(sc); + ifp->if_oerrors++; printf("dc%d: watchdog timeout\n", sc->dc_unit); @@ -3085,6 +3097,8 @@ static void dc_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) dc_start(ifp); + DC_UNLOCK(sc); + return; } @@ -3098,6 +3112,8 @@ static void dc_stop(sc) register int i; struct ifnet *ifp; + DC_LOCK(sc); + ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; @@ -3141,6 +3157,8 @@ static void dc_stop(sc) ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + DC_UNLOCK(sc); + return; } diff --git a/sys/dev/dc/if_dcreg.h b/sys/dev/dc/if_dcreg.h index 9c6cfc41bf43..e72d8b45c2c0 100644 --- a/sys/dev/dc/if_dcreg.h +++ b/sys/dev/dc/if_dcreg.h @@ -676,8 +676,13 @@ struct dc_softc { #ifdef SRM_MEDIA int dc_srm_media; #endif + struct mtx dc_mtx; }; + +#define DC_LOCK(_sc) mtx_enter(&(_sc)->dc_mtx, MTX_DEF) +#define DC_UNLOCK(_sc) mtx_exit(&(_sc)->dc_mtx, MTX_DEF) + #define DC_TX_POLL 0x00000001 #define DC_TX_COALESCE 0x00000002 #define DC_TX_ADMTEK_WAR 0x00000004 diff --git a/sys/dev/sf/if_sf.c b/sys/dev/sf/if_sf.c index 52c6f8854f1f..a7d14522004e 100644 --- a/sys/dev/sf/if_sf.c +++ b/sys/dev/sf/if_sf.c @@ -531,9 +531,9 @@ static int sf_ioctl(ifp, command, data) struct sf_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; - int s, error = 0; + int error = 0; - s = splimp(); + SF_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -575,7 +575,7 @@ static int sf_ioctl(ifp, command, data) break; } - (void)splx(s); + SF_UNLOCK(sc); return(error); } @@ -670,14 +670,12 @@ static int sf_probe(dev) static int sf_attach(dev) device_t dev; { - int s, i; + int i; u_int32_t command; struct sf_softc *sc; struct ifnet *ifp; int unit, rid, error = 0; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct sf_softc)); @@ -768,7 +766,8 @@ static int sf_attach(dev) } callout_handle_init(&sc->sf_stat_ch); - + mtx_init(&sc->sf_mtx, "sf", MTX_DEF); + SF_LOCK(sc); /* Reset the adapter. */ sf_reset(sc); @@ -832,9 +831,12 @@ static int sf_attach(dev) * Call MI attach routine. */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); + SF_UNLOCK(sc); + return(0); fail: - splx(s); + SF_UNLOCK(sc); + mtx_destroy(&sc->sf_mtx); return(error); } @@ -843,11 +845,9 @@ static int sf_detach(dev) { struct sf_softc *sc; struct ifnet *ifp; - int s; - - s = splimp(); sc = device_get_softc(dev); + SF_LOCK(sc); ifp = &sc->arpcom.ac_if; ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); @@ -862,7 +862,8 @@ static int sf_detach(dev) contigfree(sc->sf_ldata, sizeof(struct sf_list_data), M_DEVBUF); - splx(s); + SF_UNLOCK(sc); + mtx_destroy(&sc->sf_mtx); return(0); } @@ -1086,10 +1087,14 @@ static void sf_intr(arg) u_int32_t status; sc = arg; + SF_LOCK(sc); + ifp = &sc->arpcom.ac_if; - if (!(csr_read_4(sc, SF_ISR_SHADOW) & SF_ISR_PCIINT_ASSERTED)) + if (!(csr_read_4(sc, SF_ISR_SHADOW) & SF_ISR_PCIINT_ASSERTED)) { + SF_UNLOCK(sc); return; + } /* Disable interrupts. */ csr_write_4(sc, SF_IMR, 0x00000000); @@ -1124,6 +1129,7 @@ static void sf_intr(arg) if (ifp->if_snd.ifq_head != NULL) sf_start(ifp); + SF_UNLOCK(sc); return; } @@ -1133,11 +1139,10 @@ static void sf_init(xsc) struct sf_softc *sc; struct ifnet *ifp; struct mii_data *mii; - int i, s; - - s = splimp(); + int i; sc = xsc; + SF_LOCK(sc); ifp = &sc->arpcom.ac_if; mii = device_get_softc(sc->sf_miibus); @@ -1162,7 +1167,7 @@ static void sf_init(xsc) if (sf_init_rx_ring(sc) == ENOBUFS) { printf("sf%d: initialization failed: no " "memory for rx buffers\n", sc->sf_unit); - (void)splx(s); + SF_UNLOCK(sc); return; } @@ -1237,7 +1242,7 @@ static void sf_init(xsc) sc->sf_stat_ch = timeout(sf_stats_update, sc, hz); - splx(s); + SF_UNLOCK(sc); return; } @@ -1314,12 +1319,17 @@ static void sf_start(ifp) int i, txprod; sc = ifp->if_softc; + SF_LOCK(sc); - if (!sc->sf_link) + if (!sc->sf_link) { + SF_UNLOCK(sc); return; + } - if (ifp->if_flags & IFF_OACTIVE) + if (ifp->if_flags & IFF_OACTIVE) { + SF_UNLOCK(sc); return; + } txprod = csr_read_4(sc, SF_TXDQ_PRODIDX); i = SF_IDX_HI(txprod) >> 4; @@ -1345,8 +1355,10 @@ static void sf_start(ifp) break; } - if (cur_tx == NULL) + if (cur_tx == NULL) { + SF_UNLOCK(sc); return; + } /* Transmit */ csr_write_4(sc, SF_TXDQ_PRODIDX, @@ -1355,6 +1367,8 @@ static void sf_start(ifp) ifp->if_timer = 5; + SF_UNLOCK(sc); + return; } @@ -1364,6 +1378,8 @@ static void sf_stop(sc) int i; struct ifnet *ifp; + SF_LOCK(sc); + ifp = &sc->arpcom.ac_if; untimeout(sf_stats_update, sc, sc->sf_stat_ch); @@ -1396,6 +1412,7 @@ static void sf_stop(sc) } ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); + SF_UNLOCK(sc); return; } @@ -1415,11 +1432,10 @@ static void sf_stats_update(xsc) struct mii_data *mii; struct sf_stats stats; u_int32_t *ptr; - int i, s; - - s = splimp(); + int i; sc = xsc; + SF_LOCK(sc); ifp = &sc->arpcom.ac_if; mii = device_get_softc(sc->sf_miibus); @@ -1447,7 +1463,7 @@ static void sf_stats_update(xsc) sc->sf_stat_ch = timeout(sf_stats_update, sc, hz); - splx(s); + SF_UNLOCK(sc); return; } @@ -1459,6 +1475,8 @@ static void sf_watchdog(ifp) sc = ifp->if_softc; + SF_LOCK(sc); + ifp->if_oerrors++; printf("sf%d: watchdog timeout\n", sc->sf_unit); @@ -1469,6 +1487,8 @@ static void sf_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) sf_start(ifp); + SF_UNLOCK(sc); + return; } diff --git a/sys/dev/sf/if_sfreg.h b/sys/dev/sf/if_sfreg.h index 49fdd5ae1afc..c2dc20e73c6d 100644 --- a/sys/dev/sf/if_sfreg.h +++ b/sys/dev/sf/if_sfreg.h @@ -1044,8 +1044,13 @@ struct sf_softc { u_int8_t sf_link; int sf_if_flags; struct callout_handle sf_stat_ch; + struct mtx sf_mtx; }; + +#define SF_LOCK(_sc) mtx_enter(&(_sc)->sf_mtx, MTX_DEF) +#define SF_UNLOCK(_sc) mtx_exit(&(_sc)->sf_mtx, MTX_DEF) + #define SF_TIMEOUT 1000 #ifdef __alpha__ diff --git a/sys/dev/sk/if_sk.c b/sys/dev/sk/if_sk.c index a83a606445c4..963f754672b4 100644 --- a/sys/dev/sk/if_sk.c +++ b/sys/dev/sk/if_sk.c @@ -413,6 +413,8 @@ static int sk_miibus_readreg(dev, phy, reg) if (sc_if->sk_phytype == SK_PHYTYPE_XMAC && phy != 0) return(0); + SK_IF_LOCK(sc_if); + SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8)); SK_XM_READ_2(sc_if, XM_PHY_DATA); if (sc_if->sk_phytype != SK_PHYTYPE_XMAC) { @@ -430,7 +432,9 @@ static int sk_miibus_readreg(dev, phy, reg) } } DELAY(1); - return(SK_XM_READ_2(sc_if, XM_PHY_DATA)); + i = SK_XM_READ_2(sc_if, XM_PHY_DATA); + SK_IF_UNLOCK(sc_if); + return(i); } static int sk_miibus_writereg(dev, phy, reg, val) @@ -441,6 +445,7 @@ static int sk_miibus_writereg(dev, phy, reg, val) int i; sc_if = device_get_softc(dev); + SK_IF_LOCK(sc_if); SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8)); for (i = 0; i < SK_TIMEOUT; i++) { @@ -460,6 +465,8 @@ static int sk_miibus_writereg(dev, phy, reg, val) break; } + SK_IF_UNLOCK(sc_if); + if (i == SK_TIMEOUT) printf("sk%d: phy write timed out\n", sc_if->sk_unit); @@ -474,7 +481,7 @@ static void sk_miibus_statchg(dev) sc_if = device_get_softc(dev); mii = device_get_softc(sc_if->sk_miibus); - + SK_IF_LOCK(sc_if); /* * If this is a GMII PHY, manually set the XMAC's * duplex mode accordingly. @@ -486,6 +493,7 @@ static void sk_miibus_statchg(dev) SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_GMIIFDX); } } + SK_IF_UNLOCK(sc_if); return; } @@ -872,10 +880,10 @@ static int sk_ioctl(ifp, command, data) { struct sk_if_softc *sc_if = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; - int s, error = 0; + int error = 0; struct mii_data *mii; - s = splimp(); + SK_IF_LOCK(sc_if); switch(command) { case SIOCSIFADDR: @@ -928,7 +936,7 @@ static int sk_ioctl(ifp, command, data) break; } - (void)splx(s); + SK_IF_UNLOCK(sc_if); return(error); } @@ -1025,6 +1033,7 @@ static int sk_attach_xmac(dev) sc_if = device_get_softc(dev); sc = device_get_softc(device_get_parent(dev)); + SK_LOCK(sc); port = *(int *)device_get_ivars(dev); free(device_get_ivars(dev), M_DEVBUF); device_set_ivars(dev, NULL); @@ -1113,6 +1122,7 @@ static int sk_attach_xmac(dev) if (sc_if->sk_rdata == NULL) { printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit); sc->sk_if[port] = NULL; + SK_UNLOCK(sc); return(ENOMEM); } @@ -1125,6 +1135,7 @@ static int sk_attach_xmac(dev) contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data), M_DEVBUF); sc->sk_if[port] = NULL; + SK_UNLOCK(sc); return(ENOMEM); } @@ -1151,6 +1162,7 @@ static int sk_attach_xmac(dev) printf("skc%d: no PHY found!\n", sc_if->sk_unit); contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data), M_DEVBUF); + SK_UNLOCK(sc); return(ENXIO); } @@ -1160,6 +1172,8 @@ static int sk_attach_xmac(dev) ether_ifattach(ifp, ETHER_BPF_SUPPORTED); callout_handle_init(&sc_if->sk_tick_ch); + SK_UNLOCK(sc); + return(0); } @@ -1170,13 +1184,10 @@ static int sk_attach_xmac(dev) static int sk_attach(dev) device_t dev; { - int s; u_int32_t command; struct sk_softc *sc; int unit, error = 0, rid, *port; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct sk_softc)); @@ -1266,6 +1277,8 @@ static int sk_attach(dev) goto fail; } + mtx_init(&sc->sk_mtx, "skc", MTX_DEF); + SK_LOCK(sc); /* Reset the adapter. */ sk_reset(sc); @@ -1345,9 +1358,12 @@ static int sk_attach(dev) CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON); bus_generic_attach(dev); + SK_UNLOCK(sc); + return(0); fail: - splx(s); + SK_UNLOCK(sc); + mtx_destroy(&sc->sk_mtx); return(error); } @@ -1357,12 +1373,11 @@ static int sk_detach_xmac(dev) struct sk_softc *sc; struct sk_if_softc *sc_if; struct ifnet *ifp; - int s; - - s = splimp(); sc = device_get_softc(device_get_parent(dev)); sc_if = device_get_softc(dev); + SK_IF_LOCK(sc_if); + ifp = &sc_if->arpcom.ac_if; sk_stop(sc_if); ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); @@ -1371,6 +1386,7 @@ static int sk_detach_xmac(dev) device_delete_child(dev, sc_if->sk_miibus); contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF); contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data), M_DEVBUF); + SK_IF_UNLOCK(sc_if); return(0); } @@ -1379,11 +1395,9 @@ static int sk_detach(dev) device_t dev; { struct sk_softc *sc; - int s; - - s = splimp(); sc = device_get_softc(dev); + SK_LOCK(sc); bus_generic_detach(dev); if (sc->sk_devs[SK_PORT_A] != NULL) @@ -1395,7 +1409,8 @@ static int sk_detach(dev) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq); bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res); - splx(s); + SK_UNLOCK(sc); + mtx_destroy(&sc->sk_mtx); return(0); } @@ -1460,6 +1475,8 @@ static void sk_start(ifp) sc_if = ifp->if_softc; sc = sc_if->sk_softc; + SK_IF_LOCK(sc_if); + idx = sc_if->sk_cdata.sk_tx_prod; while(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) { @@ -1492,6 +1509,7 @@ static void sk_start(ifp) /* Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; + SK_IF_UNLOCK(sc_if); return; } @@ -1516,6 +1534,7 @@ static void sk_shutdown(dev) struct sk_softc *sc; sc = device_get_softc(dev); + SK_LOCK(sc); /* Turn off the 'driver is loaded' LED. */ CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_OFF); @@ -1525,6 +1544,7 @@ static void sk_shutdown(dev) * assert the resets on the attached XMAC(s). */ sk_reset(sc); + SK_UNLOCK(sc); return; } @@ -1644,14 +1664,18 @@ static void sk_tick(xsc_if) int i; sc_if = xsc_if; + SK_IF_LOCK(sc_if); ifp = &sc_if->arpcom.ac_if; mii = device_get_softc(sc_if->sk_miibus); - if (!(ifp->if_flags & IFF_UP)) + if (!(ifp->if_flags & IFF_UP)) { + SK_IF_UNLOCK(sc_if); return; + } if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) { sk_intr_bcom(sc_if); + SK_IF_UNLOCK(sc_if); return; } @@ -1669,6 +1693,7 @@ static void sk_tick(xsc_if) if (i != 3) { sc_if->sk_tick_ch = timeout(sk_tick, sc_if, hz); + SK_IF_UNLOCK(sc_if); return; } @@ -1679,6 +1704,7 @@ static void sk_tick(xsc_if) mii_pollstat(mii); untimeout(sk_tick, sc_if, sc_if->sk_tick_ch); + SK_IF_UNLOCK(sc_if); return; } @@ -1785,6 +1811,8 @@ static void sk_intr(xsc) struct ifnet *ifp0 = NULL, *ifp1 = NULL; u_int32_t status; + SK_LOCK(sc); + sc_if0 = sc->sk_if[SK_PORT_A]; sc_if1 = sc->sk_if[SK_PORT_B]; @@ -1846,6 +1874,8 @@ static void sk_intr(xsc) if (ifp1 != NULL && ifp1->if_snd.ifq_head != NULL) sk_start(ifp1); + SK_UNLOCK(sc); + return; } @@ -2028,9 +2058,8 @@ static void sk_init(xsc) struct sk_softc *sc; struct ifnet *ifp; struct mii_data *mii; - int s; - s = splimp(); + SK_IF_LOCK(sc_if); ifp = &sc_if->arpcom.ac_if; sc = sc_if->sk_softc; @@ -2100,7 +2129,7 @@ static void sk_init(xsc) printf("sk%d: initialization failed: no " "memory for rx buffers\n", sc_if->sk_unit); sk_stop(sc_if); - (void)splx(s); + SK_IF_UNLOCK(sc_if); return; } sk_init_tx_ring(sc_if); @@ -2126,7 +2155,7 @@ static void sk_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - splx(s); + SK_IF_UNLOCK(sc_if); return; } @@ -2138,6 +2167,7 @@ static void sk_stop(sc_if) struct sk_softc *sc; struct ifnet *ifp; + SK_IF_LOCK(sc_if); sc = sc_if->sk_softc; ifp = &sc_if->arpcom.ac_if; @@ -2198,6 +2228,6 @@ static void sk_stop(sc_if) } ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); - + SK_IF_UNLOCK(sc_if); return; } diff --git a/sys/dev/sk/if_skreg.h b/sys/dev/sk/if_skreg.h index 92a26bea909d..6f31d1de0c47 100644 --- a/sys/dev/sk/if_skreg.h +++ b/sys/dev/sk/if_skreg.h @@ -1179,8 +1179,14 @@ struct sk_softc { u_int32_t sk_intrmask; struct sk_if_softc *sk_if[2]; device_t sk_devs[2]; + struct mtx sk_mtx; }; +#define SK_LOCK(_sc) mtx_enter(&(_sc)->sk_mtx, MTX_DEF) +#define SK_UNLOCK(_sc) mtx_exit(&(_sc)->sk_mtx, MTX_DEF) +#define SK_IF_LOCK(_sc) mtx_enter(&(_sc)->sk_softc->sk_mtx, MTX_DEF) +#define SK_IF_UNLOCK(_sc) mtx_exit(&(_sc)->sk_softc->sk_mtx, MTX_DEF) + /* Softc for each logical interface */ struct sk_if_softc { struct arpcom arpcom; /* interface info */ diff --git a/sys/dev/ti/if_ti.c b/sys/dev/ti/if_ti.c index f1cfee5dca8e..04ec29d99f65 100644 --- a/sys/dev/ti/if_ti.c +++ b/sys/dev/ti/if_ti.c @@ -1477,14 +1477,11 @@ static int ti_probe(dev) static int ti_attach(dev) device_t dev; { - int s; u_int32_t command; struct ifnet *ifp; struct ti_softc *sc; int unit, error = 0, rid; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct ti_softc)); @@ -1540,6 +1537,9 @@ static int ti_attach(dev) goto fail; } + mtx_init(&sc->ti_mtx, "ti", MTX_DEF); + TI_LOCK(sc); + sc->ti_unit = unit; if (ti_chipinit(sc)) { @@ -1689,10 +1689,12 @@ static int ti_attach(dev) * Call MI attach routine. */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); + TI_UNLOCK(sc); + return(0); fail: - splx(s); - + TI_UNLOCK(sc); + mtx_destroy(&sc->ti_mtx); return(error); } @@ -1701,11 +1703,10 @@ static int ti_detach(dev) { struct ti_softc *sc; struct ifnet *ifp; - int s; - s = splimp(); sc = device_get_softc(dev); + TI_LOCK(sc); ifp = &sc->arpcom.ac_if; ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); @@ -1719,7 +1720,8 @@ static int ti_detach(dev) contigfree(sc->ti_rdata, sizeof(struct ti_ring_data), M_DEVBUF); ifmedia_removeall(&sc->ifmedia); - splx(s); + TI_UNLOCK(sc); + mtx_destroy(&sc->ti_mtx); return(0); } @@ -1907,13 +1909,16 @@ static void ti_intr(xsc) struct ifnet *ifp; sc = xsc; + TI_LOCK(sc); ifp = &sc->arpcom.ac_if; #ifdef notdef /* Avoid this for now -- checking this register is expensive. */ /* Make sure this is really our interrupt. */ - if (!(CSR_READ_4(sc, TI_MISC_HOST_CTL) & TI_MHC_INTSTATE)) + if (!(CSR_READ_4(sc, TI_MISC_HOST_CTL) & TI_MHC_INTSTATE)) { + TI_UNLOCK(sc); return; + } #endif /* Ack interrupt and stop others from occuring. */ @@ -1935,6 +1940,8 @@ static void ti_intr(xsc) if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL) ti_start(ifp); + TI_UNLOCK(sc); + return; } @@ -2069,6 +2076,7 @@ static void ti_start(ifp) u_int32_t prodidx = 0; sc = ifp->if_softc; + TI_LOCK(sc); prodidx = CSR_READ_4(sc, TI_MB_SENDPROD_IDX); @@ -2121,6 +2129,7 @@ static void ti_start(ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; + TI_UNLOCK(sc); return; } @@ -2129,21 +2138,19 @@ static void ti_init(xsc) void *xsc; { struct ti_softc *sc = xsc; - int s; - - s = splimp(); /* Cancel pending I/O and flush buffers. */ ti_stop(sc); + TI_LOCK(sc); /* Init the gen info block, ring control blocks and firmware. */ if (ti_gibinit(sc)) { printf("ti%d: initialization failure\n", sc->ti_unit); - splx(s); + TI_UNLOCK(sc); return; } - splx(s); + TI_UNLOCK(sc); return; } @@ -2355,10 +2362,10 @@ static int ti_ioctl(ifp, command, data) { struct ti_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; - int s, error = 0; + int error = 0; struct ti_cmd_desc cmd; - s = splimp(); + TI_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -2419,7 +2426,7 @@ static int ti_ioctl(ifp, command, data) break; } - (void)splx(s); + TI_UNLOCK(sc); return(error); } @@ -2430,12 +2437,14 @@ static void ti_watchdog(ifp) struct ti_softc *sc; sc = ifp->if_softc; + TI_LOCK(sc); printf("ti%d: watchdog timeout -- resetting\n", sc->ti_unit); ti_stop(sc); ti_init(sc); ifp->if_oerrors++; + TI_UNLOCK(sc); return; } @@ -2450,6 +2459,8 @@ static void ti_stop(sc) struct ifnet *ifp; struct ti_cmd_desc cmd; + TI_LOCK(sc); + ifp = &sc->arpcom.ac_if; /* Disable host interrupts. */ @@ -2482,6 +2493,7 @@ static void ti_stop(sc) sc->ti_tx_saved_considx = TI_TXCONS_UNSET; ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + TI_UNLOCK(sc); return; } @@ -2496,8 +2508,9 @@ static void ti_shutdown(dev) struct ti_softc *sc; sc = device_get_softc(dev); - + TI_LOCK(sc); ti_chipinit(sc); + TI_UNLOCK(sc); return; } diff --git a/sys/dev/ti/if_tireg.h b/sys/dev/ti/if_tireg.h index 6346c67e3380..d64cc7a9c704 100644 --- a/sys/dev/ti/if_tireg.h +++ b/sys/dev/ti/if_tireg.h @@ -1148,8 +1148,12 @@ struct ti_softc { u_int32_t ti_tx_buf_ratio; int ti_if_flags; int ti_txcnt; + struct mtx ti_mtx; }; +#define TI_LOCK(_sc) mtx_enter(&(_sc)->ti_mtx, MTX_DEF) +#define TI_UNLOCK(_sc) mtx_exit(&(_sc)->ti_mtx, MTX_DEF) + /* * Microchip Technology 24Cxx EEPROM control bytes */ diff --git a/sys/dev/vr/if_vr.c b/sys/dev/vr/if_vr.c index 3649d7ede0c4..10b994232659 100644 --- a/sys/dev/vr/if_vr.c +++ b/sys/dev/vr/if_vr.c @@ -285,9 +285,9 @@ static int vr_mii_readreg(sc, frame) struct vr_mii_frame *frame; { - int i, ack, s; + int i, ack; - s = splimp(); + VR_LOCK(sc); /* * Set up frame for RX. @@ -364,7 +364,7 @@ static int vr_mii_readreg(sc, frame) SIO_SET(VR_MIICMD_CLK); DELAY(1); - splx(s); + VR_UNLOCK(sc); if (ack) return(1); @@ -379,9 +379,7 @@ static int vr_mii_writereg(sc, frame) struct vr_mii_frame *frame; { - int s; - - s = splimp(); + VR_LOCK(sc); CSR_WRITE_1(sc, VR_MIICMD, 0); VR_SETBIT(sc, VR_MIICMD, VR_MIICMD_DIRECTPGM); @@ -419,7 +417,7 @@ static int vr_mii_writereg(sc, frame) */ SIO_CLR(VR_MIICMD_DIR); - splx(s); + VR_UNLOCK(sc); return(0); } @@ -467,8 +465,10 @@ static void vr_miibus_statchg(dev) struct mii_data *mii; sc = device_get_softc(dev); + VR_LOCK(sc); mii = device_get_softc(sc->vr_miibus); vr_setcfg(sc, mii->mii_media_active); + VR_UNLOCK(sc); return; } @@ -633,15 +633,13 @@ static int vr_probe(dev) static int vr_attach(dev) device_t dev; { - int i, s; + int i; u_char eaddr[ETHER_ADDR_LEN]; u_int32_t command; struct vr_softc *sc; struct ifnet *ifp; int unit, error = 0, rid; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct vr_softc *)); @@ -731,6 +729,8 @@ static int vr_attach(dev) goto fail; } + mtx_init(&sc->vr_mtx, "vr", MTX_DEF); + VR_LOCK(sc); /* Reset the adapter. */ vr_reset(sc); @@ -803,9 +803,13 @@ static int vr_attach(dev) * Call MI attach routine. */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); + VR_UNLOCK(sc); + return(0); fail: - splx(s); + VR_UNLOCK(sc); + mtx_destroy(&sc->vr_mtx); + return(error); } @@ -814,11 +818,9 @@ static int vr_detach(dev) { struct vr_softc *sc; struct ifnet *ifp; - int s; - - s = splimp(); sc = device_get_softc(dev); + VR_LOCK(sc); ifp = &sc->arpcom.ac_if; vr_stop(sc); @@ -833,7 +835,8 @@ static int vr_detach(dev) contigfree(sc->vr_ldata, sizeof(struct vr_list_data), M_DEVBUF); - splx(s); + VR_UNLOCK(sc); + mtx_destroy(&sc->vr_mtx); return(0); } @@ -1146,17 +1149,15 @@ static void vr_tick(xsc) { struct vr_softc *sc; struct mii_data *mii; - int s; - - s = splimp(); sc = xsc; + VR_LOCK(sc); mii = device_get_softc(sc->vr_miibus); mii_tick(mii); sc->vr_stat_ch = timeout(vr_tick, sc, hz); - splx(s); + VR_UNLOCK(sc); return; } @@ -1169,11 +1170,13 @@ static void vr_intr(arg) u_int16_t status; sc = arg; + VR_LOCK(sc); ifp = &sc->arpcom.ac_if; /* Supress unwanted interrupts. */ if (!(ifp->if_flags & IFF_UP)) { vr_stop(sc); + VR_UNLOCK(sc); return; } @@ -1226,6 +1229,8 @@ static void vr_intr(arg) vr_start(ifp); } + VR_UNLOCK(sc); + return; } @@ -1314,8 +1319,11 @@ static void vr_start(ifp) sc = ifp->if_softc; - if (ifp->if_flags & IFF_OACTIVE) + VR_LOCK(sc); + if (ifp->if_flags & IFF_OACTIVE) { + VR_UNLOCK(sc); return; + } /* * Check for an available queue slot. If there are none, @@ -1357,8 +1365,10 @@ static void vr_start(ifp) /* * If there are no frames queued, bail. */ - if (cur_tx == NULL) + if (cur_tx == NULL) { + VR_UNLOCK(sc); return; + } sc->vr_cdata.vr_tx_tail = cur_tx; @@ -1369,6 +1379,7 @@ static void vr_start(ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; + VR_UNLOCK(sc); return; } @@ -1379,9 +1390,8 @@ static void vr_init(xsc) struct vr_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; struct mii_data *mii; - int s; - s = splimp(); + VR_LOCK(sc); mii = device_get_softc(sc->vr_miibus); @@ -1402,7 +1412,7 @@ static void vr_init(xsc) printf("vr%d: initialization failed: no " "memory for rx buffers\n", sc->vr_unit); vr_stop(sc); - (void)splx(s); + VR_UNLOCK(sc); return; } @@ -1451,10 +1461,10 @@ static void vr_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); - sc->vr_stat_ch = timeout(vr_tick, sc, hz); + VR_UNLOCK(sc); + return; } @@ -1501,9 +1511,9 @@ static int vr_ioctl(ifp, command, data) struct vr_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; - int s, error = 0; + int error = 0; - s = splimp(); + VR_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -1535,7 +1545,7 @@ static int vr_ioctl(ifp, command, data) break; } - (void)splx(s); + VR_UNLOCK(sc); return(error); } @@ -1547,6 +1557,7 @@ static void vr_watchdog(ifp) sc = ifp->if_softc; + VR_LOCK(sc); ifp->if_oerrors++; printf("vr%d: watchdog timeout\n", sc->vr_unit); @@ -1557,6 +1568,8 @@ static void vr_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) vr_start(ifp); + VR_UNLOCK(sc); + return; } @@ -1570,6 +1583,8 @@ static void vr_stop(sc) register int i; struct ifnet *ifp; + VR_LOCK(sc); + ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; @@ -1607,6 +1622,7 @@ static void vr_stop(sc) sizeof(sc->vr_ldata->vr_tx_list)); ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + VR_UNLOCK(sc); return; } diff --git a/sys/dev/vr/if_vrreg.h b/sys/dev/vr/if_vrreg.h index 2f2ac97ed3ff..8217a8c7596a 100644 --- a/sys/dev/vr/if_vrreg.h +++ b/sys/dev/vr/if_vrreg.h @@ -411,8 +411,12 @@ struct vr_softc { struct vr_list_data *vr_ldata; struct vr_chain_data vr_cdata; struct callout_handle vr_stat_ch; + struct mtx vr_mtx; }; +#define VR_LOCK(_sc) mtx_enter(&(_sc)->vr_mtx, MTX_DEF) +#define VR_UNLOCK(_sc) mtx_exit(&(_sc)->vr_mtx, MTX_DEF) + /* * register space access macros */ diff --git a/sys/pci/if_dc.c b/sys/pci/if_dc.c index 695b019fec29..f7c97a1bf240 100644 --- a/sys/pci/if_dc.c +++ b/sys/pci/if_dc.c @@ -109,6 +109,7 @@ #include #include #include +#include #include #include @@ -555,9 +556,9 @@ static int dc_mii_readreg(sc, frame) struct dc_mii_frame *frame; { - int i, ack, s; + int i, ack; - s = splimp(); + DC_LOCK(sc); /* * Set up frame for RX. @@ -612,7 +613,7 @@ static int dc_mii_readreg(sc, frame) dc_mii_writebit(sc, 0); dc_mii_writebit(sc, 0); - splx(s); + DC_UNLOCK(sc); if (ack) return(1); @@ -627,9 +628,7 @@ static int dc_mii_writereg(sc, frame) struct dc_mii_frame *frame; { - int s; - - s = splimp(); + DC_LOCK(sc); /* * Set up frame for TX. */ @@ -654,7 +653,7 @@ static int dc_mii_writereg(sc, frame) dc_mii_writebit(sc, 0); dc_mii_writebit(sc, 0); - splx(s); + DC_UNLOCK(sc); return(0); } @@ -1626,7 +1625,7 @@ static void dc_parse_21143_srom(sc) static int dc_attach(dev) device_t dev; { - int s, tmp = 0; + int tmp = 0; u_char eaddr[ETHER_ADDR_LEN]; u_int32_t command; struct dc_softc *sc; @@ -1634,8 +1633,6 @@ static int dc_attach(dev) u_int32_t revision; int unit, error = 0, rid, mac_offset; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct dc_softc)); @@ -1701,7 +1698,9 @@ static int dc_attach(dev) printf("dc%d: couldn't set up irq\n", unit); goto fail; } - + + mtx_init(&sc->dc_mtx, "dc", MTX_DEF); + DC_LOCK(sc); /* Need this info to decide on a chip type. */ sc->dc_info = dc_devtype(dev); revision = pci_read_config(dev, DC_PCI_CFRV, 4) & 0x000000FF; @@ -1966,10 +1965,12 @@ static int dc_attach(dev) } #endif + DC_UNLOCK(sc); + return(0); fail: - splx(s); - + DC_UNLOCK(sc); + mtx_destroy(&sc->dc_mtx); return(error); } @@ -1978,12 +1979,12 @@ static int dc_detach(dev) { struct dc_softc *sc; struct ifnet *ifp; - int s; struct dc_mediainfo *m; - s = splimp(); - sc = device_get_softc(dev); + + DC_LOCK(sc); + ifp = &sc->arpcom.ac_if; dc_stop(sc); @@ -2006,7 +2007,8 @@ static int dc_detach(dev) sc->dc_mi = m; } - splx(s); + DC_UNLOCK(sc); + mtx_destroy(&sc->dc_mtx); return(0); } @@ -2457,12 +2459,10 @@ static void dc_tick(xsc) struct dc_softc *sc; struct mii_data *mii; struct ifnet *ifp; - int s; u_int32_t r; - s = splimp(); - sc = xsc; + DC_LOCK(sc); ifp = &sc->arpcom.ac_if; mii = device_get_softc(sc->dc_miibus); @@ -2526,7 +2526,7 @@ static void dc_tick(xsc) else sc->dc_stat_ch = timeout(dc_tick, sc, hz); - splx(s); + DC_UNLOCK(sc); return; } @@ -2539,12 +2539,14 @@ static void dc_intr(arg) u_int32_t status; sc = arg; + DC_LOCK(sc); ifp = &sc->arpcom.ac_if; /* Supress unwanted interrupts */ if (!(ifp->if_flags & IFF_UP)) { if (CSR_READ_4(sc, DC_ISR) & DC_INTRS) dc_stop(sc); + DC_UNLOCK(sc); return; } @@ -2621,6 +2623,8 @@ static void dc_intr(arg) if (ifp->if_snd.ifq_head != NULL) dc_start(ifp); + DC_UNLOCK(sc); + return; } @@ -2737,11 +2741,17 @@ static void dc_start(ifp) sc = ifp->if_softc; - if (!sc->dc_link) - return; + DC_LOCK(sc); - if (ifp->if_flags & IFF_OACTIVE) + if (!sc->dc_link) { + DC_UNLOCK(sc); return; + } + + if (ifp->if_flags & IFF_OACTIVE) { + DC_UNLOCK(sc); + return; + } idx = sc->dc_cdata.dc_tx_prod; @@ -2787,6 +2797,8 @@ static void dc_start(ifp) */ ifp->if_timer = 5; + DC_UNLOCK(sc); + return; } @@ -2796,9 +2808,8 @@ static void dc_init(xsc) struct dc_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; struct mii_data *mii; - int s; - s = splimp(); + DC_LOCK(sc); mii = device_get_softc(sc->dc_miibus); @@ -2876,7 +2887,7 @@ static void dc_init(xsc) printf("dc%d: initialization failed: no " "memory for rx buffers\n", sc->dc_unit); dc_stop(sc); - (void)splx(s); + DC_UNLOCK(sc); return; } @@ -2929,8 +2940,6 @@ static void dc_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); - /* Don't start the ticker if this is a homePNA link. */ if (IFM_SUBTYPE(mii->mii_media.ifm_media) == IFM_homePNA) sc->dc_link = 1; @@ -2950,6 +2959,7 @@ static void dc_init(xsc) sc->dc_srm_media = 0; } #endif + DC_UNLOCK(sc); return; } @@ -3013,9 +3023,9 @@ static int dc_ioctl(ifp, command, data) struct dc_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; - int s, error = 0; + int error = 0; - s = splimp(); + DC_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -3063,7 +3073,7 @@ static int dc_ioctl(ifp, command, data) break; } - (void)splx(s); + DC_UNLOCK(sc); return(error); } @@ -3075,6 +3085,8 @@ static void dc_watchdog(ifp) sc = ifp->if_softc; + DC_LOCK(sc); + ifp->if_oerrors++; printf("dc%d: watchdog timeout\n", sc->dc_unit); @@ -3085,6 +3097,8 @@ static void dc_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) dc_start(ifp); + DC_UNLOCK(sc); + return; } @@ -3098,6 +3112,8 @@ static void dc_stop(sc) register int i; struct ifnet *ifp; + DC_LOCK(sc); + ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; @@ -3141,6 +3157,8 @@ static void dc_stop(sc) ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + DC_UNLOCK(sc); + return; } diff --git a/sys/pci/if_dcreg.h b/sys/pci/if_dcreg.h index 9c6cfc41bf43..e72d8b45c2c0 100644 --- a/sys/pci/if_dcreg.h +++ b/sys/pci/if_dcreg.h @@ -676,8 +676,13 @@ struct dc_softc { #ifdef SRM_MEDIA int dc_srm_media; #endif + struct mtx dc_mtx; }; + +#define DC_LOCK(_sc) mtx_enter(&(_sc)->dc_mtx, MTX_DEF) +#define DC_UNLOCK(_sc) mtx_exit(&(_sc)->dc_mtx, MTX_DEF) + #define DC_TX_POLL 0x00000001 #define DC_TX_COALESCE 0x00000002 #define DC_TX_ADMTEK_WAR 0x00000004 diff --git a/sys/pci/if_pcn.c b/sys/pci/if_pcn.c index 49241bd0ffc3..9accefb02302 100644 --- a/sys/pci/if_pcn.c +++ b/sys/pci/if_pcn.c @@ -398,12 +398,16 @@ static int pcn_probe(dev) } sc->pcn_btag = rman_get_bustag(sc->pcn_res); sc->pcn_bhandle = rman_get_bushandle(sc->pcn_res); + mtx_init(&sc->pcn_mtx, "pcn", MTX_DEF); + PCN_LOCK(sc); pcn_reset(sc); chip_id = pcn_csr_read(sc, PCN_CSR_CHIPID1); chip_id <<= 16; chip_id |= pcn_csr_read(sc, PCN_CSR_CHIPID0); bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res); + PCN_UNLOCK(sc); + mtx_destroy(&sc->pcn_mtx); chip_id >>= 12; sc->pcn_type = chip_id & PART_MASK; switch(sc->pcn_type) { @@ -434,15 +438,12 @@ static int pcn_probe(dev) static int pcn_attach(dev) device_t dev; { - int s; u_int32_t eaddr[2]; u_int32_t command; struct pcn_softc *sc; struct ifnet *ifp; int unit, error = 0, rid; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); @@ -532,6 +533,10 @@ static int pcn_attach(dev) goto fail; } + /* Initialize our mutex. */ + mtx_init(&sc->pcn_mtx, "pcn", MTX_DEF); + PCN_LOCK(sc); + /* Reset the adapter. */ pcn_reset(sc); @@ -596,9 +601,13 @@ static int pcn_attach(dev) */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); callout_handle_init(&sc->pcn_stat_ch); + PCN_UNLOCK(sc); + return(0); fail: - splx(s); + PCN_UNLOCK(sc); + mtx_destroy(&sc->pcn_mtx); + return(error); } @@ -607,13 +616,12 @@ static int pcn_detach(dev) { struct pcn_softc *sc; struct ifnet *ifp; - int s; - - s = splimp(); sc = device_get_softc(dev); ifp = &sc->arpcom.ac_if; + PCN_LOCK(sc); + pcn_reset(sc); pcn_stop(sc); ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); @@ -628,8 +636,9 @@ static int pcn_detach(dev) bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res); contigfree(sc->pcn_ldata, sizeof(struct pcn_list_data), M_DEVBUF); + PCN_UNLOCK(sc); - splx(s); + mtx_destroy(&sc->pcn_mtx); return(0); } @@ -860,12 +869,10 @@ static void pcn_tick(xsc) struct pcn_softc *sc; struct mii_data *mii; struct ifnet *ifp; - int s; - - s = splimp(); sc = xsc; ifp = &sc->arpcom.ac_if; + PCN_LOCK(sc); mii = device_get_softc(sc->pcn_miibus); mii_tick(mii); @@ -884,7 +891,7 @@ static void pcn_tick(xsc) sc->pcn_stat_ch = timeout(pcn_tick, sc, hz); - splx(s); + PCN_UNLOCK(sc); return; } @@ -996,13 +1003,19 @@ static void pcn_start(ifp) sc = ifp->if_softc; - if (!sc->pcn_link) + PCN_LOCK(sc); + + if (!sc->pcn_link) { + PCN_UNLOCK(sc); return; + } idx = sc->pcn_cdata.pcn_tx_prod; - if (ifp->if_flags & IFF_OACTIVE) + if (ifp->if_flags & IFF_OACTIVE) { + PCN_UNLOCK(sc); return; + } while(sc->pcn_cdata.pcn_tx_chain[idx] == NULL) { IF_DEQUEUE(&ifp->if_snd, m_head); @@ -1033,6 +1046,8 @@ static void pcn_start(ifp) */ ifp->if_timer = 5; + PCN_UNLOCK(sc); + return; } @@ -1042,9 +1057,8 @@ static void pcn_init(xsc) struct pcn_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; struct mii_data *mii = NULL; - int s; - s = splimp(); + PCN_LOCK(sc); /* * Cancel pending I/O and free all RX/TX buffers. @@ -1067,7 +1081,7 @@ static void pcn_init(xsc) printf("pcn%d: initialization failed: no " "memory for rx buffers\n", sc->pcn_unit); pcn_stop(sc); - (void)splx(s); + PCN_UNLOCK(sc); return; } @@ -1149,8 +1163,8 @@ static void pcn_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); sc->pcn_stat_ch = timeout(pcn_tick, sc, hz); + PCN_UNLOCK(sc); return; } @@ -1207,9 +1221,9 @@ static int pcn_ioctl(ifp, command, data) struct pcn_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii = NULL; - int s, error = 0; + int error = 0; - s = splimp(); + PCN_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -1265,7 +1279,7 @@ static int pcn_ioctl(ifp, command, data) break; } - (void)splx(s); + PCN_UNLOCK(sc); return(error); } @@ -1277,6 +1291,8 @@ static void pcn_watchdog(ifp) sc = ifp->if_softc; + PCN_LOCK(sc); + ifp->if_oerrors++; printf("pcn%d: watchdog timeout\n", sc->pcn_unit); @@ -1287,6 +1303,8 @@ static void pcn_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) pcn_start(ifp); + PCN_UNLOCK(sc); + return; } @@ -1301,6 +1319,7 @@ static void pcn_stop(sc) struct ifnet *ifp; ifp = &sc->arpcom.ac_if; + PCN_LOCK(sc); ifp->if_timer = 0; untimeout(pcn_tick, sc, sc->pcn_stat_ch); @@ -1333,6 +1352,7 @@ static void pcn_stop(sc) sizeof(sc->pcn_ldata->pcn_tx_list)); ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + PCN_UNLOCK(sc); return; } @@ -1348,8 +1368,10 @@ static void pcn_shutdown(dev) sc = device_get_softc(dev); + PCN_LOCK(sc); pcn_reset(sc); pcn_stop(sc); + PCN_UNLOCK(sc); return; } diff --git a/sys/pci/if_pcnreg.h b/sys/pci/if_pcnreg.h index 0ae5cf35e950..026c0ea93009 100644 --- a/sys/pci/if_pcnreg.h +++ b/sys/pci/if_pcnreg.h @@ -448,8 +448,12 @@ struct pcn_softc { struct pcn_list_data *pcn_ldata; struct pcn_ring_data pcn_cdata; struct callout_handle pcn_stat_ch; + struct mtx pcn_mtx; }; +#define PCN_LOCK(_sc) mtx_enter(&(_sc)->pcn_mtx, MTX_DEF) +#define PCN_UNLOCK(_sc) mtx_exit(&(_sc)->pcn_mtx, MTX_DEF) + /* * register space access macros */ diff --git a/sys/pci/if_rl.c b/sys/pci/if_rl.c index 78b80a2cf823..010f612e246f 100644 --- a/sys/pci/if_rl.c +++ b/sys/pci/if_rl.c @@ -401,9 +401,9 @@ static int rl_mii_readreg(sc, frame) struct rl_mii_frame *frame; { - int i, ack, s; + int i, ack; - s = splimp(); + RL_LOCK(sc); /* * Set up frame for RX. @@ -479,7 +479,7 @@ static int rl_mii_readreg(sc, frame) MII_SET(RL_MII_CLK); DELAY(1); - splx(s); + RL_UNLOCK(sc); if (ack) return(1); @@ -494,9 +494,8 @@ static int rl_mii_writereg(sc, frame) struct rl_mii_frame *frame; { - int s; + RL_LOCK(sc); - s = splimp(); /* * Set up frame for TX. */ @@ -530,7 +529,7 @@ static int rl_mii_writereg(sc, frame) */ MII_CLR(RL_MII_DIR); - splx(s); + RL_UNLOCK(sc); return(0); } @@ -545,11 +544,14 @@ static int rl_miibus_readreg(dev, phy, reg) u_int16_t rl8139_reg = 0; sc = device_get_softc(dev); + RL_LOCK(sc); if (sc->rl_type == RL_8139) { /* Pretend the internal PHY is only at address 0 */ - if (phy) + if (phy) { + RL_UNLOCK(sc); return(0); + } switch(reg) { case MII_BMCR: rl8139_reg = RL_BMCR; @@ -568,13 +570,16 @@ static int rl_miibus_readreg(dev, phy, reg) break; case MII_PHYIDR1: case MII_PHYIDR2: + RL_UNLOCK(sc); return(0); break; default: printf("rl%d: bad phy register\n", sc->rl_unit); + RL_UNLOCK(sc); return(0); } rval = CSR_READ_2(sc, rl8139_reg); + RL_UNLOCK(sc); return(rval); } @@ -583,6 +588,7 @@ static int rl_miibus_readreg(dev, phy, reg) frame.mii_phyaddr = phy; frame.mii_regaddr = reg; rl_mii_readreg(sc, &frame); + RL_UNLOCK(sc); return(frame.mii_data); } @@ -596,11 +602,14 @@ static int rl_miibus_writereg(dev, phy, reg, data) u_int16_t rl8139_reg = 0; sc = device_get_softc(dev); + RL_LOCK(sc); if (sc->rl_type == RL_8139) { /* Pretend the internal PHY is only at address 0 */ - if (phy) + if (phy) { + RL_UNLOCK(sc); return(0); + } switch(reg) { case MII_BMCR: rl8139_reg = RL_BMCR; @@ -619,13 +628,16 @@ static int rl_miibus_writereg(dev, phy, reg, data) break; case MII_PHYIDR1: case MII_PHYIDR2: + RL_UNLOCK(sc); return(0); break; default: printf("rl%d: bad phy register\n", sc->rl_unit); + RL_UNLOCK(sc); return(0); } CSR_WRITE_2(sc, rl8139_reg, data); + RL_UNLOCK(sc); return(0); } @@ -637,6 +649,7 @@ static int rl_miibus_writereg(dev, phy, reg, data) rl_mii_writereg(sc, &frame); + RL_UNLOCK(sc); return(0); } @@ -776,7 +789,6 @@ static int rl_probe(dev) static int rl_attach(dev) device_t dev; { - int s; u_char eaddr[ETHER_ADDR_LEN]; u_int32_t command; struct rl_softc *sc; @@ -784,8 +796,6 @@ static int rl_attach(dev) u_int16_t rl_did = 0; int unit, error = 0, rid; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct rl_softc)); @@ -877,6 +887,9 @@ static int rl_attach(dev) callout_handle_init(&sc->rl_stat_ch); + mtx_init(&sc->rl_mtx, "rl", MTX_DEF); + RL_LOCK(sc); + /* Reset the adapter. */ rl_reset(sc); @@ -959,9 +972,12 @@ static int rl_attach(dev) * Call MI attach routine. */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); + RL_UNLOCK(sc); + return(0); fail: - splx(s); + RL_UNLOCK(sc); + mtx_destroy(&sc->rl_mtx); return(error); } @@ -970,11 +986,9 @@ static int rl_detach(dev) { struct rl_softc *sc; struct ifnet *ifp; - int s; - - s = splimp(); sc = device_get_softc(dev); + RL_LOCK(sc); ifp = &sc->arpcom.ac_if; ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); @@ -989,7 +1003,8 @@ static int rl_detach(dev) contigfree(sc->rl_cdata.rl_rx_buf, RL_RXBUFLEN + 32, M_DEVBUF); - splx(s); + RL_UNLOCK(sc); + mtx_destroy(&sc->rl_mtx); return(0); } @@ -1231,18 +1246,15 @@ static void rl_tick(xsc) { struct rl_softc *sc; struct mii_data *mii; - int s; - - s = splimp(); sc = xsc; + RL_LOCK(sc); mii = device_get_softc(sc->rl_miibus); mii_tick(mii); - splx(s); - sc->rl_stat_ch = timeout(rl_tick, sc, hz); + RL_UNLOCK(sc); return; } @@ -1255,6 +1267,7 @@ static void rl_intr(arg) u_int16_t status; sc = arg; + RL_LOCK(sc); ifp = &sc->arpcom.ac_if; /* Disable interrupts. */ @@ -1291,6 +1304,8 @@ static void rl_intr(arg) if (ifp->if_snd.ifq_head != NULL) rl_start(ifp); + RL_UNLOCK(sc); + return; } @@ -1360,6 +1375,7 @@ static void rl_start(ifp) struct mbuf *m_head = NULL; sc = ifp->if_softc; + RL_LOCK(sc); while(RL_CUR_TXMBUF(sc) == NULL) { IF_DEQUEUE(&ifp->if_snd, m_head); @@ -1403,6 +1419,7 @@ static void rl_start(ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; + RL_UNLOCK(sc); return; } @@ -1413,11 +1430,10 @@ static void rl_init(xsc) struct rl_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; struct mii_data *mii; - int s, i; + int i; u_int32_t rxcfg = 0; - s = splimp(); - + RL_LOCK(sc); mii = device_get_softc(sc->rl_miibus); /* @@ -1497,9 +1513,8 @@ static void rl_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); - sc->rl_stat_ch = timeout(rl_tick, sc, hz); + RL_UNLOCK(sc); return; } @@ -1548,9 +1563,9 @@ static int rl_ioctl(ifp, command, data) struct rl_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; - int s, error = 0; + int error = 0; - s = splimp(); + RL_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -1582,7 +1597,7 @@ static int rl_ioctl(ifp, command, data) break; } - (void)splx(s); + RL_UNLOCK(sc); return(error); } @@ -1593,13 +1608,14 @@ static void rl_watchdog(ifp) struct rl_softc *sc; sc = ifp->if_softc; - + RL_LOCK(sc); printf("rl%d: watchdog timeout\n", sc->rl_unit); ifp->if_oerrors++; rl_txeof(sc); rl_rxeof(sc); rl_init(sc); + RL_UNLOCK(sc); return; } @@ -1614,6 +1630,7 @@ static void rl_stop(sc) register int i; struct ifnet *ifp; + RL_LOCK(sc); ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; @@ -1634,7 +1651,7 @@ static void rl_stop(sc) } ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); - + RL_UNLOCK(sc); return; } diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h index 0bb9ffcc48cb..2f087688e2c5 100644 --- a/sys/pci/if_rlreg.h +++ b/sys/pci/if_rlreg.h @@ -368,8 +368,12 @@ struct rl_softc { int rl_txthresh; struct rl_chain_data rl_cdata; struct callout_handle rl_stat_ch; + struct mtx rl_mtx; }; +#define RL_LOCK(_sc) mtx_enter(&(_sc)->rl_mtx, MTX_DEF) +#define RL_UNLOCK(_sc) mtx_exit(&(_sc)->rl_mtx, MTX_DEF) + /* * register space access macros */ diff --git a/sys/pci/if_sf.c b/sys/pci/if_sf.c index 52c6f8854f1f..a7d14522004e 100644 --- a/sys/pci/if_sf.c +++ b/sys/pci/if_sf.c @@ -531,9 +531,9 @@ static int sf_ioctl(ifp, command, data) struct sf_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; - int s, error = 0; + int error = 0; - s = splimp(); + SF_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -575,7 +575,7 @@ static int sf_ioctl(ifp, command, data) break; } - (void)splx(s); + SF_UNLOCK(sc); return(error); } @@ -670,14 +670,12 @@ static int sf_probe(dev) static int sf_attach(dev) device_t dev; { - int s, i; + int i; u_int32_t command; struct sf_softc *sc; struct ifnet *ifp; int unit, rid, error = 0; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct sf_softc)); @@ -768,7 +766,8 @@ static int sf_attach(dev) } callout_handle_init(&sc->sf_stat_ch); - + mtx_init(&sc->sf_mtx, "sf", MTX_DEF); + SF_LOCK(sc); /* Reset the adapter. */ sf_reset(sc); @@ -832,9 +831,12 @@ static int sf_attach(dev) * Call MI attach routine. */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); + SF_UNLOCK(sc); + return(0); fail: - splx(s); + SF_UNLOCK(sc); + mtx_destroy(&sc->sf_mtx); return(error); } @@ -843,11 +845,9 @@ static int sf_detach(dev) { struct sf_softc *sc; struct ifnet *ifp; - int s; - - s = splimp(); sc = device_get_softc(dev); + SF_LOCK(sc); ifp = &sc->arpcom.ac_if; ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); @@ -862,7 +862,8 @@ static int sf_detach(dev) contigfree(sc->sf_ldata, sizeof(struct sf_list_data), M_DEVBUF); - splx(s); + SF_UNLOCK(sc); + mtx_destroy(&sc->sf_mtx); return(0); } @@ -1086,10 +1087,14 @@ static void sf_intr(arg) u_int32_t status; sc = arg; + SF_LOCK(sc); + ifp = &sc->arpcom.ac_if; - if (!(csr_read_4(sc, SF_ISR_SHADOW) & SF_ISR_PCIINT_ASSERTED)) + if (!(csr_read_4(sc, SF_ISR_SHADOW) & SF_ISR_PCIINT_ASSERTED)) { + SF_UNLOCK(sc); return; + } /* Disable interrupts. */ csr_write_4(sc, SF_IMR, 0x00000000); @@ -1124,6 +1129,7 @@ static void sf_intr(arg) if (ifp->if_snd.ifq_head != NULL) sf_start(ifp); + SF_UNLOCK(sc); return; } @@ -1133,11 +1139,10 @@ static void sf_init(xsc) struct sf_softc *sc; struct ifnet *ifp; struct mii_data *mii; - int i, s; - - s = splimp(); + int i; sc = xsc; + SF_LOCK(sc); ifp = &sc->arpcom.ac_if; mii = device_get_softc(sc->sf_miibus); @@ -1162,7 +1167,7 @@ static void sf_init(xsc) if (sf_init_rx_ring(sc) == ENOBUFS) { printf("sf%d: initialization failed: no " "memory for rx buffers\n", sc->sf_unit); - (void)splx(s); + SF_UNLOCK(sc); return; } @@ -1237,7 +1242,7 @@ static void sf_init(xsc) sc->sf_stat_ch = timeout(sf_stats_update, sc, hz); - splx(s); + SF_UNLOCK(sc); return; } @@ -1314,12 +1319,17 @@ static void sf_start(ifp) int i, txprod; sc = ifp->if_softc; + SF_LOCK(sc); - if (!sc->sf_link) + if (!sc->sf_link) { + SF_UNLOCK(sc); return; + } - if (ifp->if_flags & IFF_OACTIVE) + if (ifp->if_flags & IFF_OACTIVE) { + SF_UNLOCK(sc); return; + } txprod = csr_read_4(sc, SF_TXDQ_PRODIDX); i = SF_IDX_HI(txprod) >> 4; @@ -1345,8 +1355,10 @@ static void sf_start(ifp) break; } - if (cur_tx == NULL) + if (cur_tx == NULL) { + SF_UNLOCK(sc); return; + } /* Transmit */ csr_write_4(sc, SF_TXDQ_PRODIDX, @@ -1355,6 +1367,8 @@ static void sf_start(ifp) ifp->if_timer = 5; + SF_UNLOCK(sc); + return; } @@ -1364,6 +1378,8 @@ static void sf_stop(sc) int i; struct ifnet *ifp; + SF_LOCK(sc); + ifp = &sc->arpcom.ac_if; untimeout(sf_stats_update, sc, sc->sf_stat_ch); @@ -1396,6 +1412,7 @@ static void sf_stop(sc) } ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); + SF_UNLOCK(sc); return; } @@ -1415,11 +1432,10 @@ static void sf_stats_update(xsc) struct mii_data *mii; struct sf_stats stats; u_int32_t *ptr; - int i, s; - - s = splimp(); + int i; sc = xsc; + SF_LOCK(sc); ifp = &sc->arpcom.ac_if; mii = device_get_softc(sc->sf_miibus); @@ -1447,7 +1463,7 @@ static void sf_stats_update(xsc) sc->sf_stat_ch = timeout(sf_stats_update, sc, hz); - splx(s); + SF_UNLOCK(sc); return; } @@ -1459,6 +1475,8 @@ static void sf_watchdog(ifp) sc = ifp->if_softc; + SF_LOCK(sc); + ifp->if_oerrors++; printf("sf%d: watchdog timeout\n", sc->sf_unit); @@ -1469,6 +1487,8 @@ static void sf_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) sf_start(ifp); + SF_UNLOCK(sc); + return; } diff --git a/sys/pci/if_sfreg.h b/sys/pci/if_sfreg.h index 49fdd5ae1afc..c2dc20e73c6d 100644 --- a/sys/pci/if_sfreg.h +++ b/sys/pci/if_sfreg.h @@ -1044,8 +1044,13 @@ struct sf_softc { u_int8_t sf_link; int sf_if_flags; struct callout_handle sf_stat_ch; + struct mtx sf_mtx; }; + +#define SF_LOCK(_sc) mtx_enter(&(_sc)->sf_mtx, MTX_DEF) +#define SF_UNLOCK(_sc) mtx_exit(&(_sc)->sf_mtx, MTX_DEF) + #define SF_TIMEOUT 1000 #ifdef __alpha__ diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c index cee8639c796d..cca772c15435 100644 --- a/sys/pci/if_sis.c +++ b/sys/pci/if_sis.c @@ -629,15 +629,12 @@ static int sis_probe(dev) static int sis_attach(dev) device_t dev; { - int s; u_char eaddr[ETHER_ADDR_LEN]; u_int32_t command; struct sis_softc *sc; struct ifnet *ifp; int unit, error = 0, rid; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct sis_softc)); @@ -735,6 +732,9 @@ static int sis_attach(dev) goto fail; } + mtx_init(&sc->sis_mtx, "sis", MTX_DEF); + SIS_LOCK(sc); + /* Reset the adapter. */ sis_reset(sc); @@ -837,9 +837,12 @@ static int sis_attach(dev) */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); callout_handle_init(&sc->sis_stat_ch); + SIS_UNLOCK(sc); + return(0); fail: - splx(s); + SIS_UNLOCK(sc); + mtx_destroy(&sc->sis_mtx); return(error); } @@ -848,11 +851,10 @@ static int sis_detach(dev) { struct sis_softc *sc; struct ifnet *ifp; - int s; - s = splimp(); sc = device_get_softc(dev); + SIS_LOCK(sc); ifp = &sc->arpcom.ac_if; sis_reset(sc); @@ -868,7 +870,8 @@ static int sis_detach(dev) contigfree(sc->sis_ldata, sizeof(struct sis_list_data), M_DEVBUF); - splx(s); + SIS_UNLOCK(sc); + mtx_destroy(&sc->sis_mtx); return(0); } @@ -1129,11 +1132,9 @@ static void sis_tick(xsc) struct sis_softc *sc; struct mii_data *mii; struct ifnet *ifp; - int s; - - s = splimp(); sc = xsc; + SIS_LOCK(sc); ifp = &sc->arpcom.ac_if; mii = device_get_softc(sc->sis_miibus); @@ -1150,7 +1151,7 @@ static void sis_tick(xsc) sc->sis_stat_ch = timeout(sis_tick, sc, hz); - splx(s); + SIS_UNLOCK(sc); return; } @@ -1163,11 +1164,13 @@ static void sis_intr(arg) u_int32_t status; sc = arg; + SIS_LOCK(sc); ifp = &sc->arpcom.ac_if; /* Supress unwanted interrupts */ if (!(ifp->if_flags & IFF_UP)) { sis_stop(sc); + SIS_UNLOCK(sc); return; } @@ -1208,6 +1211,8 @@ static void sis_intr(arg) if (ifp->if_snd.ifq_head != NULL) sis_start(ifp); + SIS_UNLOCK(sc); + return; } @@ -1275,14 +1280,19 @@ static void sis_start(ifp) u_int32_t idx; sc = ifp->if_softc; + SIS_LOCK(sc); - if (!sc->sis_link) + if (!sc->sis_link) { + SIS_UNLOCK(sc); return; + } idx = sc->sis_cdata.sis_tx_prod; - if (ifp->if_flags & IFF_OACTIVE) + if (ifp->if_flags & IFF_OACTIVE) { + SIS_UNLOCK(sc); return; + } while(sc->sis_ldata->sis_tx_list[idx].sis_mbuf == NULL) { IF_DEQUEUE(&ifp->if_snd, m_head); @@ -1313,6 +1323,8 @@ static void sis_start(ifp) */ ifp->if_timer = 5; + SIS_UNLOCK(sc); + return; } @@ -1322,9 +1334,8 @@ static void sis_init(xsc) struct sis_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; struct mii_data *mii; - int s; - s = splimp(); + SIS_LOCK(sc); /* * Cancel pending I/O and free all RX/TX buffers. @@ -1361,7 +1372,7 @@ static void sis_init(xsc) printf("sis%d: initialization failed: no " "memory for rx buffers\n", sc->sis_unit); sis_stop(sc); - (void)splx(s); + SIS_UNLOCK(sc); return; } @@ -1469,10 +1480,10 @@ static void sis_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); - sc->sis_stat_ch = timeout(sis_tick, sc, hz); + SIS_UNLOCK(sc); + return; } @@ -1528,9 +1539,9 @@ static int sis_ioctl(ifp, command, data) struct sis_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; - int s, error = 0; + int error = 0; - s = splimp(); + SIS_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -1565,7 +1576,7 @@ static int sis_ioctl(ifp, command, data) break; } - (void)splx(s); + SIS_UNLOCK(sc); return(error); } @@ -1577,6 +1588,8 @@ static void sis_watchdog(ifp) sc = ifp->if_softc; + SIS_LOCK(sc); + ifp->if_oerrors++; printf("sis%d: watchdog timeout\n", sc->sis_unit); @@ -1587,6 +1600,8 @@ static void sis_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) sis_start(ifp); + SIS_UNLOCK(sc); + return; } @@ -1600,6 +1615,7 @@ static void sis_stop(sc) register int i; struct ifnet *ifp; + SIS_LOCK(sc); ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; @@ -1640,6 +1656,8 @@ static void sis_stop(sc) ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + SIS_UNLOCK(sc); + return; } @@ -1653,9 +1671,10 @@ static void sis_shutdown(dev) struct sis_softc *sc; sc = device_get_softc(dev); - + SIS_LOCK(sc); sis_reset(sc); sis_stop(sc); + SIS_UNLOCK(sc); return; } diff --git a/sys/pci/if_sisreg.h b/sys/pci/if_sisreg.h index ee46c92b2b86..d1781b7a0429 100644 --- a/sys/pci/if_sisreg.h +++ b/sys/pci/if_sisreg.h @@ -389,8 +389,12 @@ struct sis_softc { struct sis_list_data *sis_ldata; struct sis_ring_data sis_cdata; struct callout_handle sis_stat_ch; + struct mtx sis_mtx; }; +#define SIS_LOCK(_sc) mtx_enter(&(_sc)->sis_mtx, MTX_DEF) +#define SIS_UNLOCK(_sc) mtx_exit(&(_sc)->sis_mtx, MTX_DEF) + /* * register space access macros */ diff --git a/sys/pci/if_sk.c b/sys/pci/if_sk.c index a83a606445c4..963f754672b4 100644 --- a/sys/pci/if_sk.c +++ b/sys/pci/if_sk.c @@ -413,6 +413,8 @@ static int sk_miibus_readreg(dev, phy, reg) if (sc_if->sk_phytype == SK_PHYTYPE_XMAC && phy != 0) return(0); + SK_IF_LOCK(sc_if); + SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8)); SK_XM_READ_2(sc_if, XM_PHY_DATA); if (sc_if->sk_phytype != SK_PHYTYPE_XMAC) { @@ -430,7 +432,9 @@ static int sk_miibus_readreg(dev, phy, reg) } } DELAY(1); - return(SK_XM_READ_2(sc_if, XM_PHY_DATA)); + i = SK_XM_READ_2(sc_if, XM_PHY_DATA); + SK_IF_UNLOCK(sc_if); + return(i); } static int sk_miibus_writereg(dev, phy, reg, val) @@ -441,6 +445,7 @@ static int sk_miibus_writereg(dev, phy, reg, val) int i; sc_if = device_get_softc(dev); + SK_IF_LOCK(sc_if); SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8)); for (i = 0; i < SK_TIMEOUT; i++) { @@ -460,6 +465,8 @@ static int sk_miibus_writereg(dev, phy, reg, val) break; } + SK_IF_UNLOCK(sc_if); + if (i == SK_TIMEOUT) printf("sk%d: phy write timed out\n", sc_if->sk_unit); @@ -474,7 +481,7 @@ static void sk_miibus_statchg(dev) sc_if = device_get_softc(dev); mii = device_get_softc(sc_if->sk_miibus); - + SK_IF_LOCK(sc_if); /* * If this is a GMII PHY, manually set the XMAC's * duplex mode accordingly. @@ -486,6 +493,7 @@ static void sk_miibus_statchg(dev) SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_GMIIFDX); } } + SK_IF_UNLOCK(sc_if); return; } @@ -872,10 +880,10 @@ static int sk_ioctl(ifp, command, data) { struct sk_if_softc *sc_if = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; - int s, error = 0; + int error = 0; struct mii_data *mii; - s = splimp(); + SK_IF_LOCK(sc_if); switch(command) { case SIOCSIFADDR: @@ -928,7 +936,7 @@ static int sk_ioctl(ifp, command, data) break; } - (void)splx(s); + SK_IF_UNLOCK(sc_if); return(error); } @@ -1025,6 +1033,7 @@ static int sk_attach_xmac(dev) sc_if = device_get_softc(dev); sc = device_get_softc(device_get_parent(dev)); + SK_LOCK(sc); port = *(int *)device_get_ivars(dev); free(device_get_ivars(dev), M_DEVBUF); device_set_ivars(dev, NULL); @@ -1113,6 +1122,7 @@ static int sk_attach_xmac(dev) if (sc_if->sk_rdata == NULL) { printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit); sc->sk_if[port] = NULL; + SK_UNLOCK(sc); return(ENOMEM); } @@ -1125,6 +1135,7 @@ static int sk_attach_xmac(dev) contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data), M_DEVBUF); sc->sk_if[port] = NULL; + SK_UNLOCK(sc); return(ENOMEM); } @@ -1151,6 +1162,7 @@ static int sk_attach_xmac(dev) printf("skc%d: no PHY found!\n", sc_if->sk_unit); contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data), M_DEVBUF); + SK_UNLOCK(sc); return(ENXIO); } @@ -1160,6 +1172,8 @@ static int sk_attach_xmac(dev) ether_ifattach(ifp, ETHER_BPF_SUPPORTED); callout_handle_init(&sc_if->sk_tick_ch); + SK_UNLOCK(sc); + return(0); } @@ -1170,13 +1184,10 @@ static int sk_attach_xmac(dev) static int sk_attach(dev) device_t dev; { - int s; u_int32_t command; struct sk_softc *sc; int unit, error = 0, rid, *port; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct sk_softc)); @@ -1266,6 +1277,8 @@ static int sk_attach(dev) goto fail; } + mtx_init(&sc->sk_mtx, "skc", MTX_DEF); + SK_LOCK(sc); /* Reset the adapter. */ sk_reset(sc); @@ -1345,9 +1358,12 @@ static int sk_attach(dev) CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON); bus_generic_attach(dev); + SK_UNLOCK(sc); + return(0); fail: - splx(s); + SK_UNLOCK(sc); + mtx_destroy(&sc->sk_mtx); return(error); } @@ -1357,12 +1373,11 @@ static int sk_detach_xmac(dev) struct sk_softc *sc; struct sk_if_softc *sc_if; struct ifnet *ifp; - int s; - - s = splimp(); sc = device_get_softc(device_get_parent(dev)); sc_if = device_get_softc(dev); + SK_IF_LOCK(sc_if); + ifp = &sc_if->arpcom.ac_if; sk_stop(sc_if); ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); @@ -1371,6 +1386,7 @@ static int sk_detach_xmac(dev) device_delete_child(dev, sc_if->sk_miibus); contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF); contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data), M_DEVBUF); + SK_IF_UNLOCK(sc_if); return(0); } @@ -1379,11 +1395,9 @@ static int sk_detach(dev) device_t dev; { struct sk_softc *sc; - int s; - - s = splimp(); sc = device_get_softc(dev); + SK_LOCK(sc); bus_generic_detach(dev); if (sc->sk_devs[SK_PORT_A] != NULL) @@ -1395,7 +1409,8 @@ static int sk_detach(dev) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq); bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res); - splx(s); + SK_UNLOCK(sc); + mtx_destroy(&sc->sk_mtx); return(0); } @@ -1460,6 +1475,8 @@ static void sk_start(ifp) sc_if = ifp->if_softc; sc = sc_if->sk_softc; + SK_IF_LOCK(sc_if); + idx = sc_if->sk_cdata.sk_tx_prod; while(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) { @@ -1492,6 +1509,7 @@ static void sk_start(ifp) /* Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; + SK_IF_UNLOCK(sc_if); return; } @@ -1516,6 +1534,7 @@ static void sk_shutdown(dev) struct sk_softc *sc; sc = device_get_softc(dev); + SK_LOCK(sc); /* Turn off the 'driver is loaded' LED. */ CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_OFF); @@ -1525,6 +1544,7 @@ static void sk_shutdown(dev) * assert the resets on the attached XMAC(s). */ sk_reset(sc); + SK_UNLOCK(sc); return; } @@ -1644,14 +1664,18 @@ static void sk_tick(xsc_if) int i; sc_if = xsc_if; + SK_IF_LOCK(sc_if); ifp = &sc_if->arpcom.ac_if; mii = device_get_softc(sc_if->sk_miibus); - if (!(ifp->if_flags & IFF_UP)) + if (!(ifp->if_flags & IFF_UP)) { + SK_IF_UNLOCK(sc_if); return; + } if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) { sk_intr_bcom(sc_if); + SK_IF_UNLOCK(sc_if); return; } @@ -1669,6 +1693,7 @@ static void sk_tick(xsc_if) if (i != 3) { sc_if->sk_tick_ch = timeout(sk_tick, sc_if, hz); + SK_IF_UNLOCK(sc_if); return; } @@ -1679,6 +1704,7 @@ static void sk_tick(xsc_if) mii_pollstat(mii); untimeout(sk_tick, sc_if, sc_if->sk_tick_ch); + SK_IF_UNLOCK(sc_if); return; } @@ -1785,6 +1811,8 @@ static void sk_intr(xsc) struct ifnet *ifp0 = NULL, *ifp1 = NULL; u_int32_t status; + SK_LOCK(sc); + sc_if0 = sc->sk_if[SK_PORT_A]; sc_if1 = sc->sk_if[SK_PORT_B]; @@ -1846,6 +1874,8 @@ static void sk_intr(xsc) if (ifp1 != NULL && ifp1->if_snd.ifq_head != NULL) sk_start(ifp1); + SK_UNLOCK(sc); + return; } @@ -2028,9 +2058,8 @@ static void sk_init(xsc) struct sk_softc *sc; struct ifnet *ifp; struct mii_data *mii; - int s; - s = splimp(); + SK_IF_LOCK(sc_if); ifp = &sc_if->arpcom.ac_if; sc = sc_if->sk_softc; @@ -2100,7 +2129,7 @@ static void sk_init(xsc) printf("sk%d: initialization failed: no " "memory for rx buffers\n", sc_if->sk_unit); sk_stop(sc_if); - (void)splx(s); + SK_IF_UNLOCK(sc_if); return; } sk_init_tx_ring(sc_if); @@ -2126,7 +2155,7 @@ static void sk_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - splx(s); + SK_IF_UNLOCK(sc_if); return; } @@ -2138,6 +2167,7 @@ static void sk_stop(sc_if) struct sk_softc *sc; struct ifnet *ifp; + SK_IF_LOCK(sc_if); sc = sc_if->sk_softc; ifp = &sc_if->arpcom.ac_if; @@ -2198,6 +2228,6 @@ static void sk_stop(sc_if) } ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); - + SK_IF_UNLOCK(sc_if); return; } diff --git a/sys/pci/if_skreg.h b/sys/pci/if_skreg.h index 92a26bea909d..6f31d1de0c47 100644 --- a/sys/pci/if_skreg.h +++ b/sys/pci/if_skreg.h @@ -1179,8 +1179,14 @@ struct sk_softc { u_int32_t sk_intrmask; struct sk_if_softc *sk_if[2]; device_t sk_devs[2]; + struct mtx sk_mtx; }; +#define SK_LOCK(_sc) mtx_enter(&(_sc)->sk_mtx, MTX_DEF) +#define SK_UNLOCK(_sc) mtx_exit(&(_sc)->sk_mtx, MTX_DEF) +#define SK_IF_LOCK(_sc) mtx_enter(&(_sc)->sk_softc->sk_mtx, MTX_DEF) +#define SK_IF_UNLOCK(_sc) mtx_exit(&(_sc)->sk_softc->sk_mtx, MTX_DEF) + /* Softc for each logical interface */ struct sk_if_softc { struct arpcom arpcom; /* interface info */ diff --git a/sys/pci/if_ti.c b/sys/pci/if_ti.c index f1cfee5dca8e..04ec29d99f65 100644 --- a/sys/pci/if_ti.c +++ b/sys/pci/if_ti.c @@ -1477,14 +1477,11 @@ static int ti_probe(dev) static int ti_attach(dev) device_t dev; { - int s; u_int32_t command; struct ifnet *ifp; struct ti_softc *sc; int unit, error = 0, rid; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct ti_softc)); @@ -1540,6 +1537,9 @@ static int ti_attach(dev) goto fail; } + mtx_init(&sc->ti_mtx, "ti", MTX_DEF); + TI_LOCK(sc); + sc->ti_unit = unit; if (ti_chipinit(sc)) { @@ -1689,10 +1689,12 @@ static int ti_attach(dev) * Call MI attach routine. */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); + TI_UNLOCK(sc); + return(0); fail: - splx(s); - + TI_UNLOCK(sc); + mtx_destroy(&sc->ti_mtx); return(error); } @@ -1701,11 +1703,10 @@ static int ti_detach(dev) { struct ti_softc *sc; struct ifnet *ifp; - int s; - s = splimp(); sc = device_get_softc(dev); + TI_LOCK(sc); ifp = &sc->arpcom.ac_if; ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); @@ -1719,7 +1720,8 @@ static int ti_detach(dev) contigfree(sc->ti_rdata, sizeof(struct ti_ring_data), M_DEVBUF); ifmedia_removeall(&sc->ifmedia); - splx(s); + TI_UNLOCK(sc); + mtx_destroy(&sc->ti_mtx); return(0); } @@ -1907,13 +1909,16 @@ static void ti_intr(xsc) struct ifnet *ifp; sc = xsc; + TI_LOCK(sc); ifp = &sc->arpcom.ac_if; #ifdef notdef /* Avoid this for now -- checking this register is expensive. */ /* Make sure this is really our interrupt. */ - if (!(CSR_READ_4(sc, TI_MISC_HOST_CTL) & TI_MHC_INTSTATE)) + if (!(CSR_READ_4(sc, TI_MISC_HOST_CTL) & TI_MHC_INTSTATE)) { + TI_UNLOCK(sc); return; + } #endif /* Ack interrupt and stop others from occuring. */ @@ -1935,6 +1940,8 @@ static void ti_intr(xsc) if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL) ti_start(ifp); + TI_UNLOCK(sc); + return; } @@ -2069,6 +2076,7 @@ static void ti_start(ifp) u_int32_t prodidx = 0; sc = ifp->if_softc; + TI_LOCK(sc); prodidx = CSR_READ_4(sc, TI_MB_SENDPROD_IDX); @@ -2121,6 +2129,7 @@ static void ti_start(ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; + TI_UNLOCK(sc); return; } @@ -2129,21 +2138,19 @@ static void ti_init(xsc) void *xsc; { struct ti_softc *sc = xsc; - int s; - - s = splimp(); /* Cancel pending I/O and flush buffers. */ ti_stop(sc); + TI_LOCK(sc); /* Init the gen info block, ring control blocks and firmware. */ if (ti_gibinit(sc)) { printf("ti%d: initialization failure\n", sc->ti_unit); - splx(s); + TI_UNLOCK(sc); return; } - splx(s); + TI_UNLOCK(sc); return; } @@ -2355,10 +2362,10 @@ static int ti_ioctl(ifp, command, data) { struct ti_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; - int s, error = 0; + int error = 0; struct ti_cmd_desc cmd; - s = splimp(); + TI_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -2419,7 +2426,7 @@ static int ti_ioctl(ifp, command, data) break; } - (void)splx(s); + TI_UNLOCK(sc); return(error); } @@ -2430,12 +2437,14 @@ static void ti_watchdog(ifp) struct ti_softc *sc; sc = ifp->if_softc; + TI_LOCK(sc); printf("ti%d: watchdog timeout -- resetting\n", sc->ti_unit); ti_stop(sc); ti_init(sc); ifp->if_oerrors++; + TI_UNLOCK(sc); return; } @@ -2450,6 +2459,8 @@ static void ti_stop(sc) struct ifnet *ifp; struct ti_cmd_desc cmd; + TI_LOCK(sc); + ifp = &sc->arpcom.ac_if; /* Disable host interrupts. */ @@ -2482,6 +2493,7 @@ static void ti_stop(sc) sc->ti_tx_saved_considx = TI_TXCONS_UNSET; ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + TI_UNLOCK(sc); return; } @@ -2496,8 +2508,9 @@ static void ti_shutdown(dev) struct ti_softc *sc; sc = device_get_softc(dev); - + TI_LOCK(sc); ti_chipinit(sc); + TI_UNLOCK(sc); return; } diff --git a/sys/pci/if_tireg.h b/sys/pci/if_tireg.h index 6346c67e3380..d64cc7a9c704 100644 --- a/sys/pci/if_tireg.h +++ b/sys/pci/if_tireg.h @@ -1148,8 +1148,12 @@ struct ti_softc { u_int32_t ti_tx_buf_ratio; int ti_if_flags; int ti_txcnt; + struct mtx ti_mtx; }; +#define TI_LOCK(_sc) mtx_enter(&(_sc)->ti_mtx, MTX_DEF) +#define TI_UNLOCK(_sc) mtx_exit(&(_sc)->ti_mtx, MTX_DEF) + /* * Microchip Technology 24Cxx EEPROM control bytes */ diff --git a/sys/pci/if_tl.c b/sys/pci/if_tl.c index a18ac22a63bf..0d5a286e164e 100644 --- a/sys/pci/if_tl.c +++ b/sys/pci/if_tl.c @@ -648,10 +648,10 @@ static int tl_mii_readreg(sc, frame) struct tl_mii_frame *frame; { - int i, ack, s; + int i, ack; int minten = 0; - s = splimp(); + TL_LOCK(sc); tl_mii_sync(sc); @@ -731,7 +731,7 @@ static int tl_mii_readreg(sc, frame) tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MINTEN); } - splx(s); + TL_UNLOCK(sc); if (ack) return(1); @@ -743,12 +743,12 @@ static int tl_mii_writereg(sc, frame) struct tl_mii_frame *frame; { - int s; int minten; + TL_LOCK(sc); + tl_mii_sync(sc); - s = splimp(); /* * Set up frame for TX. */ @@ -789,7 +789,7 @@ static int tl_mii_writereg(sc, frame) if (minten) tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MINTEN); - splx(s); + TL_UNLOCK(sc); return(0); } @@ -837,6 +837,7 @@ static void tl_miibus_statchg(dev) struct mii_data *mii; sc = device_get_softc(dev); + TL_LOCK(sc); mii = device_get_softc(sc->tl_miibus); if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) { @@ -844,6 +845,7 @@ static void tl_miibus_statchg(dev) } else { tl_dio_clrbit(sc, TL_NETCMD, TL_CMD_DUPLEX); } + TL_UNLOCK(sc); return; } @@ -1105,7 +1107,7 @@ static int tl_probe(dev) static int tl_attach(dev) device_t dev; { - int s, i; + int i; u_int32_t command; u_int16_t did, vid; struct tl_type *t; @@ -1113,8 +1115,6 @@ static int tl_attach(dev) struct tl_softc *sc; int unit, error = 0, rid; - s = splimp(); - vid = pci_get_vendor(dev); did = pci_get_device(dev); sc = device_get_softc(dev); @@ -1245,6 +1245,9 @@ static int tl_attach(dev) if (t->tl_vid == OLICOM_VENDORID) sc->tl_eeaddr = TL_EEPROM_EADDR_OC; + mtx_init(&sc->tl_mtx, "tl", MTX_DEF); + TL_LOCK(sc); + /* Reset the adapter. */ tl_softreset(sc, 1); tl_hardreset(dev); @@ -1338,9 +1341,12 @@ static int tl_attach(dev) * Call MI attach routine. */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); + TL_UNLOCK(sc); + return(0); fail: - splx(s); + TL_UNLOCK(sc); + mtx_destroy(&sc->tl_mtx); return(error); } @@ -1349,11 +1355,9 @@ static int tl_detach(dev) { struct tl_softc *sc; struct ifnet *ifp; - int s; - - s = splimp(); sc = device_get_softc(dev); + TL_LOCK(sc); ifp = &sc->arpcom.ac_if; tl_stop(sc); @@ -1370,7 +1374,8 @@ static int tl_detach(dev) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->tl_irq); bus_release_resource(dev, TL_RES, TL_RID, sc->tl_res); - splx(s); + TL_UNLOCK(sc); + mtx_destroy(&sc->tl_mtx); return(0); } @@ -1722,6 +1727,7 @@ static void tl_intr(xsc) u_int8_t ivec = 0; sc = xsc; + TL_LOCK(sc); /* Disable interrupts */ ints = CSR_READ_2(sc, TL_HOST_INT); @@ -1780,6 +1786,8 @@ static void tl_intr(xsc) if (ifp->if_snd.ifq_head != NULL) tl_start(ifp); + TL_UNLOCK(sc); + return; } @@ -1791,13 +1799,11 @@ static void tl_stats_update(xsc) struct tl_stats tl_stats; struct mii_data *mii; u_int32_t *p; - int s; - - s = splimp(); bzero((char *)&tl_stats, sizeof(struct tl_stats)); sc = xsc; + TL_LOCK(sc); ifp = &sc->arpcom.ac_if; p = (u_int32_t *)&tl_stats; @@ -1838,7 +1844,7 @@ static void tl_stats_update(xsc) mii_tick(mii); } - splx(s); + TL_UNLOCK(sc); return; } @@ -1953,6 +1959,7 @@ static void tl_start(ifp) struct tl_chain *prev = NULL, *cur_tx = NULL, *start_tx; sc = ifp->if_softc; + TL_LOCK(sc); /* * Check for an available queue slot. If there are none, @@ -1960,6 +1967,7 @@ static void tl_start(ifp) */ if (sc->tl_cdata.tl_tx_free == NULL) { ifp->if_flags |= IFF_OACTIVE; + TL_UNLOCK(sc); return; } @@ -1997,8 +2005,10 @@ static void tl_start(ifp) /* * If there are no packets queued, bail. */ - if (cur_tx == NULL) + if (cur_tx == NULL) { + TL_UNLOCK(sc); return; + } /* * That's all we can stands, we can't stands no more. @@ -2028,6 +2038,7 @@ static void tl_start(ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; + TL_UNLOCK(sc); return; } @@ -2037,10 +2048,9 @@ static void tl_init(xsc) { struct tl_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; - int s; struct mii_data *mii; - s = splimp(); + TL_LOCK(sc); ifp = &sc->arpcom.ac_if; @@ -2085,6 +2095,7 @@ static void tl_init(xsc) printf("tl%d: initialization failed: no " "memory for rx buffers\n", sc->tl_unit); tl_stop(sc); + TL_UNLOCK(sc); return; } @@ -2111,10 +2122,9 @@ static void tl_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); - /* Start the stats update counter */ sc->tl_stat_ch = timeout(tl_stats_update, sc, hz); + TL_UNLOCK(sc); return; } @@ -2266,6 +2276,8 @@ static void tl_stop(sc) register int i; struct ifnet *ifp; + TL_LOCK(sc); + ifp = &sc->arpcom.ac_if; /* Stop the stats updater. */ @@ -2316,6 +2328,7 @@ static void tl_stop(sc) sizeof(sc->tl_ldata->tl_tx_list)); ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + TL_UNLOCK(sc); return; } diff --git a/sys/pci/if_tlreg.h b/sys/pci/if_tlreg.h index 29c7e62d4fc0..eb57a2c413b9 100644 --- a/sys/pci/if_tlreg.h +++ b/sys/pci/if_tlreg.h @@ -126,8 +126,12 @@ struct tl_softc { u_int8_t tl_bitrate; int tl_if_flags; struct callout_handle tl_stat_ch; + struct mtx tl_mtx; }; +#define TL_LOCK(_sc) mtx_enter(&(_sc)->tl_mtx, MTX_DEF) +#define TL_UNLOCK(_sc) mtx_exit(&(_sc)->tl_mtx, MTX_DEF) + /* * Transmit interrupt threshold. */ diff --git a/sys/pci/if_vr.c b/sys/pci/if_vr.c index 3649d7ede0c4..10b994232659 100644 --- a/sys/pci/if_vr.c +++ b/sys/pci/if_vr.c @@ -285,9 +285,9 @@ static int vr_mii_readreg(sc, frame) struct vr_mii_frame *frame; { - int i, ack, s; + int i, ack; - s = splimp(); + VR_LOCK(sc); /* * Set up frame for RX. @@ -364,7 +364,7 @@ static int vr_mii_readreg(sc, frame) SIO_SET(VR_MIICMD_CLK); DELAY(1); - splx(s); + VR_UNLOCK(sc); if (ack) return(1); @@ -379,9 +379,7 @@ static int vr_mii_writereg(sc, frame) struct vr_mii_frame *frame; { - int s; - - s = splimp(); + VR_LOCK(sc); CSR_WRITE_1(sc, VR_MIICMD, 0); VR_SETBIT(sc, VR_MIICMD, VR_MIICMD_DIRECTPGM); @@ -419,7 +417,7 @@ static int vr_mii_writereg(sc, frame) */ SIO_CLR(VR_MIICMD_DIR); - splx(s); + VR_UNLOCK(sc); return(0); } @@ -467,8 +465,10 @@ static void vr_miibus_statchg(dev) struct mii_data *mii; sc = device_get_softc(dev); + VR_LOCK(sc); mii = device_get_softc(sc->vr_miibus); vr_setcfg(sc, mii->mii_media_active); + VR_UNLOCK(sc); return; } @@ -633,15 +633,13 @@ static int vr_probe(dev) static int vr_attach(dev) device_t dev; { - int i, s; + int i; u_char eaddr[ETHER_ADDR_LEN]; u_int32_t command; struct vr_softc *sc; struct ifnet *ifp; int unit, error = 0, rid; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct vr_softc *)); @@ -731,6 +729,8 @@ static int vr_attach(dev) goto fail; } + mtx_init(&sc->vr_mtx, "vr", MTX_DEF); + VR_LOCK(sc); /* Reset the adapter. */ vr_reset(sc); @@ -803,9 +803,13 @@ static int vr_attach(dev) * Call MI attach routine. */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); + VR_UNLOCK(sc); + return(0); fail: - splx(s); + VR_UNLOCK(sc); + mtx_destroy(&sc->vr_mtx); + return(error); } @@ -814,11 +818,9 @@ static int vr_detach(dev) { struct vr_softc *sc; struct ifnet *ifp; - int s; - - s = splimp(); sc = device_get_softc(dev); + VR_LOCK(sc); ifp = &sc->arpcom.ac_if; vr_stop(sc); @@ -833,7 +835,8 @@ static int vr_detach(dev) contigfree(sc->vr_ldata, sizeof(struct vr_list_data), M_DEVBUF); - splx(s); + VR_UNLOCK(sc); + mtx_destroy(&sc->vr_mtx); return(0); } @@ -1146,17 +1149,15 @@ static void vr_tick(xsc) { struct vr_softc *sc; struct mii_data *mii; - int s; - - s = splimp(); sc = xsc; + VR_LOCK(sc); mii = device_get_softc(sc->vr_miibus); mii_tick(mii); sc->vr_stat_ch = timeout(vr_tick, sc, hz); - splx(s); + VR_UNLOCK(sc); return; } @@ -1169,11 +1170,13 @@ static void vr_intr(arg) u_int16_t status; sc = arg; + VR_LOCK(sc); ifp = &sc->arpcom.ac_if; /* Supress unwanted interrupts. */ if (!(ifp->if_flags & IFF_UP)) { vr_stop(sc); + VR_UNLOCK(sc); return; } @@ -1226,6 +1229,8 @@ static void vr_intr(arg) vr_start(ifp); } + VR_UNLOCK(sc); + return; } @@ -1314,8 +1319,11 @@ static void vr_start(ifp) sc = ifp->if_softc; - if (ifp->if_flags & IFF_OACTIVE) + VR_LOCK(sc); + if (ifp->if_flags & IFF_OACTIVE) { + VR_UNLOCK(sc); return; + } /* * Check for an available queue slot. If there are none, @@ -1357,8 +1365,10 @@ static void vr_start(ifp) /* * If there are no frames queued, bail. */ - if (cur_tx == NULL) + if (cur_tx == NULL) { + VR_UNLOCK(sc); return; + } sc->vr_cdata.vr_tx_tail = cur_tx; @@ -1369,6 +1379,7 @@ static void vr_start(ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; + VR_UNLOCK(sc); return; } @@ -1379,9 +1390,8 @@ static void vr_init(xsc) struct vr_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; struct mii_data *mii; - int s; - s = splimp(); + VR_LOCK(sc); mii = device_get_softc(sc->vr_miibus); @@ -1402,7 +1412,7 @@ static void vr_init(xsc) printf("vr%d: initialization failed: no " "memory for rx buffers\n", sc->vr_unit); vr_stop(sc); - (void)splx(s); + VR_UNLOCK(sc); return; } @@ -1451,10 +1461,10 @@ static void vr_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); - sc->vr_stat_ch = timeout(vr_tick, sc, hz); + VR_UNLOCK(sc); + return; } @@ -1501,9 +1511,9 @@ static int vr_ioctl(ifp, command, data) struct vr_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; - int s, error = 0; + int error = 0; - s = splimp(); + VR_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -1535,7 +1545,7 @@ static int vr_ioctl(ifp, command, data) break; } - (void)splx(s); + VR_UNLOCK(sc); return(error); } @@ -1547,6 +1557,7 @@ static void vr_watchdog(ifp) sc = ifp->if_softc; + VR_LOCK(sc); ifp->if_oerrors++; printf("vr%d: watchdog timeout\n", sc->vr_unit); @@ -1557,6 +1568,8 @@ static void vr_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) vr_start(ifp); + VR_UNLOCK(sc); + return; } @@ -1570,6 +1583,8 @@ static void vr_stop(sc) register int i; struct ifnet *ifp; + VR_LOCK(sc); + ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; @@ -1607,6 +1622,7 @@ static void vr_stop(sc) sizeof(sc->vr_ldata->vr_tx_list)); ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + VR_UNLOCK(sc); return; } diff --git a/sys/pci/if_vrreg.h b/sys/pci/if_vrreg.h index 2f2ac97ed3ff..8217a8c7596a 100644 --- a/sys/pci/if_vrreg.h +++ b/sys/pci/if_vrreg.h @@ -411,8 +411,12 @@ struct vr_softc { struct vr_list_data *vr_ldata; struct vr_chain_data vr_cdata; struct callout_handle vr_stat_ch; + struct mtx vr_mtx; }; +#define VR_LOCK(_sc) mtx_enter(&(_sc)->vr_mtx, MTX_DEF) +#define VR_UNLOCK(_sc) mtx_exit(&(_sc)->vr_mtx, MTX_DEF) + /* * register space access macros */ diff --git a/sys/pci/if_wb.c b/sys/pci/if_wb.c index b33c542ed5bc..55316e3b24f3 100644 --- a/sys/pci/if_wb.c +++ b/sys/pci/if_wb.c @@ -392,9 +392,9 @@ static int wb_mii_readreg(sc, frame) struct wb_mii_frame *frame; { - int i, ack, s; + int i, ack; - s = splimp(); + WB_LOCK(sc); /* * Set up frame for RX. @@ -473,7 +473,7 @@ static int wb_mii_readreg(sc, frame) SIO_SET(WB_SIO_MII_CLK); DELAY(1); - splx(s); + WB_UNLOCK(sc); if (ack) return(1); @@ -488,9 +488,8 @@ static int wb_mii_writereg(sc, frame) struct wb_mii_frame *frame; { - int s; + WB_LOCK(sc); - s = splimp(); /* * Set up frame for TX. */ @@ -524,7 +523,7 @@ static int wb_mii_writereg(sc, frame) */ SIO_CLR(WB_SIO_MII_DIR); - splx(s); + WB_UNLOCK(sc); return(0); } @@ -574,8 +573,10 @@ static void wb_miibus_statchg(dev) struct mii_data *mii; sc = device_get_softc(dev); + WB_LOCK(sc); mii = device_get_softc(sc->wb_miibus); wb_setcfg(sc, mii->mii_media_active); + WB_UNLOCK(sc); return; } @@ -808,15 +809,12 @@ static int wb_probe(dev) static int wb_attach(dev) device_t dev; { - int s; u_char eaddr[ETHER_ADDR_LEN]; u_int32_t command; struct wb_softc *sc; struct ifnet *ifp; int unit, error = 0, rid; - s = splimp(); - sc = device_get_softc(dev); unit = device_get_unit(dev); @@ -909,6 +907,9 @@ static int wb_attach(dev) /* Save the cache line size. */ sc->wb_cachesize = pci_read_config(dev, WB_PCI_CACHELEN, 4) & 0xFF; + mtx_init(&sc->wb_mtx, "wb", MTX_DEF); + WB_LOCK(sc); + /* Reset the adapter. */ wb_reset(sc); @@ -970,11 +971,14 @@ static int wb_attach(dev) * Call MI attach routine. */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); + WB_UNLOCK(sc); + return(0); fail: if (error) device_delete_child(dev, sc->wb_miibus); - splx(s); + WB_UNLOCK(sc); + mtx_destroy(&sc->wb_mtx); return(error); } @@ -984,11 +988,9 @@ static int wb_detach(dev) { struct wb_softc *sc; struct ifnet *ifp; - int s; - - s = splimp(); sc = device_get_softc(dev); + WB_LOCK(sc); ifp = &sc->arpcom.ac_if; wb_stop(sc); @@ -1004,7 +1006,8 @@ static int wb_detach(dev) free(sc->wb_ldata_ptr, M_DEVBUF); - splx(s); + WB_UNLOCK(sc); + mtx_destroy(&sc->wb_mtx); return(0); } @@ -1303,10 +1306,13 @@ static void wb_intr(arg) u_int32_t status; sc = arg; + WB_LOCK(sc); ifp = &sc->arpcom.ac_if; - if (!(ifp->if_flags & IFF_UP)) + if (!(ifp->if_flags & IFF_UP)) { + WB_UNLOCK(sc); return; + } /* Disable interrupts. */ CSR_WRITE_4(sc, WB_IMR, 0x00000000); @@ -1374,6 +1380,8 @@ static void wb_intr(arg) wb_start(ifp); } + WB_UNLOCK(sc); + return; } @@ -1382,18 +1390,16 @@ static void wb_tick(xsc) { struct wb_softc *sc; struct mii_data *mii; - int s; - - s = splimp(); sc = xsc; + WB_LOCK(sc); mii = device_get_softc(sc->wb_miibus); mii_tick(mii); sc->wb_stat_ch = timeout(wb_tick, sc, hz); - splx(s); + WB_UNLOCK(sc); return; } @@ -1508,6 +1514,7 @@ static void wb_start(ifp) struct wb_chain *cur_tx = NULL, *start_tx; sc = ifp->if_softc; + WB_LOCK(sc); /* * Check for an available queue slot. If there are none, @@ -1515,6 +1522,7 @@ static void wb_start(ifp) */ if (sc->wb_cdata.wb_tx_free->wb_mbuf != NULL) { ifp->if_flags |= IFF_OACTIVE; + WB_UNLOCK(sc); return; } @@ -1546,8 +1554,10 @@ static void wb_start(ifp) /* * If there are no packets queued, bail. */ - if (cur_tx == NULL) + if (cur_tx == NULL) { + WB_UNLOCK(sc); return; + } /* * Place the request for the upload interrupt @@ -1584,6 +1594,7 @@ static void wb_start(ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; + WB_UNLOCK(sc); return; } @@ -1593,11 +1604,10 @@ static void wb_init(xsc) { struct wb_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; - int s, i; + int i; struct mii_data *mii; - s = splimp(); - + WB_LOCK(sc); mii = device_get_softc(sc->wb_miibus); /* @@ -1648,7 +1658,7 @@ static void wb_init(xsc) printf("wb%d: initialization failed: no " "memory for rx buffers\n", sc->wb_unit); wb_stop(sc); - (void)splx(s); + WB_UNLOCK(sc); return; } @@ -1701,9 +1711,8 @@ static void wb_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); - sc->wb_stat_ch = timeout(wb_tick, sc, hz); + WB_UNLOCK(sc); return; } @@ -1753,9 +1762,9 @@ static int wb_ioctl(ifp, command, data) struct wb_softc *sc = ifp->if_softc; struct mii_data *mii; struct ifreq *ifr = (struct ifreq *) data; - int s, error = 0; + int error = 0; - s = splimp(); + WB_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -1787,7 +1796,7 @@ static int wb_ioctl(ifp, command, data) break; } - (void)splx(s); + WB_UNLOCK(sc); return(error); } @@ -1799,6 +1808,7 @@ static void wb_watchdog(ifp) sc = ifp->if_softc; + WB_LOCK(sc); ifp->if_oerrors++; printf("wb%d: watchdog timeout\n", sc->wb_unit); #ifdef foo @@ -1812,6 +1822,7 @@ static void wb_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) wb_start(ifp); + WB_UNLOCK(sc); return; } @@ -1826,6 +1837,7 @@ static void wb_stop(sc) register int i; struct ifnet *ifp; + WB_LOCK(sc); ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; @@ -1862,6 +1874,7 @@ static void wb_stop(sc) sizeof(sc->wb_ldata->wb_tx_list)); ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + WB_UNLOCK(sc); return; } diff --git a/sys/pci/if_wbreg.h b/sys/pci/if_wbreg.h index 5bfccd84c9ba..6f585142fa40 100644 --- a/sys/pci/if_wbreg.h +++ b/sys/pci/if_wbreg.h @@ -378,8 +378,12 @@ struct wb_softc { struct wb_list_data *wb_ldata; struct wb_chain_data wb_cdata; struct callout_handle wb_stat_ch; + struct mtx wb_mtx; }; +#define WB_LOCK(_sc) mtx_enter(&(_sc)->wb_mtx, MTX_DEF) +#define WB_UNLOCK(_sc) mtx_exit(&(_sc)->wb_mtx, MTX_DEF) + /* * register space access macros */ diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c index 8f724677664a..7e1f64bbbbfc 100644 --- a/sys/pci/if_xl.c +++ b/sys/pci/if_xl.c @@ -387,9 +387,9 @@ static int xl_mii_readreg(sc, frame) struct xl_mii_frame *frame; { - int i, ack, s; + int i, ack; - s = splimp(); + XL_LOCK(sc); /* * Set up frame for RX. @@ -470,7 +470,7 @@ static int xl_mii_readreg(sc, frame) MII_SET(XL_MII_CLK); DELAY(1); - splx(s); + XL_UNLOCK(sc); if (ack) return(1); @@ -485,9 +485,8 @@ static int xl_mii_writereg(sc, frame) struct xl_mii_frame *frame; { - int s; + XL_LOCK(sc); - s = splimp(); /* * Set up frame for TX. */ @@ -526,7 +525,7 @@ static int xl_mii_writereg(sc, frame) */ MII_CLR(XL_MII_DIR); - splx(s); + XL_UNLOCK(sc); return(0); } @@ -592,6 +591,8 @@ static void xl_miibus_statchg(dev) sc = device_get_softc(dev); mii = device_get_softc(sc->xl_miibus); + XL_LOCK(sc); + xl_setcfg(sc); /* Set ASIC's duplex mode to match the PHY. */ @@ -602,6 +603,8 @@ static void xl_miibus_statchg(dev) CSR_WRITE_1(sc, XL_W3_MAC_CTRL, (CSR_READ_1(sc, XL_W3_MAC_CTRL) & ~XL_MACCTRL_DUPLEX)); + XL_UNLOCK(sc); + return; } @@ -626,6 +629,8 @@ static void xl_miibus_mediainit(dev) mii = device_get_softc(sc->xl_miibus); ifm = &mii->mii_media; + XL_LOCK(sc); + if (sc->xl_media & (XL_MEDIAOPT_AUI|XL_MEDIAOPT_10FL)) { /* * Check for a 10baseFL board in disguise. @@ -652,6 +657,8 @@ static void xl_miibus_mediainit(dev) ifmedia_add(ifm, IFM_ETHER|IFM_10_2, 0, NULL); } + XL_UNLOCK(sc); + return; } @@ -1341,6 +1348,9 @@ static int xl_attach(dev) goto fail; } + mtx_init(&sc->xl_mtx, "xl", MTX_DEF); + XL_LOCK(sc); + /* Reset the adapter. */ xl_reset(sc); @@ -1556,9 +1566,13 @@ static int xl_attach(dev) * Call MI attach routine. */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); + XL_UNLOCK(sc); + return(0); fail: - splx(s); + XL_UNLOCK(sc); + mtx_destroy(&sc->xl_mtx); + return(error); } @@ -1567,11 +1581,9 @@ static int xl_detach(dev) { struct xl_softc *sc; struct ifnet *ifp; - int s; - - s = splimp(); sc = device_get_softc(dev); + XL_LOCK(sc); ifp = &sc->arpcom.ac_if; xl_reset(sc); @@ -1594,7 +1606,8 @@ static int xl_detach(dev) ifmedia_removeall(&sc->ifmedia); contigfree(sc->xl_ldata, sizeof(struct xl_list_data), M_DEVBUF); - splx(s); + XL_UNLOCK(sc); + mtx_destroy(&sc->xl_mtx); return(0); } @@ -2024,6 +2037,7 @@ static void xl_intr(arg) u_int16_t status; sc = arg; + XL_LOCK(sc); ifp = &sc->arpcom.ac_if; while((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS) { @@ -2069,6 +2083,8 @@ static void xl_intr(arg) if (ifp->if_snd.ifq_head != NULL) (*ifp->if_start)(ifp); + XL_LOCK(sc); + return; } @@ -2215,7 +2231,7 @@ static void xl_start(ifp) struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx; sc = ifp->if_softc; - + XL_LOCK(sc); /* * Check for an available queue slot. If there are none, * punt. @@ -2225,6 +2241,7 @@ static void xl_start(ifp) xl_txeof(sc); if (sc->xl_cdata.xl_tx_free == NULL) { ifp->if_flags |= IFF_OACTIVE; + XL_UNLOCK(sc); return; } } @@ -2263,8 +2280,10 @@ static void xl_start(ifp) /* * If there are no packets queued, bail. */ - if (cur_tx == NULL) + if (cur_tx == NULL) { + XL_UNLOCK(sc); return; + } /* * Place the request for the upload interrupt @@ -2322,6 +2341,8 @@ static void xl_start(ifp) */ xl_rxeof(sc); + XL_UNLOCK(sc); + return; } @@ -2371,9 +2392,12 @@ static void xl_start_90xB(ifp) int idx; sc = ifp->if_softc; + XL_LOCK(sc); - if (ifp->if_flags & IFF_OACTIVE) + if (ifp->if_flags & IFF_OACTIVE) { + XL_UNLOCK(sc); return; + } idx = sc->xl_cdata.xl_tx_prod; start_tx = &sc->xl_cdata.xl_tx_chain[idx]; @@ -2413,8 +2437,10 @@ static void xl_start_90xB(ifp) /* * If there are no packets queued, bail. */ - if (cur_tx == NULL) + if (cur_tx == NULL) { + XL_UNLOCK(sc); return; + } /* * Place the request for the upload interrupt @@ -2434,6 +2460,8 @@ static void xl_start_90xB(ifp) */ ifp->if_timer = 5; + XL_UNLOCK(sc); + return; } @@ -2442,11 +2470,11 @@ static void xl_init(xsc) { struct xl_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; - int s, i; + int i; u_int16_t rxfilt = 0; struct mii_data *mii = NULL; - s = splimp(); + XL_LOCK(sc); /* * Cancel pending I/O and free all RX/TX buffers. @@ -2610,7 +2638,8 @@ static void xl_init(xsc) CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF); CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|XL_INTRS); CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS); - if (sc->xl_flags & XL_FLAG_FUNCREG) bus_space_write_4 (sc->xl_ftag, sc->xl_fhandle, 4, 0x8000); + if (sc->xl_flags & XL_FLAG_FUNCREG) + bus_space_write_4(sc->xl_ftag, sc->xl_fhandle, 4, 0x8000); /* Set the RX early threshold */ CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_THRESH|(XL_PACKET_SIZE >>2)); @@ -2631,10 +2660,10 @@ static void xl_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); - sc->xl_stat_ch = timeout(xl_stats_update, sc, hz); + XL_UNLOCK(sc); + return; } @@ -2752,11 +2781,11 @@ static int xl_ioctl(ifp, command, data) { struct xl_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; - int s, error = 0; + int error = 0; struct mii_data *mii = NULL; u_int8_t rxfilt; - s = splimp(); + XL_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -2815,7 +2844,7 @@ static int xl_ioctl(ifp, command, data) break; } - (void)splx(s); + XL_UNLOCK(sc); return(error); } @@ -2828,6 +2857,8 @@ static void xl_watchdog(ifp) sc = ifp->if_softc; + XL_LOCK(sc); + ifp->if_oerrors++; XL_SEL_WIN(4); status = CSR_READ_2(sc, XL_W4_MEDIA_STATUS); @@ -2845,6 +2876,8 @@ static void xl_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) (*ifp->if_start)(ifp); + XL_UNLOCK(sc); + return; } @@ -2858,6 +2891,8 @@ static void xl_stop(sc) register int i; struct ifnet *ifp; + XL_LOCK(sc); + ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; @@ -2910,6 +2945,8 @@ static void xl_stop(sc) ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + XL_UNLOCK(sc); + return; } @@ -2924,8 +2961,10 @@ static void xl_shutdown(dev) sc = device_get_softc(dev); + XL_LOCK(sc); xl_reset(sc); xl_stop(sc); + XL_UNLOCK(sc); return; } diff --git a/sys/pci/if_xlreg.h b/sys/pci/if_xlreg.h index eccf66971552..108823c65077 100644 --- a/sys/pci/if_xlreg.h +++ b/sys/pci/if_xlreg.h @@ -579,8 +579,12 @@ struct xl_softc { struct resource *xl_fres; bus_space_handle_t xl_fhandle; bus_space_tag_t xl_ftag; + struct mtx xl_mtx; }; +#define XL_LOCK(_sc) mtx_enter(&(_sc)->xl_mtx, MTX_DEF) +#define XL_UNLOCK(_sc) mtx_exit(&(_sc)->xl_mtx, MTX_DEF) + #define xl_rx_goodframes(x) \ ((x.xl_upper_frames_ok & 0x03) << 8) | x.xl_rx_frames_ok