summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2009-02-12 18:57:18 +0000
committerthompsa <thompsa@FreeBSD.org>2009-02-12 18:57:18 +0000
commit251dd2ca418183142f0f78ada90a77fa46a3b88f (patch)
treeb2387f8d726c23cdd8238be123008604c2dc3292 /sys
parentcc499f763ee65f3e6109a50d14b10ef520ca6079 (diff)
downloadFreeBSD-src-251dd2ca418183142f0f78ada90a77fa46a3b88f.zip
FreeBSD-src-251dd2ca418183142f0f78ada90a77fa46a3b88f.tar.gz
Add a ieee80211_waitfor_parent() function that will wait for all deferred
parent interface tasks to complete. This had been added to the ioctl path but it is also need elsewhere like detach so its safe to teardown. Reported by: Hans Petter Selasky Submitted by: sam
Diffstat (limited to 'sys')
-rw-r--r--sys/net80211/ieee80211.c2
-rw-r--r--sys/net80211/ieee80211_ioctl.c2
-rw-r--r--sys/net80211/ieee80211_proto.c15
-rw-r--r--sys/net80211/ieee80211_proto.h1
4 files changed, 18 insertions, 2 deletions
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index 4dd8776..7a02eda 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -289,9 +289,9 @@ ieee80211_ifdetach(struct ieee80211com *ic)
struct ifnet *ifp = ic->ic_ifp;
struct ieee80211vap *vap;
- /* XXX ieee80211_stop_all? */
while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
ieee80211_vap_destroy(vap);
+ ieee80211_waitfor_parent(ic);
ieee80211_sysctl_detach(ic);
ieee80211_regdomain_detach(ic);
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index db36adb..7f7417e 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -3265,7 +3265,7 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
IEEE80211_UNLOCK(ic);
/* Wait for parent ioctl handler if it was queued */
- taskqueue_drain(taskqueue_thread, &ic->ic_parent_task);
+ ieee80211_waitfor_parent(ic);
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 31b68fd..b31d3af 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -1072,6 +1072,17 @@ parent_updown(void *arg, int npending)
}
/*
+ * Block until the parent is in a known state. This is
+ * used after any operations that dispatch a task (e.g.
+ * to auto-configure the parent device up/down).
+ */
+void
+ieee80211_waitfor_parent(struct ieee80211com *ic)
+{
+ taskqueue_drain(taskqueue_thread, &ic->ic_parent_task);
+}
+
+/*
* Start a vap running. If this is the first vap to be
* set running on the underlying device then we
* automatically bring the device up.
@@ -1258,6 +1269,8 @@ ieee80211_stop_all(struct ieee80211com *ic)
ieee80211_stop_locked(vap);
}
IEEE80211_UNLOCK(ic);
+
+ ieee80211_waitfor_parent(ic);
}
/*
@@ -1278,6 +1291,8 @@ ieee80211_suspend_all(struct ieee80211com *ic)
}
}
IEEE80211_UNLOCK(ic);
+
+ ieee80211_waitfor_parent(ic);
}
/*
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index f7395b6..fa50758 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -260,6 +260,7 @@ ieee80211_gettid(const struct ieee80211_frame *wh)
return tid;
}
+void ieee80211_waitfor_parent(struct ieee80211com *);
void ieee80211_start_locked(struct ieee80211vap *);
void ieee80211_init(void *);
void ieee80211_start_all(struct ieee80211com *);
OpenPOWER on IntegriCloud