--- //depot/vendor/freebsd/src/sys/dev/my/if_my.c 2005/08/10 20:25:25 +++ //depot/user/jhb/acpipci/dev/my/if_my.c 2005/08/10 20:45:43 @@ -127,8 +127,10 @@ static void my_txeoc(struct my_softc *); static void my_intr(void *); static void my_start(struct ifnet *); +static void my_start_locked(struct ifnet *); static int my_ioctl(struct ifnet *, u_long, caddr_t); static void my_init(void *); +static void my_init_locked(struct my_softc *); static void my_stop(struct my_softc *); static void my_watchdog(struct ifnet *); static void my_shutdown(device_t); @@ -179,7 +181,7 @@ int i; int mask, data; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); /* enable MII output */ miir = CSR_READ_4(sc, MY_MANAGEMENT); @@ -221,7 +223,6 @@ miir &= ~MY_MASK_MIIR_MII_WRITE; } - MY_UNLOCK(sc); return miir; } @@ -232,7 +233,7 @@ long miir; int mask, data; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); if (sc->my_info->my_did == MTD803ID) data = CSR_READ_2(sc, MY_PHYBASE + reg * 2); @@ -266,7 +267,6 @@ CSR_WRITE_4(sc, MY_MANAGEMENT, miir); } - MY_UNLOCK(sc); return (u_int16_t) data; } @@ -277,7 +277,7 @@ long miir; int mask; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); if (sc->my_info->my_did == MTD803ID) CSR_WRITE_2(sc, MY_PHYBASE + reg * 2, data); @@ -307,7 +307,6 @@ miir &= ~MY_MASK_MIIR_MII_MDC; CSR_WRITE_4(sc, MY_MANAGEMENT, miir); } - MY_UNLOCK(sc); return; } @@ -325,7 +324,7 @@ u_int32_t rxfilt; int mcnt = 0; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; @@ -337,8 +336,6 @@ CSR_WRITE_4(sc, MY_MAR0, 0xFFFFFFFF); CSR_WRITE_4(sc, MY_MAR1, 0xFFFFFFFF); - MY_UNLOCK(sc); - return; } /* first, zot all the existing hash bits */ @@ -367,7 +364,6 @@ CSR_WRITE_4(sc, MY_MAR0, hashes[0]); CSR_WRITE_4(sc, MY_MAR1, hashes[1]); CSR_WRITE_4(sc, MY_TCRRCR, rxfilt); - MY_UNLOCK(sc); return; } @@ -379,7 +375,7 @@ { u_int16_t phy_sts = 0; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); my_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET); DELAY(500); @@ -389,7 +385,6 @@ phy_sts |= PHY_BMCR_AUTONEGENBL | PHY_BMCR_AUTONEGRSTR; my_phy_writereg(sc, PHY_BMCR, phy_sts); - MY_UNLOCK(sc); return; } @@ -405,7 +400,7 @@ struct ifnet *ifp; struct ifmedia *ifm; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); ifm = &sc->ifmedia; ifp = sc->my_ifp; @@ -422,7 +417,6 @@ if (verbose) if_printf(ifp, "autonegotiation not supported\n"); ifm->ifm_media = IFM_ETHER | IFM_10_T | IFM_HDX; - MY_UNLOCK(sc); return; } #endif @@ -453,7 +447,6 @@ ifp->if_timer = 5; sc->my_autoneg = 1; sc->my_want_auto = 0; - MY_UNLOCK(sc); return; case MY_FLAG_DELAYTIMEO: ifp->if_timer = 0; @@ -551,13 +544,12 @@ if_printf(ifp, "no carrier\n"); } - my_init(sc); + my_init_locked(sc); if (sc->my_tx_pend) { sc->my_autoneg = 0; sc->my_tx_pend = 0; - my_start(ifp); + my_start_locked(ifp); } - MY_UNLOCK(sc); return; } @@ -570,7 +562,7 @@ u_int16_t bmsr; struct ifnet *ifp; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; bmsr = my_phy_readreg(sc, PHY_BMSR); if (bootverbose) @@ -648,7 +640,6 @@ ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL); sc->ifmedia.ifm_media = IFM_ETHER | IFM_AUTO; } - MY_UNLOCK(sc); return; } @@ -661,7 +652,7 @@ u_int16_t bmcr; struct ifnet *ifp; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; /* * If an autoneg session is in progress, stop it. @@ -708,7 +699,6 @@ } my_phy_writereg(sc, PHY_BMCR, bmcr); my_setcfg(sc, bmcr); - MY_UNLOCK(sc); return; } @@ -722,7 +712,7 @@ { int i, restart = 0; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); if (CSR_READ_4(sc, MY_TCRRCR) & (MY_TE | MY_RE)) { restart = 1; MY_CLRBIT(sc, MY_TCRRCR, (MY_TE | MY_RE)); @@ -748,7 +738,6 @@ MY_CLRBIT(sc, MY_TCRRCR, MY_FD); if (restart) MY_SETBIT(sc, MY_TCRRCR, MY_TE | MY_RE); - MY_UNLOCK(sc); return; } @@ -757,7 +746,7 @@ { register int i; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); MY_SETBIT(sc, MY_BCR, MY_SWR); for (i = 0; i < MY_TIMEOUT; i++) { DELAY(10); @@ -769,7 +758,6 @@ /* Wait a little while for the chip to get its brains in order. */ DELAY(1000); - MY_UNLOCK(sc); return; } @@ -802,7 +790,7 @@ static int my_attach(device_t dev) { - int s, i; + int i; u_char eaddr[ETHER_ADDR_LEN]; u_int32_t iobase; struct my_softc *sc; @@ -814,17 +802,16 @@ u_int16_t phy_vid, phy_did, phy_sts = 0; int rid, error = 0; - s = splimp(); sc = device_get_softc(dev); mtx_init(&sc->my_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); - MY_LOCK(sc); + MTX_DEF); /* * Map control/status registers. */ pci_enable_busmaster(dev); + /* XXX: This code doesn't do any good. */ if (my_info_tmp->my_did == MTD800ID) { iobase = pci_read_config(dev, MY_PCI_LOIO, 4); if (iobase & 0x300) @@ -837,7 +824,7 @@ if (sc->my_res == NULL) { device_printf(dev, "couldn't map ports/memory\n"); error = ENXIO; - goto fail; + goto destroy_mutex; } sc->my_btag = rman_get_bustag(sc->my_res); sc->my_bhandle = rman_get_bushandle(sc->my_res); @@ -848,25 +835,16 @@ if (sc->my_irq == NULL) { device_printf(dev, "couldn't map interrupt\n"); - bus_release_resource(dev, MY_RES, MY_RID, sc->my_res); error = ENXIO; - goto fail; + goto release_io; } - error = bus_setup_intr(dev, sc->my_irq, INTR_TYPE_NET, - my_intr, sc, &sc->my_intrhand); - if (error) { - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->my_irq); - bus_release_resource(dev, MY_RES, MY_RID, sc->my_res); - device_printf(dev, "couldn't set up irq\n"); - goto fail; - } - callout_handle_init(&sc->my_stat_ch); - sc->my_info = my_info_tmp; /* Reset the adapter. */ + MY_LOCK(sc); my_reset(sc); + MY_UNLOCK(sc); /* * Get station address @@ -879,7 +857,7 @@ if (sc->my_ldata_ptr == NULL) { device_printf(dev, "no memory for list buffers!\n"); error = ENXIO; - goto fail; + goto release_irq; } sc->my_ldata = (struct my_list_data *) sc->my_ldata_ptr; round = (uintptr_t)sc->my_ldata_ptr & 0xF; @@ -898,7 +876,7 @@ if (ifp == NULL) { device_printf(dev, "can not if_alloc()\n"); error = ENOSPC; - goto fail; + goto free_ldata; } ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); @@ -916,6 +894,7 @@ else { if (bootverbose) device_printf(dev, "probing for a PHY\n"); + MY_LOCK(sc); for (i = MY_PHYADDR_MIN; i < MY_PHYADDR_MAX + 1; i++) { if (bootverbose) device_printf(dev, "checking address: %d\n", i); @@ -949,31 +928,48 @@ device_printf(dev, "PHY type: %s\n", sc->my_pinfo->my_name); } else { + MY_UNLOCK(sc); device_printf(dev, "MII without any phy!\n"); error = ENXIO; - goto fail; + goto free_if; } + MY_UNLOCK(sc); } /* Do ifmedia setup. */ ifmedia_init(&sc->ifmedia, 0, my_ifmedia_upd, my_ifmedia_sts); + MY_LOCK(sc); my_getmode_mii(sc); my_autoneg_mii(sc, MY_FLAG_FORCEDELAY, 1); media = sc->ifmedia.ifm_media; my_stop(sc); + MY_UNLOCK(sc); ifmedia_set(&sc->ifmedia, media); ether_ifattach(ifp, eaddr); + + error = bus_setup_intr(dev, sc->my_irq, INTR_TYPE_NET | INTR_MPSAFE, + my_intr, sc, &sc->my_intrhand); + + if (error) { + device_printf(dev, "couldn't set up irq\n"); + goto detach_if; + } - MY_UNLOCK(sc); return (0); -fail: - MY_UNLOCK(sc); +detach_if: + ether_ifdetach(ifp); +free_if: + if_free(ifp); +free_ldata: + free(sc->my_ldata_ptr, M_DEVBUF); +release_irq: + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->my_irq); +release_io: + bus_release_resource(dev, MY_RES, MY_RID, sc->my_res); +destroy_mutex: mtx_destroy(&sc->my_mtx); - if (sc->my_ldata_ptr != NULL) - free(sc->my_ldata_ptr, M_DEVBUF); - splx(s); return (error); } @@ -982,21 +978,20 @@ { struct my_softc *sc; struct ifnet *ifp; - int s; - s = splimp(); sc = device_get_softc(dev); MY_LOCK(sc); + my_stop(sc); + MY_UNLOCK(sc); + bus_teardown_intr(dev, sc->my_irq, sc->my_intrhand); + ifp = sc->my_ifp; ether_ifdetach(ifp); if_free(ifp); - my_stop(sc); + free(sc->my_ldata_ptr, M_DEVBUF); - bus_teardown_intr(dev, sc->my_irq, sc->my_intrhand); bus_release_resource(dev, SYS_RES_IRQ, 0, sc->my_irq); bus_release_resource(dev, MY_RES, MY_RID, sc->my_res); - MY_UNLOCK(sc); - splx(s); mtx_destroy(&sc->my_mtx); return (0); } @@ -1012,7 +1007,7 @@ struct my_list_data *ld; int i; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); cd = &sc->my_cdata; ld = sc->my_ldata; for (i = 0; i < MY_TX_LIST_CNT; i++) { @@ -1025,7 +1020,6 @@ } cd->my_tx_free = &cd->my_tx_chain[0]; cd->my_tx_tail = cd->my_tx_head = NULL; - MY_UNLOCK(sc); return (0); } @@ -1041,7 +1035,7 @@ struct my_list_data *ld; int i; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); cd = &sc->my_cdata; ld = sc->my_ldata; for (i = 0; i < MY_RX_LIST_CNT; i++) { @@ -1062,7 +1056,6 @@ } } cd->my_rx_head = &cd->my_rx_chain[0]; - MY_UNLOCK(sc); return (0); } @@ -1074,12 +1067,11 @@ { struct mbuf *m_new = NULL; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); MGETHDR(m_new, M_DONTWAIT, MT_DATA); if (m_new == NULL) { if_printf(sc->my_ifp, "no memory for rx list -- packet dropped!\n"); - MY_UNLOCK(sc); return (ENOBUFS); } MCLGET(m_new, M_DONTWAIT); @@ -1087,14 +1079,12 @@ if_printf(sc->my_ifp, "no memory for rx list -- packet dropped!\n"); m_freem(m_new); - MY_UNLOCK(sc); return (ENOBUFS); } c->my_mbuf = m_new; c->my_ptr->my_data = vtophys(mtod(m_new, caddr_t)); c->my_ptr->my_ctl = (MCLBYTES - 1) << MY_RBSShift; c->my_ptr->my_status = MY_OWNByNIC; - MY_UNLOCK(sc); return (0); } @@ -1112,7 +1102,7 @@ int total_len = 0; u_int32_t rxstat; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; while (!((rxstat = sc->my_cdata.my_rx_head->my_ptr->my_status) & MY_OWNByNIC)) { @@ -1177,7 +1167,6 @@ (*ifp->if_input)(ifp, m); MY_LOCK(sc); } - MY_UNLOCK(sc); return; } @@ -1192,12 +1181,11 @@ struct my_chain *cur_tx; struct ifnet *ifp; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; /* Clear the timeout timer. */ ifp->if_timer = 0; if (sc->my_cdata.my_tx_head == NULL) { - MY_UNLOCK(sc); return; } /* @@ -1235,7 +1223,6 @@ if (CSR_READ_4(sc, MY_TCRRCR) & MY_Enhanced) { ifp->if_collisions += (CSR_READ_4(sc, MY_TSR) & MY_NCRMask); } - MY_UNLOCK(sc); return; } @@ -1247,7 +1234,7 @@ { struct ifnet *ifp; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; ifp->if_timer = 0; if (sc->my_cdata.my_tx_head == NULL) { @@ -1262,7 +1249,6 @@ CSR_WRITE_4(sc, MY_TXPDR, 0xFFFFFFFF); } } - MY_UNLOCK(sc); return; } @@ -1300,7 +1286,7 @@ #ifdef foo my_stop(sc); my_reset(sc); - my_init(sc); + my_init_locked(sc); #endif } if (status & MY_TI) /* tx interrupt */ @@ -1313,7 +1299,7 @@ #if 0 /* 90/1/18 delete */ if (status & MY_FBE) { my_reset(sc); - my_init(sc); + my_init_locked(sc); } #endif @@ -1322,7 +1308,7 @@ /* Re-enable interrupts. */ CSR_WRITE_4(sc, MY_IMR, MY_INTRS); if (ifp->if_snd.ifq_head != NULL) - my_start(ifp); + my_start_locked(ifp); MY_UNLOCK(sc); return; } @@ -1338,7 +1324,7 @@ int total_len; struct mbuf *m, *m_new = NULL; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); /* calculate the total tx pkt length */ total_len = 0; for (m = m_head; m != NULL; m = m->m_next) @@ -1352,7 +1338,6 @@ MGETHDR(m_new, M_DONTWAIT, MT_DATA); if (m_new == NULL) { if_printf(sc->my_ifp, "no memory for tx list"); - MY_UNLOCK(sc); return (1); } if (m_head->m_pkthdr.len > MHLEN) { @@ -1360,7 +1345,6 @@ if (!(m_new->m_flags & M_EXT)) { m_freem(m_new); if_printf(sc->my_ifp, "no memory for tx list"); - MY_UNLOCK(sc); return (1); } } @@ -1381,7 +1365,6 @@ c->my_mbuf = m_head; c->my_lastdesc = 0; MY_TXNEXT(c) = vtophys(&c->my_nextdesc->my_ptr->my_frag[0]); - MY_UNLOCK(sc); return (0); } @@ -1395,14 +1378,24 @@ my_start(struct ifnet * ifp) { struct my_softc *sc; + + sc = ifp->if_softc; + MY_LOCK(sc); + my_start_locked(ifp); + MY_UNLOCK(sc); +} + +static void +my_start_locked(struct ifnet * ifp) +{ + struct my_softc *sc; struct mbuf *m_head = NULL; struct my_chain *cur_tx = NULL, *start_tx; sc = ifp->if_softc; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); if (sc->my_autoneg) { sc->my_tx_pend = 1; - MY_UNLOCK(sc); return; } /* @@ -1410,7 +1403,6 @@ */ if (sc->my_cdata.my_tx_free->my_mbuf != NULL) { ifp->if_drv_flags |= IFF_DRV_OACTIVE; - MY_UNLOCK(sc); return; } start_tx = sc->my_cdata.my_tx_free; @@ -1440,7 +1432,6 @@ * If there are no packets queued, bail. */ if (cur_tx == NULL) { - MY_UNLOCK(sc); return; } /* @@ -1461,7 +1452,6 @@ * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; - MY_UNLOCK(sc); return; } @@ -1469,16 +1459,22 @@ my_init(void *xsc) { struct my_softc *sc = xsc; + + MY_LOCK(sc); + my_init_locked(sc); + MY_UNLOCK(sc); +} + +static void +my_init_locked(struct my_softc *sc) +{ struct ifnet *ifp = sc->my_ifp; - int s; u_int16_t phy_bmcr = 0; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); if (sc->my_autoneg) { - MY_UNLOCK(sc); return; } - s = splimp(); if (sc->my_pinfo != NULL) phy_bmcr = my_phy_readreg(sc, PHY_BMCR); /* @@ -1508,8 +1504,6 @@ if (my_list_rx_init(sc) == ENOBUFS) { if_printf(ifp, "init failed: no memory for rx buffers\n"); my_stop(sc); - (void)splx(s); - MY_UNLOCK(sc); return; } /* Init TX descriptors. */ @@ -1557,8 +1551,6 @@ my_phy_writereg(sc, PHY_BMCR, phy_bmcr); ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - (void)splx(s); - MY_UNLOCK(sc); return; } @@ -1653,21 +1645,23 @@ { struct my_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; - int s, error = 0; + int error; - s = splimp(); - MY_LOCK(sc); switch (command) { case SIOCSIFFLAGS: + MY_LOCK(sc); if (ifp->if_flags & IFF_UP) - my_init(sc); + my_init_locked(sc); else if (ifp->if_drv_flags & IFF_DRV_RUNNING) my_stop(sc); + MY_UNLOCK(sc); error = 0; break; case SIOCADDMULTI: case SIOCDELMULTI: + MY_LOCK(sc); my_setmulti(sc); + MY_UNLOCK(sc); error = 0; break; case SIOCGIFMEDIA: @@ -1678,8 +1672,6 @@ error = ether_ioctl(ifp, command, data); break; } - MY_UNLOCK(sc); - (void)splx(s); return (error); } @@ -1701,9 +1693,9 @@ if_printf(ifp, "no carrier - transceiver cable problem?\n"); my_stop(sc); my_reset(sc); - my_init(sc); + my_init_locked(sc); if (ifp->if_snd.ifq_head != NULL) - my_start(ifp); + my_start_locked(ifp); MY_LOCK(sc); return; } @@ -1718,7 +1710,7 @@ register int i; struct ifnet *ifp; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; ifp->if_timer = 0; @@ -1750,7 +1742,6 @@ bzero((char *)&sc->my_ldata->my_tx_list, sizeof(sc->my_ldata->my_tx_list)); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - MY_UNLOCK(sc); return; } @@ -1764,6 +1755,8 @@ struct my_softc *sc; sc = device_get_softc(dev); + MY_LOCK(sc); my_stop(sc); + MY_UNLOCK(sc); return; } --- //depot/vendor/freebsd/src/sys/dev/my/if_myreg.h 2005/08/10 20:20:40 +++ //depot/user/jhb/acpipci/dev/my/if_myreg.h 2005/08/10 20:45:43 @@ -369,7 +369,6 @@ struct my_list_data *my_ldata; struct my_chain_data my_cdata; device_t my_miibus; - struct callout_handle my_stat_ch; /* Add by Surfer 2001/12/2 */ struct mtx my_mtx; @@ -378,6 +377,7 @@ /* Add by Surfer 2001/12/2 */ #define MY_LOCK(_sc) mtx_lock(&(_sc)->my_mtx) #define MY_UNLOCK(_sc) mtx_unlock(&(_sc)->my_mtx) +#define MY_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->my_mtx, MA_OWNED) /* * register space access macros