|
@@ -3162,7 +3162,7 @@ static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
|
|
|
|
|
|
static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
|
|
|
{
|
|
|
- sema_init(&cfg_priv->event_sync, 0);
|
|
|
+ init_waitqueue_head(&cfg_priv->event_waitq);
|
|
|
cfg_priv->event_tsk = kthread_run(brcmf_event_handler, cfg_priv,
|
|
|
"wl_event_handler");
|
|
|
if (IS_ERR(cfg_priv->event_tsk)) {
|
|
@@ -3224,7 +3224,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");
|
|
|
- up(&iscan->sync);
|
|
|
+ wake_up(&iscan->waitq);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -3330,13 +3330,19 @@ static s32 brcmf_iscan_thread(void *data)
|
|
|
(struct brcmf_cfg80211_iscan_ctrl *)data;
|
|
|
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, ¶m);
|
|
|
allow_signal(SIGTERM);
|
|
|
status = BRCMF_SCAN_RESULTS_PARTIAL;
|
|
|
- while (likely(!down_interruptible(&iscan->sync))) {
|
|
|
+ add_wait_queue(&iscan->waitq, &wait);
|
|
|
+ while (1) {
|
|
|
+ prepare_to_wait(&iscan->waitq, &wait, TASK_INTERRUPTIBLE);
|
|
|
+
|
|
|
+ schedule();
|
|
|
+
|
|
|
if (kthread_should_stop())
|
|
|
break;
|
|
|
if (iscan->timer_on) {
|
|
@@ -3353,6 +3359,7 @@ static s32 brcmf_iscan_thread(void *data)
|
|
|
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;
|
|
@@ -3380,7 +3387,7 @@ static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
|
|
|
|
|
|
if (cfg_priv->iscan_on && !iscan->tsk) {
|
|
|
iscan->state = WL_ISCAN_STATE_IDLE;
|
|
|
- sema_init(&iscan->sync, 0);
|
|
|
+ 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");
|
|
@@ -3528,7 +3535,7 @@ void brcmf_cfg80211_detach(void)
|
|
|
|
|
|
static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv)
|
|
|
{
|
|
|
- up(&cfg_priv->event_sync);
|
|
|
+ wake_up(&cfg_priv->event_waitq);
|
|
|
}
|
|
|
|
|
|
static s32 brcmf_event_handler(void *data)
|
|
@@ -3537,27 +3544,39 @@ static s32 brcmf_event_handler(void *data)
|
|
|
(struct brcmf_cfg80211_priv *)data;
|
|
|
struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
|
|
|
struct brcmf_cfg80211_event_q *e;
|
|
|
+ DECLARE_WAITQUEUE(wait, current);
|
|
|
|
|
|
sched_setscheduler(current, SCHED_FIFO, ¶m);
|
|
|
allow_signal(SIGTERM);
|
|
|
- while (likely(!down_interruptible(&cfg_priv->event_sync))) {
|
|
|
+ add_wait_queue(&cfg_priv->event_waitq, &wait);
|
|
|
+ while (1) {
|
|
|
+ prepare_to_wait(&cfg_priv->event_waitq, &wait,
|
|
|
+ TASK_INTERRUPTIBLE);
|
|
|
+
|
|
|
+ schedule();
|
|
|
+
|
|
|
if (kthread_should_stop())
|
|
|
break;
|
|
|
+
|
|
|
e = brcmf_deq_event(cfg_priv);
|
|
|
if (unlikely(!e)) {
|
|
|
WL_ERR("event queue empty...\n");
|
|
|
- BUG();
|
|
|
+ continue;
|
|
|
}
|
|
|
- WL_INFO("event type (%d)\n", e->etype);
|
|
|
- if (cfg_priv->el.handler[e->etype])
|
|
|
- cfg_priv->el.handler[e->etype](cfg_priv,
|
|
|
- cfg_to_ndev(cfg_priv),
|
|
|
- &e->emsg, e->edata);
|
|
|
- else
|
|
|
- WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
|
|
|
|
|
|
- brcmf_put_event(e);
|
|
|
+ do {
|
|
|
+ WL_INFO("event type (%d)\n", e->etype);
|
|
|
+ if (cfg_priv->el.handler[e->etype])
|
|
|
+ cfg_priv->el.handler[e->etype](cfg_priv,
|
|
|
+ cfg_to_ndev(cfg_priv),
|
|
|
+ &e->emsg, e->edata);
|
|
|
+ else
|
|
|
+ WL_INFO("Unknown Event (%d): ignoring\n",
|
|
|
+ e->etype);
|
|
|
+ brcmf_put_event(e);
|
|
|
+ } while ((e = brcmf_deq_event(cfg_priv)));
|
|
|
}
|
|
|
+ finish_wait(&cfg_priv->event_waitq, &wait);
|
|
|
WL_INFO("was terminated\n");
|
|
|
return 0;
|
|
|
}
|