diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-04-10 09:31:39 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-10 09:31:39 -0400 |
commit | 6fe5468f452c0c40348ebd4e737758a842286ca8 (patch) | |
tree | befe5ab33c457a9e695b65be72600f383266e611 /net | |
parent | deb09280cd72ceb8b0679490f076d0e9f30dd456 (diff) | |
parent | 69a2bac8984c4e6dba78b330ed183fd580c65e99 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts:
drivers/net/wireless/rt2x00/rt2x00pci.c
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 6 | ||||
-rw-r--r-- | net/mac80211/chan.c | 17 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 4 | ||||
-rw-r--r-- | net/mac80211/iface.c | 2 | ||||
-rw-r--r-- | net/mac80211/offchannel.c | 23 | ||||
-rw-r--r-- | net/nfc/llcp/llcp.c | 8 | ||||
-rw-r--r-- | net/nfc/llcp/sock.c | 6 | ||||
-rw-r--r-- | net/wireless/sme.c | 2 |
8 files changed, 44 insertions, 24 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index e5c1441ac2b8..c50c19402588 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -2641,7 +2641,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, | |||
2641 | list_del(&dep->list); | 2641 | list_del(&dep->list); |
2642 | mutex_unlock(&local->mtx); | 2642 | mutex_unlock(&local->mtx); |
2643 | 2643 | ||
2644 | ieee80211_roc_notify_destroy(dep); | 2644 | ieee80211_roc_notify_destroy(dep, true); |
2645 | return 0; | 2645 | return 0; |
2646 | } | 2646 | } |
2647 | 2647 | ||
@@ -2681,7 +2681,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, | |||
2681 | ieee80211_start_next_roc(local); | 2681 | ieee80211_start_next_roc(local); |
2682 | mutex_unlock(&local->mtx); | 2682 | mutex_unlock(&local->mtx); |
2683 | 2683 | ||
2684 | ieee80211_roc_notify_destroy(found); | 2684 | ieee80211_roc_notify_destroy(found, true); |
2685 | } else { | 2685 | } else { |
2686 | /* work may be pending so use it all the time */ | 2686 | /* work may be pending so use it all the time */ |
2687 | found->abort = true; | 2687 | found->abort = true; |
@@ -2691,6 +2691,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, | |||
2691 | 2691 | ||
2692 | /* work will clean up etc */ | 2692 | /* work will clean up etc */ |
2693 | flush_delayed_work(&found->work); | 2693 | flush_delayed_work(&found->work); |
2694 | WARN_ON(!found->to_be_freed); | ||
2695 | kfree(found); | ||
2694 | } | 2696 | } |
2695 | 2697 | ||
2696 | return 0; | 2698 | return 0; |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 78c0d90dd641..931be419ab5a 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -63,6 +63,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
63 | enum ieee80211_chanctx_mode mode) | 63 | enum ieee80211_chanctx_mode mode) |
64 | { | 64 | { |
65 | struct ieee80211_chanctx *ctx; | 65 | struct ieee80211_chanctx *ctx; |
66 | u32 changed; | ||
66 | int err; | 67 | int err; |
67 | 68 | ||
68 | lockdep_assert_held(&local->chanctx_mtx); | 69 | lockdep_assert_held(&local->chanctx_mtx); |
@@ -76,6 +77,13 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
76 | ctx->conf.rx_chains_dynamic = 1; | 77 | ctx->conf.rx_chains_dynamic = 1; |
77 | ctx->mode = mode; | 78 | ctx->mode = mode; |
78 | 79 | ||
80 | /* acquire mutex to prevent idle from changing */ | ||
81 | mutex_lock(&local->mtx); | ||
82 | /* turn idle off *before* setting channel -- some drivers need that */ | ||
83 | changed = ieee80211_idle_off(local); | ||
84 | if (changed) | ||
85 | ieee80211_hw_config(local, changed); | ||
86 | |||
79 | if (!local->use_chanctx) { | 87 | if (!local->use_chanctx) { |
80 | local->_oper_channel_type = | 88 | local->_oper_channel_type = |
81 | cfg80211_get_chandef_type(chandef); | 89 | cfg80211_get_chandef_type(chandef); |
@@ -85,14 +93,17 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
85 | err = drv_add_chanctx(local, ctx); | 93 | err = drv_add_chanctx(local, ctx); |
86 | if (err) { | 94 | if (err) { |
87 | kfree(ctx); | 95 | kfree(ctx); |
88 | return ERR_PTR(err); | 96 | ctx = ERR_PTR(err); |
97 | |||
98 | ieee80211_recalc_idle(local); | ||
99 | goto out; | ||
89 | } | 100 | } |
90 | } | 101 | } |
91 | 102 | ||
103 | /* and keep the mutex held until the new chanctx is on the list */ | ||
92 | list_add_rcu(&ctx->list, &local->chanctx_list); | 104 | list_add_rcu(&ctx->list, &local->chanctx_list); |
93 | 105 | ||
94 | mutex_lock(&local->mtx); | 106 | out: |
95 | ieee80211_recalc_idle(local); | ||
96 | mutex_unlock(&local->mtx); | 107 | mutex_unlock(&local->mtx); |
97 | 108 | ||
98 | return ctx; | 109 | return ctx; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ae2d1754b792..0b09716d22ad 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -309,6 +309,7 @@ struct ieee80211_roc_work { | |||
309 | struct ieee80211_channel *chan; | 309 | struct ieee80211_channel *chan; |
310 | 310 | ||
311 | bool started, abort, hw_begun, notified; | 311 | bool started, abort, hw_begun, notified; |
312 | bool to_be_freed; | ||
312 | 313 | ||
313 | unsigned long hw_start_time; | 314 | unsigned long hw_start_time; |
314 | 315 | ||
@@ -1330,7 +1331,7 @@ void ieee80211_offchannel_return(struct ieee80211_local *local); | |||
1330 | void ieee80211_roc_setup(struct ieee80211_local *local); | 1331 | void ieee80211_roc_setup(struct ieee80211_local *local); |
1331 | void ieee80211_start_next_roc(struct ieee80211_local *local); | 1332 | void ieee80211_start_next_roc(struct ieee80211_local *local); |
1332 | void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); | 1333 | void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); |
1333 | void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc); | 1334 | void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free); |
1334 | void ieee80211_sw_roc_work(struct work_struct *work); | 1335 | void ieee80211_sw_roc_work(struct work_struct *work); |
1335 | void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); | 1336 | void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); |
1336 | 1337 | ||
@@ -1344,6 +1345,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
1344 | enum nl80211_iftype type); | 1345 | enum nl80211_iftype type); |
1345 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); | 1346 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); |
1346 | void ieee80211_remove_interfaces(struct ieee80211_local *local); | 1347 | void ieee80211_remove_interfaces(struct ieee80211_local *local); |
1348 | u32 ieee80211_idle_off(struct ieee80211_local *local); | ||
1347 | void ieee80211_recalc_idle(struct ieee80211_local *local); | 1349 | void ieee80211_recalc_idle(struct ieee80211_local *local); |
1348 | void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, | 1350 | void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, |
1349 | const int offset); | 1351 | const int offset); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 2a3c1e9bdf25..69aaba79a9f7 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -78,7 +78,7 @@ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) | |||
78 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); | 78 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); |
79 | } | 79 | } |
80 | 80 | ||
81 | static u32 ieee80211_idle_off(struct ieee80211_local *local) | 81 | u32 ieee80211_idle_off(struct ieee80211_local *local) |
82 | { | 82 | { |
83 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) | 83 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) |
84 | return 0; | 84 | return 0; |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index b01eb7314ec6..cce795871ab1 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -297,10 +297,13 @@ void ieee80211_start_next_roc(struct ieee80211_local *local) | |||
297 | } | 297 | } |
298 | } | 298 | } |
299 | 299 | ||
300 | void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) | 300 | void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free) |
301 | { | 301 | { |
302 | struct ieee80211_roc_work *dep, *tmp; | 302 | struct ieee80211_roc_work *dep, *tmp; |
303 | 303 | ||
304 | if (WARN_ON(roc->to_be_freed)) | ||
305 | return; | ||
306 | |||
304 | /* was never transmitted */ | 307 | /* was never transmitted */ |
305 | if (roc->frame) { | 308 | if (roc->frame) { |
306 | cfg80211_mgmt_tx_status(&roc->sdata->wdev, | 309 | cfg80211_mgmt_tx_status(&roc->sdata->wdev, |
@@ -316,9 +319,12 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) | |||
316 | GFP_KERNEL); | 319 | GFP_KERNEL); |
317 | 320 | ||
318 | list_for_each_entry_safe(dep, tmp, &roc->dependents, list) | 321 | list_for_each_entry_safe(dep, tmp, &roc->dependents, list) |
319 | ieee80211_roc_notify_destroy(dep); | 322 | ieee80211_roc_notify_destroy(dep, true); |
320 | 323 | ||
321 | kfree(roc); | 324 | if (free) |
325 | kfree(roc); | ||
326 | else | ||
327 | roc->to_be_freed = true; | ||
322 | } | 328 | } |
323 | 329 | ||
324 | void ieee80211_sw_roc_work(struct work_struct *work) | 330 | void ieee80211_sw_roc_work(struct work_struct *work) |
@@ -331,6 +337,9 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
331 | 337 | ||
332 | mutex_lock(&local->mtx); | 338 | mutex_lock(&local->mtx); |
333 | 339 | ||
340 | if (roc->to_be_freed) | ||
341 | goto out_unlock; | ||
342 | |||
334 | if (roc->abort) | 343 | if (roc->abort) |
335 | goto finish; | 344 | goto finish; |
336 | 345 | ||
@@ -370,7 +379,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
370 | finish: | 379 | finish: |
371 | list_del(&roc->list); | 380 | list_del(&roc->list); |
372 | started = roc->started; | 381 | started = roc->started; |
373 | ieee80211_roc_notify_destroy(roc); | 382 | ieee80211_roc_notify_destroy(roc, !roc->abort); |
374 | 383 | ||
375 | if (started) { | 384 | if (started) { |
376 | ieee80211_flush_queues(local, NULL); | 385 | ieee80211_flush_queues(local, NULL); |
@@ -410,7 +419,7 @@ static void ieee80211_hw_roc_done(struct work_struct *work) | |||
410 | 419 | ||
411 | list_del(&roc->list); | 420 | list_del(&roc->list); |
412 | 421 | ||
413 | ieee80211_roc_notify_destroy(roc); | 422 | ieee80211_roc_notify_destroy(roc, true); |
414 | 423 | ||
415 | /* if there's another roc, start it now */ | 424 | /* if there's another roc, start it now */ |
416 | ieee80211_start_next_roc(local); | 425 | ieee80211_start_next_roc(local); |
@@ -460,12 +469,14 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) | |||
460 | list_for_each_entry_safe(roc, tmp, &tmp_list, list) { | 469 | list_for_each_entry_safe(roc, tmp, &tmp_list, list) { |
461 | if (local->ops->remain_on_channel) { | 470 | if (local->ops->remain_on_channel) { |
462 | list_del(&roc->list); | 471 | list_del(&roc->list); |
463 | ieee80211_roc_notify_destroy(roc); | 472 | ieee80211_roc_notify_destroy(roc, true); |
464 | } else { | 473 | } else { |
465 | ieee80211_queue_delayed_work(&local->hw, &roc->work, 0); | 474 | ieee80211_queue_delayed_work(&local->hw, &roc->work, 0); |
466 | 475 | ||
467 | /* work will clean up etc */ | 476 | /* work will clean up etc */ |
468 | flush_delayed_work(&roc->work); | 477 | flush_delayed_work(&roc->work); |
478 | WARN_ON(!roc->to_be_freed); | ||
479 | kfree(roc); | ||
469 | } | 480 | } |
470 | } | 481 | } |
471 | 482 | ||
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index bb67b98b9797..7de0368aff0c 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c | |||
@@ -107,8 +107,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, | |||
107 | accept_sk->sk_state_change(sk); | 107 | accept_sk->sk_state_change(sk); |
108 | 108 | ||
109 | bh_unlock_sock(accept_sk); | 109 | bh_unlock_sock(accept_sk); |
110 | |||
111 | sock_orphan(accept_sk); | ||
112 | } | 110 | } |
113 | 111 | ||
114 | if (listen == true) { | 112 | if (listen == true) { |
@@ -134,8 +132,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, | |||
134 | 132 | ||
135 | bh_unlock_sock(sk); | 133 | bh_unlock_sock(sk); |
136 | 134 | ||
137 | sock_orphan(sk); | ||
138 | |||
139 | sk_del_node_init(sk); | 135 | sk_del_node_init(sk); |
140 | } | 136 | } |
141 | 137 | ||
@@ -164,8 +160,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, | |||
164 | 160 | ||
165 | bh_unlock_sock(sk); | 161 | bh_unlock_sock(sk); |
166 | 162 | ||
167 | sock_orphan(sk); | ||
168 | |||
169 | sk_del_node_init(sk); | 163 | sk_del_node_init(sk); |
170 | } | 164 | } |
171 | 165 | ||
@@ -869,7 +863,6 @@ static void nfc_llcp_recv_ui(struct nfc_llcp_local *local, | |||
869 | skb_get(skb); | 863 | skb_get(skb); |
870 | } else { | 864 | } else { |
871 | pr_err("Receive queue is full\n"); | 865 | pr_err("Receive queue is full\n"); |
872 | kfree_skb(skb); | ||
873 | } | 866 | } |
874 | 867 | ||
875 | nfc_llcp_sock_put(llcp_sock); | 868 | nfc_llcp_sock_put(llcp_sock); |
@@ -1072,7 +1065,6 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, | |||
1072 | skb_get(skb); | 1065 | skb_get(skb); |
1073 | } else { | 1066 | } else { |
1074 | pr_err("Receive queue is full\n"); | 1067 | pr_err("Receive queue is full\n"); |
1075 | kfree_skb(skb); | ||
1076 | } | 1068 | } |
1077 | } | 1069 | } |
1078 | 1070 | ||
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index f1b377e247fe..6fa76704cb13 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c | |||
@@ -388,7 +388,9 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent, | |||
388 | } | 388 | } |
389 | 389 | ||
390 | if (sk->sk_state == LLCP_CONNECTED || !newsock) { | 390 | if (sk->sk_state == LLCP_CONNECTED || !newsock) { |
391 | nfc_llcp_accept_unlink(sk); | 391 | list_del_init(&lsk->accept_queue); |
392 | sock_put(sk); | ||
393 | |||
392 | if (newsock) | 394 | if (newsock) |
393 | sock_graft(sk, newsock); | 395 | sock_graft(sk, newsock); |
394 | 396 | ||
@@ -582,8 +584,6 @@ static int llcp_sock_release(struct socket *sock) | |||
582 | nfc_llcp_accept_unlink(accept_sk); | 584 | nfc_llcp_accept_unlink(accept_sk); |
583 | 585 | ||
584 | release_sock(accept_sk); | 586 | release_sock(accept_sk); |
585 | |||
586 | sock_orphan(accept_sk); | ||
587 | } | 587 | } |
588 | } | 588 | } |
589 | 589 | ||
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 818ad637819a..a9dc5c736df0 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -228,6 +228,7 @@ void cfg80211_conn_work(struct work_struct *work) | |||
228 | rtnl_lock(); | 228 | rtnl_lock(); |
229 | cfg80211_lock_rdev(rdev); | 229 | cfg80211_lock_rdev(rdev); |
230 | mutex_lock(&rdev->devlist_mtx); | 230 | mutex_lock(&rdev->devlist_mtx); |
231 | mutex_lock(&rdev->sched_scan_mtx); | ||
231 | 232 | ||
232 | list_for_each_entry(wdev, &rdev->wdev_list, list) { | 233 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
233 | wdev_lock(wdev); | 234 | wdev_lock(wdev); |
@@ -252,6 +253,7 @@ void cfg80211_conn_work(struct work_struct *work) | |||
252 | wdev_unlock(wdev); | 253 | wdev_unlock(wdev); |
253 | } | 254 | } |
254 | 255 | ||
256 | mutex_unlock(&rdev->sched_scan_mtx); | ||
255 | mutex_unlock(&rdev->devlist_mtx); | 257 | mutex_unlock(&rdev->devlist_mtx); |
256 | cfg80211_unlock_rdev(rdev); | 258 | cfg80211_unlock_rdev(rdev); |
257 | rtnl_unlock(); | 259 | rtnl_unlock(); |