summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorKevin Lo <kevlo@cvs.openbsd.org>2011-08-21 15:25:21 +0000
committerKevin Lo <kevlo@cvs.openbsd.org>2011-08-21 15:25:21 +0000
commit7212d06c0e5938a8c576561b6e540e019bad36bb (patch)
tree124a6764cdede17d9370ad4f1222591d39077ed1 /sys/dev
parent680e42a8a8eeff4b57ed079a67b9111107daa9bd (diff)
Help with the watchdog timeouts seen when unplugging the cable from
the alc(4) NIC while running or the NIC not working if the cable is not plugged in upon boot up. From Brad; tested by matteo filippetto, Gabriel Linder and edd@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_alc.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/sys/dev/pci/if_alc.c b/sys/dev/pci/if_alc.c
index 75447886762..b1c03400458 100644
--- a/sys/dev/pci/if_alc.c
+++ b/sys/dev/pci/if_alc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_alc.c,v 1.15 2011/06/17 07:16:42 kevlo Exp $ */
+/* $OpenBSD: if_alc.c,v 1.16 2011/08/21 15:25:20 kevlo Exp $ */
/*-
* Copyright (c) 2009, Pyun YongHyeon <yongari@FreeBSD.org>
* All rights reserved.
@@ -214,14 +214,12 @@ alc_miibus_statchg(struct device *dev)
{
struct alc_softc *sc = (struct alc_softc *)dev;
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
- struct mii_data *mii;
+ struct mii_data *mii = &sc->sc_miibus;
uint32_t reg;
if ((ifp->if_flags & IFF_RUNNING) == 0)
return;
- mii = &sc->sc_miibus;
-
sc->alc_flags &= ~ALC_FLAG_LINK;
if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
(IFM_ACTIVE | IFM_AVALID)) {
@@ -260,6 +258,9 @@ alc_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
struct alc_softc *sc = ifp->if_softc;
struct mii_data *mii = &sc->sc_miibus;
+ if ((ifp->if_flags & IFF_UP) == 0)
+ return;
+
mii_pollstat(mii);
ifmr->ifm_status = mii->mii_media_status;
ifmr->ifm_active = mii->mii_media_active;
@@ -1381,6 +1382,10 @@ alc_start(struct ifnet *ifp)
if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
return;
+ if ((sc->alc_flags & ALC_FLAG_LINK) == 0)
+ return;
+ if (IFQ_IS_EMPTY(&ifp->if_snd))
+ return;
for (;;) {
IFQ_DEQUEUE(&ifp->if_snd, m_head);
@@ -1441,9 +1446,7 @@ alc_watchdog(struct ifnet *ifp)
printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
ifp->if_oerrors++;
alc_init(ifp);
-
- if (!IFQ_IS_EMPTY(&ifp->if_snd))
- alc_start(ifp);
+ alc_start(ifp);
}
int
@@ -1726,12 +1729,12 @@ alc_intr(void *arg)
return (0);
}
- if (status & INTR_TX_PKT) {
+ if (status & INTR_TX_PKT)
alc_txeof(sc);
- if (!IFQ_IS_EMPTY(&ifp->if_snd))
- alc_start(ifp);
- }
+
+ alc_start(ifp);
}
+
claimed = 1;
back:
/* Re-enable interrupts. */