Author: thompsa
Date: Thu Feb 12 18:57:18 2009
New Revision: 188533
URL: http://svn.freebsd.org/changeset/base/188533

Log:
  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

Modified:
  head/sys/net80211/ieee80211.c
  head/sys/net80211/ieee80211_ioctl.c
  head/sys/net80211/ieee80211_proto.c
  head/sys/net80211/ieee80211_proto.h

Modified: head/sys/net80211/ieee80211.c
==============================================================================
--- head/sys/net80211/ieee80211.c       Thu Feb 12 18:50:27 2009        
(r188532)
+++ head/sys/net80211/ieee80211.c       Thu Feb 12 18:57:18 2009        
(r188533)
@@ -289,9 +289,9 @@ ieee80211_ifdetach(struct ieee80211com *
        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);

Modified: head/sys/net80211/ieee80211_ioctl.c
==============================================================================
--- head/sys/net80211/ieee80211_ioctl.c Thu Feb 12 18:50:27 2009        
(r188532)
+++ head/sys/net80211/ieee80211_ioctl.c Thu Feb 12 18:57:18 2009        
(r188533)
@@ -3265,7 +3265,7 @@ ieee80211_ioctl(struct ifnet *ifp, u_lon
                }
                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:

Modified: head/sys/net80211/ieee80211_proto.c
==============================================================================
--- head/sys/net80211/ieee80211_proto.c Thu Feb 12 18:50:27 2009        
(r188532)
+++ head/sys/net80211/ieee80211_proto.c Thu Feb 12 18:57:18 2009        
(r188533)
@@ -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 *
                        ieee80211_stop_locked(vap);
        }
        IEEE80211_UNLOCK(ic);
+
+       ieee80211_waitfor_parent(ic);
 }
 
 /*
@@ -1278,6 +1291,8 @@ ieee80211_suspend_all(struct ieee80211co
                }
        }
        IEEE80211_UNLOCK(ic);
+
+       ieee80211_waitfor_parent(ic);
 }
 
 /*

Modified: head/sys/net80211/ieee80211_proto.h
==============================================================================
--- head/sys/net80211/ieee80211_proto.h Thu Feb 12 18:50:27 2009        
(r188532)
+++ head/sys/net80211/ieee80211_proto.h Thu Feb 12 18:57:18 2009        
(r188533)
@@ -260,6 +260,7 @@ ieee80211_gettid(const struct ieee80211_
        return tid;
 }
 
+void   ieee80211_waitfor_parent(struct ieee80211com *);
 void   ieee80211_start_locked(struct ieee80211vap *);
 void   ieee80211_init(void *);
 void   ieee80211_start_all(struct ieee80211com *);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to