diff --git a/sys/pci/if_dc.c b/sys/pci/if_dc.c index b1ef62aef091..fce20b4e4f5b 100644 --- a/sys/pci/if_dc.c +++ b/sys/pci/if_dc.c @@ -235,8 +235,10 @@ static void dc_tick(void *); 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 @@ DRIVER_MODULE(miibus, dc, miibus_driver, miibus_devclass, 0, 0); #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 @@ dc_mii_readreg(struct dc_softc *sc, struct dc_mii_frame *frame) { int i, ack; - DC_LOCK(sc); - /* * Set up frame for RX. */ @@ -724,8 +722,6 @@ fail: dc_mii_writebit(sc, 0); dc_mii_writebit(sc, 0); - DC_UNLOCK(sc); - if (ack) return (1); return (0); @@ -738,7 +734,6 @@ static int 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_writereg(struct dc_softc *sc, struct dc_mii_frame *frame) dc_mii_writebit(sc, 0); dc_mii_writebit(sc, 0); - DC_UNLOCK(sc); - return (0); } @@ -864,8 +857,8 @@ dc_miibus_readreg(device_t dev, int phy, int reg) phy_reg = DC_AL_ANER; break; default: - printf("dc%d: phy_read: bad phy register %x\n", - sc->dc_unit, reg); + device_printf(dev, "phy_read: bad phy register %x\n", + reg); return (0); break; } @@ -940,8 +933,8 @@ dc_miibus_writereg(device_t dev, int phy, int reg, int data) phy_reg = DC_AL_ANER; break; default: - printf("dc%d: phy_write: bad phy register %x\n", - sc->dc_unit, reg); + device_printf(dev, "phy_write: bad phy register %x\n", + reg); return (0); break; } @@ -1388,8 +1381,8 @@ dc_setcfg(struct dc_softc *sc, int media) } if (i == DC_TIMEOUT) - printf("dc%d: failed to force tx and " - "rx to idle state\n", sc->dc_unit); + if_printf(sc->dc_ifp, + "failed to force tx and rx to idle state\n"); } if (IFM_SUBTYPE(media) == IFM_100_TX) { @@ -1529,7 +1522,7 @@ dc_reset(struct dc_softc *sc) } if (i == DC_TIMEOUT) - printf("dc%d: reset never completed!\n", sc->dc_unit); + if_printf(sc->dc_ifp, "reset never completed!\n"); /* Wait a little while for the chip to get its brains in order. */ DELAY(1000); @@ -1837,15 +1830,14 @@ dc_attach(device_t dev) struct dc_softc *sc; struct ifnet *ifp; u_int32_t revision; - int unit, error = 0, rid, mac_offset; + int error = 0, rid, mac_offset; int i; u_int8_t *mac; sc = device_get_softc(dev); - unit = device_get_unit(dev); mtx_init(&sc->dc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); + MTX_DEF); /* * Map control/status registers. @@ -1856,7 +1848,7 @@ dc_attach(device_t dev) sc->dc_res = bus_alloc_resource_any(dev, DC_RES, &rid, RF_ACTIVE); if (sc->dc_res == NULL) { - printf("dc%d: couldn't map ports/memory\n", unit); + device_printf(dev, "couldn't map ports/memory\n"); error = ENXIO; goto fail; } @@ -1870,7 +1862,7 @@ dc_attach(device_t dev) RF_SHAREABLE | RF_ACTIVE); if (sc->dc_irq == NULL) { - printf("dc%d: couldn't map interrupt\n", unit); + device_printf(dev, "couldn't map interrupt\n"); error = ENXIO; goto fail; } @@ -2001,8 +1993,7 @@ dc_attach(device_t dev) dc_read_srom(sc, sc->dc_romwidth); break; default: - printf("dc%d: unknown device: %x\n", sc->dc_unit, - sc->dc_info->dc_did); + device_printf(dev, "unknown device: %x\n", sc->dc_info->dc_did); break; } @@ -2097,21 +2088,19 @@ dc_attach(device_t dev) break; } - sc->dc_unit = unit; - /* Allocate a busdma tag and DMA safe memory for TX/RX descriptors. */ error = bus_dma_tag_create(NULL, PAGE_SIZE, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, sizeof(struct dc_list_data), 1, sizeof(struct dc_list_data), 0, NULL, NULL, &sc->dc_ltag); if (error) { - printf("dc%d: failed to allocate busdma tag\n", unit); + device_printf(dev, "failed to allocate busdma tag\n"); error = ENXIO; goto fail; } error = bus_dmamem_alloc(sc->dc_ltag, (void **)&sc->dc_ldata, BUS_DMA_NOWAIT | BUS_DMA_ZERO, &sc->dc_lmap); if (error) { - printf("dc%d: failed to allocate DMA safe memory\n", unit); + device_printf(dev, "failed to allocate DMA safe memory\n"); error = ENXIO; goto fail; } @@ -2119,7 +2108,7 @@ dc_attach(device_t dev) sizeof(struct dc_list_data), dc_dma_map_addr, &sc->dc_laddr, BUS_DMA_NOWAIT); if (error) { - printf("dc%d: cannot get address of the descriptors\n", unit); + device_printf(dev, "cannot get address of the descriptors\n"); error = ENXIO; goto fail; } @@ -2132,21 +2121,21 @@ dc_attach(device_t dev) BUS_SPACE_MAXADDR, NULL, NULL, DC_SFRAME_LEN + DC_MIN_FRAMELEN, 1, DC_SFRAME_LEN + DC_MIN_FRAMELEN, 0, NULL, NULL, &sc->dc_stag); if (error) { - printf("dc%d: failed to allocate busdma tag\n", unit); + device_printf(dev, "failed to allocate busdma tag\n"); error = ENXIO; goto fail; } error = bus_dmamem_alloc(sc->dc_stag, (void **)&sc->dc_cdata.dc_sbuf, BUS_DMA_NOWAIT, &sc->dc_smap); if (error) { - printf("dc%d: failed to allocate DMA safe memory\n", unit); + device_printf(dev, "failed to allocate DMA safe memory\n"); error = ENXIO; goto fail; } error = bus_dmamap_load(sc->dc_stag, sc->dc_smap, sc->dc_cdata.dc_sbuf, DC_SFRAME_LEN, dc_dma_map_addr, &sc->dc_saddr, BUS_DMA_NOWAIT); if (error) { - printf("dc%d: cannot get address of the descriptors\n", unit); + device_printf(dev, "cannot get address of the descriptors\n"); error = ENXIO; goto fail; } @@ -2156,7 +2145,7 @@ dc_attach(device_t dev) BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, DC_TX_LIST_CNT, MCLBYTES, 0, NULL, NULL, &sc->dc_mtag); if (error) { - printf("dc%d: failed to allocate busdma tag\n", unit); + device_printf(dev, "failed to allocate busdma tag\n"); error = ENXIO; goto fail; } @@ -2166,7 +2155,7 @@ dc_attach(device_t dev) error = bus_dmamap_create(sc->dc_mtag, 0, &sc->dc_cdata.dc_tx_map[i]); if (error) { - printf("dc%d: failed to init TX ring\n", unit); + device_printf(dev, "failed to init TX ring\n"); error = ENXIO; goto fail; } @@ -2175,21 +2164,21 @@ dc_attach(device_t dev) error = bus_dmamap_create(sc->dc_mtag, 0, &sc->dc_cdata.dc_rx_map[i]); if (error) { - printf("dc%d: failed to init RX ring\n", unit); + device_printf(dev, "failed to init RX ring\n"); error = ENXIO; goto fail; } } error = bus_dmamap_create(sc->dc_mtag, 0, &sc->dc_sparemap); if (error) { - printf("dc%d: failed to init RX ring\n", unit); + device_printf(dev, "failed to init RX ring\n"); error = ENXIO; goto fail; } ifp = sc->dc_ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { - printf("dc%d: can not if_alloc()\n", unit); + device_printf(dev, "can not if_alloc()\n"); error = ENOSPC; goto fail; } @@ -2198,8 +2187,6 @@ dc_attach(device_t dev) /* 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; @@ -2259,7 +2246,7 @@ dc_attach(device_t dev) } if (error) { - printf("dc%d: MII without any PHY!\n", sc->dc_unit); + device_printf(dev, "MII without any PHY!\n"); goto fail; } @@ -2280,7 +2267,7 @@ dc_attach(device_t dev) #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; @@ -2314,12 +2301,11 @@ dc_attach(device_t dev) 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) { - printf("dc%d: couldn't set up irq\n", unit); + device_printf(dev, "couldn't set up irq\n"); ether_ifdetach(ifp); if_free(ifp); goto fail; @@ -2348,13 +2334,15 @@ dc_detach(device_t dev) 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); } @@ -2394,7 +2382,6 @@ dc_detach(device_t dev) } free(sc->dc_srom, M_DEVBUF); - DC_UNLOCK(sc); mtx_destroy(&sc->dc_mtx); return (0); @@ -2755,7 +2742,7 @@ dc_rxeof(struct dc_softc *sc) DC_INC(i, DC_RX_LIST_CNT); continue; } else { - dc_init(sc); + dc_init_locked(sc); return; } } @@ -2883,7 +2870,7 @@ dc_txeof(struct dc_softc *sc) if (txstat & DC_TXSTAT_LATECOLL) ifp->if_collisions++; if (!(txstat & DC_TXSTAT_UNDERRUN)) { - dc_init(sc); + dc_init_locked(sc); return; } } @@ -2922,7 +2909,7 @@ dc_tick(void *xsc) u_int32_t r; sc = xsc; - DC_LOCK(sc); + DC_LOCK_ASSERT(sc); ifp = sc->dc_ifp; mii = device_get_softc(sc->dc_miibus); @@ -2976,15 +2963,13 @@ dc_tick(void *xsc) 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); } /* @@ -2998,7 +2983,7 @@ dc_tx_underrun(struct dc_softc *sc) int i; if (DC_IS_DAVICOM(sc)) - dc_init(sc); + dc_init_locked(sc); if (DC_IS_INTEL(sc)) { /* @@ -3015,13 +3000,13 @@ dc_tx_underrun(struct dc_softc *sc) DELAY(10); } if (i == DC_TIMEOUT) { - printf("dc%d: failed to force tx to idle state\n", - sc->dc_unit); - dc_init(sc); + if_printf(sc->dc_ifp, + "failed to force tx to idle state\n"); + dc_init_locked(sc); } } - printf("dc%d: TX underrun -- ", sc->dc_unit); + if_printf(sc->dc_ifp, "TX underrun -- "); sc->dc_txthresh += DC_TXTHRESH_INC; if (sc->dc_txthresh > DC_TXTHRESH_MAX) { printf("using store and forward mode\n"); @@ -3059,7 +3044,7 @@ dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) 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; @@ -3090,9 +3075,9 @@ dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) dc_tx_underrun(sc); if (status & DC_ISR_BUS_ERR) { - printf("dc_poll: dc%d bus error\n", sc->dc_unit); + if_printf(ifp, "dc_poll: bus error\n"); dc_reset(sc); - dc_init(sc); + dc_init_locked(sc); } } DC_UNLOCK(sc); @@ -3179,7 +3164,7 @@ dc_intr(void *arg) if (status & DC_ISR_BUS_ERR) { dc_reset(sc); - dc_init(sc); + dc_init_locked(sc); } } @@ -3187,7 +3172,7 @@ dc_intr(void *arg) 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: @@ -3314,6 +3299,17 @@ dc_encap(struct dc_softc *sc, struct mbuf **m_head) static void 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; @@ -3322,17 +3318,13 @@ dc_start(struct ifnet *ifp) 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; @@ -3384,18 +3376,37 @@ dc_start(struct ifnet *ifp) */ 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); @@ -3488,10 +3499,9 @@ dc_init(void *xsc) /* Init circular RX list. */ if (dc_list_rx_init(sc) == ENOBUFS) { - printf("dc%d: initialization failed: no " - "memory for rx buffers\n", sc->dc_unit); + if_printf(ifp, + "initialization failed: no memory for rx buffers\n"); dc_stop(sc); - DC_UNLOCK(sc); return; } @@ -3563,17 +3573,6 @@ dc_init(void *xsc) 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); } /* @@ -3588,6 +3587,7 @@ dc_ifmedia_upd(struct ifnet *ifp) sc = ifp->if_softc; mii = device_get_softc(sc->dc_miibus); + DC_LOCK(sc); mii_mediachg(mii); ifm = &mii->mii_media; @@ -3596,6 +3596,7 @@ dc_ifmedia_upd(struct ifnet *ifp) dc_setcfg(sc, ifm->ifm_media); else sc->dc_link = 0; + DC_UNLOCK(sc); return (0); } @@ -3612,6 +3613,7 @@ dc_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 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)) { @@ -3623,6 +3625,7 @@ dc_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) } ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; + DC_UNLOCK(sc); } static int @@ -3633,10 +3636,9 @@ dc_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 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); @@ -3646,18 +3648,21 @@ dc_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 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: @@ -3665,21 +3670,23 @@ dc_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 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,14 +3700,14 @@ dc_watchdog(struct ifnet *ifp) DC_LOCK(sc); ifp->if_oerrors++; - printf("dc%d: watchdog timeout\n", sc->dc_unit); + if_printf(ifp, "watchdog timeout\n"); 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); } @@ -3718,7 +3725,7 @@ dc_stop(struct dc_softc *sc) int i; u_int32_t ctl; - DC_LOCK(sc); + DC_LOCK_ASSERT(sc); ifp = sc->dc_ifp; ifp->if_timer = 0; @@ -3766,8 +3773,6 @@ dc_stop(struct dc_softc *sc) } } bzero(&ld->dc_tx_list, sizeof(ld->dc_tx_list)); - - DC_UNLOCK(sc); } /* @@ -3779,15 +3784,13 @@ static int 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); } @@ -3801,20 +3804,18 @@ dc_resume(device_t dev) { 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); } @@ -3829,5 +3830,7 @@ dc_shutdown(device_t dev) sc = device_get_softc(dev); + DC_LOCK(sc); dc_stop(sc); + DC_UNLOCK(sc); } diff --git a/sys/pci/if_dcreg.h b/sys/pci/if_dcreg.h index a851a72d7342..ecf9962fcf55 100644 --- a/sys/pci/if_dcreg.h +++ b/sys/pci/if_dcreg.h @@ -732,7 +732,6 @@ struct dc_softc { struct resource *dc_res; struct dc_type *dc_info; /* adapter info */ device_t dc_miibus; - u_int8_t dc_unit; /* interface number */ u_int8_t dc_type; u_int8_t dc_pmode; u_int8_t dc_link; diff --git a/sys/pci/if_sf.c b/sys/pci/if_sf.c index e166b9391a28..e14ce264d120 100644 --- a/sys/pci/if_sf.c +++ b/sys/pci/if_sf.c @@ -137,12 +137,15 @@ static void sf_txeof(struct sf_softc *); 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 @@ sf_ifmedia_upd(ifp) 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 @@ sf_ifmedia_upd(ifp) mii_phy_reset(miisc); } mii_mediachg(mii); - - return(0); } /* @@ -489,11 +505,13 @@ sf_ifmedia_sts(ifp, ifmr) 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 @@ sf_ioctl(ifp, command, data) 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 @@ sf_ioctl(ifp, command, data) 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 @@ sf_ioctl(ifp, command, data) 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); } @@ -573,7 +593,7 @@ sf_reset(sc) } if (i == SF_TIMEOUT) - printf("sf%d: reset never completed!\n", sc->sf_unit); + if_printf(sc->sf_ifp, "reset never completed!\n"); /* Wait a little while for the chip to get its brains in order. */ DELAY(1000); @@ -643,14 +663,13 @@ sf_attach(dev) int i; struct sf_softc *sc; struct ifnet *ifp; - int unit, rid, error = 0; + int rid, error = 0; u_char eaddr[6]; sc = device_get_softc(dev); - unit = device_get_unit(dev); mtx_init(&sc->sf_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); + MTX_DEF); /* * Map control/status registers. */ @@ -660,7 +679,7 @@ sf_attach(dev) sc->sf_res = bus_alloc_resource_any(dev, SF_RES, &rid, RF_ACTIVE); if (sc->sf_res == NULL) { - printf ("sf%d: couldn't map ports\n", unit); + device_printf(dev, "couldn't map ports\n"); error = ENXIO; goto fail; } @@ -674,12 +693,13 @@ sf_attach(dev) RF_SHAREABLE | RF_ACTIVE); if (sc->sf_irq == NULL) { - printf("sf%d: couldn't map interrupt\n", unit); + device_printf(dev, "couldn't map interrupt\n"); error = ENXIO; 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); @@ -690,14 +710,12 @@ sf_attach(dev) eaddr[i] = sf_read_eeprom(sc, SF_EE_NODEADDR + ETHER_ADDR_LEN - i); - sc->sf_unit = unit; - /* Allocate the descriptor queues. */ sc->sf_ldata = contigmalloc(sizeof(struct sf_list_data), M_DEVBUF, M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0); if (sc->sf_ldata == NULL) { - printf("sf%d: no memory for list buffers!\n", unit); + device_printf(dev, "no memory for list buffers!\n"); error = ENXIO; goto fail; } @@ -706,7 +724,7 @@ sf_attach(dev) ifp = sc->sf_ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { - printf("sf%d: can not if_alloc()\n", sc->sf_unit); + device_printf(dev, "can not if_alloc()\n"); error = ENOSPC; goto fail; } @@ -714,7 +732,7 @@ sf_attach(dev) /* Do MII setup. */ if (mii_phy_probe(dev, &sc->sf_miibus, sf_ifmedia_upd, sf_ifmedia_sts)) { - printf("sf%d: MII without any phy!\n", sc->sf_unit); + device_printf(dev, "MII without any phy!\n"); error = ENXIO; goto fail; } @@ -722,8 +740,7 @@ sf_attach(dev) 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; @@ -743,11 +760,11 @@ sf_attach(dev) 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) { - printf("sf%d: couldn't set up irq\n", unit); + device_printf(dev, "couldn't set up irq\n"); ether_ifdetach(ifp); if_free(ifp); goto fail; @@ -776,12 +793,14 @@ sf_detach(dev) 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); } @@ -799,7 +818,6 @@ sf_detach(dev) 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); @@ -987,6 +1005,7 @@ sf_txeof(sc) 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); @@ -1034,9 +1053,9 @@ sf_txthresh_adjust(sc) txfctl &= ~SF_TXFRMCTL_TXTHRESH; txfctl |= txthresh; #ifdef DIAGNOSTIC - printf("sf%d: tx underrun, increasing " + if_printf(sc->sf_ifp, "tx underrun, increasing " "tx threshold to %d bytes\n", - sc->sf_unit, txthresh * 4); + txthresh * 4); #endif csr_write_4(sc, SF_TX_FRAMCTL, txfctl); } @@ -1075,7 +1094,7 @@ sf_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) 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; @@ -1089,11 +1108,10 @@ sf_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) 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); } } } @@ -1154,11 +1172,10 @@ sf_intr(arg) 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); } } @@ -1166,7 +1183,7 @@ sf_intr(arg) 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: @@ -1179,12 +1196,22 @@ sf_init(xsc) 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; struct mii_data *mii; int i; - sc = xsc; - SF_LOCK(sc); + SF_LOCK_ASSERT(sc); ifp = sc->sf_ifp; mii = device_get_softc(sc->sf_miibus); @@ -1207,9 +1234,8 @@ sf_init(xsc) sf_setperf(sc, 0, (caddr_t)&IFP2ENADDR(sc->sf_ifp)); if (sf_init_rx_ring(sc) == ENOBUFS) { - printf("sf%d: initialization failed: no " - "memory for rx buffers\n", sc->sf_unit); - SF_UNLOCK(sc); + if_printf(sc->sf_ifp, + "initialization failed: no memory for rx buffers\n"); return; } @@ -1284,14 +1310,12 @@ sf_init(xsc) SF_SETBIT(sc, SF_GEN_ETH_CTL, SF_ETHCTL_TX_ENB|SF_ETHCTL_TXDMA_ENB); /*mii_mediachg(mii);*/ - sf_ifmedia_upd(ifp); + sf_ifmedia_upd_locked(ifp); ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - sc->sf_stat_ch = timeout(sf_stats_update, sc, hz); - - SF_UNLOCK(sc); + callout_reset(&sc->sf_stat_callout, hz, sf_stats_update, sc); } static int @@ -1324,7 +1348,7 @@ sf_encap(sc, c, m_head) MGETHDR(m_new, M_DONTWAIT, MT_DATA); if (m_new == NULL) { - printf("sf%d: no memory for tx list\n", sc->sf_unit); + if_printf(sc->sf_ifp, "no memory for tx list\n"); return(1); } @@ -1332,8 +1356,7 @@ sf_encap(sc, c, m_head) MCLGET(m_new, M_DONTWAIT); if (!(m_new->m_flags & M_EXT)) { m_freem(m_new); - printf("sf%d: no memory for tx list\n", - sc->sf_unit); + if_printf(sc->sf_ifp, "no memory for tx list\n"); return(1); } } @@ -1363,29 +1386,37 @@ sf_start(ifp) struct ifnet *ifp; { struct sf_softc *sc; + + sc = ifp->if_softc; + SF_LOCK(sc); + sf_start_locked(ifp); + SF_UNLOCK(sc); +} + +static void +sf_start_locked(ifp) + struct ifnet *ifp; +{ + struct sf_softc *sc; struct sf_tx_bufdesc_type0 *cur_tx = NULL; struct mbuf *m_head = NULL; int i, txprod; sc = ifp->if_softc; - SF_LOCK(sc); + SF_LOCK_ASSERT(sc); - if (!sc->sf_link && ifp->if_snd.ifq_len < 10) { - SF_UNLOCK(sc); + if (!sc->sf_link && ifp->if_snd.ifq_len < 10) return; - } - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) { - SF_UNLOCK(sc); + if (ifp->if_drv_flags & IFF_DRV_OACTIVE) return; - } txprod = csr_read_4(sc, SF_TXDQ_PRODIDX); i = SF_IDX_HI(txprod) >> 4; if (sc->sf_ldata->sf_tx_dlist[i].sf_mbuf != NULL) { - printf("sf%d: TX ring full, resetting\n", sc->sf_unit); - sf_init(sc); + if_printf(ifp, "TX ring full, resetting\n"); + sf_init_locked(sc); txprod = csr_read_4(sc, SF_TXDQ_PRODIDX); i = SF_IDX_HI(txprod) >> 4; } @@ -1423,10 +1454,8 @@ sf_start(ifp) break; } - if (cur_tx == NULL) { - SF_UNLOCK(sc); + if (cur_tx == NULL) return; - } /* Transmit */ csr_write_4(sc, SF_TXDQ_PRODIDX, @@ -1434,8 +1463,6 @@ sf_start(ifp) ((i << 20) & 0xFFFF0000)); ifp->if_timer = 5; - - SF_UNLOCK(sc); } static void @@ -1445,11 +1472,11 @@ sf_stop(sc) int i; struct ifnet *ifp; - SF_LOCK(sc); + SF_LOCK_ASSERT(sc); ifp = sc->sf_ifp; - untimeout(sf_stats_update, sc, sc->sf_stat_ch); + callout_stop(&sc->sf_stat_callout); #ifdef DEVICE_POLLING ether_poll_deregister(ifp); @@ -1483,7 +1510,6 @@ sf_stop(sc) } ifp->if_drv_flags &= ~(IFF_DRV_RUNNING|IFF_DRV_OACTIVE); - SF_UNLOCK(sc); } /* @@ -1505,7 +1531,7 @@ sf_stats_update(xsc) int i; sc = xsc; - SF_LOCK(sc); + SF_LOCK_ASSERT(sc); ifp = sc->sf_ifp; mii = device_get_softc(sc->sf_miibus); @@ -1527,12 +1553,10 @@ sf_stats_update(xsc) IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { sc->sf_link++; if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - sf_start(ifp); + sf_start_locked(ifp); } - sc->sf_stat_ch = timeout(sf_stats_update, sc, hz); - - SF_UNLOCK(sc); + callout_reset(&sc->sf_stat_callout, hz, sf_stats_update, sc); } static void @@ -1546,14 +1570,14 @@ sf_watchdog(ifp) SF_LOCK(sc); ifp->if_oerrors++; - printf("sf%d: watchdog timeout\n", sc->sf_unit); + if_printf(ifp, "watchdog timeout\n"); sf_stop(sc); sf_reset(sc); - sf_init(sc); + sf_init_locked(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - sf_start(ifp); + sf_start_locked(ifp); SF_UNLOCK(sc); } @@ -1566,5 +1590,7 @@ sf_shutdown(dev) sc = device_get_softc(dev); + SF_LOCK(sc); sf_stop(sc); + SF_UNLOCK(sc); } diff --git a/sys/pci/if_sfreg.h b/sys/pci/if_sfreg.h index bbd704c3f45c..652f804faa3d 100644 --- a/sys/pci/if_sfreg.h +++ b/sys/pci/if_sfreg.h @@ -1039,12 +1039,11 @@ struct sf_softc { struct resource *sf_res; /* mem/ioport resource */ struct sf_type *sf_info; /* Starfire adapter info */ device_t sf_miibus; - u_int8_t sf_unit; /* interface number */ struct sf_list_data *sf_ldata; int sf_tx_cnt; u_int8_t sf_link; int sf_if_flags; - struct callout_handle sf_stat_ch; + struct callout sf_stat_callout; struct mtx sf_mtx; #ifdef DEVICE_POLLING int rxcycles;