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
This commit is contained in:
John Baldwin 2005-08-16 20:39:30 +00:00
parent 52d71e1a85
commit ca5fc32d02
2 changed files with 97 additions and 105 deletions

View File

@ -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;
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 +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);
}
@ -1393,16 +1375,26 @@ my_encap(struct my_softc * sc, struct my_chain * c, struct mbuf * m_head)
*/
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;
struct ifnet *ifp = sc->my_ifp;
int s;
u_int16_t phy_bmcr = 0;
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;
u_int16_t phy_bmcr = 0;
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;
}

View File

@ -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