diff options
author | nohee ko <noheek@broadcom.com> | 2010-10-12 13:33:29 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-12 14:07:45 -0700 |
commit | af73713642c1c02e5afefb0f807f406e835c0b7f (patch) | |
tree | f7ab5cb8bba046eff83db1bc60eed6290f350ec0 /drivers/staging/brcm80211/brcmfmac | |
parent | c11b0ef8fe171f0b50999d61e401e4908980a774 (diff) | |
download | op-kernel-dev-af73713642c1c02e5afefb0f807f406e835c0b7f.zip op-kernel-dev-af73713642c1c02e5afefb0f807f406e835c0b7f.tar.gz |
staging: brcm80211: bug fix- rmmod hang problem
Bug fix - rmmod hang problem.
Can keep both of kthread & down_interruptible.
And in the meantime, can terminate the threads
properly during rmmod process.
Signed-off-by: Nohee Ko <noheek@broadcom.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/brcm80211/brcmfmac')
-rw-r--r-- | drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 7 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 15 | ||||
-rw-r--r-- | drivers/staging/brcm80211/brcmfmac/wl_iw.c | 2 |
3 files changed, 23 insertions, 1 deletions
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 7d900fa..4548e1f 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -938,6 +938,8 @@ static int _dhd_sysioc_thread(void *data) bool in_ap = false; #endif + allow_signal(SIGTERM); + while (down_interruptible(&dhd->sysioc_sem) == 0) { if (kthread_should_stop()) break; @@ -1295,6 +1297,7 @@ static int dhd_watchdog_thread(void *data) } #endif /* DHD_SCHED */ + allow_signal(SIGTERM); /* Run until signal received */ while (1) { if (kthread_should_stop()) @@ -1360,6 +1363,7 @@ static int dhd_dpc_thread(void *data) } #endif /* DHD_SCHED */ + allow_signal(SIGTERM); /* Run until signal received */ while (1) { if (kthread_should_stop()) @@ -2336,17 +2340,20 @@ void dhd_detach(dhd_pub_t *dhdp) } if (dhd->watchdog_tsk) { + KILL_PROC(dhd->watchdog_tsk->pid, SIGTERM); kthread_stop(dhd->watchdog_tsk); dhd->watchdog_tsk = NULL; } if (dhd->dpc_tsk) { + KILL_PROC(dhd->dpc_tsk->pid, SIGTERM); kthread_stop(dhd->dpc_tsk); dhd->dpc_tsk = NULL; } else tasklet_kill(&dhd->tasklet); if (dhd->sysioc_tsk) { + KILL_PROC(dhd->sysioc_tsk->pid, SIGTERM); kthread_stop(dhd->sysioc_tsk); dhd->sysioc_tsk = NULL; } diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index dfa793b..d9f4e9e 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -2849,6 +2849,7 @@ static s32 wl_create_event_handler(struct wl_priv *wl) static void wl_destroy_event_handler(struct wl_priv *wl) { if (wl->event_tsk) { + KILL_PROC(wl->event_tsk->pid, SIGTERM); kthread_stop(wl->event_tsk); wl->event_tsk = NULL; } @@ -2860,6 +2861,7 @@ static void wl_term_iscan(struct wl_priv *wl) if (wl->iscan_on && iscan->tsk) { iscan->state = WL_ISCAN_STATE_IDLE; + KILL_PROC(iscan->tsk->pid, SIGTERM); kthread_stop(iscan->tsk); iscan->tsk = NULL; } @@ -2994,6 +2996,7 @@ static s32 wl_iscan_thread(void *data) int err = 0; sched_setscheduler(current, SCHED_FIFO, ¶m); + allow_signal(SIGTERM); status = WL_SCAN_RESULTS_PARTIAL; while (likely(!down_interruptible(&iscan->sync))) { if (kthread_should_stop()) @@ -3015,6 +3018,7 @@ static s32 wl_iscan_thread(void *data) del_timer_sync(&iscan->timer); iscan->timer_on = 0; } + WL_DBG(("%s was terminated\n", __func__)); return 0; } @@ -3215,6 +3219,7 @@ static s32 wl_event_handler(void *data) struct wl_event_q *e; sched_setscheduler(current, SCHED_FIFO, ¶m); + allow_signal(SIGTERM); while (likely(!down_interruptible(&wl->event_sync))) { if (kthread_should_stop()) break; @@ -3232,6 +3237,7 @@ static s32 wl_event_handler(void *data) } wl_put_event(e); } + WL_DBG(("%s was terminated\n", __func__)); return 0; } @@ -3799,7 +3805,14 @@ static s32 __wl_cfg80211_down(struct wl_priv *wl) if (wl->scan_request) { cfg80211_scan_done(wl->scan_request, true); /* true means abort */ - wl_set_mpc(ndev, 1); + /* wl_set_mpc(wl_to_ndev(wl), 1); */ /* BUG + * this operation cannot help + * but here because sdio + * is already down through + * rmmod process. + * Need to figure out how to + * address this issue + */ wl->scan_request = NULL; } clear_bit(WL_STATUS_READY, &wl->status); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 0593bb5..6a27f9b 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -1177,6 +1177,7 @@ static int _iscan_sysioc_thread(void *data) iscan_info_t *iscan = (iscan_info_t *) data; static bool iscan_pass_abort = false; + allow_signal(SIGTERM); status = WL_SCAN_RESULTS_PARTIAL; while (down_interruptible(&iscan->sysioc_sem) == 0) { if (kthread_should_stop()) @@ -3744,6 +3745,7 @@ void wl_iw_detach(void) if (!iscan) return; if (iscan->sysioc_tsk) { + KILL_PROC(iscan->sysioc_tsk->pid, SIGTERM); kthread_stop(iscan->sysioc_tsk); iscan->sysioc_tsk = NULL; } |