summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2009-12-02 12:39:30 -0800
committerDmitry Shmidt <dimitrysh@google.com>2009-12-02 12:47:32 -0800
commit93826f4d911a7efde794a19e9e72a0a8cc6360ae (patch)
tree29d112d825a592b602348baeb0e64621ef41a09a
parent08111ea8c525690e7cb10a5ca121e7659dd0ffec (diff)
downloadwlan-93826f4d911a7efde794a19e9e72a0a8cc6360ae.tar.gz
bcm4329: Fix unregister_netdevice() race conditions (b/2249878)
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
-rw-r--r--bcm4329/src/dhd/sys/dhd_linux.c61
1 files changed, 29 insertions, 32 deletions
diff --git a/bcm4329/src/dhd/sys/dhd_linux.c b/bcm4329/src/dhd/sys/dhd_linux.c
index 88c5d6a..36f695c 100644
--- a/bcm4329/src/dhd/sys/dhd_linux.c
+++ b/bcm4329/src/dhd/sys/dhd_linux.c
@@ -2050,6 +2050,14 @@ dhd_detach(dhd_pub_t *dhdp)
#if defined(CONFIG_HAS_EARLYSUSPEND)
unregister_early_suspend(&dhd->early_suspend);
#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */
+#ifdef CONFIG_WIRELESS_EXT
+ /* Attach and link in the iw */
+ wl_iw_detach();
+#endif
+ if (dhd->sysioc_pid >= 0) {
+ KILL_PROC(dhd->sysioc_pid, SIGTERM);
+ wait_for_completion(&dhd->sysioc_exited);
+ }
for (i = 1; i < DHD_MAX_IFS; i++)
if (dhd->iflist[i])
@@ -2062,46 +2070,35 @@ dhd_detach(dhd_pub_t *dhdp)
unregister_netdev(ifp->net);
}
+ if (dhd->watchdog_pid >= 0)
+ {
+ KILL_PROC(dhd->watchdog_pid, SIGTERM);
+ wait_for_completion(&dhd->watchdog_exited);
+ }
- if (dhd->watchdog_pid >= 0)
- {
- KILL_PROC(dhd->watchdog_pid, SIGTERM);
- wait_for_completion(&dhd->watchdog_exited);
- }
-
- if (dhd->dpc_pid >= 0)
- {
- KILL_PROC(dhd->dpc_pid, SIGTERM);
- wait_for_completion(&dhd->dpc_exited);
- }
- else
- tasklet_kill(&dhd->tasklet);
-
- if (dhd->sysioc_pid >= 0) {
- KILL_PROC(dhd->sysioc_pid, SIGTERM);
- wait_for_completion(&dhd->sysioc_exited);
- }
+ if (dhd->dpc_pid >= 0)
+ {
+ KILL_PROC(dhd->dpc_pid, SIGTERM);
+ wait_for_completion(&dhd->dpc_exited);
+ }
+ else
+ tasklet_kill(&dhd->tasklet);
- dhd_bus_detach(dhdp);
+ dhd_bus_detach(dhdp);
- if (dhdp->prot)
- dhd_prot_detach(dhdp);
-
-#ifdef CONFIG_WIRELESS_EXT
- /* Attach and link in the iw */
- wl_iw_detach();
-#endif
+ if (dhdp->prot)
+ dhd_prot_detach(dhdp);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
- unregister_pm_notifier(&dhd_sleep_pm_notifier);
+ unregister_pm_notifier(&dhd_sleep_pm_notifier);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
- free_netdev(ifp->net);
+ free_netdev(ifp->net);
#ifdef CONFIG_HAS_WAKELOCK
- wake_lock_destroy(&dhd->wl_wifi);
- wake_lock_destroy(&dhd->wl_rxwake);
+ wake_lock_destroy(&dhd->wl_wifi);
+ wake_lock_destroy(&dhd->wl_rxwake);
#endif
- MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
- MFREE(dhd->pub.osh, dhd, sizeof(*dhd));
+ MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
+ MFREE(dhd->pub.osh, dhd, sizeof(*dhd));
}
}
}