diff options
author | jhb <jhb@FreeBSD.org> | 2005-08-16 20:39:30 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2005-08-16 20:39:30 +0000 |
commit | 907015177644e8c45939f686c9cafc14febbb80b (patch) | |
tree | 7c3a3643ef8deb9e0e9e2696f1893ea56d236747 /sys/dev | |
parent | c1c0b1f44eab8d811187701834cddb397b22027c (diff) | |
download | FreeBSD-src-907015177644e8c45939f686c9cafc14febbb80b.zip FreeBSD-src-907015177644e8c45939f686c9cafc14febbb80b.tar.gz |
Fixup locking in if_my(4) and mark it MPSAFE:
- Add locked variants of my_start() and my_init().
- Assert that the lock is held in several places rather than recursing.
- Overhaul failure case handling in my_attach() so that it will actually
clean up completely in each of the failure cases.
- Setup the interrupt after ether_ifattach() in my_attach().
- Remove unused callout handle from softc.
- Free the metadata for the descriptors my_in detach() (we leaked it
before).
- Fix locking in my_ioctl().
- Remove spls.
Tested by: brueffer
MFC after: 3 days
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/my/if_my.c | 198 | ||||
-rw-r--r-- | sys/dev/my/if_myreg.h | 2 |
2 files changed, 96 insertions, 104 deletions
diff --git a/sys/dev/my/if_my.c b/sys/dev/my/if_my.c index 39ec004..bc5568e 100644 --- a/sys/dev/my/if_my.c +++ b/sys/dev/my/if_my.c @@ -127,8 +127,10 @@ static void my_txeof(struct my_softc *); 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 @@ my_send_cmd_to_phy(struct my_softc * sc, int opcode, int regad) 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 @@ my_send_cmd_to_phy(struct my_softc * sc, int opcode, int regad) miir &= ~MY_MASK_MIIR_MII_WRITE; } - MY_UNLOCK(sc); return miir; } @@ -232,7 +233,7 @@ my_phy_readreg(struct my_softc * sc, int reg) 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 @@ my_phy_readreg(struct my_softc * sc, int reg) CSR_WRITE_4(sc, MY_MANAGEMENT, miir); } - MY_UNLOCK(sc); return (u_int16_t) data; } @@ -277,7 +277,7 @@ my_phy_writereg(struct my_softc * sc, int reg, int data) 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 @@ my_phy_writereg(struct my_softc * sc, int reg, int data) miir &= ~MY_MASK_MIIR_MII_MDC; CSR_WRITE_4(sc, MY_MANAGEMENT, miir); } - MY_UNLOCK(sc); return; } @@ -325,7 +324,7 @@ my_setmulti(struct my_softc * sc) u_int32_t rxfilt; int mcnt = 0; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; @@ -337,8 +336,6 @@ my_setmulti(struct my_softc * sc) 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 @@ my_setmulti(struct my_softc * sc) 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 @@ my_autoneg_xmit(struct my_softc * sc) { 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 @@ my_autoneg_xmit(struct my_softc * sc) phy_sts |= PHY_BMCR_AUTONEGENBL | PHY_BMCR_AUTONEGRSTR; my_phy_writereg(sc, PHY_BMCR, phy_sts); - MY_UNLOCK(sc); return; } @@ -405,7 +400,7 @@ my_autoneg_mii(struct my_softc * sc, int flag, int verbose) struct ifnet *ifp; struct ifmedia *ifm; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); ifm = &sc->ifmedia; ifp = sc->my_ifp; @@ -422,7 +417,6 @@ my_autoneg_mii(struct my_softc * sc, int flag, int verbose) 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 @@ my_autoneg_mii(struct my_softc * sc, int flag, int verbose) 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 @@ my_autoneg_mii(struct my_softc * sc, int flag, int verbose) 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 @@ my_getmode_mii(struct my_softc * sc) 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 @@ my_getmode_mii(struct my_softc * sc) 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 @@ my_setmode_mii(struct my_softc * sc, int media) 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_setmode_mii(struct my_softc * sc, int media) } my_phy_writereg(sc, PHY_BMCR, bmcr); my_setcfg(sc, bmcr); - MY_UNLOCK(sc); return; } @@ -722,7 +712,7 @@ my_setcfg(struct my_softc * sc, int bmcr) { 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_setcfg(struct my_softc * sc, int bmcr) 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 @@ my_reset(struct my_softc * sc) { 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 @@ my_reset(struct my_softc * sc) /* Wait a little while for the chip to get its brains in order. */ DELAY(1000); - MY_UNLOCK(sc); return; } @@ -802,7 +790,7 @@ my_probe(device_t dev) 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,11 +802,9 @@ my_attach(device_t dev) 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. @@ -837,7 +823,7 @@ my_attach(device_t dev) 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 +834,16 @@ my_attach(device_t dev) 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; - } - 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; + goto release_io; } - 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 +856,7 @@ my_attach(device_t dev) 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 +875,7 @@ my_attach(device_t dev) 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 +893,7 @@ my_attach(device_t dev) 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 +927,48 @@ my_attach(device_t dev) 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 +977,20 @@ my_detach(device_t dev) { 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 +1006,7 @@ my_list_tx_init(struct my_softc * sc) 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 +1019,6 @@ my_list_tx_init(struct my_softc * sc) } 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 +1034,7 @@ my_list_rx_init(struct my_softc * sc) 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 +1055,6 @@ my_list_rx_init(struct my_softc * sc) } } cd->my_rx_head = &cd->my_rx_chain[0]; - MY_UNLOCK(sc); return (0); } @@ -1074,12 +1066,11 @@ my_newbuf(struct my_softc * sc, struct my_chain_onefrag * c) { 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 +1078,12 @@ my_newbuf(struct my_softc * sc, struct my_chain_onefrag * c) 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 +1101,7 @@ my_rxeof(struct my_softc * sc) 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 +1166,6 @@ my_rxeof(struct my_softc * sc) (*ifp->if_input)(ifp, m); MY_LOCK(sc); } - MY_UNLOCK(sc); return; } @@ -1192,12 +1180,11 @@ my_txeof(struct my_softc * sc) 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 +1222,6 @@ my_txeof(struct my_softc * sc) 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 +1233,7 @@ my_txeoc(struct my_softc * sc) { 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 +1248,6 @@ my_txeoc(struct my_softc * sc) CSR_WRITE_4(sc, MY_TXPDR, 0xFFFFFFFF); } } - MY_UNLOCK(sc); return; } @@ -1300,7 +1285,7 @@ my_intr(void *arg) #ifdef foo my_stop(sc); my_reset(sc); - my_init(sc); + my_init_locked(sc); #endif } if (status & MY_TI) /* tx interrupt */ @@ -1313,7 +1298,7 @@ my_intr(void *arg) #if 0 /* 90/1/18 delete */ if (status & MY_FBE) { my_reset(sc); - my_init(sc); + my_init_locked(sc); } #endif @@ -1322,7 +1307,7 @@ my_intr(void *arg) /* 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 +1323,7 @@ my_encap(struct my_softc * sc, struct my_chain * c, struct mbuf * m_head) 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 +1337,6 @@ my_encap(struct my_softc * sc, struct my_chain * c, struct mbuf * m_head) 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 +1344,6 @@ my_encap(struct my_softc * sc, struct my_chain * c, struct mbuf * m_head) 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 +1364,6 @@ my_encap(struct my_softc * sc, struct my_chain * c, struct mbuf * m_head) 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 +1377,24 @@ static void 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 +1402,6 @@ my_start(struct ifnet * ifp) */ 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 +1431,6 @@ my_start(struct ifnet * ifp) * If there are no packets queued, bail. */ if (cur_tx == NULL) { - MY_UNLOCK(sc); return; } /* @@ -1461,7 +1451,6 @@ my_start(struct ifnet * ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; - MY_UNLOCK(sc); return; } @@ -1469,16 +1458,22 @@ static void 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 +1503,6 @@ my_init(void *xsc) 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 +1550,6 @@ my_init(void *xsc) 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 +1644,23 @@ my_ioctl(struct ifnet * ifp, u_long command, caddr_t data) { 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 +1671,6 @@ my_ioctl(struct ifnet * ifp, u_long command, caddr_t data) error = ether_ioctl(ifp, command, data); break; } - MY_UNLOCK(sc); - (void)splx(s); return (error); } @@ -1701,9 +1692,9 @@ my_watchdog(struct ifnet * ifp) 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 +1709,7 @@ my_stop(struct my_softc * sc) register int i; struct ifnet *ifp; - MY_LOCK(sc); + MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; ifp->if_timer = 0; @@ -1750,7 +1741,6 @@ my_stop(struct my_softc * sc) 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 +1754,8 @@ my_shutdown(device_t dev) struct my_softc *sc; sc = device_get_softc(dev); + MY_LOCK(sc); my_stop(sc); + MY_UNLOCK(sc); return; } diff --git a/sys/dev/my/if_myreg.h b/sys/dev/my/if_myreg.h index 7e65fda..a552de5 100644 --- a/sys/dev/my/if_myreg.h +++ b/sys/dev/my/if_myreg.h @@ -369,7 +369,6 @@ struct my_softc { 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 @@ struct my_softc { /* 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 |