Module Name: src
Committed By: martin
Date: Sat Apr 6 16:50:48 UTC 2013
Modified Files:
src/sys/dev/ic: athn.c athnvar.h
Log Message:
Fix return type and value of athn_resume (true for success, not 0 for no
error).
Avoid endless recursion in athn_init when the device had been suspended
via pmf_device_recursive_resume -> athn_resume -> athn_init.
Avoid touching the hardware when the device is not fully powered up yet.
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/ic/athn.c src/sys/dev/ic/athnvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/ic/athn.c
diff -u src/sys/dev/ic/athn.c:1.3 src/sys/dev/ic/athn.c:1.4
--- src/sys/dev/ic/athn.c:1.3 Sat Apr 6 14:57:38 2013
+++ src/sys/dev/ic/athn.c Sat Apr 6 16:50:48 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: athn.c,v 1.3 2013/04/06 14:57:38 martin Exp $ */
+/* $NetBSD: athn.c,v 1.4 2013/04/06 16:50:48 martin Exp $ */
/* $OpenBSD: athn.c,v 1.75 2013/01/14 09:50:31 jsing Exp $ */
/*-
@@ -23,7 +23,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: athn.c,v 1.3 2013/04/06 14:57:38 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: athn.c,v 1.4 2013/04/06 16:50:48 martin Exp $");
#ifndef _MODULE
#include "athn_usb.h" /* for NATHN_USB */
@@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: athn.c,v 1.3
#include <sys/queue.h>
#include <sys/callout.h>
#include <sys/conf.h>
+#include <sys/cpu.h>
#include <sys/device.h>
#include <sys/bus.h>
@@ -527,6 +528,13 @@ athn_intr(void *xsc)
if (!IS_UP_AND_RUNNING(ifp))
return 0;
+ if (!device_activation(sc->sc_dev, DEVACT_LEVEL_DRIVER))
+ /*
+ * The hardware is not ready/present, don't touch anything.
+ * Note this can happen early on if the IRQ is shared.
+ */
+ return 0;
+
return sc->sc_ops.intr(sc);
}
@@ -2605,7 +2613,8 @@ athn_start(struct ifnet *ifp)
struct ieee80211_node *ni;
struct mbuf *m;
- if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
+ if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING
+ || !device_is_active(sc->sc_dev))
return;
for (;;) {
@@ -2806,11 +2815,22 @@ athn_init(struct ifnet *ifp)
size_t i;
int error;
- if (device_is_active(sc->sc_dev))
+ KASSERT(!cpu_intr_p());
+
+ if (device_is_active(sc->sc_dev)) {
athn_stop(ifp, 0); /* XXX: necessary? */
- else if (!pmf_device_subtree_resume(sc->sc_dev, &sc->sc_qual) ||
- !device_is_active(sc->sc_dev))
- return 0;
+ } else {
+ short flags = ifp->if_flags;
+ ifp->if_flags &= ~IFF_UP;
+ /* avoid recursion in athn_resume */
+ if (!pmf_device_subtree_resume(sc->sc_dev, &sc->sc_qual) ||
+ !device_is_active(sc->sc_dev)) {
+ printf("%s: failed to power up device\n",
+ device_xname(sc->sc_dev));
+ return 0;
+ }
+ ifp->if_flags = flags;
+ }
curchan = ic->ic_curchan;
extchan = NULL;
@@ -2977,12 +2997,13 @@ athn_suspend(struct athn_softc *sc)
athn_stop(ifp, 1);
}
-PUBLIC int
+PUBLIC bool
athn_resume(struct athn_softc *sc)
{
struct ifnet *ifp = &sc->sc_if;
if (ifp->if_flags & IFF_UP)
- return athn_init(ifp);
- return 0;
+ athn_init(ifp);
+
+ return true;
}
Index: src/sys/dev/ic/athnvar.h
diff -u src/sys/dev/ic/athnvar.h:1.3 src/sys/dev/ic/athnvar.h:1.4
--- src/sys/dev/ic/athnvar.h:1.3 Wed Apr 3 14:20:03 2013
+++ src/sys/dev/ic/athnvar.h Sat Apr 6 16:50:48 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: athnvar.h,v 1.3 2013/04/03 14:20:03 christos Exp $ */
+/* $NetBSD: athnvar.h,v 1.4 2013/04/06 16:50:48 martin Exp $ */
/* $OpenBSD: athnvar.h,v 1.33 2012/10/20 09:54:20 stsp Exp $ */
/*-
@@ -621,7 +621,7 @@ struct athn_softc {
int athn_attach(struct athn_softc *);
void athn_detach(struct athn_softc *);
void athn_suspend(struct athn_softc *);
-int athn_resume(struct athn_softc *);
+bool athn_resume(struct athn_softc *);
int athn_intr(void *);
/* used by if_athn_usb.c */