diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-03-18 09:39:21 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-03-18 09:39:21 -0400 |
commit | 49c87cd1eac1f798c5bad7f7eb809e6df36b6c56 (patch) | |
tree | 8d6905466a05d6539e06d189cf88b71095ac0a79 /net/nfc | |
parent | 4969b41798e512689bba57c8c44d873216eba814 (diff) | |
parent | 9437a248e7cac427c898bdb11bd1ac6844a1ead4 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts:
net/nfc/llcp/llcp.c
Diffstat (limited to 'net/nfc')
-rw-r--r-- | net/nfc/llcp/llcp.c | 62 | ||||
-rw-r--r-- | net/nfc/llcp/sock.c | 2 |
2 files changed, 55 insertions, 9 deletions
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 3361170cb262..bb67b98b9797 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c | |||
@@ -68,7 +68,8 @@ static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock) | |||
68 | } | 68 | } |
69 | } | 69 | } |
70 | 70 | ||
71 | static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) | 71 | static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, |
72 | int err) | ||
72 | { | 73 | { |
73 | struct sock *sk; | 74 | struct sock *sk; |
74 | struct hlist_node *tmp; | 75 | struct hlist_node *tmp; |
@@ -100,7 +101,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) | |||
100 | 101 | ||
101 | nfc_llcp_accept_unlink(accept_sk); | 102 | nfc_llcp_accept_unlink(accept_sk); |
102 | 103 | ||
104 | if (err) | ||
105 | accept_sk->sk_err = err; | ||
103 | accept_sk->sk_state = LLCP_CLOSED; | 106 | accept_sk->sk_state = LLCP_CLOSED; |
107 | accept_sk->sk_state_change(sk); | ||
104 | 108 | ||
105 | bh_unlock_sock(accept_sk); | 109 | bh_unlock_sock(accept_sk); |
106 | 110 | ||
@@ -123,7 +127,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) | |||
123 | continue; | 127 | continue; |
124 | } | 128 | } |
125 | 129 | ||
130 | if (err) | ||
131 | sk->sk_err = err; | ||
126 | sk->sk_state = LLCP_CLOSED; | 132 | sk->sk_state = LLCP_CLOSED; |
133 | sk->sk_state_change(sk); | ||
127 | 134 | ||
128 | bh_unlock_sock(sk); | 135 | bh_unlock_sock(sk); |
129 | 136 | ||
@@ -133,6 +140,36 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) | |||
133 | } | 140 | } |
134 | 141 | ||
135 | write_unlock(&local->sockets.lock); | 142 | write_unlock(&local->sockets.lock); |
143 | |||
144 | /* | ||
145 | * If we want to keep the listening sockets alive, | ||
146 | * we don't touch the RAW ones. | ||
147 | */ | ||
148 | if (listen == true) | ||
149 | return; | ||
150 | |||
151 | write_lock(&local->raw_sockets.lock); | ||
152 | |||
153 | sk_for_each_safe(sk, tmp, &local->raw_sockets.head) { | ||
154 | llcp_sock = nfc_llcp_sock(sk); | ||
155 | |||
156 | bh_lock_sock(sk); | ||
157 | |||
158 | nfc_llcp_socket_purge(llcp_sock); | ||
159 | |||
160 | if (err) | ||
161 | sk->sk_err = err; | ||
162 | sk->sk_state = LLCP_CLOSED; | ||
163 | sk->sk_state_change(sk); | ||
164 | |||
165 | bh_unlock_sock(sk); | ||
166 | |||
167 | sock_orphan(sk); | ||
168 | |||
169 | sk_del_node_init(sk); | ||
170 | } | ||
171 | |||
172 | write_unlock(&local->raw_sockets.lock); | ||
136 | } | 173 | } |
137 | 174 | ||
138 | struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) | 175 | struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) |
@@ -142,14 +179,9 @@ struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) | |||
142 | return local; | 179 | return local; |
143 | } | 180 | } |
144 | 181 | ||
145 | static void local_release(struct kref *ref) | 182 | static void local_cleanup(struct nfc_llcp_local *local, bool listen) |
146 | { | 183 | { |
147 | struct nfc_llcp_local *local; | 184 | nfc_llcp_socket_release(local, listen, ENXIO); |
148 | |||
149 | local = container_of(ref, struct nfc_llcp_local, ref); | ||
150 | |||
151 | list_del(&local->list); | ||
152 | nfc_llcp_socket_release(local, false); | ||
153 | del_timer_sync(&local->link_timer); | 185 | del_timer_sync(&local->link_timer); |
154 | skb_queue_purge(&local->tx_queue); | 186 | skb_queue_purge(&local->tx_queue); |
155 | cancel_work_sync(&local->tx_work); | 187 | cancel_work_sync(&local->tx_work); |
@@ -159,6 +191,16 @@ static void local_release(struct kref *ref) | |||
159 | del_timer_sync(&local->sdreq_timer); | 191 | del_timer_sync(&local->sdreq_timer); |
160 | cancel_work_sync(&local->sdreq_timeout_work); | 192 | cancel_work_sync(&local->sdreq_timeout_work); |
161 | nfc_llcp_free_sdp_tlv_list(&local->pending_sdreqs); | 193 | nfc_llcp_free_sdp_tlv_list(&local->pending_sdreqs); |
194 | } | ||
195 | |||
196 | static void local_release(struct kref *ref) | ||
197 | { | ||
198 | struct nfc_llcp_local *local; | ||
199 | |||
200 | local = container_of(ref, struct nfc_llcp_local, ref); | ||
201 | |||
202 | list_del(&local->list); | ||
203 | local_cleanup(local, false); | ||
162 | kfree(local); | 204 | kfree(local); |
163 | } | 205 | } |
164 | 206 | ||
@@ -1433,7 +1475,7 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev) | |||
1433 | return; | 1475 | return; |
1434 | 1476 | ||
1435 | /* Close and purge all existing sockets */ | 1477 | /* Close and purge all existing sockets */ |
1436 | nfc_llcp_socket_release(local, true); | 1478 | nfc_llcp_socket_release(local, true, 0); |
1437 | } | 1479 | } |
1438 | 1480 | ||
1439 | void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, | 1481 | void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, |
@@ -1519,6 +1561,8 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev) | |||
1519 | return; | 1561 | return; |
1520 | } | 1562 | } |
1521 | 1563 | ||
1564 | local_cleanup(local, false); | ||
1565 | |||
1522 | nfc_llcp_local_put(local); | 1566 | nfc_llcp_local_put(local); |
1523 | } | 1567 | } |
1524 | 1568 | ||
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index 827d7d755d09..f1b377e247fe 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c | |||
@@ -396,6 +396,8 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent, | |||
396 | 396 | ||
397 | pr_debug("Returning sk state %d\n", sk->sk_state); | 397 | pr_debug("Returning sk state %d\n", sk->sk_state); |
398 | 398 | ||
399 | sk_acceptq_removed(parent); | ||
400 | |||
399 | return sk; | 401 | return sk; |
400 | } | 402 | } |
401 | 403 | ||