staging: brcm80211: stop using kthread for iscan status check in fullmac
authorFranky Lin <frankyl@broadcom.com>
Mon, 12 Sep 2011 10:14:45 +0000 (12:14 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 12 Sep 2011 14:55:44 +0000 (16:55 +0200)
Use work queue instead.

Reported-by: Johannes Berg <johannes@sipsolutions.net>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Reviewed-by: Howard Harte <hharte@broadcom.com>
Signed-off-by: Roland Vossen <rvossen@broadcom.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h

index db51c466f2e577548afe6c0566e20917beadc93b..c8e47ff9117d477a030f2f96f330b34ee6b6729e 100644 (file)
@@ -271,7 +271,6 @@ static s32 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar,
 static void brcmf_iscan_timer(unsigned long data);
 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv);
 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv);
-static s32 brcmf_iscan_thread(void *data);
 static s32 brcmf_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
                                 void *param, s32 paramlen, void *bufptr,
                                 s32 buflen);
@@ -3151,18 +3150,15 @@ static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
        struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
        struct brcmf_ssid ssid;
 
-       if (cfg_priv->iscan_on && iscan->tsk) {
+       if (cfg_priv->iscan_on) {
                iscan->state = WL_ISCAN_STATE_IDLE;
-               send_sig(SIGTERM, iscan->tsk, 1);
 
-               /*
-                * The iscan task may want to acquire the rtnl_lock
-                * so release it here upon stopping the task.
-                */
-               rtnl_unlock();
-               kthread_stop(iscan->tsk);
-               rtnl_lock();
-               iscan->tsk = NULL;
+               if (iscan->timer_on) {
+                       del_timer_sync(&iscan->timer);
+                       iscan->timer_on = 0;
+               }
+
+               cancel_work_sync(&iscan->work);
 
                /* Abort iscan running in FW */
                memset(&ssid, 0, sizeof(ssid));
@@ -3195,7 +3191,7 @@ static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
 {
        if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
                WL_SCAN("wake up iscan\n");
-               wake_up(&iscan->waitq);
+               schedule_work(&iscan->work);
                return 0;
        }
 
@@ -3294,50 +3290,28 @@ static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
        return err;
 }
 
-static s32 brcmf_iscan_thread(void *data)
+static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
 {
-       struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
        struct brcmf_cfg80211_iscan_ctrl *iscan =
-                       (struct brcmf_cfg80211_iscan_ctrl *)data;
+                       container_of(work, struct brcmf_cfg80211_iscan_ctrl,
+                                    work);
        struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
        struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
-       DECLARE_WAITQUEUE(wait, current);
-       u32 status;
-       int err = 0;
-
-       sched_setscheduler(current, SCHED_FIFO, &param);
-       allow_signal(SIGTERM);
-       status = BRCMF_SCAN_RESULTS_PARTIAL;
-       add_wait_queue(&iscan->waitq, &wait);
-       while (1) {
-               prepare_to_wait(&iscan->waitq, &wait, TASK_INTERRUPTIBLE);
-
-               schedule();
+       u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
 
-               if (kthread_should_stop())
-                       break;
-               if (iscan->timer_on) {
-                       del_timer_sync(&iscan->timer);
-                       iscan->timer_on = 0;
-               }
-               rtnl_lock();
-               err = brcmf_get_iscan_results(iscan, &status,
-                                             &cfg_priv->bss_list);
-               if (unlikely(err)) {
-                       status = BRCMF_SCAN_RESULTS_ABORTED;
-                       WL_ERR("Abort iscan\n");
-               }
-               rtnl_unlock();
-               el->handler[status](cfg_priv);
-       }
-       finish_wait(&iscan->waitq, &wait);
        if (iscan->timer_on) {
                del_timer_sync(&iscan->timer);
                iscan->timer_on = 0;
        }
-       WL_SCAN("ISCAN thread terminated\n");
 
-       return 0;
+       rtnl_lock();
+       if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
+               status = BRCMF_SCAN_RESULTS_ABORTED;
+               WL_ERR("Abort iscan\n");
+       }
+       rtnl_unlock();
+
+       el->handler[status](cfg_priv);
 }
 
 static void brcmf_iscan_timer(unsigned long data)
@@ -3356,15 +3330,9 @@ static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
 {
        struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
 
-       if (cfg_priv->iscan_on && !iscan->tsk) {
+       if (cfg_priv->iscan_on) {
                iscan->state = WL_ISCAN_STATE_IDLE;
-               init_waitqueue_head(&iscan->waitq);
-               iscan->tsk = kthread_run(brcmf_iscan_thread, iscan, "wl_iscan");
-               if (IS_ERR(iscan->tsk)) {
-                       WL_ERR("Could not create iscan thread\n");
-                       iscan->tsk = NULL;
-                       return -ENOMEM;
-               }
+               INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
        }
 
        return 0;
index 0542bac2d79e59068c4854623517890d9d1e117c..98cd47da86b66b2226bf42655e01023106797c6d 100644 (file)
@@ -248,8 +248,7 @@ struct brcmf_cfg80211_iscan_ctrl {
        u32 timer_ms;
        u32 timer_on;
        s32 state;
-       struct task_struct *tsk;
-       wait_queue_head_t waitq;
+       struct work_struct work;
        struct brcmf_cfg80211_iscan_eloop el;
        void *data;
        s8 ioctl_buf[BRCMF_C_IOCTL_SMLEN];