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
This commit is contained in:
parent
cc499f763e
commit
251dd2ca41
@ -289,9 +289,9 @@ ieee80211_ifdetach(struct ieee80211com *ic)
|
|||||||
struct ifnet *ifp = ic->ic_ifp;
|
struct ifnet *ifp = ic->ic_ifp;
|
||||||
struct ieee80211vap *vap;
|
struct ieee80211vap *vap;
|
||||||
|
|
||||||
/* XXX ieee80211_stop_all? */
|
|
||||||
while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
|
while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
|
||||||
ieee80211_vap_destroy(vap);
|
ieee80211_vap_destroy(vap);
|
||||||
|
ieee80211_waitfor_parent(ic);
|
||||||
|
|
||||||
ieee80211_sysctl_detach(ic);
|
ieee80211_sysctl_detach(ic);
|
||||||
ieee80211_regdomain_detach(ic);
|
ieee80211_regdomain_detach(ic);
|
||||||
|
@ -3265,7 +3265,7 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|||||||
}
|
}
|
||||||
IEEE80211_UNLOCK(ic);
|
IEEE80211_UNLOCK(ic);
|
||||||
/* Wait for parent ioctl handler if it was queued */
|
/* Wait for parent ioctl handler if it was queued */
|
||||||
taskqueue_drain(taskqueue_thread, &ic->ic_parent_task);
|
ieee80211_waitfor_parent(ic);
|
||||||
break;
|
break;
|
||||||
case SIOCADDMULTI:
|
case SIOCADDMULTI:
|
||||||
case SIOCDELMULTI:
|
case SIOCDELMULTI:
|
||||||
|
@ -1071,6 +1071,17 @@ parent_updown(void *arg, int npending)
|
|||||||
parent->if_ioctl(parent, SIOCSIFFLAGS, NULL);
|
parent->if_ioctl(parent, SIOCSIFFLAGS, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* Start a vap running. If this is the first vap to be
|
||||||
* set running on the underlying device then we
|
* set running on the underlying device then we
|
||||||
@ -1258,6 +1269,8 @@ ieee80211_stop_all(struct ieee80211com *ic)
|
|||||||
ieee80211_stop_locked(vap);
|
ieee80211_stop_locked(vap);
|
||||||
}
|
}
|
||||||
IEEE80211_UNLOCK(ic);
|
IEEE80211_UNLOCK(ic);
|
||||||
|
|
||||||
|
ieee80211_waitfor_parent(ic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1278,6 +1291,8 @@ ieee80211_suspend_all(struct ieee80211com *ic)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
IEEE80211_UNLOCK(ic);
|
IEEE80211_UNLOCK(ic);
|
||||||
|
|
||||||
|
ieee80211_waitfor_parent(ic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -260,6 +260,7 @@ ieee80211_gettid(const struct ieee80211_frame *wh)
|
|||||||
return tid;
|
return tid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ieee80211_waitfor_parent(struct ieee80211com *);
|
||||||
void ieee80211_start_locked(struct ieee80211vap *);
|
void ieee80211_start_locked(struct ieee80211vap *);
|
||||||
void ieee80211_init(void *);
|
void ieee80211_init(void *);
|
||||||
void ieee80211_start_all(struct ieee80211com *);
|
void ieee80211_start_all(struct ieee80211com *);
|
||||||
|
Loading…
Reference in New Issue
Block a user