--- //depot/vendor/freebsd/src/sys/dev/fxp/if_fxp.c 2005/06/11 00:50:21 +++ //depot/user/jhb/acpipci/dev/fxp/if_fxp.c 2005/08/02 14:58:28 @@ -375,7 +375,7 @@ uint16_t data, myea[ETHER_ADDR_LEN / 2]; u_char eaddr[ETHER_ADDR_LEN]; int i, rid, m1, m2, prefer_iomap; - int error, s; + int error; error = 0; sc = device_get_softc(dev); @@ -386,8 +386,6 @@ ifmedia_init(&sc->sc_media, 0, fxp_serial_ifmedia_upd, fxp_serial_ifmedia_sts); - s = splimp(); - ifp = sc->ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { device_printf(dev, "can not if_alloc()\n"); @@ -810,7 +808,6 @@ } fail: - splx(s); if (error) fxp_release(sc); return (error); @@ -894,33 +891,29 @@ fxp_detach(device_t dev) { struct fxp_softc *sc = device_get_softc(dev); - int s; FXP_LOCK(sc); - s = splimp(); - sc->suspended = 1; /* Do same thing as we do for suspend */ /* - * Close down routes etc. - */ - ether_ifdetach(sc->ifp); - - /* * Stop DMA and drop transmit queue, but disable interrupts first. */ CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE); fxp_stop(sc); FXP_UNLOCK(sc); + callout_drain(&sc->stat_ch); /* + * Close down routes etc. + */ + ether_ifdetach(sc->ifp); + + /* * Unhook interrupt before dropping lock. This is to prevent * races with fxp_intr(). */ bus_teardown_intr(sc->dev, sc->irq, sc->ih); sc->ih = NULL; - splx(s); - /* Release our allocated resources. */ fxp_release(sc); return (0); @@ -934,12 +927,16 @@ static int fxp_shutdown(device_t dev) { + struct fxp_softc *sc = device_get_softc(dev); + /* * Make sure that DMA is disabled prior to reboot. Not doing * do could allow DMA to corrupt kernel memory during the * reboot before the driver initializes. */ - fxp_stop((struct fxp_softc *) device_get_softc(dev)); + FXP_LOCK(sc); + fxp_stop(sc); + FXP_UNLOCK(sc); return (0); } @@ -952,17 +949,14 @@ fxp_suspend(device_t dev) { struct fxp_softc *sc = device_get_softc(dev); - int s; FXP_LOCK(sc); - s = splimp(); fxp_stop(sc); sc->suspended = 1; FXP_UNLOCK(sc); - splx(s); return (0); } @@ -975,16 +969,18 @@ { struct fxp_softc *sc = device_get_softc(dev); struct ifnet *ifp = sc->ifp; +#ifdef not_needed_anymore uint16_t pci_command; - int s; +#endif FXP_LOCK(sc); - s = splimp(); +#ifdef not_needed_anymore /* reenable busmastering */ pci_command = pci_read_config(dev, PCIR_COMMAND, 2); pci_command |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); pci_write_config(dev, PCIR_COMMAND, pci_command, 2); +#endif CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET); DELAY(10); @@ -996,7 +992,6 @@ sc->suspended = 0; FXP_UNLOCK(sc); - splx(s); return (0); } @@ -1429,6 +1424,7 @@ * This could cause us to overwrite the completion status. * XXX This is probably bogus and we're _not_ looking * for atomicity here. + * XXX: looks like a job for bus_space (jhb) */ atomic_clear_16(&sc->fxp_desc.tx_last->tx_cb->cb_command, htole16(FXP_CB_COMMAND_S)); @@ -1751,10 +1747,12 @@ struct fxp_softc *sc = xsc; struct ifnet *ifp = sc->ifp; struct fxp_stats *sp = sc->fxp_stats; - int s; FXP_LOCK(sc); - s = splimp(); + if (!(ifp->if_flags & IFF_RUNNING)) { + FXP_UNLOCK(sc); + return; + } bus_dmamap_sync(sc->fxp_stag, sc->fxp_smap, BUS_DMASYNC_POSTREAD); ifp->if_opackets += le32toh(sp->tx_good); ifp->if_collisions += le32toh(sp->tx_total_collisions); @@ -1840,7 +1838,6 @@ */ callout_reset(&sc->stat_ch, hz, fxp_tick, sc); FXP_UNLOCK(sc); - splx(s); } /* @@ -1940,10 +1937,9 @@ struct fxp_cb_tx *tcbp; struct fxp_tx *txp; struct fxp_cb_mcs *mcsp; - int i, prm, s; + int i, prm; FXP_LOCK_ASSERT(sc, MA_OWNED); - s = splimp(); /* * Cancel any pending I/O */ @@ -2194,7 +2190,6 @@ * Start stats updater. */ callout_reset(&sc->stat_ch, hz, fxp_tick, sc); - splx(s); } static int @@ -2207,8 +2202,11 @@ static void fxp_serial_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) { + struct fxp_softc *sc = ifp->if_softc; + FXP_LOCK(sc); ifmr->ifm_active = IFM_ETHER|IFM_MANUAL; + FXP_UNLOCK(sc); } /* @@ -2221,7 +2219,9 @@ struct mii_data *mii; mii = device_get_softc(sc->miibus); + FXP_LOCK(sc); mii_mediachg(mii); + FXP_UNLOCK(sc); return (0); } @@ -2235,6 +2235,7 @@ struct mii_data *mii; mii = device_get_softc(sc->miibus); + FXP_LOCK(sc); mii_pollstat(mii); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; @@ -2243,6 +2244,7 @@ sc->cu_resume_bug = 1; else sc->cu_resume_bug = 0; + FXP_UNLOCK(sc); } /* @@ -2339,6 +2341,8 @@ int count = 10000; int value; + if (sc->ifp->if_init != NULL) + FXP_LOCK_ASSERT(sc, MA_OWNED); CSR_WRITE_4(sc, FXP_CSR_MDICONTROL, (FXP_MDI_READ << 26) | (reg << 16) | (phy << 21)); @@ -2358,6 +2362,8 @@ struct fxp_softc *sc = device_get_softc(dev); int count = 10000; + if (sc->ifp->if_init != NULL) + FXP_LOCK_ASSERT(sc, MA_OWNED); CSR_WRITE_4(sc, FXP_CSR_MDICONTROL, (FXP_MDI_WRITE << 26) | (reg << 16) | (phy << 21) | (value & 0xffff)); @@ -2376,20 +2382,11 @@ struct fxp_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *)data; struct mii_data *mii; - int flag, mask, s, error = 0; + int flag, mask, error = 0; - /* - * Detaching causes us to call ioctl with the mutex owned. Preclude - * that by saying we're busy if the lock is already held. - */ - if (FXP_LOCKED(sc)) - return (EBUSY); - - FXP_LOCK(sc); - s = splimp(); - switch (command) { case SIOCSIFFLAGS: + FXP_LOCK(sc); if (ifp->if_flags & IFF_ALLMULTI) sc->flags |= FXP_FLAG_ALL_MCAST; else @@ -2407,10 +2404,12 @@ if (ifp->if_flags & IFF_RUNNING) fxp_stop(sc); } + FXP_UNLOCK(sc); break; case SIOCADDMULTI: case SIOCDELMULTI: + FXP_LOCK(sc); if (ifp->if_flags & IFF_ALLMULTI) sc->flags |= FXP_FLAG_ALL_MCAST; else @@ -2427,6 +2426,7 @@ */ if (sc->flags & FXP_FLAG_ALL_MCAST) fxp_init_body(sc); + FXP_UNLOCK(sc); error = 0; break; @@ -2442,6 +2442,7 @@ break; case SIOCSIFCAP: + FXP_LOCK(sc); mask = ifp->if_capenable ^ ifr->ifr_reqcap; if (mask & IFCAP_POLLING) ifp->if_capenable ^= IFCAP_POLLING; @@ -2455,19 +2456,12 @@ if (ifp->if_flags & IFF_UP) fxp_init_body(sc); } + FXP_UNLOCK(sc); break; default: - /* - * ether_ioctl() will eventually call fxp_start() which - * will result in mutex recursion so drop it first. - */ - FXP_UNLOCK(sc); error = ether_ioctl(ifp, command, data); } - if (FXP_LOCKED(sc)) - FXP_UNLOCK(sc); - splx(s); return (error); } @@ -2484,11 +2478,7 @@ nmcasts = 0; if ((sc->flags & FXP_FLAG_ALL_MCAST) == 0) { -#if __FreeBSD_version < 500000 - LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { -#else TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { -#endif if (ifma->ifma_addr->sa_family != AF_LINK) continue; if (nmcasts >= MAXMCADDR) { --- //depot/vendor/freebsd/src/sys/dev/fxp/if_fxpvar.h 2005/06/10 16:51:34 +++ //depot/user/jhb/acpipci/dev/fxp/if_fxpvar.h 2005/08/01 15:32:58 @@ -101,21 +101,10 @@ */ #define TUNABLE_BUNDLE_MAX 6 -#if __FreeBSD_version < 500000 -#define FXP_LOCK(_sc) -#define FXP_UNLOCK(_sc) -#define FXP_LOCKED(_sc) -#define FXP_LOCK_ASSERT(_sc, _what) -#define INTR_MPSAFE 0 -#define mtx_init(a, b, c, d) -#define mtx_destroy(a) -struct mtx { int dummy; }; -#else #define FXP_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) #define FXP_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) #define FXP_LOCKED(_sc) mtx_owned(&(_sc)->sc_mtx) #define FXP_LOCK_ASSERT(_sc, _what) mtx_assert(&(_sc)->sc_mtx, (_what)) -#endif /* * Structures to handle TX and RX descriptors.