--- //depot/vendor/freebsd/src/sys/pci/if_xl.c 2005/08/09 10:22:44 +++ //depot/user/jhb/acpipci/pci/if_xl.c 2005/08/17 14:40:04 @@ -458,7 +458,8 @@ { int i, ack; - /*XL_LOCK_ASSERT(sc);*/ + if (sc->xl_ifp->if_input != NULL) + XL_LOCK_ASSERT(sc); /* Set up frame for RX. */ frame->mii_stdelim = XL_MII_STARTDELIM; @@ -528,7 +529,8 @@ xl_mii_writereg(struct xl_softc *sc, struct xl_mii_frame *frame) { - /*XL_LOCK_ASSERT(sc);*/ + if (sc->xl_ifp->if_input != NULL) + XL_LOCK_ASSERT(sc); /* Set up frame for TX. */ frame->mii_stdelim = XL_MII_STARTDELIM; @@ -567,6 +569,8 @@ struct xl_mii_frame frame; sc = device_get_softc(dev); + if (sc->xl_ifp->if_input != NULL) + XL_LOCK_ASSERT(sc); /* * Pretend that PHYs are only available at MII address 24. @@ -594,6 +598,8 @@ struct xl_mii_frame frame; sc = device_get_softc(dev); + if (sc->xl_ifp->if_input != NULL) + XL_LOCK_ASSERT(sc); if ((sc->xl_flags & XL_FLAG_PHYOK) == 0 && phy != 24) return (0); @@ -617,7 +623,8 @@ sc = device_get_softc(dev); mii = device_get_softc(sc->xl_miibus); - /*XL_LOCK_ASSERT(sc);*/ + if (sc->xl_ifp->if_input != NULL) + XL_LOCK_ASSERT(sc); xl_setcfg(sc); @@ -651,7 +658,8 @@ mii = device_get_softc(sc->xl_miibus); ifm = &mii->mii_media; - /*XL_LOCK_ASSERT(sc);*/ + if (sc->xl_ifp->if_input != NULL) + XL_LOCK_ASSERT(sc); if (sc->xl_media & (XL_MEDIAOPT_AUI | XL_MEDIAOPT_10FL)) { /* @@ -716,8 +724,6 @@ int err = 0, i; u_int16_t word = 0, *ptr; - XL_LOCK_ASSERT(sc); - #define EEPROM_5BIT_OFFSET(A) ((((A) << 2) & 0x7F00) | ((A) & 0x003F)) #define EEPROM_8BIT_OFFSET(A) ((A) & 0x003F) /* @@ -904,7 +910,7 @@ u_int16_t mediastat; char *pmsg = "", *dmsg = ""; - /*XL_LOCK_ASSERT(sc);*/ + XL_LOCK_ASSERT(sc); XL_SEL_WIN(4); mediastat = CSR_READ_2(sc, XL_W4_MEDIA_STATUS); @@ -1091,8 +1097,6 @@ xl_mediacheck(struct xl_softc *sc) { - XL_LOCK_ASSERT(sc); - /* * If some of the media options bits are set, assume they are * correct. If not, try to figure it out down below. @@ -1364,10 +1368,10 @@ ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + /* Reset the adapter. */ XL_LOCK(sc); - - /* Reset the adapter. */ xl_reset(sc); + XL_UNLOCK(sc); /* * Get station address from the EEPROM. @@ -1375,14 +1379,11 @@ if (xl_read_eeprom(sc, (caddr_t)&eaddr, XL_EE_OEM_ADR0, 3, 1)) { device_printf(dev, "failed to read station address\n"); error = ENXIO; - XL_UNLOCK(sc); goto fail; } - XL_UNLOCK(sc); - sc->xl_unit = unit; - callout_handle_init(&sc->xl_stat_ch); + callout_init_mtx(&sc->xl_stat_callout, &sc->xl_mtx, 0); TASK_INIT(&sc->xl_task, 0, xl_rxeof_task, sc); /* @@ -1473,8 +1474,6 @@ if (error) goto fail; - XL_LOCK(sc); - /* * Figure out the card type. 3c905B adapters have the * 'supportsNoTxLength' bit set in the capabilities @@ -1533,9 +1532,6 @@ xl_mediacheck(sc); - /* XXX Downcalls to ifmedia, miibus about to happen. */ - XL_UNLOCK(sc); - if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BTX || sc->xl_media & XL_MEDIAOPT_BT4) { @@ -1556,12 +1552,8 @@ * a 10/100 card of some kind, we need to force the transceiver * type to something sane. */ - if (sc->xl_xcvr == XL_XCVR_AUTO) { - /* XXX Direct hardware access needs lock coverage. */ - XL_LOCK(sc); + if (sc->xl_xcvr == XL_XCVR_AUTO) xl_choose_xcvr(sc, bootverbose); - XL_UNLOCK(sc); - } /* * Do ifmedia setup. @@ -1610,7 +1602,6 @@ ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_FX, 0, NULL); } - /* XXX: Unlocked, leaf will take lock. */ media = IFM_ETHER|IFM_100_TX|IFM_FDX; xl_choose_media(sc, &media); @@ -1618,7 +1609,6 @@ ifmedia_set(&sc->ifmedia, media); done: - /* XXX: Unlocked hardware access, narrow race. */ if (sc->xl_flags & XL_FLAG_NO_XCVR_PWR) { XL_SEL_WIN(0); CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS); @@ -1648,7 +1638,8 @@ /* * Choose a default media. * XXX This is a leaf function only called by xl_attach() and - * acquires/releases the non-recursible driver mutex. + * acquires/releases the non-recursible driver mutex to + * satisfy lock assertions. */ static void xl_choose_media(struct xl_softc *sc, int *media) @@ -1715,7 +1706,6 @@ ifp = sc->xl_ifp; KASSERT(mtx_initialized(&sc->xl_mtx), ("xl mutex not initialized")); - XL_LOCK(sc); if (sc->xl_flags & XL_FLAG_USE_MMIO) { rid = XL_PCI_LOMEM; @@ -1727,8 +1717,12 @@ /* These should only be active if attach succeeded */ if (device_is_attached(dev)) { + XL_LOCK(sc); xl_reset(sc); xl_stop(sc); + XL_UNLOCK(sc); + taskqueue_drain(taskqueue_swi, &sc->xl_task); + callout_drain(&sc->xl_stat_callout); ether_ifdetach(ifp); if_free(ifp); } @@ -1766,7 +1760,6 @@ bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag); } - XL_UNLOCK(sc); mtx_destroy(&sc->xl_mtx); return (0); @@ -2076,6 +2069,14 @@ XL_UNLOCK(sc); (*ifp->if_input)(ifp, m); XL_LOCK(sc); + + /* + * If we are running from the taskqueue, the interface + * might have been stopped while we were passing the last + * packet up the network stack. + */ + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + return; } /* @@ -2111,7 +2112,8 @@ NET_LOCK_GIANT(); XL_LOCK(sc); - xl_rxeof(sc); + if (sc->xl_ifp->if_drv_flags & IFF_DRV_RUNNING) + xl_rxeof(sc); XL_UNLOCK(sc); NET_UNLOCK_GIANT(); } @@ -2441,9 +2443,8 @@ { struct xl_softc *sc = xsc; - XL_LOCK(sc); + XL_LOCK_ASSERT(sc); xl_stats_update_locked(sc); - XL_UNLOCK(sc); } static void @@ -2490,7 +2491,7 @@ XL_SEL_WIN(7); if (!sc->xl_stats_no_timeout) - sc->xl_stat_ch = timeout(xl_stats_update, sc, hz); + callout_reset(&sc->xl_stat_callout, hz, xl_stats_update, sc); } /* @@ -3032,7 +3033,7 @@ ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - sc->xl_stat_ch = timeout(xl_stats_update, sc, hz); + callout_reset(&sc->xl_stat_callout, hz, xl_stats_update, sc); } /* @@ -3045,7 +3046,7 @@ struct ifmedia *ifm = NULL; struct mii_data *mii = NULL; - /*XL_LOCK_ASSERT(sc);*/ + XL_LOCK(sc); if (sc->xl_miibus != NULL) mii = device_get_softc(sc->xl_miibus); @@ -3069,11 +3070,13 @@ if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BTX || sc->xl_media & XL_MEDIAOPT_BT4) { - xl_init(sc); /* XXX */ + xl_init_locked(sc); } else { xl_setmode(sc, ifm->ifm_media); } + XL_UNLOCK(sc); + return (0); } @@ -3088,7 +3091,7 @@ u_int16_t status = 0; struct mii_data *mii = NULL; - /*XL_LOCK_ASSERT(sc);*/ + XL_LOCK(sc); if (sc->xl_miibus != NULL) mii = device_get_softc(sc->xl_miibus); @@ -3148,6 +3151,8 @@ if_printf(ifp, "unknown XCVR type: %d\n", icfg); break; } + + XL_UNLOCK(sc); } static int @@ -3205,8 +3210,6 @@ break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: - /* XXX Downcall from ifmedia possibly with locks held. */ - /*XL_LOCK(sc);*/ if (sc->xl_miibus != NULL) mii = device_get_softc(sc->xl_miibus); if (mii == NULL) @@ -3215,7 +3218,6 @@ else error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); - /*XL_UNLOCK(sc);*/ break; case SIOCSIFCAP: XL_LOCK(sc); @@ -3286,7 +3288,9 @@ ether_poll_deregister(ifp); #endif /* DEVICE_POLLING */ - taskqueue_drain(taskqueue_swi, &sc->xl_task); +#ifdef notnow + taskqueue_stop(taskqueue_swi, &sc->xl_task); +#endif CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISABLE); CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE); @@ -3311,7 +3315,7 @@ bus_space_write_4(sc->xl_ftag, sc->xl_fhandle, 4, 0x8000); /* Stop the stats updater. */ - untimeout(xl_stats_update, sc, sc->xl_stat_ch); + callout_stop(&sc->xl_stat_callout); /* * Free data in the RX lists. --- //depot/vendor/freebsd/src/sys/pci/if_xlreg.h 2005/06/10 16:51:34 +++ //depot/user/jhb/acpipci/pci/if_xlreg.h 2005/08/11 21:33:07 @@ -601,7 +601,7 @@ int xl_if_flags; struct xl_list_data xl_ldata; struct xl_chain_data xl_cdata; - struct callout_handle xl_stat_ch; + struct callout xl_stat_callout; int xl_flags; struct resource *xl_fres; bus_space_handle_t xl_fhandle;