diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-07-11 14:46:59 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-07-11 14:46:59 -0400 |
commit | d8598981146241064993e371cea8333f59553cb6 (patch) | |
tree | bb92a46fb9fe75ee9c4fdbbe0a5b6eafc6818ef3 /net | |
parent | 8ae2e12f1534e647d4a816755e5a09c2de6f9fca (diff) | |
parent | 34459512ffa7236c849466e3bd604801389734e1 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Conflicts:
drivers/net/wireless/ath/ath5k/sysfs.c
net/bluetooth/l2cap_core.c
net/mac80211/wpa.c
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_conn.c | 3 | ||||
-rw-r--r-- | net/bluetooth/hidp/core.c | 18 | ||||
-rw-r--r-- | net/bluetooth/hidp/hidp.h | 1 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 5 | ||||
-rw-r--r-- | net/mac80211/scan.c | 3 | ||||
-rw-r--r-- | net/wireless/core.c | 12 | ||||
-rw-r--r-- | net/wireless/core.h | 2 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 24 | ||||
-rw-r--r-- | net/wireless/scan.c | 10 |
9 files changed, 54 insertions, 24 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index fa48c0b3d93c..ea7f031f3b04 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -444,6 +444,9 @@ int hci_conn_del(struct hci_conn *conn) | |||
444 | 444 | ||
445 | hci_dev_put(hdev); | 445 | hci_dev_put(hdev); |
446 | 446 | ||
447 | if (conn->handle == 0) | ||
448 | kfree(conn); | ||
449 | |||
447 | return 0; | 450 | return 0; |
448 | } | 451 | } |
449 | 452 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index c405a954a603..43b4c2deb7cc 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -464,7 +464,8 @@ static void hidp_idle_timeout(unsigned long arg) | |||
464 | { | 464 | { |
465 | struct hidp_session *session = (struct hidp_session *) arg; | 465 | struct hidp_session *session = (struct hidp_session *) arg; |
466 | 466 | ||
467 | kthread_stop(session->task); | 467 | atomic_inc(&session->terminate); |
468 | wake_up_process(session->task); | ||
468 | } | 469 | } |
469 | 470 | ||
470 | static void hidp_set_timer(struct hidp_session *session) | 471 | static void hidp_set_timer(struct hidp_session *session) |
@@ -535,7 +536,8 @@ static void hidp_process_hid_control(struct hidp_session *session, | |||
535 | skb_queue_purge(&session->ctrl_transmit); | 536 | skb_queue_purge(&session->ctrl_transmit); |
536 | skb_queue_purge(&session->intr_transmit); | 537 | skb_queue_purge(&session->intr_transmit); |
537 | 538 | ||
538 | kthread_stop(session->task); | 539 | atomic_inc(&session->terminate); |
540 | wake_up_process(current); | ||
539 | } | 541 | } |
540 | } | 542 | } |
541 | 543 | ||
@@ -706,9 +708,8 @@ static int hidp_session(void *arg) | |||
706 | add_wait_queue(sk_sleep(intr_sk), &intr_wait); | 708 | add_wait_queue(sk_sleep(intr_sk), &intr_wait); |
707 | session->waiting_for_startup = 0; | 709 | session->waiting_for_startup = 0; |
708 | wake_up_interruptible(&session->startup_queue); | 710 | wake_up_interruptible(&session->startup_queue); |
709 | while (!kthread_should_stop()) { | 711 | set_current_state(TASK_INTERRUPTIBLE); |
710 | set_current_state(TASK_INTERRUPTIBLE); | 712 | while (!atomic_read(&session->terminate)) { |
711 | |||
712 | if (ctrl_sk->sk_state != BT_CONNECTED || | 713 | if (ctrl_sk->sk_state != BT_CONNECTED || |
713 | intr_sk->sk_state != BT_CONNECTED) | 714 | intr_sk->sk_state != BT_CONNECTED) |
714 | break; | 715 | break; |
@@ -726,6 +727,7 @@ static int hidp_session(void *arg) | |||
726 | hidp_process_transmit(session); | 727 | hidp_process_transmit(session); |
727 | 728 | ||
728 | schedule(); | 729 | schedule(); |
730 | set_current_state(TASK_INTERRUPTIBLE); | ||
729 | } | 731 | } |
730 | set_current_state(TASK_RUNNING); | 732 | set_current_state(TASK_RUNNING); |
731 | remove_wait_queue(sk_sleep(intr_sk), &intr_wait); | 733 | remove_wait_queue(sk_sleep(intr_sk), &intr_wait); |
@@ -1060,7 +1062,8 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1060 | err_add_device: | 1062 | err_add_device: |
1061 | hid_destroy_device(session->hid); | 1063 | hid_destroy_device(session->hid); |
1062 | session->hid = NULL; | 1064 | session->hid = NULL; |
1063 | kthread_stop(session->task); | 1065 | atomic_inc(&session->terminate); |
1066 | wake_up_process(session->task); | ||
1064 | 1067 | ||
1065 | unlink: | 1068 | unlink: |
1066 | hidp_del_timer(session); | 1069 | hidp_del_timer(session); |
@@ -1111,7 +1114,8 @@ int hidp_del_connection(struct hidp_conndel_req *req) | |||
1111 | skb_queue_purge(&session->ctrl_transmit); | 1114 | skb_queue_purge(&session->ctrl_transmit); |
1112 | skb_queue_purge(&session->intr_transmit); | 1115 | skb_queue_purge(&session->intr_transmit); |
1113 | 1116 | ||
1114 | kthread_stop(session->task); | 1117 | atomic_inc(&session->terminate); |
1118 | wake_up_process(session->task); | ||
1115 | } | 1119 | } |
1116 | } else | 1120 | } else |
1117 | err = -ENOENT; | 1121 | err = -ENOENT; |
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index 19e95004b286..af1bcc823f26 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h | |||
@@ -142,6 +142,7 @@ struct hidp_session { | |||
142 | uint ctrl_mtu; | 142 | uint ctrl_mtu; |
143 | uint intr_mtu; | 143 | uint intr_mtu; |
144 | 144 | ||
145 | atomic_t terminate; | ||
145 | struct task_struct *task; | 146 | struct task_struct *task; |
146 | 147 | ||
147 | unsigned char keys[8]; | 148 | unsigned char keys[8]; |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 9ec9c8c5eb5e..fc219ec28711 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -2530,7 +2530,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2530 | 2530 | ||
2531 | sk = chan->sk; | 2531 | sk = chan->sk; |
2532 | 2532 | ||
2533 | if (chan->state != BT_CONFIG) { | 2533 | if ((bt_sk(sk)->defer_setup && chan->state != BT_CONNECT2) || |
2534 | (!bt_sk(sk)->defer_setup && chan->state != BT_CONFIG)) { | ||
2534 | struct l2cap_cmd_rej rej; | 2535 | struct l2cap_cmd_rej rej; |
2535 | 2536 | ||
2536 | rej.reason = cpu_to_le16(0x0002); | 2537 | rej.reason = cpu_to_le16(0x0002); |
@@ -2541,7 +2542,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2541 | 2542 | ||
2542 | /* Reject if config buffer is too small. */ | 2543 | /* Reject if config buffer is too small. */ |
2543 | len = cmd_len - sizeof(*req); | 2544 | len = cmd_len - sizeof(*req); |
2544 | if (chan->conf_len + len > sizeof(chan->conf_req)) { | 2545 | if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) { |
2545 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 2546 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
2546 | l2cap_build_conf_rsp(chan, rsp, | 2547 | l2cap_build_conf_rsp(chan, rsp, |
2547 | L2CAP_CONF_REJECT, flags), rsp); | 2548 | L2CAP_CONF_REJECT, flags), rsp); |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index e5a6ea4a94ea..08a45ac3d6f8 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -884,7 +884,8 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
884 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | 884 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
885 | local->sched_scan_ies.ie[i] = kzalloc(2 + | 885 | local->sched_scan_ies.ie[i] = kzalloc(2 + |
886 | IEEE80211_MAX_SSID_LEN + | 886 | IEEE80211_MAX_SSID_LEN + |
887 | local->scan_ies_len, | 887 | local->scan_ies_len + |
888 | req->ie_len, | ||
888 | GFP_KERNEL); | 889 | GFP_KERNEL); |
889 | if (!local->sched_scan_ies.ie[i]) { | 890 | if (!local->sched_scan_ies.ie[i]) { |
890 | ret = -ENOMEM; | 891 | ret = -ENOMEM; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index c22ef3492ee6..880dbe2e6f94 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -366,6 +366,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
366 | 366 | ||
367 | mutex_init(&rdev->mtx); | 367 | mutex_init(&rdev->mtx); |
368 | mutex_init(&rdev->devlist_mtx); | 368 | mutex_init(&rdev->devlist_mtx); |
369 | mutex_init(&rdev->sched_scan_mtx); | ||
369 | INIT_LIST_HEAD(&rdev->netdev_list); | 370 | INIT_LIST_HEAD(&rdev->netdev_list); |
370 | spin_lock_init(&rdev->bss_lock); | 371 | spin_lock_init(&rdev->bss_lock); |
371 | INIT_LIST_HEAD(&rdev->bss_list); | 372 | INIT_LIST_HEAD(&rdev->bss_list); |
@@ -701,6 +702,7 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev) | |||
701 | rfkill_destroy(rdev->rfkill); | 702 | rfkill_destroy(rdev->rfkill); |
702 | mutex_destroy(&rdev->mtx); | 703 | mutex_destroy(&rdev->mtx); |
703 | mutex_destroy(&rdev->devlist_mtx); | 704 | mutex_destroy(&rdev->devlist_mtx); |
705 | mutex_destroy(&rdev->sched_scan_mtx); | ||
704 | list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) | 706 | list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) |
705 | cfg80211_put_bss(&scan->pub); | 707 | cfg80211_put_bss(&scan->pub); |
706 | cfg80211_rdev_free_wowlan(rdev); | 708 | cfg80211_rdev_free_wowlan(rdev); |
@@ -737,12 +739,16 @@ static void wdev_cleanup_work(struct work_struct *work) | |||
737 | ___cfg80211_scan_done(rdev, true); | 739 | ___cfg80211_scan_done(rdev, true); |
738 | } | 740 | } |
739 | 741 | ||
742 | cfg80211_unlock_rdev(rdev); | ||
743 | |||
744 | mutex_lock(&rdev->sched_scan_mtx); | ||
745 | |||
740 | if (WARN_ON(rdev->sched_scan_req && | 746 | if (WARN_ON(rdev->sched_scan_req && |
741 | rdev->sched_scan_req->dev == wdev->netdev)) { | 747 | rdev->sched_scan_req->dev == wdev->netdev)) { |
742 | __cfg80211_stop_sched_scan(rdev, false); | 748 | __cfg80211_stop_sched_scan(rdev, false); |
743 | } | 749 | } |
744 | 750 | ||
745 | cfg80211_unlock_rdev(rdev); | 751 | mutex_unlock(&rdev->sched_scan_mtx); |
746 | 752 | ||
747 | mutex_lock(&rdev->devlist_mtx); | 753 | mutex_lock(&rdev->devlist_mtx); |
748 | rdev->opencount--; | 754 | rdev->opencount--; |
@@ -830,9 +836,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, | |||
830 | break; | 836 | break; |
831 | case NL80211_IFTYPE_P2P_CLIENT: | 837 | case NL80211_IFTYPE_P2P_CLIENT: |
832 | case NL80211_IFTYPE_STATION: | 838 | case NL80211_IFTYPE_STATION: |
833 | cfg80211_lock_rdev(rdev); | 839 | mutex_lock(&rdev->sched_scan_mtx); |
834 | __cfg80211_stop_sched_scan(rdev, false); | 840 | __cfg80211_stop_sched_scan(rdev, false); |
835 | cfg80211_unlock_rdev(rdev); | 841 | mutex_unlock(&rdev->sched_scan_mtx); |
836 | 842 | ||
837 | wdev_lock(wdev); | 843 | wdev_lock(wdev); |
838 | #ifdef CONFIG_CFG80211_WEXT | 844 | #ifdef CONFIG_CFG80211_WEXT |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 3dce1f167eba..a570ff9214ec 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -65,6 +65,8 @@ struct cfg80211_registered_device { | |||
65 | struct work_struct scan_done_wk; | 65 | struct work_struct scan_done_wk; |
66 | struct work_struct sched_scan_results_wk; | 66 | struct work_struct sched_scan_results_wk; |
67 | 67 | ||
68 | struct mutex sched_scan_mtx; | ||
69 | |||
68 | #ifdef CONFIG_NL80211_TESTMODE | 70 | #ifdef CONFIG_NL80211_TESTMODE |
69 | struct genl_info *testmode_info; | 71 | struct genl_info *testmode_info; |
70 | #endif | 72 | #endif |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 491b0ba40c43..6a82c898f831 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -3470,9 +3470,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3470 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3470 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
3471 | return -EINVAL; | 3471 | return -EINVAL; |
3472 | 3472 | ||
3473 | if (rdev->sched_scan_req) | ||
3474 | return -EINPROGRESS; | ||
3475 | |||
3476 | if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]) | 3473 | if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]) |
3477 | return -EINVAL; | 3474 | return -EINVAL; |
3478 | 3475 | ||
@@ -3511,12 +3508,21 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3511 | if (ie_len > wiphy->max_scan_ie_len) | 3508 | if (ie_len > wiphy->max_scan_ie_len) |
3512 | return -EINVAL; | 3509 | return -EINVAL; |
3513 | 3510 | ||
3511 | mutex_lock(&rdev->sched_scan_mtx); | ||
3512 | |||
3513 | if (rdev->sched_scan_req) { | ||
3514 | err = -EINPROGRESS; | ||
3515 | goto out; | ||
3516 | } | ||
3517 | |||
3514 | request = kzalloc(sizeof(*request) | 3518 | request = kzalloc(sizeof(*request) |
3515 | + sizeof(*request->ssids) * n_ssids | 3519 | + sizeof(*request->ssids) * n_ssids |
3516 | + sizeof(*request->channels) * n_channels | 3520 | + sizeof(*request->channels) * n_channels |
3517 | + ie_len, GFP_KERNEL); | 3521 | + ie_len, GFP_KERNEL); |
3518 | if (!request) | 3522 | if (!request) { |
3519 | return -ENOMEM; | 3523 | err = -ENOMEM; |
3524 | goto out; | ||
3525 | } | ||
3520 | 3526 | ||
3521 | if (n_ssids) | 3527 | if (n_ssids) |
3522 | request->ssids = (void *)&request->channels[n_channels]; | 3528 | request->ssids = (void *)&request->channels[n_channels]; |
@@ -3614,6 +3620,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3614 | out_free: | 3620 | out_free: |
3615 | kfree(request); | 3621 | kfree(request); |
3616 | out: | 3622 | out: |
3623 | mutex_unlock(&rdev->sched_scan_mtx); | ||
3617 | return err; | 3624 | return err; |
3618 | } | 3625 | } |
3619 | 3626 | ||
@@ -3621,12 +3628,17 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb, | |||
3621 | struct genl_info *info) | 3628 | struct genl_info *info) |
3622 | { | 3629 | { |
3623 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3630 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3631 | int err; | ||
3624 | 3632 | ||
3625 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || | 3633 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || |
3626 | !rdev->ops->sched_scan_stop) | 3634 | !rdev->ops->sched_scan_stop) |
3627 | return -EOPNOTSUPP; | 3635 | return -EOPNOTSUPP; |
3628 | 3636 | ||
3629 | return __cfg80211_stop_sched_scan(rdev, false); | 3637 | mutex_lock(&rdev->sched_scan_mtx); |
3638 | err = __cfg80211_stop_sched_scan(rdev, false); | ||
3639 | mutex_unlock(&rdev->sched_scan_mtx); | ||
3640 | |||
3641 | return err; | ||
3630 | } | 3642 | } |
3631 | 3643 | ||
3632 | static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, | 3644 | static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index ce04566a2ecc..1c4672e35144 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -100,14 +100,14 @@ void __cfg80211_sched_scan_results(struct work_struct *wk) | |||
100 | rdev = container_of(wk, struct cfg80211_registered_device, | 100 | rdev = container_of(wk, struct cfg80211_registered_device, |
101 | sched_scan_results_wk); | 101 | sched_scan_results_wk); |
102 | 102 | ||
103 | cfg80211_lock_rdev(rdev); | 103 | mutex_lock(&rdev->sched_scan_mtx); |
104 | 104 | ||
105 | /* we don't have sched_scan_req anymore if the scan is stopping */ | 105 | /* we don't have sched_scan_req anymore if the scan is stopping */ |
106 | if (rdev->sched_scan_req) | 106 | if (rdev->sched_scan_req) |
107 | nl80211_send_sched_scan_results(rdev, | 107 | nl80211_send_sched_scan_results(rdev, |
108 | rdev->sched_scan_req->dev); | 108 | rdev->sched_scan_req->dev); |
109 | 109 | ||
110 | cfg80211_unlock_rdev(rdev); | 110 | mutex_unlock(&rdev->sched_scan_mtx); |
111 | } | 111 | } |
112 | 112 | ||
113 | void cfg80211_sched_scan_results(struct wiphy *wiphy) | 113 | void cfg80211_sched_scan_results(struct wiphy *wiphy) |
@@ -123,9 +123,9 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy) | |||
123 | { | 123 | { |
124 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 124 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
125 | 125 | ||
126 | cfg80211_lock_rdev(rdev); | 126 | mutex_lock(&rdev->sched_scan_mtx); |
127 | __cfg80211_stop_sched_scan(rdev, true); | 127 | __cfg80211_stop_sched_scan(rdev, true); |
128 | cfg80211_unlock_rdev(rdev); | 128 | mutex_unlock(&rdev->sched_scan_mtx); |
129 | } | 129 | } |
130 | EXPORT_SYMBOL(cfg80211_sched_scan_stopped); | 130 | EXPORT_SYMBOL(cfg80211_sched_scan_stopped); |
131 | 131 | ||
@@ -134,7 +134,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | |||
134 | { | 134 | { |
135 | struct net_device *dev; | 135 | struct net_device *dev; |
136 | 136 | ||
137 | ASSERT_RDEV_LOCK(rdev); | 137 | lockdep_assert_held(&rdev->sched_scan_mtx); |
138 | 138 | ||
139 | if (!rdev->sched_scan_req) | 139 | if (!rdev->sched_scan_req) |
140 | return -ENOENT; | 140 | return -ENOENT; |