diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2009-12-02 12:39:30 -0800 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2009-12-02 12:47:32 -0800 |
commit | 93826f4d911a7efde794a19e9e72a0a8cc6360ae (patch) | |
tree | 29d112d825a592b602348baeb0e64621ef41a09a | |
parent | 08111ea8c525690e7cb10a5ca121e7659dd0ffec (diff) | |
download | wlan-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.c | 61 |
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)); } } } |