--- //depot/vendor/freebsd/src/sys/pci/if_wb.c 2005/08/31 18:05:33 +++ //depot/user/jhb/acpipci/pci/if_wb.c 2005/08/31 20:21:53 @@ -155,8 +155,10 @@ static void wb_intr(void *); static void wb_tick(void *); static void wb_start(struct ifnet *); +static void wb_start_locked(struct ifnet *); static int wb_ioctl(struct ifnet *, u_long, caddr_t); static void wb_init(void *); +static void wb_init_locked(struct wb_softc *); static void wb_stop(struct wb_softc *); static void wb_watchdog(struct ifnet *); static void wb_shutdown(device_t); @@ -392,7 +394,8 @@ { int i, ack; - WB_LOCK(sc); + if (sc->wb_ifp->if_input != NULL) + WB_LOCK_ASSERT(sc); /* * Set up frame for RX. @@ -471,8 +474,6 @@ SIO_SET(WB_SIO_MII_CLK); DELAY(1); - WB_UNLOCK(sc); - if (ack) return(1); return(0); @@ -487,7 +488,9 @@ struct wb_mii_frame *frame; { - WB_LOCK(sc); + + if (sc->wb_ifp->if_input != NULL) + WB_LOCK_ASSERT(sc); /* * Set up frame for TX. @@ -522,8 +525,6 @@ */ SIO_CLR(WB_SIO_MII_DIR); - WB_UNLOCK(sc); - return(0); } @@ -575,10 +576,10 @@ struct mii_data *mii; sc = device_get_softc(dev); - WB_LOCK(sc); + if (sc->wb_ifp->if_input != NULL) + WB_LOCK_ASSERT(sc); mii = device_get_softc(sc->wb_miibus); wb_setcfg(sc, mii->mii_media_active); - WB_UNLOCK(sc); return; } @@ -796,6 +797,8 @@ mtx_init(&sc->wb_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); + callout_init_mtx(&sc->wb_stat_callout, &sc->wb_mtx, 0); + /* * Map control/status registers. */ @@ -855,8 +858,7 @@ ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSGIANT; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = wb_ioctl; ifp->if_start = wb_start; ifp->if_watchdog = wb_watchdog; @@ -879,7 +881,7 @@ ether_ifattach(ifp, eaddr); /* Hook interrupt last to avoid having to lock softc */ - error = bus_setup_intr(dev, sc->wb_irq, INTR_TYPE_NET, + error = bus_setup_intr(dev, sc->wb_irq, INTR_TYPE_NET | INTR_MPSAFE, wb_intr, sc, &sc->wb_intrhand); if (error) { @@ -912,7 +914,6 @@ sc = device_get_softc(dev); KASSERT(mtx_initialized(&sc->wb_mtx), ("wb mutex not initialized")); - WB_LOCK(sc); ifp = sc->wb_ifp; /* @@ -920,7 +921,10 @@ * This should only be done if attach succeeded. */ if (device_is_attached(dev)) { + WB_LOCK(sc); wb_stop(sc); + WB_UNLOCK(sc); + callout_drain(&sc->wb_stat_callout); ether_ifdetach(ifp); if_free(ifp); } @@ -940,7 +944,6 @@ M_DEVBUF); } - WB_UNLOCK(sc); mtx_destroy(&sc->wb_mtx); return(0); @@ -1098,7 +1101,7 @@ "bug, forcing reset\n"); wb_fixmedia(sc); wb_reset(sc); - wb_init(sc); + wb_init_locked(sc); return; } @@ -1248,7 +1251,7 @@ WB_LOCK(sc); ifp = sc->wb_ifp; - if (!(ifp->if_flags & IFF_UP)) { + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { WB_UNLOCK(sc); return; } @@ -1270,7 +1273,7 @@ wb_reset(sc); if (status & WB_ISR_RX_ERR) wb_fixmedia(sc); - wb_init(sc); + wb_init_locked(sc); continue; } @@ -1307,7 +1310,7 @@ if (status & WB_ISR_BUS_ERR) { wb_reset(sc); - wb_init(sc); + wb_init_locked(sc); } } @@ -1316,7 +1319,7 @@ CSR_WRITE_4(sc, WB_IMR, WB_INTRS); if (ifp->if_snd.ifq_head != NULL) { - wb_start(ifp); + wb_start_locked(ifp); } WB_UNLOCK(sc); @@ -1332,14 +1335,12 @@ struct mii_data *mii; sc = xsc; - WB_LOCK(sc); + WB_LOCK_ASSERT(sc); mii = device_get_softc(sc->wb_miibus); mii_tick(mii); - sc->wb_stat_ch = timeout(wb_tick, sc, hz); - - WB_UNLOCK(sc); + callout_reset(&sc->wb_stat_callout, hz, wb_tick, sc); return; } @@ -1448,11 +1449,23 @@ struct ifnet *ifp; { struct wb_softc *sc; + + sc = ifp->if_softc; + WB_LOCK(sc); + wb_start_locked(ifp); + WB_UNLOCK(sc); +} + +static void +wb_start_locked(ifp) + struct ifnet *ifp; +{ + struct wb_softc *sc; struct mbuf *m_head = NULL; struct wb_chain *cur_tx = NULL, *start_tx; sc = ifp->if_softc; - WB_LOCK(sc); + WB_LOCK_ASSERT(sc); /* * Check for an available queue slot. If there are none, @@ -1460,7 +1473,6 @@ */ if (sc->wb_cdata.wb_tx_free->wb_mbuf != NULL) { ifp->if_drv_flags |= IFF_DRV_OACTIVE; - WB_UNLOCK(sc); return; } @@ -1491,10 +1503,8 @@ /* * If there are no packets queued, bail. */ - if (cur_tx == NULL) { - WB_UNLOCK(sc); + if (cur_tx == NULL) return; - } /* * Place the request for the upload interrupt @@ -1531,7 +1541,6 @@ * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; - WB_UNLOCK(sc); return; } @@ -1541,11 +1550,21 @@ void *xsc; { struct wb_softc *sc = xsc; + + WB_LOCK(sc); + wb_init_locked(sc); + WB_UNLOCK(sc); +} + +static void +wb_init_locked(sc) + struct wb_softc *sc; +{ struct ifnet *ifp = sc->wb_ifp; int i; struct mii_data *mii; - WB_LOCK(sc); + WB_LOCK_ASSERT(sc); mii = device_get_softc(sc->wb_miibus); /* @@ -1596,7 +1615,6 @@ if_printf(ifp, "initialization failed: no memory for rx buffers\n"); wb_stop(sc); - WB_UNLOCK(sc); return; } @@ -1649,8 +1667,7 @@ ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - sc->wb_stat_ch = timeout(wb_tick, sc, hz); - WB_UNLOCK(sc); + callout_reset(&sc->wb_stat_callout, hz, wb_tick, sc); return; } @@ -1666,8 +1683,10 @@ sc = ifp->if_softc; + WB_LOCK(sc); if (ifp->if_flags & IFF_UP) - wb_init(sc); + wb_init_locked(sc); + WB_UNLOCK(sc); return(0); } @@ -1685,11 +1704,13 @@ sc = ifp->if_softc; + WB_LOCK(sc); mii = device_get_softc(sc->wb_miibus); mii_pollstat(mii); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; + WB_UNLOCK(sc); return; } @@ -1705,21 +1726,23 @@ struct ifreq *ifr = (struct ifreq *) data; int error = 0; - WB_LOCK(sc); - switch(command) { case SIOCSIFFLAGS: + WB_LOCK(sc); if (ifp->if_flags & IFF_UP) { - wb_init(sc); + wb_init_locked(sc); } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) wb_stop(sc); } + WB_UNLOCK(sc); error = 0; break; case SIOCADDMULTI: case SIOCDELMULTI: + WB_LOCK(sc); wb_setmulti(sc); + WB_UNLOCK(sc); error = 0; break; case SIOCGIFMEDIA: @@ -1754,10 +1777,10 @@ #endif wb_stop(sc); wb_reset(sc); - wb_init(sc); + wb_init_locked(sc); if (ifp->if_snd.ifq_head != NULL) - wb_start(ifp); + wb_start_locked(ifp); WB_UNLOCK(sc); return; @@ -1774,11 +1797,11 @@ register int i; struct ifnet *ifp; - WB_LOCK(sc); + WB_LOCK_ASSERT(sc); ifp = sc->wb_ifp; ifp->if_timer = 0; - untimeout(wb_tick, sc, sc->wb_stat_ch); + callout_stop(&sc->wb_stat_callout); WB_CLRBIT(sc, WB_NETCFG, (WB_NETCFG_RX_ON|WB_NETCFG_TX_ON)); CSR_WRITE_4(sc, WB_IMR, 0x00000000); @@ -1811,7 +1834,6 @@ sizeof(sc->wb_ldata->wb_tx_list)); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - WB_UNLOCK(sc); return; } @@ -1827,7 +1849,10 @@ struct wb_softc *sc; sc = device_get_softc(dev); + + WB_LOCK(sc); wb_stop(sc); + WB_UNLOCK(sc); return; } --- //depot/vendor/freebsd/src/sys/pci/if_wbreg.h 2005/08/31 18:05:33 +++ //depot/user/jhb/acpipci/pci/if_wbreg.h 2005/08/31 20:06:55 @@ -376,7 +376,7 @@ caddr_t wb_ldata_ptr; struct wb_list_data *wb_ldata; struct wb_chain_data wb_cdata; - struct callout_handle wb_stat_ch; + struct callout wb_stat_callout; struct mtx wb_mtx; };